خدمة "التجوّل الافتراضي"

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

نظرة عامة

اختَر النظام الأساسي: Android iOS JavaScript

وتوفّر ميزة "التجوّل الافتراضي من Google" إطلالات بانورامية بزاوية 360 درجة من الطرق المحدّدة في جميع أنحاء منطقة التغطية. إن تغطية واجهة برمجة التطبيقات لميزة "التجوّل الافتراضي" هي نفسها المستخدمة في تطبيق "خرائط Google" (https://maps.google.com/). تتوفّر قائمة بالمدن المتوافقة حاليًا لميزة "التجوّل الافتراضي" على الموقع الإلكتروني لتطبيق "خرائط Google".

تظهر أدناه صورة نموذجية لميزة "التجوّل الافتراضي".


توفّر واجهة برمجة تطبيقات JavaScript للخرائط خدمة "التجوّل الافتراضي" للحصول على الصور المستخدَمة في ميزة "التجوّل الافتراضي" في "خرائط Google" ومعالجتها. تتوفّر خدمة "التجوّل الافتراضي" هذه بشكل مضمّن في المتصفّح.

استخدام خريطة "التجوّل الافتراضي"

على الرغم من إمكانية استخدام ميزة "التجوّل الافتراضي" ضمن عنصر DOM مستقل، إلا أنّها مفيدة للغاية عند الإشارة إلى موقع جغرافي على الخريطة. يتم تفعيل "التجوّل الافتراضي" تلقائيًا على الخريطة، ويظهر عنصر تحكّم الدليل في "التجوّل الافتراضي" مدمجًا في عناصر التحكم في التكبير/التصغير والتكبير/التصغير. يمكنك إخفاء عنصر التحكّم هذا ضمن الخريطة MapOptions عن طريق ضبط streetViewControl على false. يمكنك أيضًا تغيير الموضع التلقائي للتحكّم في "التجوّل الافتراضي" من خلال ضبط الخاصية Map's streetViewControlOptions.position على خاصية ControlPosition جديدة.

يتيح لك عنصر التحكّم في "التجوّل الافتراضي" إمكانية مشاهدة مناظر بانورامية للتجوّل الافتراضي على الخريطة. عندما ينقر المستخدم مع الاستمرار على الدليل، يتم تعديل الخريطة لعرض مخططات زرقاء حول الشوارع التي تم تفعيل ميزة "التجوّل الافتراضي"، ما يؤدي إلى تقديم تجربة مستخدم مشابهة لتطبيق "خرائط Google".

عندما يسقط المستخدم علامة "الدليل" على أحد الشوارع، يتم تحديث الخريطة لعرض صورة بانورامية على "التجوّل الافتراضي" للموقع الجغرافي المُشار إليه.

بانوراما في "التجوّل الافتراضي"

تتوفّر صور "التجوّل الافتراضي" من خلال استخدام الكائن StreetViewPanorama، والذي يوفّر واجهة واجهة برمجة تطبيقات لميزة "التجوّل الافتراضي" &view;" تحتوي كل خريطة على صورة بانورامية لميزة"التجوّل الافتراضي"، والتي يمكنك استردادها من خلال وصف الطريقة getStreetView() على الخريطة. عند إضافة عنصر تحكّم في "التجوّل الافتراضي" إلى الخريطة من خلال ضبط خيار streetViewControl على true، سيتم تلقائيًا ربط عنصر تحكّم "الدليل" بهذه البانوراما التلقائية في "التجوّل الافتراضي".

يمكنك أيضًا إنشاء كائن StreetViewPanorama وضبط الخريطة لاستخدام ذلك العنصر بدلاً من الإعداد التلقائي، وذلك من خلال ضبط السمة streetView على الخريطة بشكل صريح على ذلك العنصر الذي تم إنشاؤه. يمكنك إلغاء العرض التلقائي التلقائي إذا كنت تريد تعديل السلوك التلقائي، مثل المشاركة التلقائية للتراكبات بين الخريطة والبانوراما. (اطّلِع على التراكبات ضمن "التجوّل الافتراضي" في ما يلي).

حاويات التجوّل الافتراضي

ويمكنك بدلاً من ذلك عرض السمة StreetViewPanorama ضمن عنصر DOM منفصل، وغالبًا ما يكون عنصر <div>. ما عليك سوى تمرير عنصر DOM في أداة إنشاء StreetViewPanorama's. وللحصول على العرض الأمثل للصور، ننصح باستخدام حجم لا يقل عن 200 بكسل × 200 بكسل.

ملاحظة: على الرغم من أن وظيفة "التجوّل الافتراضي" مصمّمة للاستخدام مع خريطة، إلا أن هذا الاستخدام غير مطلوب. يمكنك استخدام عنصر مستقل في "التجوّل الافتراضي" بدون خريطة.

مواقع التجوّل الافتراضي ونقطة المشاهدة (POV)

تتيح لك أداة الإنشاء StreetViewPanorama أيضًا ضبط موقع "التجوّل الافتراضي" ووجهة الرؤية باستخدام المعلمة StreetViewOptions. يمكنك طلب setPosition() وsetPov() على العنصر بعد الإنشاء لتغيير موقعه وموقعه الجغرافي.

يحدّد موقع "التجوّل الافتراضي" موضع تركيز الكاميرا لصورة، ولكنه لا يحدّد اتجاه الكاميرا لهذه الصورة. لهذا الغرض، يحدّد الكائن StreetViewPov خاصيتين:

  • تحدّد السمة heading (التلقائية 0) زاوية التدوير حول موضع الكاميرا بالدرجات مقارنةً بصحيحة الشمال. يتم قياس العناوين في اتجاه عقارب الساعة (90 درجة صحيحة للشرق).
  • تحدّد السمة pitch (التلقائية 0) "الزاوية" و""up;quot; أو &;;quot;down" من العرض التقديمي التلقائي المبدئي للكاميرا والذي يكون غالبًا (ولكن ليس دائمًا) أفقيًا بشكل مسطّح. (على سبيل المثال، ستُظهر الصورة التي تم التقاطها على تل درجة صوت تلقائية غير أفقية.) يتم قياس زوايا العرض التقديمي المخطّط من خلال تقديم قيم موجبة للبحث عنها (تصل إلى +90 درجة بشكل مباشر وعند تعلّمها متعامد مع درجة الصوت التلقائية) والقيم السلبية المتّجهة للأسفل (تصل إلى -90 درجة مباشرةً وإلى قيمة عمودية تلقائية).

غالبًا ما يتم استخدام العنصر StreetViewPov لتحديد وجهة نظر كاميرا"التجوّل الافتراضي". يمكنك أيضًا تحديد وجهة نظر المصوّر، أي الاتجاه الذي تواجهه السيارة أو الدراجة الثلاثية، باستخدام الطريقة StreetViewPanorama.getPhotographerPov().

يعرض الرمز التالي خريطة لمدينة "بوسطن" مع إطلالات أولية على "حديقة فينواي". سيؤدي اختيار الدليل وسحبه إلى موقع متوافق على الخريطة إلى تغيير الصورة البانورامية للتجوّل الافتراضي:

TypeScript

function initialize() {
  const fenway = { lat: 42.345573, lng: -71.098326 };
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: fenway,
      zoom: 14,
    }
  );
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement,
    {
      position: fenway,
      pov: {
        heading: 34,
        pitch: 10,
      },
    }
  );

  map.setStreetView(panorama);
}

