스트리트 뷰 서비스

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

개요

플랫폼 선택: Android iOS 자바스크립트

Google 스트리트 뷰는 서비스 지역을 통해 지정된 도로에서 360도 파노라마 뷰를 제공합니다. 스트리트 뷰의 API 서비스 범위는 Google 지도 애플리케이션(https://maps.google.com/)의 서비스 지역과 동일합니다. 현재 스트리트 뷰가 지원되는 도시의 목록은 Google 지도 웹사이트에서 확인할 수 있습니다.

아래는 샘플 스트리트 뷰 이미지입니다.


Maps JavaScript API는 Google 지도 스트리트 뷰에서 사용되는 이미지를 얻고 조작하기 위한 스트리트 뷰 서비스를 제공합니다. 이 스트리트 뷰 서비스는 브라우저 내에서 기본적으로 지원됩니다.

스트리트 뷰 지도 사용

스트리트 뷰는 독립형 DOM 요소 내에서 사용할 수 있지만 지도에 위치를 나타낼 때 가장 유용합니다. 기본적으로 스트리트 뷰는 지도에서 사용할 수 있으며 스트리트 뷰 페그맨 컨트롤은 탐색 (확대/축소 및 화면 이동) 컨트롤 내에 통합되어 표시됩니다. streetViewControlfalse로 설정하여 지도의 MapOptions 내에서 이 컨트롤을 숨길 수 있습니다. MapstreetViewControlOptions.position 속성을 새 ControlPosition로 설정하여 스트리트 뷰 컨트롤의 기본 위치를 변경할 수도 있습니다.

스트리트 뷰 페그맨 컨트롤을 사용하면 지도 내에서 직접 스트리트 뷰 파노라마를 볼 수 있습니다. 사용자가 페그맨을 클릭하고 유지하면 스트리트 뷰가 지원되는 거리 주위에 파란색 윤곽선이 표시되도록 지도가 업데이트되어 Google 지도 앱과 유사한 사용자 환경을 제공합니다.

사용자가 거리에 페그맨 마커를 드롭하면 지도가 업데이트되어 지정된 위치의 스트리트 뷰 파노라마를 표시합니다.

스트리트 뷰 파노라마

스트리트 뷰 이미지는 스트리트 뷰 API 함수에 API 인터페이스를 제공하는 StreetViewPanorama 객체의 사용을 통해 지원됩니다. 각 지도에는 기본 스트리트 뷰 파노라마가 포함되어 있으며 지도의 getStreetView() 메서드를 호출하여 가져올 수 있습니다. streetViewControl 옵션을 true로 설정하여 스트리트 뷰 컨트롤을 지도에 추가하면 페그맨 컨트롤이 기본 스트리트 뷰 파노라마에 자동으로 연결됩니다.

지도의 streetView 속성을 구성된 객체로 명시적으로 설정하여 나만의 StreetViewPanorama 객체를 만들고 지도에서 기본값 대신 이 객체를 사용하도록 설정할 수도 있습니다. 지도와 파노라마 간 오버레이 자동 공유와 같은 기본 동작을 수정하려면 기본 파노라마를 재정의해야 할 수 있습니다. 아래의 스트리트 뷰 내의 오버레이를 참고하세요.

스트리트 뷰 컨테이너

대신 별도의 DOM 요소(종종 <div> 요소) 내에 StreetViewPanorama를 표시할 수 있습니다. StreetViewPanorama의 생성자 내에 DOM 요소를 전달하기만 하면 됩니다. 이미지를 최적의 상태로 표시하려면 최소 크기를 200x200픽셀로 설정하는 것이 좋습니다.

참고: 스트리트 뷰 기능은 지도와 함께 사용하도록 설계되었지만 필수는 아닙니다. 지도 없이 독립형 스트리트 뷰 객체를 사용할 수 있습니다.

스트리트 뷰 위치 및 시점(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;

자바스크립트

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

  map.setStreetView(panorama);
}

window.initialize = initialize;

CSS

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

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

HTML

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

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

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

샘플 사용해 보기

모바일 기기에서 모션 추적

기기 방향 이벤트를 지원하는 기기에서 API는 기기 이동에 따라 스트리트 뷰 시점을 변경할 수 있는 기능을 사용자에게 제공합니다. 사용자는 기기를 움직이면서 주변을 둘러볼 수 있습니다. 이를 모션 추적 또는 기기 회전 추적이라고 합니다.

앱 개발자는 다음과 같이 기본 동작을 변경할 수 있습니다.

  • 모션 추적 기능을 활성화/비활성화합니다. 기본적으로 모션 추적은 이를 지원하는 모든 기기에서 사용 설정됩니다. 다음 샘플에서는 모션 추적을 사용 중지하지만 모션 추적 컨트롤은 계속 표시합니다. (사용자는 컨트롤을 탭하여 모션 추적을 켤 수 있습니다.)
    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를 사용하여 지도를 만들 때 지도에 생성된 마커는 해당 파노라마가 표시되어 있는 경우 지도에 연결된 스트리트 뷰 파노라마와 자동으로 공유됩니다. 기본 스트리트 뷰 파노라마를 가져오려면 Map 객체에서 getStreetView()를 호출하세요. 지도의 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;

자바스크립트

let panorama;

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

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

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

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

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

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

window.initMap = initMap;

CSS

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

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

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

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

HTML

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

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

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

샘플 사용해 보기

스트리트 뷰 이벤트

스트리트 뷰를 탐색하거나 방향을 조작할 때 StreetViewPanorama의 상태 변경을 나타내는 여러 이벤트를 모니터링하는 것이 좋습니다.

  • pano_changed는 개별 파노라마 ID가 변경될 때마다 발생합니다. 이 이벤트는 파노라마가 트리거된 시간까지 파노라마 내 관련 데이터 (예: 링크)도 변경되지 않았을 수 있습니다. 이 이벤트는 파노라마 ID가 변경되었음을 나타낼 뿐입니다. 이 파노라마를 참조하는 데 사용할 수 있는 파노라마 ID는 현재 브라우저 세션 내에서만 안정적입니다.
  • position_changed는 파노라마의 기본(LatLng) 위치가 변경될 때마다 발생합니다. 파노라마를 회전하면 이 이벤트가 트리거되지 않습니다. 연결된 파노라마 ID를 변경하지 않고도 파노라마의 기본 위치를 변경할 수 있습니다. API가 가장 가까운 파노라마 ID를 파노라마의 위치에 자동으로 연결하기 때문입니다.
  • pov_changed는 스트리트 뷰의 StreetViewPov가 변경될 때마다 실행됩니다. 위치와 파노라마 ID가 안정적으로 유지되는 동안 이 이벤트가 발생할 수 있습니다.
  • links_changed는 스트리트 뷰의 링크가 변경될 때마다 실행됩니다. 이 이벤트는 pano_changed를 통해 표시된 파노라마 ID가 변경된 후 비동기적으로 실행될 수 있습니다.
  • visible_changed는 스트리트 뷰의 공개 상태가 변경될 때마다 실행됩니다. 이 이벤트는 pano_changed를 통해 표시된 파노라마 ID가 변경된 후 비동기적으로 실행될 수 있습니다.

다음 코드는 기본 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;

자바스크립트

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

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

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

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

    const links = panorama.getLinks();

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

      linksTable.appendChild(row);

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

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

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

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

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

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

window.initPano = initPano;

CSS

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

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

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

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

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

HTML

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

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

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

샘플 사용해 보기

스트리트 뷰 컨트롤

StreetViewPanorama를 표시하면 기본적으로 다양한 컨트롤이 파노라마에 나타납니다. StreetViewPanoramaOptions 내의 적절한 필드를 true 또는 false로 설정하여 이러한 컨트롤을 사용 설정하거나 사용 중지할 수 있습니다.

  • panControl는 파노라마를 회전하는 방법을 제공합니다. 이 컨트롤은 기본적으로 표준 통합 나침반 및 화면 이동 컨트롤로 표시됩니다. panControlOptions 필드 내에 PanControlOptions를 제공하여 컨트롤의 위치를 변경할 수 있습니다.
  • zoomControl는 이미지 내에서 확대/축소하는 방법을 제공합니다. 이 컨트롤은 기본적으로 파노라마의 오른쪽 하단 근처에 표시됩니다. zoomControlOptions 필드 내에 ZoomControlOptions를 제공하여 컨트롤의 모양을 변경할 수 있습니다.
  • addressControl는 연결된 위치의 주소를 나타내는 텍스트 오버레이를 제공하고 Google 지도에서 위치를 여는 링크를 제공합니다. addressControlOptions 필드 내에 StreetViewAddressControlOptions를 제공하여 컨트롤의 모양을 변경할 수 있습니다.
  • fullscreenControl는 전체 화면 모드로 스트리트 뷰를 여는 옵션을 제공합니다. fullscreenControlOptions 필드 내에 FullscreenControlOptions를 제공하여 컨트롤의 모양을 변경할 수 있습니다.
  • motionTrackingControl는 휴대기기에서 모션 추적을 사용 설정 또는 사용 중지하는 옵션을 제공합니다. 이 컨트롤은 기기 방향 이벤트를 지원하는 기기에만 표시됩니다. 기본적으로 컨트롤은 파노라마의 오른쪽 하단 근처에 표시됩니다. MotionTrackingControlOptions를 제공하여 컨트롤의 위치를 변경할 수 있습니다. 자세한 내용은 모션 추적 섹션을 참고하세요.
  • linksControl는 인접한 파노라마 이미지로 이동하기 위한 이미지에 가이드 화살표를 제공합니다.
  • 닫기 컨트롤은 사용자가 스트리트 뷰 뷰어를 닫을 수 있게 해줍니다. enableCloseButtontrue 또는 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;

자바스크립트

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

window.initPano = initPano;

CSS

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

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

HTML

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

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

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

샘플 사용해 보기

스트리트 뷰 데이터에 직접 액세스

지도/파노라마를 직접 조작하지 않고도 스트리트 뷰 데이터의 가용성을 프로그래매틱 방식으로 결정하거나 특정 파노라마에 대한 정보를 반환할 수 있습니다. 이렇게 하려면 Google의 스트리트 뷰 서비스에 저장된 인터페이스를 제공하는 StreetViewService 객체를 사용하면 됩니다.

스트리트 뷰 서비스 요청

Google Maps API는 외부 서버를 호출해야 하므로 스트리트 뷰 서비스에 대한 액세스는 비동기식입니다. 따라서 요청 완료 시 실행할 콜백 메서드를 전달해야 합니다. 이 콜백 메서드는 결과를 처리합니다.

StreetViewPanoRequest 또는 StreetViewLocationRequest를 사용하여 StreetViewService에 대한 요청을 시작할 수 있습니다.

StreetViewPanoRequest를 사용하는 요청은 파노라마를 고유하게 식별하는 참조 ID를 통해 파노라마 데이터를 반환합니다. 이 참조 ID는 해당 파노라마 이미지의 수명 동안만 안정적입니다.

StreetViewLocationRequest를 사용하는 요청은 다음 매개변수를 사용하여 지정된 위치에서 파노라마 데이터를 검색합니다.

  • location는 파노라마를 검색할 위치 (위도 및 경도)를 지정합니다.
  • preference는 반경 내에서 제공된 파노라마의 위치(제공된 위치와 가장 가까운 위치 또는 반경 내에서 가장 좋은 파노라마)를 설정합니다.
  • radius는 미터로 지정된 반경을 설정합니다. 여기에서 지정된 위도와 경도를 중심으로 파노라마를 검색합니다. 입력하지 않으면 기본값은 50입니다.
  • source는 검색할 파노라마의 소스를 지정합니다. 유효한 값은 다음과 같습니다.
    • default는 스트리트 뷰의 기본 소스를 사용합니다. 검색은 특정 소스로 제한되지 않습니다.
    • outdoor은(는) 야외 컬렉션으로 검색을 제한합니다. 지정된 위치에 야외 파노라마가 없을 수도 있습니다.

스트리트 뷰 서비스 응답

getPanorama() 함수를 사용하려면 스트리트 뷰 서비스에서 결과를 검색할 때 실행할 콜백 함수가 필요합니다. 이 콜백 함수는 StreetViewPanoramaData 객체 내의 파노라마 데이터 세트와 요청 상태를 나타내는 StreetViewStatus 코드를 순서대로 반환합니다.

StreetViewPanoramaData 객체 사양에는 스트리트 뷰 파노라마에 대한 다음 형식의 메타데이터가 포함됩니다.

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

이 데이터 객체는 StreetViewPanorama 객체 자체가 아닙니다. 이 데이터를 사용하여 스트리트 뷰 객체를 만들려면 StreetViewPanorama를 만들고 setPano()를 호출하여 반환된 location.pano 필드에 설명된 대로 ID를 전달해야 합니다.

status 코드는 다음 값 중 하나를 반환할 수 있습니다.

  • OK는 서비스가 일치하는 파노라마를 찾았음을 나타냅니다.
  • ZERO_RESULTS - 전달된 기준과 일치하는 파노라마를 찾을 수 없음을 나타냅니다.
  • UNKNOWN_ERROR는 정확한 이유를 알 수 없지만 스트리트 뷰 요청을 처리할 수 없음을 나타냅니다.

다음 코드는 클릭하면 해당 위치의 StreetViewPanorama를 표시하는 마커를 만들어 사용자의 지도 클릭에 응답하는 StreetViewService를 만듭니다. 이 코드는 서비스에서 반환된 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;

자바스크립트

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

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

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

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

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

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

window.initMap = initMap;

CSS

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

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

HTML

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

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

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

샘플 사용해 보기

사용자 지정 스트리트 뷰 파노라마 제공

Maps JavaScript API는 StreetViewPanorama 객체 내에 맞춤 파노라마의 표시를 지원합니다. 맞춤 파노라마를 사용하면 건물의 내부, 경치 좋은 장소에서 본 전망 또는 상상 속의 모습을 보여줄 수 있습니다. 이러한 맞춤 파노라마를 Google의 기존 스트리트 뷰 파노라마에 연결할 수도 있습니다.

맞춤 파노라마 이미지 집합을 설정하려면 다음 단계를 따르세요.

  • 각 사용자 지정 파노라마에 기본 파노라마 이미지를 생성합니다. 이 기본 이미지는 확대된 상태로 제공할 해상도가 가장 높은 이미지여야 합니다.
  • (선택사항이지만 권장됨) 기본 이미지와 다양한 확대/축소 수준에서 파노라마 타일 집합을 만듭니다.
  • 사용자 지정 파노라마 간의 링크를 생성합니다.
  • (선택사항) Google의 기존 스트리트 뷰 이미지 내에 '진입' 파노라마를 지정하고 커스텀 세트와 표준 세트 간의 링크를 맞춤설정합니다.
  • StreetViewPanoramaData 객체 내에 각 파노라마 이미지의 메타데이터를 정의합니다.
  • 맞춤 파노라마 데이터 및 이미지를 결정하는 메서드를 구현하고 이 메서드를 StreetViewPanorama 객체 내에서 맞춤 핸들러로 지정합니다.

다음 섹션은 이 과정을 설명합니다.

사용자 지정 파노라마 생성

각 스트리트 뷰 파노라마는 단일 이미지 또는 이미지 집합으로, 단일 위치에서 완전한 360도 뷰를 제공합니다. StreetViewPanorama 객체는 정방형 (Plate Carrée) 프로젝션을 준수하는 이미지를 사용합니다. 이러한 프로젝션에는 360도 가로 뷰 (완전한 래핑)와 180도 세로 뷰 (위에서 아래로 수직)가 포함됩니다. 이 시야각으로 인해 이미지는 가로세로 비율이 2:1입니다. 아래는 전체 래핑 파노라마입니다.

일반적으로 파노라마 이미지는 한 위치에서 여러 장의 사진을 촬영한 후 파노라마 소프트웨어를 사용하여 여러 사진을 하나로 병합합니다. 자세한 내용은 위키백과에서 사진 병합 애플리케이션 비교를 참고하세요. 이러한 이미지는 단일 파노라마 장소를 공유해야 하며, 이 위치에서 각 파노라마 이미지를 촬영합니다. 그 결과로 얻는 360도 파노라마 이미지는 이미지가 구체의 2차원 표면에 래핑된 투영을 정의할 수 있습니다.

직선 좌표계를 사용하여 파노라마를 구체에서 투영으로 처리하면 이미지를 직선 타일로 분할하고 계산된 타일 좌표를 기반으로 이미지를 제공할 수 있습니다.

사용자 지정 파노라마 타일 생성

또한 스트리트 뷰는 기본 뷰를 확대/축소할 수 있는 확대/축소 컨트롤을 사용하여 다양한 수준의 이미지 세부정보를 지원합니다. 일반적으로 스트리트 뷰는 모든 파노라마 이미지에 5개 수준의 확대/축소 해상도를 제공합니다. 단일 파노라마 이미지를 사용하여 모든 확대/축소 수준을 제공하는 경우 이 이미지는 크기가 매우 크고 애플리케이션의 속도가 크게 저하되거나, 더 높은 확대/축소 수준에서는 해상도가 낮아 화소가 지나치게 적은 이미지를 제공할 수 있습니다. 그러나 다행히 다른 확대/축소 수준에서 Google 지도 타일을 게재하는 데 사용되는 것과 유사한 디자인 패턴을 사용하여 각 확대/축소 수준의 파노라마에 적절한 해상도 이미지를 제공할 수 있습니다.

StreetViewPanorama를 처음 로드하면 기본적으로 확대/축소 수준 1에서 파노라마 가로 너비의 25% (원호의 90도)로 구성된 이미지가 표시됩니다. 이 뷰는 일반적인 사람의 시야와 대략 일치합니다. 이 기본 보기에서 축소하면 기본적으로 더 넓은 원호를 제공하는 반면, 확대하면 시야가 더 작은 원호로 좁힙니다. StreetViewPanorama는 선택한 확대/축소 수준에 적절한 시야를 자동으로 계산한 다음 가로 시야의 크기와 대략 일치하는 타일 집합을 선택하여 이 해상도에 가장 적합한 이미지를 선택합니다. 다음 시야는 스트리트 뷰 확대/축소 수준에 매핑됩니다.

스트리트 뷰 확대/축소 수준 시야각(도)
0 180
1(기본값) 90
2 45
3 22.5
4 11.25

스트리트 뷰 내에 표시되는 이미지의 크기는 전적으로 스트리트 뷰 컨테이너의 화면 크기 (너비)에 따라 다릅니다. 더 넓은 컨테이너를 제공하는 경우 서비스는 여전히 특정 확대/축소 수준에 대해 동일한 시야를 제공하지만 해당 해상도에 더 적합한 타일을 선택할 수 있습니다.

각 파노라마는 정방형 프로젝션으로 구성되므로 파노라마 타일을 비교적 쉽게 만들 수 있습니다. 시야가 정사각형이기 때문에 프로젝션이 가로세로 비율이 2:1인 이미지를 제공하므로 2:1 비율이 있는 타일은 사용이 더 쉽습니다.

2:1 타일의 경우 전체 파노라마를 포함하는 단일 이미지는 확대/축소 수준 0에서 전체 파노라마(기본 이미지)를 나타내며 증가하는 각 확대/축소 수준은 4개의 zoomLevel 타일을 제공합니다. (예: 확대/축소 수준 2에서 전체 파노라마는 16개의 타일로 구성됩니다.) 참고: 스트리트 뷰 타일 지정의 확대/축소 수준은 스트리트 뷰 컨트롤을 사용하여 제공되는 확대/축소 수준과 직접 일치하지 않습니다. 스트리트 뷰 컨트롤 확대/축소 수준은 적절한 타일이 선택된 시야 (FoV)를 선택합니다.

일반적으로 프로그래매틱 방식으로 선택할 수 있도록 이미지 타일에 이름을 지정하는 것이 좋습니다. 이러한 이름 지정 체계는 아래의 맞춤 파노라마 요청 처리에서 설명합니다.

사용자 지정 파노라마 요청 처리

맞춤 파노라마를 사용하려면 맞춤 파노라마 사진 제공자 메서드의 이름을 지정하여 StreetViewPanorama.registerPanoProvider()를 호출하세요. 파노라마 제공자 메서드는 StreetViewPanoramaData 객체를 반환해야 하며 다음 서명을 갖습니다.

Function(pano):StreetViewPanoramaData

StreetViewPanoramaData는 다음 형식의 객체입니다.

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

다음과 같이 맞춤 파노라마를 표시합니다.

  • StreetViewPanoramaOptions.pano 속성을 맞춤 값으로 설정합니다.
  • StreetViewPanorama.registerPanoProvider()를 호출하여 맞춤 파노라마 제공자 함수를 제공합니다.
  • 맞춤 파노라마 제공자 함수를 구현하여 지정된 pano 값을 처리합니다.
  • StreetViewPanoramaData 객체를 구성합니다.
  • StreetViewTileData.getTileUrl 속성을 제공하는 맞춤 타일 제공자 함수의 이름으로 설정합니다. 예를 들면 getCustomPanoramaTileUrl입니다.
  • 아래 샘플과 같이 맞춤 타일 제공자 함수를 구현합니다.
  • StreetViewPanoramaData 객체를 반환합니다.

참고: 맞춤 파노라마를 표시할 때 StreetViewPanorama에 직접 position을 설정하지 마세요. 그러한 위치를 사용하면 스트리트 뷰 서비스가 해당 위치와 가까운 기본 스트리트 뷰 이미지를 요청하게 됩니다. 대신 맞춤 StreetViewPanoramaData 객체의 location.latLng 필드 내에서 이 위치를 설정하세요.

다음 예는 Google 시드니 사무실의 맞춤 파노라마를 표시합니다. 이 예에서는 지도 또는 기본 스트리트 뷰 이미지를 사용하지 않습니다.

TypeScript

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

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

자바스크립트

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

window.initPano = initPano;

CSS

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

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

HTML

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

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

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

샘플 사용해 보기

맞춤 파노라마 제공자는 전달된 파노라마 ID, 확대/축소 수준, 파노라마 타일 좌표를 고려하여 적절한 타일을 반환합니다. 이미지 선택은 이러한 전달된 값에 따라 달라지므로 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;

자바스크립트

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

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

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

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

window.initMap = initMap;

CSS

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

#street-view {
  height: 100%;
}

HTML

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

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

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

샘플 사용해 보기