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

نظرة عامة

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

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

في ما يلي نموذج لصورة "التجوّل الافتراضي".


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

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

وعلى الرغم من أنه يمكن استخدام ميزة "التجوّل الافتراضي" عنصر DOM المستقل، فهو الأكثر مفيدة عند الإشارة إلى موقع ما على الخريطة. بشكلٍ افتراضي، تكون ميزة "التجوّل الافتراضي" مفعّلة على الخريطة، وستظهر عنصر تحكم الدليل في التجوّل الافتراضي مدمجة في عناصر تحكم التنقل (التكبير/التصغير والتحريك). يمكنك إخفاء هذا المحتوى. التحكم داخل MapOptions على الخريطة من خلال إعداد من streetViewControl إلى false. يمكنك أيضًا تغيير الموضع الافتراضي لعنصر التحكم في التجوّل الافتراضي من خلال يَتِمُّ الْآنْ ضَبْطُ streetViewControlOptions.position فِي Map. إلى ControlPosition جديد.

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

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

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

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

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

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

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

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

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

كما تسمح لك الدالة الإنشائية StreetViewPanorama بما يلي: تعيين موقع ووجهة نظر "التجوّل الافتراضي" باستخدام مَعلمة StreetViewOptions. يمكنك استدعاء setPosition() وsetPov() على الكائن بعد البناء لتغيير موقعه ووجهة نظره.

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

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

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

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

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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <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 التلقائي مع العناصر الأصلية. عرض الخريطة التراكبات. تظهر التراكبات بشكل عام على "مستوى الشارع" ثابت في 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);

  const cafeIcon = document.createElement("img");
  cafeIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/cafe_icon.svg";

  const dollarIcon = document.createElement("img");
  dollarIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/bank_icon.svg";

  const busIcon = document.createElement("img");
  busIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/bus_icon.svg";


  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    title: "Cafe",
    icon: cafeIcon.src,
  });

  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    title: "Bank",
    icon: dollarIcon.src,
  });

  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    title: "Bus Stop",
    icon: busIcon.src,
  });

  // 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);

  const cafeIcon = document.createElement("img");

  cafeIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/cafe_icon.svg";

  const dollarIcon = document.createElement("img");

  dollarIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/bank_icon.svg";

  const busIcon = document.createElement("img");

  busIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/bus_icon.svg";

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    title: "Cafe",
    icon: cafeIcon.src,
  });
  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    title: "Bank",
    icon: dollarIcon.src,
  });
  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    title: "Bus Stop",
    icon: busIcon.src,
  });

  // 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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=weekly"
      defer
    ></script>
  </body>
</html>
الاطّلاع على مثال

تجربة "عيّنة"

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

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

  • يتم إطلاق pano_changed عند التقاط الصورة البانورامية الفردية. التغييرات في المعرّفات لا يضمن هذا الحدث أن تكون أي بيانات مرتبطة به ضمن تم تغيير البانوراما (مثل الروابط) أيضًا بحلول الوقت الذي يقع فيه هذا الحدث ؛ يشير هذا الحدث فقط إلى أن البانوراما تم تغيير المعرّف. لاحظ أن معرّف البانوراما (الذي يمكنك استخدامه كمرجع هذه البانوراما) ثابتة فقط ضمن جلسة المتصفح الحالية.
  • يتم تنشيط position_changed عند حدوث (LatLng) موضع تغيير البانوراما. دوّارة لن تؤدي البانوراما إلى تشغيل هذا الحدث. لاحظ أنه يمكنك تغيير الموضع الأساسي للبانوراما بدون تغيير الموضع pano ID، نظرًا لأن واجهة برمجة التطبيقات ستربط تلقائيًا أقرب معرف البانوراما في موضع البانوراما.
  • يتم إطلاق pov_changed عند رصد StreetViewPov تغيير تجدر الإشارة إلى أنّ هذا الحدث قد يتم تنشيطه. مع الحفاظ على الموضع ومعرّف البانوراما.
  • يتم إطلاق links_changed عند رصد الروابط الجديدة. لاحظ أن هذا الحدث قد يتم تنشيطه بشكل غير متزامن بعد التغيير في معرّف البانوراما المشار إليه من خلال pano_changed.
  • يتم إطلاق visible_changed عند رصد مستوى الرؤية للتغيير. لاحظ أن هذا الحدث قد يتم تنشيطه بشكل غير متزامن بعد التغيير في معرّف البانوراما المشار إليه من خلال 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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
الاطّلاع على مثال

تجربة "عيّنة"

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

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

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

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

يمكنك تقديم طلبات إلى StreetViewService باستخدام StreetViewPanoRequest أو StreetViewLocationRequest

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

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

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

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

الدالة getPanorama() تحتاج إلى دالة معاودة الاتصال لتنفيذها عند استرداد نتيجة من خدمة "التجوّل الافتراضي". تُرجع دالة معاودة الاتصال هذه مجموعة من بيانات بانوراما داخل كائن 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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <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 تستخدم صورًا تتوافق مع شكل الإسقاط المتساوي المستطيلات (اللوحة Carrée). مثل هذا الإسقاط يحتوي على 360 درجة للعرض الأفقي (عرض التفافي كامل) و180 درجة العرض العمودي (من أعلى إلى أسفل مباشرة). هذه الحقول من المشاهدات تؤدي إلى صورة بنسبة عرض إلى ارتفاع تبلغ 2:1. حاسمة البانوراما الدائرية الكاملة موضحة أدناه.

منظر بانورامي لشارع في المدينة

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

جسم كروي مع إطلالة بانورامية على شارع على سطحه

التعامل مع البانوراما كإسقاط على كرة ذات خط مستقيم يكون نظام الإحداثيات مفيدًا عند تقسيم الصورة إلى المربّعات المستقيمة الخطية، وعرض الصور استنادًا إلى مربّع محسوب الإحداثيات.

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

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

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

مستوى التكبير/التصغير في التجوّل الافتراضي مجال العرض (بالدرجات)
0 180
1 (افتراضي) 90
2 45
3 22.5
4 11.25

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

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

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

إطلالة بانورامية على شارع في المدينة مقسّم إلى أجزاء من البلاط

بشكل عام، سترغب في تسمية مربعات الصور لديك بحيث يمكن تم تحديدها آليًا. يُعد نظام التسمية هذا كما هو موضح أدناه في قسم التعامل مع المخصص طلبات البانوراما:

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

لاستخدام بانوراما مخصّصة، اتصل 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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <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", // 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.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>

    <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 script 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. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
الاطّلاع على مثال

تجربة "عيّنة"