declare global {
  interface Window {
    initialize: () => void;
  }
}
window.initialize = initialize;

JavaScript

function initialize() {
  const fenway = { lat: 42.345573, lng: -71.098326 };
  const map = new google.maps.Map(document.getElementById("map"), {
    center: fenway,
    zoom: 14,
  });
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano"),
    {
      position: fenway,
      pov: {
        heading: 34,
        pitch: 10,
      },
    }
  );

  map.setStreetView(panorama);
}

window.initialize = initialize;

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map,
#pano {
  float: left;
  height: 100%;
  width: 50%;
}

HTML

<html>
  <head>
    <title>Street View split-map-panes</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>
    <div id="pano"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initialize&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

تتبُّع الحركة على الأجهزة الجوّالة

على الأجهزة التي تتيح استخدام أحداث اتجاه الجهاز، توفّر واجهة برمجة التطبيقات للمستخدمين إمكانية تغيير "التجوّل الافتراضي" استنادًا إلى حركة الجهاز. ويمكن للمستخدمين الاطّلاع على أجهزتهم من خلال نقل أجهزتهم. ويُعرف هذا الإجراء باسم تتبّع الحركة أو تتبُّع تدوير الجهاز.

بصفتك مطوِّر تطبيقات، يمكنك تغيير السلوك التلقائي كما يلي:

  • تفعيل وظيفة تتبُّع الحركة أو إيقافها. يتم تفعيل ميزة تتبُّع الحركة بشكل تلقائي على أي جهاز متوافق معها. يعمل النموذج التالي على إيقاف تتبُّع الحركة، ولكنه يترك عنصر التحكُّم في تتبُّع الحركة مرئيًا. (يمكن للمستخدم تفعيل ميزة تتبُّع الحركة من خلال النقر على عنصر التحكّم).
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false
        });
    
  • إخفاء عنصر التحكّم في تتبّع الحركة أو إظهاره يظهر عنصر التحكّم تلقائيًا على الأجهزة التي تتوافق مع ميزة تتبُّع الحركة. يمكن للمستخدم النقر على عنصر التحكّم لتفعيل ميزة تتبُّع الحركة أو إيقافها. وتجدر الإشارة إلى أنّ عنصر التحكّم لن يظهر أبدًا إذا كان الجهاز لا يوفّر ميزة تتبُّع الحركة، بغض النظر عن قيمة motionTrackingControl.

    يعمل النموذج التالي على إيقاف كل من تتبُّع الحركة والتحكّم في تتبُّع الحركة. في هذه الحالة، لا يمكن للمستخدم تفعيل تتبُّع الحركة:

    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false,
          motionTrackingControl: false
        });
    
  • غيِّر الموضع التلقائي للتحكّم في تتبُّع الحركة. يظهر عنصر التحكّم تلقائيًا بالقرب من أسفل يسار الصورة البانورامية (الموضع RIGHT_BOTTOM). يحدد النموذج التالي موضع عنصر التحكّم إلى أسفل اليسار:
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTrackingControlOptions: {
            position: google.maps.ControlPosition.LEFT_BOTTOM
          }
        });
    

للاطّلاع على تتبُّع الحركة عمليًا، يمكنك عرض العيّنة التالية على جهاز جوّال (أو أي جهاز يتوافق مع أحداث اتجاه الجهاز):


عرض مثال

العناصر المركّبة في "التجوّل الافتراضي"

يتيح الكائن StreetViewPanorama التلقائي العرض الأصلي لـ تراكبات الخريطة. تظهر العناصر المركّبة بشكل عام على مستوى &الشارع&quot، على مستوى الشوارع&quot، وتكون مثبّتة في LatLng مواضع إعلان. (ستظهر علامات محدّدة ذيل ذي ذراعين على مستوى المستوى الأفقي من الموقع الأفقي في بانوراما "التجوّل الافتراضي" على سبيل المثال).

في الوقت الحالي، تقتصر أنواع التراكبات المتوافقة مع صور "التجوّل الافتراضي" على Marker وInfoWindow وOverlayView مخصّصة. قد يتم عرض العناصر المركّبة التي تعرضها على الخريطة في بانوراما "التجوّل الافتراضي" من خلال التعامل مع البانوراما كبديل لعنصر Map، مع استدعاء setMap() وتمرير StreetViewPanorama كوسيطة بدلاً من خريطة. وبالمثل، قد يتم فتح نوافذ المعلومات بطريقة بانورامية في ميزة "التجوّل الافتراضي" من خلال الاتصال open()، مع تمرير StreetViewPanorama() بدلاً من خريطة.

إضافةً إلى ذلك، عند إنشاء خريطة باستخدام StreetViewPanorama التلقائي، تتم مشاركة أي علامات تم إنشاؤها على الخريطة تلقائيًا مع عرض "التجوّل الافتراضي" المرتبط بالخريطة، بشرط أن تكون البانوراما مرئية. لاسترداد صورة التجوّل الافتراضي التلقائية، يمكنك استدعاء getStreetView() على الكائن Map. ويُرجى العِلم بأنّه في حال ضبط السمة streetView في الخريطة بشكلٍ صريح على StreetViewPanorama من العناصر التي تنشئها، سيتم إلغاء البانوراما التلقائية.

