سرویس نمای خیابان

نمای کلی

پلتفرم مورد نظر را انتخاب کنید: اندروید، iOS، جاوا اسکریپت

نمای خیابان گوگل (Google Street View) نمای پانورامای ۳۶۰ درجه از جاده‌های تعیین‌شده در سراسر منطقه تحت پوشش خود ارائه می‌دهد. پوشش API نمای خیابان همانند برنامه نقشه‌های گوگل ( https://maps.google.com/ ) است. لیست شهرهایی که در حال حاضر برای نمای خیابان پشتیبانی می‌شوند، در وب‌سایت نقشه‌های گوگل موجود است.

نمونه‌ای از تصویر نمای خیابان در زیر نشان داده شده است.


API جاوا اسکریپت Maps یک سرویس نمای خیابان برای دریافت و دستکاری تصاویر مورد استفاده در نمای خیابان Google Maps ارائه می‌دهد. این سرویس نمای خیابان به صورت بومی در مرورگر پشتیبانی می‌شود.

استفاده از نقشه نمای خیابان

اگرچه می‌توان از نمای خیابان (Street View) در یک عنصر DOM مستقل استفاده کرد، اما بیشترین کاربرد آن هنگام نشان دادن یک مکان روی نقشه است. به طور پیش‌فرض، نمای خیابان روی نقشه فعال است و یک کنترل نمای خیابان Pegman در کنترل‌های ناوبری (بزرگنمایی و حرکت افقی) ادغام شده است. می‌توانید با تنظیم streetViewControl روی false ، این کنترل را در MapOptions نقشه پنهان کنید. همچنین می‌توانید موقعیت پیش‌فرض کنترل نمای خیابان را با تنظیم ویژگی streetViewControlOptions.position Map روی یک ControlPosition جدید تغییر دهید.

کنترل نمای خیابان پگمن به شما امکان می‌دهد پانوراماهای نمای خیابان را مستقیماً درون نقشه مشاهده کنید. وقتی کاربر روی پگمن کلیک کرده و نگه می‌دارد، نقشه به‌روزرسانی می‌شود تا خطوط آبی‌رنگی را در اطراف خیابان‌های دارای نمای خیابان نشان دهد و تجربه کاربری مشابه برنامه نقشه‌های گوگل را ارائه دهد.

وقتی کاربر نشانگر پگمن را روی یک خیابان می‌اندازد، نقشه به‌روزرسانی می‌شود تا یک پانورامای نمای خیابان از مکان مشخص‌شده نمایش داده شود.

پانوراماهای نمای خیابان

تصاویر نمای خیابان (Street View) از طریق استفاده از شیء StreetViewPanorama پشتیبانی می‌شوند، که یک رابط API برای "بیننده" نمای خیابان فراهم می‌کند. هر نقشه شامل یک پانورامای نمای خیابان پیش‌فرض است که می‌توانید با فراخوانی متد getStreetView() نقشه، آن را بازیابی کنید. وقتی با تنظیم گزینه streetViewControl روی true ، یک کنترل نمای خیابان به نقشه اضافه می‌کنید، به طور خودکار کنترل Pegman را به این پانورامای نمای خیابان پیش‌فرض متصل می‌کنید.

همچنین می‌توانید شیء StreetViewPanorama خودتان را ایجاد کنید و نقشه را طوری تنظیم کنید که به جای پیش‌فرض، از آن استفاده کند، برای این کار می‌توانید ویژگی streetView نقشه را به طور صریح روی آن شیء ساخته شده تنظیم کنید. اگر می‌خواهید رفتار پیش‌فرض، مانند اشتراک‌گذاری خودکار همپوشانی‌ها بین نقشه و پانوراما را تغییر دهید، می‌توانید پانورامای پیش‌فرض را لغو کنید. (به بخش همپوشانی‌ها در نمای خیابان در زیر مراجعه کنید.)

کانتینرهای نمای خیابان

در عوض، می‌توانید یک StreetViewPanorama درون یک عنصر DOM جداگانه، اغلب یک عنصر <div> ، نمایش دهید. کافیست عنصر DOM را درون سازنده‌ی StreetViewPanorama ارسال کنید. برای نمایش بهینه تصاویر، حداقل اندازه ۲۰۰ پیکسل در ۲۰۰ پیکسل را توصیه می‌کنیم.

توجه: اگرچه قابلیت نمای خیابان برای استفاده در کنار نقشه طراحی شده است، اما این استفاده الزامی نیست. می‌توانید از یک شیء نمای خیابان مستقل بدون نقشه استفاده کنید.

مکان‌ها و نقطه دید خیابان (POV)

سازنده‌ی StreetViewPanorama همچنین به شما امکان می‌دهد مکان و نقطه دید Street View را با استفاده از پارامتر StreetViewOptions تنظیم کنید. می‌توانید پس از ساخت، setPosition() و setPov() را روی شیء فراخوانی کنید تا مکان و POV آن را تغییر دهید.

موقعیت نمای خیابان، محل فوکوس دوربین را برای یک تصویر تعریف می‌کند، اما جهت دوربین را برای آن تصویر مشخص نمی‌کند. برای این منظور، شیء StreetViewPov دو ویژگی را تعریف می‌کند:

  • heading (پیش‌فرض 0 ) زاویه چرخش حول مکان دوربین را بر حسب درجه نسبت به شمال واقعی تعریف می‌کند. عنوان‌ها در جهت عقربه‌های ساعت اندازه‌گیری می‌شوند (۹۰ درجه شرق واقعی است).
  • pitch (پیش‌فرض 0 ) واریانس زاویه را به صورت "بالا" یا "پایین" از زاویه پیش‌فرض اولیه دوربین تعریف می‌کند، که اغلب (اما نه همیشه) افقی و مسطح است. (برای مثال، تصویری که روی تپه گرفته شده است، احتمالاً زاویه شیب پیش‌فرضی را نشان می‌دهد که افقی نیست.) زوایای شیب با مقادیر مثبت رو به بالا (تا +۹۰ درجه مستقیم به بالا و عمود بر زاویه پیش‌فرض) و مقادیر منفی رو به پایین (تا -۹۰ درجه مستقیم به پایین و عمود بر زاویه پیش‌فرض) اندازه‌گیری می‌شوند.

شیء StreetViewPov اغلب برای تعیین نقطه دید دوربین Street View استفاده می‌شود. همچنین می‌توانید نقطه دید عکاس - معمولاً جهتی که ماشین یا سه‌چرخه به سمت آن بوده است - را با متد StreetViewPanorama.getPhotographerPov() تعیین کنید.

کد زیر نقشه‌ای از بوستون را با نمای اولیه از پارک فنوی نمایش می‌دهد. انتخاب Pegman و کشیدن آن به یک مکان پشتیبانی شده روی نقشه، نمای پانورامای خیابان را تغییر می‌دهد:

تایپ اسکریپت

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;

جاوا اسکریپت

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;

سی‌اس‌اس

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

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

اچ‌تی‌ام‌ال

<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>
مشاهده مثال

نمونه را امتحان کنید

ردیابی حرکت در دستگاه‌های تلفن همراه

در دستگاه‌هایی که از رویدادهای جهت‌یابی دستگاه پشتیبانی می‌کنند، API به کاربران این امکان را می‌دهد که نقطه دید Street View را بر اساس حرکت دستگاه تغییر دهند. کاربران می‌توانند با حرکت دادن دستگاه‌های خود به اطراف نگاه کنند. به این قابلیت ردیابی حرکت یا ردیابی چرخش دستگاه گفته می‌شود.

به عنوان توسعه‌دهنده‌ی برنامه، می‌توانید رفتار پیش‌فرض را به صورت زیر تغییر دهید:

  • قابلیت ردیابی حرکت را فعال یا غیرفعال کنید. به طور پیش‌فرض، ردیابی حرکت در هر دستگاهی که از آن پشتیبانی کند فعال است. نمونه زیر ردیابی حرکت را غیرفعال می‌کند، اما کنترل ردیابی حرکت را قابل مشاهده باقی می‌گذارد. (توجه داشته باشید که کاربر می‌تواند با ضربه زدن روی کنترل، ردیابی حرکت را فعال کند.)
    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 با ساختار خودتان تنظیم کنید، پانورامای پیش‌فرض را لغو خواهید کرد.

مثال زیر نشانگرهایی را نشان می‌دهد که مکان‌های مختلف اطراف Astor Place، شهر نیویورک را مشخص می‌کنند. برای نمایش نشانگرهای مشترک در StreetViewPanorama ، حالت نمایش را به Street View تغییر دهید.

تایپ اسکریپت

let panorama: google.maps.StreetViewPanorama;
let innerMap: google.maps.Map;

async function initMap() {
    // Request needed libraries.
    const { Map } = (await google.maps.importLibrary(
        'maps'
    )) as google.maps.MapsLibrary;

    // Set the location of Astor Place.
    const astorPlace = { lat: 40.729884, lng: -73.990988 };

    const mapElement = document.querySelector(
        'gmp-map'
    ) as google.maps.MapElement;

    innerMap = mapElement.innerMap;

    document
        .getElementById('streetview-toggle-button')!
        .addEventListener('click', toggleStreetView);

    const cafeIcon = document.createElement('img');
    cafeIcon.src = new URL('./public/cafe_icon.svg', import.meta.url).href;

    const dollarIcon = document.createElement('img');
    dollarIcon.src = new URL('./public/bank_icon.svg', import.meta.url).href;

    const busIcon = document.createElement('img');
    busIcon.src = new URL('./public/bus_icon.svg', import.meta.url).href;

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

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

    const busMarker = new google.maps.Marker({
        position: { lat: 40.729559, lng: -73.990741 },
        map: innerMap,
        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 = innerMap.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);
    }
}

initMap();

جاوا اسکریپت

let panorama;
let innerMap;
async function initMap() {
    // Request needed libraries.
    const { Map } = (await google.maps.importLibrary('maps'));
    // Set the location of Astor Place.
    const astorPlace = { lat: 40.729884, lng: -73.990988 };
    const mapElement = document.querySelector('gmp-map');
    innerMap = mapElement.innerMap;
    document
        .getElementById('streetview-toggle-button')
        .addEventListener('click', toggleStreetView);
    const cafeIcon = document.createElement('img');
    cafeIcon.src = new URL('./public/cafe_icon.svg', import.meta.url).href;
    const dollarIcon = document.createElement('img');
    dollarIcon.src = new URL('./public/bank_icon.svg', import.meta.url).href;
    const busIcon = document.createElement('img');
    busIcon.src = new URL('./public/bus_icon.svg', import.meta.url).href;
    // Set up the markers on the map
    const cafeMarker = new google.maps.Marker({
        position: { lat: 40.730031, lng: -73.991428 },
        map: innerMap,
        title: 'Cafe',
        icon: cafeIcon.src,
    });
    const bankMarker = new google.maps.Marker({
        position: { lat: 40.729681, lng: -73.991138 },
        map: innerMap,
        title: 'Bank',
        icon: dollarIcon.src,
    });
    const busMarker = new google.maps.Marker({
        position: { lat: 40.729559, lng: -73.990741 },
        map: innerMap,
        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 = innerMap.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);
    }
}
initMap();
export {};

سی‌اس‌اس

/* 
 * 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;
}

#streetview-toggle-button {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 17px;
  border: none;
  background: white;
  cursor: pointer;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  margin: 10px 0px 10px -2px;
  font-family: Roboto, Arial, sans-serif;
  font-size: 18px;
  font-weight: 400;
  color: rgb(86, 86, 86);
}

#streetview-toggle-button:hover {
  background: #f4f4f4;
  color: #000;
}

اچ‌تی‌ام‌ال

<html>
    <head>
        <title>Overlays Within Street View</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
    </head>
    <body>
        <gmp-map map-id="DEMO_MAP_ID" center="40.729884, -73.990988" zoom="18">
            <input type="button" value="Toggle Street View" id="streetview-toggle-button" slot="control-block-start-inline-start" />
        </gmp-map>
    </body>
</html>
مشاهده مثال

نمونه را امتحان کنید

رویدادهای نمای خیابان

هنگام پیمایش بین Street View یا دستکاری جهت آن، ممکن است بخواهید چندین رویداد را که نشان دهنده تغییرات در وضعیت StreetViewPanorama هستند، زیر نظر بگیرید:

  • pano_changed هر زمان که شناسه pano تغییر کند، فعال می‌شود. این رویداد تضمین نمی‌کند که هیچ داده مرتبطی در پانوراما (مانند لینک‌ها) نیز تا زمان فعال شدن این رویداد تغییر کرده باشد؛ این رویداد فقط نشان می‌دهد که شناسه pano تغییر کرده است. توجه داشته باشید که شناسه pano (که می‌توانید از آن برای ارجاع به این پانوراما استفاده کنید) فقط در جلسه مرورگر فعلی پایدار است.
  • position_changed هر زمان که موقعیت زیرین ( LatLng ) پانوراما تغییر کند، فعال می‌شود. چرخاندن یک پانوراما این رویداد را فعال نمی‌کند. توجه داشته باشید که می‌توانید موقعیت زیرین یک پانوراما را بدون تغییر شناسه پانورامای مرتبط تغییر دهید، زیرا API به طور خودکار نزدیکترین شناسه پانوراما را به موقعیت پانوراما مرتبط می‌کند.
  • pov_changed هر زمان که StreetViewPov مربوط به نمای خیابان تغییر کند، فعال می‌شود. توجه داشته باشید که این رویداد ممکن است در حالی که موقعیت و شناسه pano ثابت می‌مانند، فعال شود.
  • links_changed هر زمان که لینک‌های نمای خیابان تغییر کنند، فعال می‌شود. توجه داشته باشید که این رویداد ممکن است پس از تغییر در شناسه pano که از طریق pano_changed نشان داده شده است، به صورت غیرهمزمان فعال شود.
  • visible_changed هر زمان که میزان دید نمای خیابان تغییر کند، فعال می‌شود. توجه داشته باشید که این رویداد ممکن است به صورت ناهمزمان پس از تغییر در شناسه pano نشان داده شده از طریق pano_changed فعال شود.

کد زیر نشان می‌دهد که چگونه می‌توان این رویدادها را برای جمع‌آوری داده‌ها در مورد StreetViewPanorama اصلی مدیریت کرد:

تایپ اسکریپت

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;

جاوا اسکریپت

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;

سی‌اس‌اس

/* 
 * 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>
  <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 راهی برای چرخاندن پانوراما فراهم می‌کند. این کنترل به طور پیش‌فرض به عنوان یک کنترل استاندارد قطب‌نما و pan ظاهر می‌شود. شما می‌توانید موقعیت کنترل را با وارد کردن PanControlOptions در فیلد panControlOptions تغییر دهید.
  • یک zoomControl راهی برای بزرگنمایی تصویر فراهم می‌کند. این کنترل به طور پیش‌فرض در نزدیکی پایین سمت راست پانوراما ظاهر می‌شود. می‌توانید ظاهر کنترل را با وارد کردن ZoomControlOptions در فیلد zoomControlOptions تغییر دهید.
  • یک addressControl یک پوشش متنی ارائه می‌دهد که آدرس مکان مرتبط را نشان می‌دهد و پیوندی برای باز کردن مکان در Google Maps ارائه می‌دهد. می‌توانید ظاهر کنترل را با ارائه StreetViewAddressControlOptions در فیلد addressControlOptions تغییر دهید.
  • یک fullscreenControl گزینه‌ای برای باز کردن نمای خیابان (Street View) در حالت تمام‌صفحه ارائه می‌دهد. می‌توانید ظاهر کنترل را با ارائه FullscreenControlOptions در فیلد fullscreenControlOptions تغییر دهید.
  • یک motionTrackingControl گزینه‌ای برای فعال یا غیرفعال کردن ردیابی حرکت در دستگاه‌های تلفن همراه ارائه می‌دهد. این کنترل فقط در دستگاه‌هایی که از رویدادهای جهت‌گیری دستگاه پشتیبانی می‌کنند، ظاهر می‌شود. به طور پیش‌فرض، کنترل در نزدیکی پایین سمت راست پانوراما ظاهر می‌شود. می‌توانید موقعیت کنترل را با ارائه MotionTrackingControlOptions تغییر دهید. برای اطلاعات بیشتر، به بخش ردیابی حرکت مراجعه کنید.
  • یک linksControl فلش‌های راهنمایی روی تصویر برای حرکت به تصاویر پانورامای مجاور فراهم می‌کند.
  • کنترل بستن به کاربر اجازه می‌دهد تا نمایشگر نمای خیابان را ببندد. می‌توانید با تنظیم enableCloseButton روی true یا false کنترل بستن را فعال یا غیرفعال کنید.

مثال زیر کنترل‌های نمایش داده شده در نمای خیابان مرتبط را تغییر داده و لینک‌های نما را حذف می‌کند:

تایپ اسکریپت

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;

جاوا اسکریپت

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;

سی‌اس‌اس

/* 
 * 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>
  <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 انجام دهید که رابطی برای داده‌های ذخیره شده در سرویس نمای خیابان گوگل فراهم می‌کند.

درخواست‌های سرویس نمای خیابان

دسترسی به سرویس Street View به صورت غیرهمزمان است، زیرا API نقشه‌های گوگل نیاز به برقراری ارتباط با یک سرور خارجی دارد. به همین دلیل، شما باید یک متد callback ارسال کنید تا پس از تکمیل درخواست اجرا شود. این متد callback نتیجه را پردازش می‌کند.

شما می‌توانید با استفاده از StreetViewPanoRequest یا StreetViewLocationRequest درخواست‌هایی را به StreetViewService ارسال کنید.

درخواستی که از StreetViewPanoRequest استفاده می‌کند، داده‌های پانوراما را با توجه به یک شناسه مرجع که به طور منحصر به فرد پانوراما را مشخص می‌کند، برمی‌گرداند. توجه داشته باشید که این شناسه‌های مرجع فقط برای طول عمر تصویر آن پانوراما پایدار هستند.

یک درخواست با استفاده از StreetViewLocationRequest با استفاده از پارامترهای زیر، داده‌های پانوراما را در یک مکان مشخص جستجو می‌کند:

  • location (طول و عرض جغرافیایی) را برای جستجوی پانوراما مشخص می‌کند.
  • preference اولویتی را تعیین می‌کند که کدام پانوراما باید در شعاع پیدا شود: نزدیکترین به مکان ارائه شده یا بهترین در شعاع.
  • radius شعاعی را که بر حسب متر مشخص شده است، برای جستجوی پانوراما با محوریت طول و عرض جغرافیایی مشخص شده تنظیم می‌کند. در صورت عدم ارائه، به طور پیش‌فرض روی ۵۰ تنظیم می‌شود.
  • source منبع پانوراماها را برای جستجو مشخص می‌کند. مقادیر معتبر عبارتند از:
    • default از منابع پیش‌فرض برای نمای خیابان استفاده می‌کند؛ جستجوها محدود به منابع خاصی نیستند.
    • outdoor جستجوها را به مجموعه‌های فضای باز محدود می‌کند. توجه داشته باشید که ممکن است تصاویر پانورامای فضای باز برای مکان مشخص شده وجود نداشته باشد.

پاسخ‌های سرویس نمای خیابان

تابع getPanorama() برای اجرا شدن هنگام بازیابی نتیجه از سرویس Street View به یک تابع فراخوانی نیاز دارد. این تابع فراخوانی مجموعه‌ای از داده‌های پانوراما را در یک شیء 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 نیست. برای ایجاد یک شیء Street View با استفاده از این داده‌ها، باید یک StreetViewPanorama ایجاد کنید و setPano() را فراخوانی کنید و شناسه‌ای را که در فیلد location.pano برگردانده شده است، به آن ارسال کنید.

کد status ممکن است یکی از مقادیر زیر را برگرداند:

  • OK نشان می‌دهد که سرویس، پانورامای منطبقی را پیدا کرده است.
  • ZERO_RESULTS نشان می‌دهد که سرویس نتوانسته پانورامای منطبق با معیارهای پذیرفته‌شده را پیدا کند.
  • UNKNOWN_ERROR نشان می‌دهد که درخواست نمای خیابان قابل پردازش نیست، هرچند دلیل دقیق آن مشخص نیست.

کد زیر یک StreetViewService ایجاد می‌کند که با ایجاد نشانگرهایی که هنگام کلیک، یک StreetViewPanorama از آن مکان را نمایش می‌دهند، به کلیک‌های کاربر روی نقشه پاسخ می‌دهد. این کد از محتویات StreetViewPanoramaData برگردانده شده از سرویس استفاده می‌کند.

تایپ اسکریپت

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

جاوا اسکریپت

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

سی‌اس‌اس

/* 
 * 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>
  <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>
مشاهده مثال

نمونه را امتحان کنید

ارائه پانوراماهای نمای خیابان سفارشی

API جاوا اسکریپت Maps از نمایش پانوراماهای سفارشی در شیء StreetViewPanorama پشتیبانی می‌کند. با استفاده از پانوراماهای سفارشی، می‌توانید نمای داخلی ساختمان‌ها، مناظر از مکان‌های دیدنی یا هر چیزی از تخیل خود را نمایش دهید. حتی می‌توانید این پانوراماهای سفارشی را به پانوراماهای Street View موجود گوگل پیوند دهید.

تنظیم مجموعه‌ای از تصاویر پانورامای سفارشی شامل مراحل زیر است:

  • برای هر پانورامای سفارشی، یک تصویر پانورامای پایه ایجاد کنید. این تصویر پایه باید بالاترین وضوح تصویری را داشته باشد که می‌خواهید تصاویر بزرگنمایی شده را با آن ارائه دهید.
  • (اختیاری، اما توصیه می‌شود) مجموعه‌ای از کاشی‌های پانوراما را در سطوح بزرگنمایی مختلف از تصویر پایه ایجاد کنید.
  • بین پانوراماهای سفارشی خود لینک ایجاد کنید.
  • (اختیاری) پانوراماهای «ورودی» را در تصاویر موجود نمای خیابان گوگل تعیین کنید و پیوندها را به/از مجموعه سفارشی به مجموعه استاندارد سفارشی کنید.
  • برای هر تصویر پانوراما درون یک شیء StreetViewPanoramaData فراداده تعریف کنید.
  • متدی را پیاده‌سازی کنید که داده‌ها و تصاویر پانورامای سفارشی را تعیین کند و آن متد را به عنوان هندلر سفارشی خود در شیء StreetViewPanorama تعیین کنید.

بخش‌های بعدی این فرآیند را توضیح می‌دهند.

ایجاد پانوراماهای سفارشی

هر پانورامای نمای خیابان، یک تصویر یا مجموعه‌ای از تصاویر است که نمای ۳۶۰ درجه کاملی از یک مکان واحد ارائه می‌دهد. شیء StreetViewPanorama از تصاویری استفاده می‌کند که با تصویر مستطیلی هم‌عرض (Plate Carrée) مطابقت دارند. چنین تصویری شامل ۳۶۰ درجه نمای افقی (یک تصویر کامل در اطراف) و ۱۸۰ درجه نمای عمودی (از مستقیم به بالا تا مستقیم به پایین) است. این میدان‌های دید منجر به تصویری با نسبت ابعاد ۲:۱ می‌شوند. یک پانورامای کامل در زیر نشان داده شده است.

نمای پانوراما از خیابان شهر

تصاویر پانوراما معمولاً با گرفتن چندین عکس از یک موقعیت و چسباندن آنها به یکدیگر با استفاده از نرم‌افزار پانوراما به دست می‌آیند. (برای اطلاعات بیشتر به بخش مقایسه برنامه‌های چسباندن عکس در ویکی‌پدیا مراجعه کنید.) چنین تصاویری باید یک مکان "دوربین" واحد را به اشتراک بگذارند که از آن هر یک از تصاویر پانوراما گرفته می‌شوند. پانورامای ۳۶۰ درجه حاصل می‌تواند یک تصویر را روی یک کره تعریف کند که تصویر در سطح دو بعدی کره پیچیده شده است.

کره‌ای با نمای پانوراما از یک خیابان بر روی سطح آن

در نظر گرفتن پانوراما به عنوان تصویری روی کره‌ای با سیستم مختصات مستقیم‌الخط، هنگام تقسیم تصویر به قطعات مستطیلی و ارائه تصاویر بر اساس مختصات قطعات محاسبه‌شده، مفید است.

ایجاد کاشی‌های پانورامای سفارشی

نمای خیابان همچنین از سطوح مختلف جزئیات تصویر با استفاده از کنترل زوم پشتیبانی می‌کند که به شما امکان می‌دهد از نمای پیش‌فرض بزرگنمایی و کوچکنمایی کنید. به طور کلی، نمای خیابان پنج سطح وضوح بزرگنمایی را برای هر تصویر پانورامای مشخص ارائه می‌دهد. اگر قرار باشد برای ارائه تمام سطوح بزرگنمایی به یک تصویر پانورامای واحد متکی باشید، چنین تصویری یا لزوماً بسیار بزرگ خواهد بود و برنامه شما را به طور قابل توجهی کند می‌کند، یا در سطوح بزرگنمایی بالاتر وضوح آنقدر ضعیف خواهد بود که تصویری با پیکسل‌های ضعیف ارائه خواهید کرد. خوشبختانه، می‌توانیم از الگوی طراحی مشابهی که برای ارائه کاشی‌های نقشه گوگل در سطوح بزرگنمایی مختلف استفاده می‌شود، برای ارائه تصاویر با وضوح مناسب برای پانوراماها در هر سطح بزرگنمایی استفاده کنیم.

وقتی یک StreetViewPanorama برای اولین بار بارگذاری می‌شود، به طور پیش‌فرض تصویری متشکل از ۲۵٪ (۹۰ درجه قوس) از عرض افقی پانوراما در سطح بزرگنمایی ۱ را نمایش می‌دهد. این نما تقریباً با میدان دید معمولی انسان مطابقت دارد. کوچک‌نمایی (zoom out) از این نمای پیش‌فرض اساساً یک قوس وسیع‌تر ایجاد می‌کند، در حالی که بزرگ‌نمایی (zoom in) میدان دید را به یک قوس کوچکتر محدود می‌کند. StreetViewPanorama به طور خودکار میدان دید مناسب را برای سطح بزرگنمایی انتخاب شده محاسبه می‌کند و سپس با انتخاب مجموعه‌ای از کاشی‌ها که تقریباً با ابعاد میدان دید افقی مطابقت دارند، مناسب‌ترین تصویر را برای آن وضوح انتخاب می‌کند. میدان‌های دید زیر به سطوح بزرگنمایی نمای خیابان نگاشت می‌شوند:

سطح بزرگنمایی نمای خیابان میدان دید (درجه)
0 ۱۸۰
۱ (پیش‌فرض) ۹۰
۲ ۴۵
۳ ۲۲.۵
۴ ۱۱.۲۵

توجه داشته باشید که اندازه تصویر نمایش داده شده در نمای خیابان کاملاً به اندازه صفحه نمایش (عرض) محفظه نمای خیابان بستگی دارد. اگر محفظه عریض‌تری ارائه دهید، این سرویس همچنان برای هر سطح بزرگنمایی، میدان دید یکسانی را ارائه می‌دهد، اگرچه ممکن است کاشی‌هایی را انتخاب کند که برای آن وضوح تصویر مناسب‌تر باشند.

از آنجا که هر پانوراما از یک تصویر مستطیلی تشکیل شده است، ایجاد کاشی‌های پانوراما نسبتاً آسان است. از آنجایی که تصویر، تصویری با نسبت ابعاد ۲:۱ ارائه می‌دهد، استفاده از کاشی‌هایی با نسبت ۲:۱ آسان‌تر است، اگرچه کاشی‌های مربعی ممکن است عملکرد بهتری روی نقشه‌های مربعی داشته باشند (زیرا میدان دید مربع خواهد بود).

برای کاشی‌های ۲:۱، یک تصویر واحد که کل پانوراما را در بر می‌گیرد، کل «جهان» پانوراما (تصویر پایه) را در سطح بزرگنمایی ۰ نشان می‌دهد، و هر سطح بزرگنمایی افزایشی، ۴ کاشی zoomLevel ارائه می‌دهد. (مثلاً در سطح بزرگنمایی ۲، کل پانوراما از ۱۶ کاشی تشکیل شده است.) توجه: سطوح بزرگنمایی در کاشی‌کاری نمای خیابان مستقیماً با سطوح بزرگنمایی ارائه شده با استفاده از کنترل نمای خیابان مطابقت ندارند. در عوض، سطوح بزرگنمایی کنترل نمای خیابان، یک میدان دید (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 تنظیم نکنید، زیرا چنین موقعیتی به سرویس Street View دستور می‌دهد تا تصاویر پیش‌فرض Street View نزدیک به آن مکان را درخواست کند. در عوض، این موقعیت را در فیلد location.latLng شیء StreetViewPanoramaData سفارشی تنظیم کنید.

مثال زیر یک پانورامای سفارشی از دفتر گوگل در سیدنی را نمایش می‌دهد. توجه داشته باشید که این مثال از نقشه یا تصاویر پیش‌فرض نمای خیابان استفاده نمی‌کند:

تایپ اسکریپت

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;

جاوا اسکریپت

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;

سی‌اس‌اس

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

مثال زیر علاوه بر فلش‌های ناوبری پیش‌فرض نمای خیابان، یک فلش دیگر به تصویر اضافه می‌کند که به گوگل سیدنی اشاره می‌کند و به تصاویر سفارشی پیوند می‌دهد:

تایپ اسکریپت

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;

جاوا اسکریپت

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;

سی‌اس‌اس

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

#street-view {
  height: 100%;
}

اچ‌تی‌ام‌ال

<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>
مشاهده مثال

نمونه را امتحان کنید