نظرة عامة
توفّر ميزة "التجوّل الافتراضي من Google" إطلالات بانورامية بزاوية 360 درجة على
الطرق المحدَّدة في جميع أنحاء منطقة التغطية. تغطية "التجوّل الافتراضي" لواجهة برمجة التطبيقات
هي نفسها المستخدَمة في تطبيق "خرائط Google"
(https://maps.google.com/
). تتوفر قائمة
المدن المتاحة حاليًا لميزة "التجوّل الافتراضي" على
الموقع الإلكتروني لتطبيق "خرائط 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()
بخصوص العنصر بعد
الإنشاء بهدف تغيير موقعه وPOV.
يحدِّد الموقع الجغرافي لميزة "التجوّل الافتراضي" موضع التركيز الخاص بالكاميرا
بالنسبة إلى الصورة، ولكنه لا يحدّد اتجاه الكاميرا
لهذه الصورة. لهذا الغرض، يحدّد الكائن StreetViewPov
سمتَين:
- تحدِّد السمة
heading
(القيمة التلقائية0
) زاوية الدوران حول موضع الكاميرا بالدرجات بالنسبة إلى الشمال الحقيقي. ويتم قياس العناوين في اتجاه عقارب الساعة (تبلغ درجة الحرارة 90 درجة صحيحًا) - تحدِّد القيمة
pitch
(التلقائية0
) تباين الزاوية "زائف" أو "السهم المتّجه للأسفل" من طبقة العرض التلقائية التي تكون عادةً أفقيًا (ولكن ليس دائمًا). (على سبيل المثال، ستُظهر الصورة التي يتم التقاطها على تلّاً درجة صوت تلقائية غير أفقية). يتم قياس زوايا العرض التقديمي المخطَّط من خلال تقديم قيم موجبة للأعلى (أو ما يصل إلى 90 درجة مستقيمًا وإما ضبطًا تلقائيًا للطبقة التلقائية) والقيم السالبة المتّجهة للأسفل (من -90 درجة إلى الأسفل مباشرةً أو عموديًا إلى حدّ العرض التلقائي).
غالبًا ما يتم استخدام العنصر StreetViewPov
لتحديد مجال رؤية كاميرا "التجوّل الافتراضي". يمكنك أيضًا تحديد وجهة النظر الخاصة بالمصوّر، وهي عادةً الاتجاه
الذي تواجهه
السيارة
أو الدرّاجة النارية باستخدام طريقة StreetViewPanorama.getPhotographerPov()
.
يعرض الرمز التالي خريطة لبوسطن مع عرض أولي لمنتزه Fenway Park. سيؤدي اختيار الدليل إلى سحبه إلى موقع معتمد على الخريطة إلى تغيير عرض التجوّل الافتراضي:
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. 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); // 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. 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>
تجربة عيّنة من المحتوى
أحداث "التجوّل الافتراضي"
عند التنقّل بين ميزة "التجوّل الافتراضي" أو التلاعب
باتجاهه، ننصحك بمراقبة عدة فعاليات تشير إلى
تغييرات في حالة StreetViewPanorama
:
- يتم تنشيط
pano_changed
كلما تغيّر رقم تعريف pano الفردي. لا تضمن هذه الفعالية أيضًا تغيير أي بيانات ذات صلة بالبانوراما (مثل الروابط) بحلول وقت بدء هذه الفعالية، حيث يشير هذا الحدث فقط إلى تغيير رقم تعريف pano. يُرجى العِلم أنّ رقم تعريف pano (الذي يمكنك استخدامه للإشارة إلى هذه الصورة البانورامية) ثابت فقط خلال جلسة المتصفّح الحالية. - يتم تنشيط
position_changed
كلما تغيّر موضع البانوراما الأساسي (LatLng
). لن يؤدي تدوير صورة بانورامية إلى تشغيل هذا الحدث. يُرجى العِلم أنّه يمكنك تغيير الموضع الأساسي للصورة البانورامية بدون تغيير رقم تعريف البانو المرتبط بها، لأنّ واجهة برمجة التطبيقات ستعمل تلقائيًا على ربط أقرب رقم تعريف للبيانو بموضع البانوراما. - يتم تنشيط
pov_changed
كلما تغيّرStreetViewPov
في "التجوّل الافتراضي". يُرجى العِلم أنّ هذه الفعالية قد يتم تنشيطها عندما يظل الموضع ورقم تعريف pano ثابتًا. - يتم تنشيط
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"> </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"> </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. 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> <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. 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 API تحتاج إلى إجراء طلب اتصال بخادم خارجي. لهذا السبب، عليك تمرير طريقة رد الاتصال ليتم تنفيذها بعد اكتمال الطلب. تعالج طريقة معاودة الاتصال هذه النتيجة.
يمكنك بدء طلبات "StreetViewService
" باستخدام StreetViewPanoRequest
أو StreetViewLocationRequest
.
يعرض طلب استخدام StreetViewPanoRequest
بيانات بانوراما
عندما يكون رقم التعريف المرجعي معروفًا بشكل فريد. يُرجى العِلم أنّ
أرقام التعريف المرجعية هذه تكون ثابتة فقط طوال مدة صور هذه البانوراما.
طلب باستخدام StreetViewLocationRequest
يبحث عن بيانات البانوراما في موقع جغرافي محدّد باستخدام المَعلمات التالية:
- تحدِّد خدمة
location
الموقع الجغرافي (خط العرض وخط الطول) للبحث عن صورة بانورامية. - تُحدِّد
preference
خيارًا مفضّلاً يجب توفُّر صورة بانورامية له في النطاق الجغرافي المحدّد: الأقرب إلى الموقع الجغرافي المقدَّم، أو الأنسب في النطاق الجغرافي المحدّد. - تحدد السمة
radius
نطاقًا جغرافيًا محددًا بالمتر، يمكن من خلاله البحث عن صورة بانورامية يتم توسيطها في خط العرض وخط الطول. ويتم إعداد القيمة على 50 تلقائيًا في حال عدم توفيرها. - يحدد
source
مصدر الصور البانورامية المراد البحث فيها. القيم الصالحة هي:- يستخدم
default
المصادر التلقائية لميزة "التجوّل الافتراضي"، ولا تقتصر عمليات البحث على مصادر معيّنة. - يقتصر
outdoor
على عمليات البحث للمجموعات الخارجية. ملاحظة: قد لا تتوفّر صور بانورامية خارجية للموقع الجغرافي المحدّد.
- يستخدم
الردود على خدمة "التجوّل الافتراضي"
تحتاج الدالة getPanorama()
إلى دالة call لتنفيذها عند استرداد نتيجة
من خدمة "التجوّل الافتراضي". تعرض دالة معاودة الاتصال هذه
مجموعة من بيانات البانوراما ضمن كائن 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. 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 في "خرائط Google" عرض الصور البانورامية المخصّصة
ضمن العنصر StreetViewPanorama
. وباستخدام الصور البانورامية المخصّصة، يمكنك عرض التصميم الداخلي للمباني أو العروض من المواقع الخلّابة أو أي شيء من مخيلتك. ويمكنك أيضًا
ربط هذه الصور البانورامية المخصّصة بصور بانورامية
في ميزة "التجوّل الافتراضي" من Google.
يتضمن إعداد مجموعة من صور البانوراما المخصّصة الخطوات التالية:
- إنشاء صورة بانورامية أساسية لكل بانوراما مخصّصة يجب أن تكون هذه الصورة الأساسية بأعلى درجة دقة تريد عرضها في الصور.
- (اختياري، ولكن ننصح به) أنشئ مجموعة من المربّعات البانورامية بمستويات تكبير مختلفة عن الصورة الأساسية.
- إنشاء روابط بين صورك البانورامية المخصّصة
- (اختياري) يمكنك تصنيف صور بانورامية "للإدخال" ضمن صور "التجوّل الافتراضي" الحالية في Google وتخصيص روابط من المجموعة المخصّصة إلى المجموعة العادية.
- حدِّد بيانات وصفية لكل صورة بانورامية
ضمن كائن
StreetViewPanoramaData
. - نفِّذ طريقة تحدّد بيانات البانوراما المخصَّصة
وصورًا وحدِّد تلك الطريقة كمعالج مخصّص
ضمن الكائن
StreetViewPanorama
.
تشرح الأقسام التالية هذه العملية.
إنشاء صور بانورامية مخصّصة
كل صورة بانورامية في "التجوّل الافتراضي" هي صورة أو مجموعة صور
توفّر عرضًا كاملاً بزاوية 360 درجة من موقع جغرافي واحد.
يستخدم الكائن StreetViewPanorama
الصور التي تتوافق مع العرض المستطيل المتساوي الشكل (اللوحة). يحتوي هذا الإسقاط على عرض أفقي
بزاوية 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، تمثّل الصورة الواحدة التي تشتمل على البانوراما الكاملة الصورة الشاملة "للعالم" (الصورة الأساسية) على مستوى التكبير/التصغير 0، مع زيادة مستوى التكبير/التصغير 4zoomLevel. (على سبيل المثال، على مستوى التكبير 2، تتألف البانوراما الكاملة من 16 فئة). ملاحظة: لا تتطابق مستويات التكبير أو التصغير في لوحات "التجوّل الافتراضي" مباشرةً مع مستويات التكبير أو التصغير كما هو الحال باستخدام عنصر التحكّم في "التجوّل الافتراضي"، وبدلاً من ذلك، تختار مستويات التكبير أو التصغير في عنصر التحكّم في "التجوّل الافتراضي" حقلاً مخصصًا لميزة "التجوّل الافتراضي".
وبوجهٍ عام، عليك تسمية مربّعات الصور حتى يمكن اختيارها آليًا. تتم مناقشة نظام التسمية هذا أدناه في معالجة طلبات بانوراما المخصصة.
التعامل مع طلبات بانوراما المخصّصة
لاستخدام صورة بانورامية مخصّصة، عليك طلب
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
عندما تريد عرض صور بانورامية مخصّصة، لأن هذا الموضع سيوجّه خدمة "التجوّل الافتراضي" إلى طلب صور "التجوّل الافتراضي" التلقائية بالقرب من ذلك الموقع الجغرافي. وبدلاً من ذلك، اضبط هذا الموضع ضمن الحقل location.latLng
المخصّص للكائن StreetViewPanoramaData
.
يوضّح المثال التالي صورة بانورامية مخصّصة لمكتب 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. 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", 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. 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>