يوضّح المثال التالي علامات تشير إلى مواقع جغرافية مختلفة في محيط "أستور بليس"، مدينة نيويورك. يمكنك تبديل العرض إلى التجوّل الافتراضي لعرض العلامات المشتركة التي يتم عرضها ضمن StreetViewPanorama.

TypeScript

let panorama: google.maps.StreetViewPanorama;

function initMap(): void {
  const astorPlace = { lat: 40.729884, lng: -73.990988 };

  // Set up the map
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: astorPlace,
      zoom: 18,
      streetViewControl: false,
    }
  );

  document
    .getElementById("toggle")!
    .addEventListener("click", toggleStreetView);

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
    title: "Cafe",
  });

  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
    title: "Bank",
  });

  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
    title: "Bus Stop",
  });

  // We get the map's default panorama and set up some defaults.
  // Note that we don't yet set it visible.
  panorama = map.getStreetView()!; // TODO fix type
  panorama.setPosition(astorPlace);
  panorama.setPov(
    /** @type {google.maps.StreetViewPov} */ {
      heading: 265,
      pitch: 0,
    }
  );
}

function toggleStreetView(): void {
  const toggle = panorama.getVisible();

  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let panorama;

function initMap() {
  const astorPlace = { lat: 40.729884, lng: -73.990988 };
  // Set up the map
  const map = new google.maps.Map(document.getElementById("map"), {
    center: astorPlace,
    zoom: 18,
    streetViewControl: false,
  });

  document.getElementById("toggle").addEventListener("click", toggleStreetView);

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
    title: "Cafe",
  });
  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
    title: "Bank",
  });
  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
    title: "Bus Stop",
  });

  // We get the map's default panorama and set up some defaults.
  // Note that we don't yet set it visible.
  panorama = map.getStreetView(); // TODO fix type
  panorama.setPosition(astorPlace);
  panorama.setPov(
    /** @type {google.maps.StreetViewPov} */ {
      heading: 265,
      pitch: 0,
    }
  );
}

function toggleStreetView() {
  const toggle = panorama.getVisible();

  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: "Roboto", "sans-serif";
  line-height: 30px;
  padding-left: 10px;
}

#floating-panel {
  margin-left: -100px;
}

HTML

<html>
  <head>
    <title>Overlays Within Street View</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="floating-panel">
      <input type="button" value="Toggle Street View" id="toggle" />
    </div>
    <div id="map"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

أحداث "التجوّل الافتراضي"

عند التنقّل بين "التجوّل الافتراضي" أو التلاعب بالاتجاه الخاص به، قد تريد مراقبة العديد من الأحداث التي تشير إلى تغييرات في حالة StreetViewPanorama:

  • يتم تنشيط pano_changed عند تغيير رقم تعريف pano الفردي. لا يضمن هذا الحدث أيضًا تغيير أي بيانات مرتبطة داخل البانوراما (مثل الروابط) بحلول وقت تشغيل هذه الفعالية، لأنّ هذا الحدث يشير فقط إلى تغيير معرّف البانو. تجدر الإشارة إلى أنّ معرّف البانو (الذي يمكنك استخدامه للإشارة إلى هذه البانوراما) هو ثابت فقط خلال جلسة المتصفّح الحالية.
  • يتم تنشيط position_changed عندما يتغير الموضع الأساسي (LatLng) للبانوراما. لن يؤدي تدوير بانوراما إلى تشغيل هذا الحدث. وتجدر الإشارة إلى أنّه يمكنك تغيير الموضع الأساسي للصورة البانورامية بدون تغيير رقم تعريف البانو المرتبط، لأنّ واجهة برمجة التطبيقات ستربط تلقائيًا أقرب رقم تعريف للبانو بالوضع الشامل للصورة البانورامية.
  • يتم تنشيط pov_changed كلما تغير StreetViewPov في "التجوّل الافتراضي". ويُرجى العِلم بأنّ هذا الحدث قد يتم تنشيطه مع الحفاظ على الموضع ورقم تعريف البانو.
  • يتم تنشيط links_changed عند تغيير روابط"التجوّل الافتراضي". يُرجى العِلم أنّ هذا الحدث قد يتم تنشيطه بشكل غير متزامن بعد تغيير في رقم تعريف pano الذي تتم الإشارة إليه من خلال pano_changed.
  • يتم تنشيط visible_changed كلما تغير مستوى رؤية"التجوّل الافتراضي". يُرجى العِلم أنّ هذا الحدث قد يتم تنشيطه بشكل غير متزامن بعد تغيير في رقم تعريف pano الذي تتم الإشارة إليه من خلال pano_changed.

يوضّح الرمز التالي كيفية معالجة هذه الأحداث لجمع بيانات عن السمة StreetViewPanorama الأساسية:

TypeScript

function initPano() {
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement,
    {
      position: { lat: 37.869, lng: -122.255 },
      pov: {
        heading: 270,
        pitch: 0,
      },
      visible: true,
    }
  );

  panorama.addListener("pano_changed", () => {
    const panoCell = document.getElementById("pano-cell") as HTMLElement;

    panoCell.innerHTML = panorama.getPano();
  });

  panorama.addListener("links_changed", () => {
    const linksTable = document.getElementById("links_table") as HTMLElement;

    while (linksTable.hasChildNodes()) {
      linksTable.removeChild(linksTable.lastChild as ChildNode);
    }

    const links = panorama.getLinks();

    for (const i in links) {
      const row = document.createElement("tr");

      linksTable.appendChild(row);

      const labelCell = document.createElement("td");

      labelCell.innerHTML = "<b>Link: " + i + "</b>";

      const valueCell = document.createElement("td");

      valueCell.innerHTML = links[i].description as string;
      linksTable.appendChild(labelCell);
      linksTable.appendChild(valueCell);
    }
  });

  panorama.addListener("position_changed", () => {
    const positionCell = document.getElementById(
      "position-cell"
    ) as HTMLElement;

    (positionCell.firstChild as HTMLElement).nodeValue =
      panorama.getPosition() + "";
  });

  panorama.addListener("pov_changed", () => {
    const headingCell = document.getElementById("heading-cell") as HTMLElement;
    const pitchCell = document.getElementById("pitch-cell") as HTMLElement;

    (headingCell.firstChild as HTMLElement).nodeValue =
      panorama.getPov().heading + "";
    (pitchCell.firstChild as HTMLElement).nodeValue =
      panorama.getPov().pitch + "";
  });
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano"),
    {
      position: { lat: 37.869, lng: -122.255 },
      pov: {
        heading: 270,
        pitch: 0,
      },
      visible: true,
    }
  );

  panorama.addListener("pano_changed", () => {
    const panoCell = document.getElementById("pano-cell");

    panoCell.innerHTML = panorama.getPano();
  });
  panorama.addListener("links_changed", () => {
    const linksTable = document.getElementById("links_table");

    while (linksTable.hasChildNodes()) {
      linksTable.removeChild(linksTable.lastChild);
    }

    const links = panorama.getLinks();

    for (const i in links) {
      const row = document.createElement("tr");

      linksTable.appendChild(row);

      const labelCell = document.createElement("td");

      labelCell.innerHTML = "<b>Link: " + i + "</b>";

      const valueCell = document.createElement("td");

      valueCell.innerHTML = links[i].description;
      linksTable.appendChild(labelCell);
      linksTable.appendChild(valueCell);
    }
  });
  panorama.addListener("position_changed", () => {
    const positionCell = document.getElementById("position-cell");

    positionCell.firstChild.nodeValue = panorama.getPosition() + "";
  });
  panorama.addListener("pov_changed", () => {
    const headingCell = document.getElementById("heading-cell");
    const pitchCell = document.getElementById("pitch-cell");

    headingCell.firstChild.nodeValue = panorama.getPov().heading + "";
    pitchCell.firstChild.nodeValue = panorama.getPov().pitch + "";
  });
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: "Roboto", "sans-serif";
  line-height: 30px;
  padding-left: 10px;
}

#pano {
  width: 50%;
  height: 100%;
  float: left;
}

#floating-panel {
  width: 45%;
  height: 100%;
  float: right;
  text-align: left;
  overflow: auto;
  position: static;
  border: 0px solid #999;
}

HTML

<html>
  <head>
    <title>Street View Events</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="pano"></div>
    <div id="floating-panel">
      <table>
        <tr>
          <td><b>Position</b></td>
          <td id="position-cell">&nbsp;</td>
        </tr>
        <tr>
          <td><b>POV Heading</b></td>
          <td id="heading-cell">270</td>
        </tr>
        <tr>
          <td><b>POV Pitch</b></td>
          <td id="pitch-cell">0.0</td>
        </tr>
        <tr>
          <td><b>Pano ID</b></td>
          <td id="pano-cell">&nbsp;</td>
        </tr>
        <table id="links_table"></table>
      </table>
    </div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

عناصر التحكم في "التجوّل الافتراضي"

عند عرض StreetViewPanorama، تظهر مجموعة متنوعة من عناصر التحكّم في البانوراما بشكل تلقائي. يمكنك تفعيل عناصر التحكّم هذه أو إيقافها من خلال ضبط الحقول المناسبة لها ضمن السمة StreetViewPanoramaOptions على السمة true أو false:

  • ويوفّر panControl طريقة لتدوير البانوراما. يظهر عنصر التحكّم هذا تلقائيًا كبوصلة مدمجة عادية والتحكم في العرض الشامل. يمكنك تغيير موضع التحكّم من خلال تقديم السمة PanControlOptions ضمن الحقل panControlOptions.
  • تقدّم zoomControl طريقة لتكبير الصورة. يظهر عنصر التحكّم هذا تلقائيًا بالقرب من أسفل يسار الصورة البانورامية. يمكنك تغيير مظهر عنصر التحكّم من خلال تقديم السمة ZoomControlOptions ضمن الحقل zoomControlOptions.
  • تقدّم السمة addressControl تراكبًا نصيًا يشير إلى عنوان الموقع الجغرافي المرتبط، ويوفّر رابطًا لفتح الموقع الجغرافي في "خرائط Google". يمكنك تغيير مظهر عنصر التحكّم من خلال تقديم السمة StreetViewAddressControlOptions ضمن الحقل addressControlOptions.
  • يوفّر fullscreenControl خيار فتح"التجوّل الافتراضي"في وضع ملء الشاشة. يمكنك تغيير مظهر عنصر التحكّم من خلال تقديم السمة FullscreenControlOptions ضمن الحقل fullscreenControlOptions.
  • توفّر motionTrackingControl خيار تفعيل ميزة تتبُّع الحركة أو إيقافها على الأجهزة الجوّالة. لا يظهر عنصر التحكّم هذا إلا على الأجهزة التي تتوافق مع أحداث اتجاه الجهاز. يظهر عنصر التحكّم تلقائيًا بالقرب من أسفل يسار الصورة البانورامية. يمكنك تغيير موضع التحكّم عن طريق تقديم القيمة MotionTrackingControlOptions. للمزيد من المعلومات، اطّلِع على القسم الذي يتناول تتبُّع الحركة.
  • توفّر علامة linksControl أسهمًا إرشادية حول الصورة للسفر إلى الصور البانورامية المجاورة.
  • يسمح عنصر التحكم في الإغلاق للمستخدم بإغلاق عارض "التجوّل الافتراضي". يمكنك تفعيل عنصر التحكّم في الإغلاق أو إيقافه من خلال ضبط enableCloseButton على true أو false.

يغيّر المثال التالي عناصر التحكم المعروضة في ميزة "التجوّل الافتراضي" المرتبطة ويزيل روابط الملف الشخصي:

TypeScript

function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map") as HTMLElement,
    {
      position: { lat: 42.345573, lng: -71.098326 },
      addressControlOptions: {
        position: google.maps.ControlPosition.BOTTOM_CENTER,
      },
      linksControl: false,
      panControl: false,
      enableCloseButton: false,
    }
  );
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map"),
    {
      position: { lat: 42.345573, lng: -71.098326 },
      addressControlOptions: {
        position: google.maps.ControlPosition.BOTTOM_CENTER,
      },
      linksControl: false,
      panControl: false,
      enableCloseButton: false,
    }
  );
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Street View Controls</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

الوصول إلى بيانات "التجوّل الافتراضي" مباشرةً

وقد ترغب في تحديد مدى توفُّر بيانات "التجوّل الافتراضي" آليًا، أو عرض معلومات عن صور بانورامية معيّنة، بدون الحاجة إلى معالجة مباشرة للخريطة/البانوراما. ويمكنك إجراء ذلك باستخدام الكائن StreetViewService، والذي يوفّر واجهة للبيانات المخزّنة في خدمة "التجوّل الافتراضي" من Google.

طلبات خدمة "التجوّل الافتراضي"

الوصول إلى خدمة "التجوّل الافتراضي" غير متزامن، لأنّ Google Maps API تحتاج إلى إجراء طلب إلى خادم خارجي. ولهذا السبب، عليك تمرير طريقة معاودة الاتصال للتنفيذ بعد اكتمال الطلب. تعالج طريقة معاودة الاتصال هذه النتيجة.

يمكنك بدء طلبات StreetViewService باستخدام StreetViewPanoRequest أو StreetViewLocationRequest.

يعرض الطلب الذي يستخدم StreetViewPanoRequest بيانات البانوراما التي يتم منحها معرّف مرجعي يحدّد البانوراما بشكل فريد. تجدُر الإشارة إلى أنّ أرقام التعريف المرجعية هذه ثابتة فقط طوال فترة عرض هذه البانوراما.

يطلب البحث باستخدام StreetViewLocationRequest بيانات البانوراما في موقع جغرافي محدّد باستخدام المعلّمات التالية:

  • تحدّد السمة location الموقع الجغرافي (خط العرض وخط الطول) للبحث عن صورة بانورامية.
  • ضبط preference الإعدادات المفضّلة التي يجب العثور على البانوراما ضمن النطاق الجغرافي: الأقرب إلى الموقع الجغرافي المقدَّم، أو الأقرب إلى النطاق الجغرافي.
  • يحدد radius نطاقًا جغرافيًا، يتم تحديده بالمتر، للبحث فيه عن صورة بانورامية، ويتمركز حول خط الطول وخط العرض. ويتم إعداد القيمة على 50 تلقائيًا في حال عدم توفيرها.
  • تُحدِّد source مصدر الصور البانورامية المطلوب البحث فيها. القيم الصالحة هي:
    • يستخدم default المصادر التلقائية لميزة"التجوّل الافتراضي"، ولا تقتصر عمليات البحث على مصادر محدّدة.
    • outdoor يقتصر على عمليات البحث التي يتم إجراؤها في المجموعات الخارجية. يُرجى ملاحظة أنه قد لا تتوفّر صور بانورامية في الهواء الطلق للموقع الجغرافي المحدّد.

الردود على خدمة "التجوّل الافتراضي"

تحتاج الدالة getPanorama() إلى دالة callback لتنفيذها عند استرداد نتيجة من خدمة "التجوّل الافتراضي". تعرض دالة رد الاتصال هذه مجموعة من بيانات البانوراما ضمن عنصر StreetViewPanoramaData ورمز StreetViewStatus الذي يشير إلى حالة الطلب، بهذا الترتيب.

تحتوي مواصفات عنصر StreetViewPanoramaData على بيانات وصفية حول صورة بانورامية للتجوّل الافتراضي على النحو التالي:

{
  "location": {
    "latLng": LatLng,
    "description": string,
    "pano": string
  },
  "copyright": string,
  "links": [{
      "heading": number,
      "description": string,
      "pano": string,
      "roadColor": string,
      "roadOpacity": number
    }],
  "tiles": {
    "worldSize": Size,
    "tileSize": Size,
    "centerHeading": number
  }
}

يُرجى العِلم بأنّ كائن البيانات هذا ليس كائن StreetViewPanorama نفسه. لإنشاء كائن في "التجوّل الافتراضي" باستخدام هذه البيانات، عليك إنشاء StreetViewPanorama والاستدعاء setPano()، مع تمرير رقم التعريف كما هو موضّح في الحقل location.pano المعروض.

قد يعرض الرمز status إحدى القيم التالية:

  • يشير OK إلى أنّ الخدمة عثرت على صورة بانورامية مطابقة.
  • يشير ZERO_RESULTS إلى أنّ الخدمة لم تتمكّن من العثور على صورة بانورامية مطابقة للمعايير التي تم اجتيازها.
  • تشير UNKNOWN_ERROR إلى تعذّرت معالجة طلب "التجوّل الافتراضي"، ولكن السبب غير معروف بالتحديد.

ينشئ الرمز التالي StreetViewService التي تستجيب لنقرات المستخدمين على الخريطة من خلال إنشاء محدّدات المواقع، وعند النقر عليها، سيتم عرض StreetViewPanorama لهذا الموقع الجغرافي. يستخدم الرمز محتوى StreetViewPanoramaData المعروض من الخدمة.

TypeScript

/*
 * Click the map to set a new location for the Street View camera.
 */

let map: google.maps.Map;

let panorama: google.maps.StreetViewPanorama;

function initMap(): void {
  const berkeley = { lat: 37.869085, lng: -122.254775 };
  const sv = new google.maps.StreetViewService();

  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement
  );

  // Set up the map.
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    center: berkeley,
    zoom: 16,
    streetViewControl: false,
  });

  // Set the initial Street View camera to the center of the map
  sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData);

  // Look for a nearby Street View panorama when the map is clicked.
  // getPanorama will return the nearest pano when the given
  // radius is 50 meters or less.
  map.addListener("click", (event) => {
    sv.getPanorama({ location: event.latLng, radius: 50 })
      .then(processSVData)
      .catch((e) =>
        console.error("Street View data not found for this location.")
      );
  });
}

function processSVData({ data }: google.maps.StreetViewResponse) {
  const location = data.location!;

  const marker = new google.maps.Marker({
    position: location.latLng,
    map,
    title: location.description,
  });

  panorama.setPano(location.pano as string);
  panorama.setPov({
    heading: 270,
    pitch: 0,
  });
  panorama.setVisible(true);

  marker.addListener("click", () => {
    const markerPanoID = location.pano;

    // Set the Pano to use the passed panoID.
    panorama.setPano(markerPanoID as string);
    panorama.setPov({
      heading: 270,
      pitch: 0,
    });
    panorama.setVisible(true);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * Click the map to set a new location for the Street View camera.
 */
let map;
let panorama;

function initMap() {
  const berkeley = { lat: 37.869085, lng: -122.254775 };
  const sv = new google.maps.StreetViewService();

  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano")
  );
  // Set up the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: berkeley,
    zoom: 16,
    streetViewControl: false,
  });
  // Set the initial Street View camera to the center of the map
  sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData);
  // Look for a nearby Street View panorama when the map is clicked.
  // getPanorama will return the nearest pano when the given
  // radius is 50 meters or less.
  map.addListener("click", (event) => {
    sv.getPanorama({ location: event.latLng, radius: 50 })
      .then(processSVData)
      .catch((e) =>
        console.error("Street View data not found for this location.")
      );
  });
}

function processSVData({ data }) {
  const location = data.location;
  const marker = new google.maps.Marker({
    position: location.latLng,
    map,
    title: location.description,
  });

  panorama.setPano(location.pano);
  panorama.setPov({
    heading: 270,
    pitch: 0,
  });
  panorama.setVisible(true);
  marker.addListener("click", () => {
    const markerPanoID = location.pano;

    // Set the Pano to use the passed panoID.
    panorama.setPano(markerPanoID);
    panorama.setPov({
      heading: 270,
      pitch: 0,
    });
    panorama.setVisible(true);
  });
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Directly Accessing Street View Data</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map" style="width: 45%; height: 100%; float: left"></div>
    <div id="pano" style="width: 45%; height: 100%; float: left"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

تقديم صور بانورامية مخصصة للتجوّل الافتراضي

تتيح واجهة برمجة تطبيقات JavaScript للخرائط عرض الصور البانورامية المخصّصة ضمن الكائن StreetViewPanorama. باستخدام مناظر بانورامية مخصّصة، يمكنك عرض التصميم الداخلي للمباني أو الإطلالات على المواقع الخلابة أو أي شيء من مخيّلتك. ويمكنك أيضًا ربط هذه الصور البانورامية المخصّصة بصور "التجوّل الافتراضي" الحالية المتوفّرة من Google.

يتضمن إعداد مجموعة من صور البانوراما المخصّصة الخطوات التالية:

  • أنشئ صورة بانورامية أساسية لكل صورة بانورامية مخصصة. ويجب أن تكون هذه الصورة الأساسية بأعلى صورة دقة تريد استخدامها في تكبير الصور.
  • (اختياري، ولكن ننصح به) يمكنك إنشاء مجموعة من المربّعات البانورامية على مستويات تكبير/تصغير مختلفة عن الصورة الأساسية.
  • إنشاء روابط بين صورك البانورامية المخصّصة.
  • (اختياري) يمكنك ضبط الصور البانورامية "&;;"والعرض الشامل ضمن صور "التجوّل الافتراضي" الحالية في Google وتخصّص الروابط من/إلى المجموعة المخصّصة إلى المجموعة العادية.
  • حدِّد البيانات الوصفية لكل صورة بانورامية داخل كائن StreetViewPanoramaData.
  • استخدِم طريقة تحدّد بيانات البانوراما المخصّصة والصور وحدِّد هذه الطريقة على أنها المعالج المخصّص ضمن الكائن StreetViewPanorama.

توضّح الأقسام التالية هذه العملية.

إنشاء بانوراما مخصّصة

كل بانوراما في "التجوّل الافتراضي" هي صورة أو مجموعة من الصور التي تقدّم عرضًا كاملاً بزاوية 360 درجة من موقع جغرافي واحد. يستخدم الكائن StreetViewPanorama صورًا تتوافق مع إسقاط (Pate Carrée) المستطيل المكافئ. يتضمّن هذا الإسقاط عرضًا أفقيًا بزاوية 360 درجة (ملفوفًا بالكامل) و180 درجة للعرض العمودي (من خط مستقيم إلى أسفل). وتؤدي حقول العرض هذه إلى صورة بنسبة عرض إلى ارتفاع 2:1. تظهر الصورة البانورامية الكاملة للالتفاف حولها أدناه.

ويتم عادةً الحصول على صور بانوراما من خلال التقاط عدة صور من موضع واحد ودمجها معًا باستخدام برنامج بانوراما. (يمكنك الاطّلاع على "ويكيبيديا" مقارنة تطبيقات تركيب الصور للحصول على مزيد من المعلومات). يجب أن تشارك هذه الصور موضعًا واحدًا "الكاميرا" ويمكن عندئذٍ للصورة البانورامية الناتجة بزاوية 360 درجة تعريف إسقاط على كرة محيطة مع التفاف الصورة إلى السطح الثنائي الأبعاد للكرة الأرضية.

يُعتبر التعامل مع البانوراما على شكل إسقاط على كرة مستطيلة باستخدام نظام إحداثيات مستطيل.

إنشاء مربعات بانوراما مخصّصة

وتتوافق ميزة "التجوّل الافتراضي" أيضًا مع مستويات مختلفة من تفاصيل الصورة من خلال استخدام عنصر تحكم في التكبير/التصغير، ما يتيح لك التكبير والتصغير من طريقة العرض التلقائية. بشكل عام، توفّر ميزة "التجوّل الافتراضي" خمسة مستويات لدقة التكبير/التصغير لأي صورة بانورامية معيّنة. إذا كنت تريد الاعتماد على صورة بانوراما واحدة لعرض كل مستويات التكبير أو التصغير، قد تكون هذه الصورة كبيرة جدًا وبطيئة جدًا في تطبيقك، أو ستكون منخفضة الدقة على مستوى تكبير/تصغير ليتم عرض صورة متقطّعة للغاية. ولحسن الحظ، يمكننا استخدام نمط تصميم مشابه يُستخدم لعرض مربعات خرائط Google على مستويات تكبير/تصغير مختلفة لتوفير صور الدقة المناسبة للصور البانورامية على كل مستوى من مستويات التكبير أو التصغير.

عندما يتم تحميل StreetViewPanorama للمرة الأولى، يتم تلقائيًا عرض صورة تتكون من 25% (90 درجة من القوس) للعرض الأفقي للبانوراما مع مستوى التكبير/التصغير 1. وتتوافق طريقة العرض هذه تقريبًا مع مجال رؤية عادي. يؤدي التكبير/التصغير&;;;;;; من طريقة العرض التلقائية هذه إلى توفير قوس عريض، بينما يؤدي التكبير إلى تضييق نطاق زاوية الرؤية إلى قوس أصغر. ويحسب StreetViewPanorama تلقائيًا حقل العرض المناسب لمستوى التكبير أو التصغير المحدد، ثم يختار الصور الأكثر ملاءمة لدرجة الدقة هذه عن طريق اختيار مجموعة مربعات تطابق أبعاد مجال الرؤية الأفقي تقريبًا. يتم ربط حقول طريقة العرض التالية بمستويات التكبير أو التصغير في "التجوّل الافتراضي":

مستوى التكبير أو التصغير لميزة "التجوّل الافتراضي" مجال الرؤية (بالدرجات)
0 180
1 (افتراضي) 90
2 45
3 22.5
4 11

لاحظ أن حجم الصورة المعروضة في "التجوّل الافتراضي" يعتمد بالكامل على حجم الشاشة (عرض) حاوية حاوية "التجوّل الافتراضي". في حال توفير حاوية أوسع، ستظل الخدمة تقدّم مجال الرؤية نفسه لأي مستوى تكبير/تصغير معيّن، على الرغم من أنها قد تختار أقسامًا أكثر ملاءمةً لهذه الدقة بدلاً من ذلك.

بما أنّ كل بانوراما تتكوّن من إسقاط متماثل الأبعاد، يمكنك إنشاء مربّعات بانورامية بسهولة نسبيًا. بما أنّ الإسقاط يقدّم صورة بنسبة عرض إلى ارتفاع 2:1، يصبح استخدام الشاشات التي تبلغ نسبتها 2:1 أكثر سهولة، على الرغم من أنّ المربّعات المربّعة قد توفّر أداءً أفضل في الخرائط المربّعة (لأنّ حقل الرؤية سيكون مربّعًا).

بالنسبة إلى مربّعات العرض بنسبة عرض إلى ارتفاع 2:1، تمثّل الصورة الواحدة التي تشمل البانوراما الكاملة البانوراما الكاملة "world" (الصورة الأساسية) على مستوى التكبير/التصغير 0، مع زيادة كل مستوى تكبير/تصغير يشمل 4zoomLevel. (على سبيل المثال، في مستوى التكبير/التصغير 2، تتألف البانوراما الكاملة من 16 جزءًا.) ملاحظة: لا تتطابق مستويات التكبير أو التصغير في ميزة "التجوّل الافتراضي" مباشرةً مع مستويات التكبير أو التصغير كما هو متوفر باستخدام عنصر التحكّم في "التجوّل الافتراضي". وبدلاً من ذلك، تحدد مستويات التكبير أو التصغير في "التجوّل الافتراضي" حقل "عرض" (VV) يتم اختيار المربّعات المناسبة له.

وبوجه عام، من المفيد تسمية أقسام الصور لكي يتم اختيارها آليًا. وتتم مناقشة نظام التسمية هذا أدناه في التعامل مع طلبات البانوراما المخصّصة.

معالجة طلبات البانوراما المخصّصة

لاستخدام صورة بانورامية مخصّصة، عليك طلب StreetViewPanorama.registerPanoProvider()، مع تحديد اسم طريقة موفّر البانوراما المخصّصة. يجب أن تعرض طريقة موفّر البانوراما عنصر StreetViewPanoramaData، ويحتوي على التوقيع التالي:

Function(pano):StreetViewPanoramaData

تمثّل السمة StreetViewPanoramaData العنصر التالي:

{
  copyright: string,
  location: {
    description: string,
    latLng: google.maps.LatLng,
    pano: string
  },
  tiles: {
    tileSize: google.maps.Size,
    worldSize: google.maps.Size,
    heading: number,
    getTileUrl: Function
  },
  links: [
    description: string,
    heading: number,
    pano: string,
    roadColor: string,
    roadOpacity: number
  ]
}

عرض صورة بانورامية مخصصة على النحو التالي:

  • ضبط السمة StreetViewPanoramaOptions.pano على قيمة مخصّصة
  • يمكنك الاتصال StreetViewPanorama.registerPanoProvider() لتوفير دالة مخصّصة بانورامية.
  • استخدِم دالة موفّر البانوراما المخصّصة للتعامل مع قيمة pano المحدّدة.
  • أنشِئ عنصر StreetViewPanoramaData.
  • اضبط السمة StreetViewTileData.getTileUrl على اسم دالة موفّر المربّع المخصّص الذي تقدّمه. مثلاً: getCustomPanoramaTileUrl.
  • نفِّذ وظيفة موفّر جزء الشاشة المخصّصة، كما هو موضّح في النماذج أدناه.
  • اعرض العنصر StreetViewPanoramaData.

ملاحظة: لا تضبط مباشرةً السمة position على StreetViewPanorama عندما تريد عرض صور بانورامية مخصّصة، لأنّ هذا الموضع سيوجّه خدمة "التجوّل الافتراضي" بطلب صور "التجوّل الافتراضي" التلقائية القريبة من ذلك الموقع الجغرافي. يمكنك بدلاً من ذلك ضبط هذا الموضع ضمن الحقل المخصّص StreetViewPanoramaData الكائن location.latLng المخصّص.

يوضّح المثال التالي صورة بانورامية مخصّصة لمكتب Google في سيدني. لاحظ أن هذا المثال لا يستخدم خريطة أو صور "التجوّل الافتراضي" التلقائية:

TypeScript

function initPano() {
  // Set up Street View and initially set it visible. Register the
  // custom panorama provider function. Set the StreetView to display
  // the custom panorama 'reception' which we check for below.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map") as HTMLElement,
    { pano: "reception", visible: true }
  );

  panorama.registerPanoProvider(getCustomPanorama);
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(
  pano: string,
  zoom: number,
  tileX: number,
  tileY: number
): string {
  return (
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
    "panoReception1024-" +
    zoom +
    "-" +
    tileX +
    "-" +
    tileY +
    ".jpg"
  );
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano: string): google.maps.StreetViewPanoramaData {
  if (pano === "reception") {
    return {
      location: {
        pano: "reception",
        description: "Google Sydney - Reception",
      },
      links: [],
      // The text for the copyright control.
      copyright: "Imagery (c) 2010 Google",
      // The definition of the tiles for this panorama.
      tiles: {
        tileSize: new google.maps.Size(1024, 512),
        worldSize: new google.maps.Size(2048, 1024),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl,
      },
    };
  }
  // @ts-ignore TODO fix typings
  return null;
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  // Set up Street View and initially set it visible. Register the
  // custom panorama provider function. Set the StreetView to display
  // the custom panorama 'reception' which we check for below.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map"),
    { pano: "reception", visible: true }
  );

  panorama.registerPanoProvider(getCustomPanorama);
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
  return (
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
    "panoReception1024-" +
    zoom +
    "-" +
    tileX +
    "-" +
    tileY +
    ".jpg"
  );
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano) {
  if (pano === "reception") {
    return {
      location: {
        pano: "reception",
        description: "Google Sydney - Reception",
      },
      links: [],
      // The text for the copyright control.
      copyright: "Imagery (c) 2010 Google",
      // The definition of the tiles for this panorama.
      tiles: {
        tileSize: new google.maps.Size(1024, 512),
        worldSize: new google.maps.Size(2048, 1024),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl,
      },
    };
  }
  // @ts-ignore TODO fix typings
  return null;
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Custom Street View Panoramas</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة

يعرض موفّر البانوراما المخصّص المربّع المناسب استنادًا إلى رقم تعريف البانوراما الذي تم تمريره، ومستوى التكبير/التصغير، وإحداثيات مربعات بانوراما. بما أنّ اختيار الصور يعتمد على هذه القيم التي تم تمريرها، من المفيد تسمية الصور التي يمكن اختيارها آليًا استنادًا إلى هذه القيم التي تم تمريرها، مثل pano_zoom_tileX_tileY.png.

يضيف المثال التالي سهمًا آخر إلى الصورة، بالإضافة إلى أسهم التنقّل الافتراضي في "التجوّل الافتراضي"، التي تشير إلى Google مدينة سيدني وتربطها بالصور المخصصة:

TypeScript

let panorama: google.maps.StreetViewPanorama;

// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
let outsideGoogle: google.maps.StreetViewPanoramaData;

// StreetViewPanoramaData for a custom panorama: the Google Sydney reception.
function getReceptionPanoramaData(): google.maps.StreetViewPanoramaData {
  return {
    location: {
      pano: "reception", // The ID for this custom panorama.
      description: "Google Sydney - Reception",
      latLng: new google.maps.LatLng(-33.86684, 151.19583),
    },
    links: [
      {
        heading: 195,
        description: "Exit",
        pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano,
      },
    ],
    copyright: "Imagery (c) 2010 Google",
    tiles: {
      tileSize: new google.maps.Size(1024, 512),
      worldSize: new google.maps.Size(2048, 1024),
      centerHeading: 105,
      getTileUrl: function (
        pano: string,
        zoom: number,
        tileX: number,
        tileY: number
      ): string {
        return (
          "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
          "panoReception1024-" +
          zoom +
          "-" +
          tileX +
          "-" +
          tileY +
          ".jpg"
        );
      },
    },
  };
}

function initPanorama() {
  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("street-view") as HTMLElement,
    { pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano }
  );
  // Register a provider for the custom panorama.
  panorama.registerPanoProvider(
    (pano: string): google.maps.StreetViewPanoramaData => {
      if (pano === "reception") {
        return getReceptionPanoramaData();
      }
      // @ts-ignore TODO fix typings
      return null;
    }
  );

  // Add a link to our custom panorama from outside the Google Sydney office.
  panorama.addListener("links_changed", () => {
    if (
      panorama.getPano() ===
      (outsideGoogle.location as google.maps.StreetViewLocation).pano
    ) {
      panorama.getLinks().push({
        description: "Google Sydney",
        heading: 25,
        pano: "reception",
      });
    }
  });
}

function initMap(): void {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  new google.maps.StreetViewService()
    .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } })
    .then(({ data }: google.maps.StreetViewResponse) => {
      outsideGoogle = data;
      initPanorama();
    });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let panorama;
// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
let outsideGoogle;

// StreetViewPanoramaData for a custom panorama: the Google Sydney reception.
function getReceptionPanoramaData() {
  return {
    location: {
      pano: "reception",
      description: "Google Sydney - Reception",
      latLng: new google.maps.LatLng(-33.86684, 151.19583),
    },
    links: [
      {
        heading: 195,
        description: "Exit",
        pano: outsideGoogle.location.pano,
      },
    ],
    copyright: "Imagery (c) 2010 Google",
    tiles: {
      tileSize: new google.maps.Size(1024, 512),
      worldSize: new google.maps.Size(2048, 1024),
      centerHeading: 105,
      getTileUrl: function (pano, zoom, tileX, tileY) {
        return (
          "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
          "panoReception1024-" +
          zoom +
          "-" +
          tileX +
          "-" +
          tileY +
          ".jpg"
        );
      },
    },
  };
}

function initPanorama() {
  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("street-view"),
    { pano: outsideGoogle.location.pano }
  );
  // Register a provider for the custom panorama.
  panorama.registerPanoProvider((pano) => {
    if (pano === "reception") {
      return getReceptionPanoramaData();
    }
    // @ts-ignore TODO fix typings
    return null;
  });
  // Add a link to our custom panorama from outside the Google Sydney office.
  panorama.addListener("links_changed", () => {
    if (panorama.getPano() === outsideGoogle.location.pano) {
      panorama.getLinks().push({
        description: "Google Sydney",
        heading: 25,
        pano: "reception",
      });
    }
  });
}

function initMap() {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  new google.maps.StreetViewService()
    .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } })
    .then(({ data }) => {
      outsideGoogle = data;
      initPanorama();
    });
}

window.initMap = initMap;

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#street-view {
  height: 100%;
}

HTML

<html>
  <head>
    <title>Custom Street View Panorama Tiles</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="street-view"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

جرّب عيّنة