Tổng quan
Chế độ xem đường phố của Google cung cấp chế độ xem toàn cảnh 360 độ từ
các con đường được chỉ định trong toàn bộ khu vực phủ sóng. Phạm vi áp dụng của API Chế độ xem đường phố cũng tương tự như phạm vi phủ sóng của ứng dụng Google Maps (https://maps.google.com/
). Danh sách các thành phố hiện được hỗ trợ cho Chế độ xem đường phố có trên trang web Google Maps.
Hình ảnh mẫu trong Chế độ xem đường phố được hiển thị bên dưới.
API JavaScript của Maps cung cấp dịch vụ Chế độ xem đường phố để lấy và chỉnh sửa hình ảnh dùng trong Chế độ xem đường phố của Google Maps. Dịch vụ Chế độ xem đường phố này được hỗ trợ sẵn trong trình duyệt.
Mức sử dụng bản đồ trong Chế độ xem đường phố
Mặc dù bạn có thể sử dụng Chế độ xem đường phố trong phần tử DOM độc lập, nhưng cách này hữu ích nhất khi chỉ ra một vị trí trên bản đồ. Theo mặc định, Chế độ xem đường phố được bật trên bản đồ và chế độ điều khiển Người hình mắc áo của Chế độ xem đường phố xuất hiện được tích hợp trong các nút điều khiển điều hướng (thu phóng và kéo). Bạn có thể ẩn chế độ điều khiển này trong MapOptions
của bản đồ bằng cách đặt streetViewControl
thành false
. Bạn cũng có thể thay đổi vị trí mặc định của chế độ điều khiển Chế độ xem đường phố bằng cách đặt thuộc tính streetViewControlOptions.position
của Map
thành ControlPosition
mới.
Kiểm soát Người hình mắc áo trong Chế độ xem đường phố cho phép bạn xem ảnh toàn cảnh của Chế độ xem đường phố trực tiếp trong bản đồ. Khi người dùng nhấp và giữ Người hình mắc áo, bản đồ sẽ cập nhật để hiển thị các đường viền màu xanh dương xung quanh các con phố có hỗ trợ Chế độ xem đường phố, mang đến trải nghiệm người dùng tương tự như ứng dụng Google Maps.
Khi người dùng thả Điểm đánh dấu Người hình mắc áo vào một đường, bản đồ sẽ cập nhật để hiển thị ảnh toàn cảnh của Chế độ xem đường phố về vị trí được chỉ định.
Ảnh toàn cảnh trong Chế độ xem đường phố
Hình ảnh trong Chế độ xem đường phố được hỗ trợ thông qua việc sử dụng đối tượng StreetViewPanorama
. Đối tượng này cung cấp giao diện API cho "người xem" Chế độ xem đường phố. Mỗi bản đồ đều chứa một ảnh toàn cảnh mặc định của Chế độ xem đường phố mà bạn có thể truy xuất bằng cách gọi phương thức getStreetView()
của bản đồ. Khi bạn thêm một chế độ điều khiển
Chế độ xem đường phố vào bản đồ bằng cách đặt tuỳ chọn streetViewControl
của chế độ đó thành true
, bạn sẽ tự động kết nối Điều khiển Người hình mắc áo
với ảnh toàn cảnh mặc định của Chế độ xem đường phố này.
Bạn cũng có thể tạo đối tượng StreetViewPanorama
của riêng mình và thiết lập để bản đồ sử dụng đối tượng đó thay vì mặc định, bằng cách đặt thuộc tính streetView
của bản đồ một cách rõ ràng cho đối tượng đã tạo đó. Bạn nên ghi đè ảnh toàn cảnh mặc định nếu muốn sửa đổi hành vi mặc định, chẳng hạn như tự động chia sẻ lớp phủ giữa bản đồ và ảnh toàn cảnh. (Xem phần Lớp phủ trong Chế độ xem đường phố bên dưới.)
Vùng chứa của Chế độ xem đường phố
Thay vào đó, bạn nên hiển thị StreetViewPanorama
trong một phần tử DOM riêng biệt, thường là phần tử <div>
.
Chỉ cần truyền phần tử DOM trong hàm khởi tạo của StreetViewPanorama
. Để hình ảnh hiển thị tối ưu, bạn nên sử dụng kích thước tối thiểu là
200 x 200 pixel.
Lưu ý: Mặc dù chức năng Chế độ xem đường phố được thiết kế để sử dụng cùng với bản đồ, nhưng việc sử dụng này là không bắt buộc. Bạn có thể sử dụng một đối tượng độc lập trong Chế độ xem đường phố mà không cần bản đồ.
Vị trí trong Chế độ xem đường phố và Chế độ xem (POV)
Hàm khởi tạo StreetViewPanorama
cũng cho phép bạn đặt vị trí và điểm nhìn của Chế độ xem đường phố bằng cách sử dụng tham số StreetViewOptions
. Bạn có thể gọi
setPosition()
và setPov()
trên đối tượng sau khi tạo để thay đổi vị trí và POV của đối tượng.
Vị trí Chế độ xem đường phố xác định vị trí của tiêu điểm máy ảnh cho một hình ảnh, nhưng không xác định hướng của máy ảnh cho hình ảnh đó. Vì mục đích đó, đối tượng StreetViewPov
xác định 2 thuộc tính:
heading
(0
mặc định) xác định góc xoay xung quanh quỹ tích máy ảnh theo độ tương đối so với hướng bắc thực. Các tiêu đề được đo theo chiều kim đồng hồ (90 độ là đúng về hướng đông).pitch
(0
mặc định) xác định phương sai góc "lên" hoặc "xuống" so với độ cao mặc định ban đầu của máy ảnh. Cao độ này thường (nhưng không phải luôn) phẳng theo chiều ngang. (Ví dụ: hình ảnh chụp trên một ngọn đồi có thể sẽ có độ cao mặc định không phải là chiều ngang.) Góc nghiêng được đo bằng các giá trị dương là nhìn lên trên (lên đến +90 độ thẳng lên và trực giao với độ cao mặc định) và giá trị âm khi nhìn xuống (đến -90 độ thẳng xuống và trực giao với độ cao mặc định).
Đối tượng StreetViewPov
thường được dùng nhất để xác định điểm nhìn của máy ảnh Chế độ xem đường phố. Bạn cũng có thể xác định góc nhìn của nhiếp ảnh gia (thường là hướng mà ô tô hoặc xe đạp ba bánh đang nhìn) bằng phương thức StreetViewPanorama.getPhotographerPov()
.
Mã sau đây hiển thị một bản đồ của Boston với hình ảnh ban đầu của Công viên Fenway. Việc chọn Người hình mắc áo và kéo Người hình mắc áo đến một vị trí được hỗ trợ trên bản đồ sẽ thay đổi ảnh toàn cảnh của Chế độ xem đường phố:
TypeScript
function initialize() { const fenway = { lat: 42.345573, lng: -71.098326 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: fenway, zoom: 14, } ); const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano") as HTMLElement, { position: fenway, pov: { heading: 34, pitch: 10, }, } ); map.setStreetView(panorama); } declare global { interface Window { initialize: () => void; } } window.initialize = initialize;
JavaScript
function initialize() { const fenway = { lat: 42.345573, lng: -71.098326 }; const map = new google.maps.Map(document.getElementById("map"), { center: fenway, zoom: 14, }); const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano"), { position: fenway, pov: { heading: 34, pitch: 10, }, }, ); map.setStreetView(panorama); } window.initialize = initialize;
CSS
html, body { height: 100%; margin: 0; padding: 0; } #map, #pano { float: left; height: 100%; width: 50%; }
HTML
<html> <head> <title>Street View split-map-panes</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <div id="pano"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initialize&v=weekly" defer ></script> </body> </html>
Thử mẫu
Theo dõi chuyển động trên thiết bị di động
Trên các thiết bị hỗ trợ sự kiện hướng thiết bị, API cho phép người dùng thay đổi góc nhìn của Chế độ xem đường phố dựa trên chuyển động của thiết bị. Người dùng có thể xem xung quanh bằng cách di chuyển thiết bị. Đây được gọi là theo dõi chuyển động hoặc theo dõi xoay thiết bị.
Là nhà phát triển ứng dụng, bạn có thể thay đổi hành vi mặc định như sau:
- Bật hoặc tắt chức năng theo dõi chuyển động. Theo mặc định, tính năng theo dõi chuyển động được bật trên mọi thiết bị hỗ trợ tính năng này. Mẫu sau đây sẽ tắt tính năng theo dõi chuyển động, nhưng vẫn hiển thị chế độ điều khiển theo dõi chuyển động.
(Lưu ý rằng người dùng có thể bật tính năng theo dõi chuyển động bằng cách nhấn vào nút điều khiển.)
var panorama = new google.maps.StreetViewPanorama( document.getElementById('pano'), { position: {lat: 37.869260, lng: -122.254811}, pov: {heading: 165, pitch: 0}, motionTracking: false });
-
Ẩn hoặc hiện chế độ điều khiển theo dõi chuyển động. Theo mặc định, chế độ điều khiển này sẽ hiển thị trên các thiết bị hỗ trợ tính năng theo dõi chuyển động. Người dùng có thể nhấn vào chế độ điều khiển để bật hoặc tắt tính năng theo dõi chuyển động. Xin lưu ý rằng chế độ điều khiển này sẽ không bao giờ xuất hiện nếu thiết bị không hỗ trợ tính năng theo dõi chuyển động, bất kể
motionTrackingControl
có giá trị nào.Mẫu sau đây sẽ tắt cả tính năng theo dõi chuyển động và tính năng điều khiển theo dõi chuyển động. Trong trường hợp này, người dùng không thể bật tính năng theo dõi chuyển động:
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 });
- Thay đổi vị trí mặc định của nút điều khiển theo dõi chuyển động. Theo mặc định, chế độ điều khiển xuất hiện gần góc dưới cùng bên phải của ảnh toàn cảnh (vị trí
RIGHT_BOTTOM
). Mẫu sau đây sẽ đặt vị trí của chế độ điều khiển thành dưới cùng bên trái: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 } });
Để xem tính năng theo dõi chuyển động trong thực tế, hãy xem mẫu sau trên thiết bị di động (hoặc bất kỳ thiết bị nào hỗ trợ sự kiện hướng thiết bị):
Lớp phủ trong Chế độ xem đường phố
Đối tượng StreetViewPanorama
mặc định hỗ trợ màn hình gốc của lớp phủ bản đồ.
Lớp phủ thường xuất hiện ở "cấp đường phố" và neo tại các vị trí LatLng
. (Ví dụ: Điểm đánh dấu sẽ xuất hiện với đuôi được neo vào mặt phẳng ngang của vị trí trong ảnh toàn cảnh của Chế độ xem đường phố.)
Hiện tại, các loại lớp phủ được hỗ trợ trên ảnh toàn cảnh của Chế độ xem đường phố chỉ giới hạn ở các Marker
, InfoWindow
và OverlayView
tuỳ chỉnh. Lớp phủ mà bạn hiển thị trên bản đồ có thể được hiển thị trên ảnh toàn cảnh của Chế độ xem đường phố bằng cách coi ảnh toàn cảnh là thay thế cho đối tượng Map
, gọi setMap()
và truyền StreetViewPanorama
làm đối số thay vì bản đồ. Tương tự, bạn có thể mở các cửa sổ thông tin trong ảnh toàn cảnh của Chế độ xem đường phố bằng cách gọi open()
, truyền StreetViewPanorama()
thay vì bản đồ.
Ngoài ra, khi tạo bản đồ có StreetViewPanorama
mặc định, mọi điểm đánh dấu được tạo trên bản đồ sẽ tự động được chia sẻ với ảnh toàn cảnh Chế độ xem đường phố được liên kết của bản đồ, miễn là người xem có thể nhìn thấy ảnh toàn cảnh. Để truy xuất ảnh toàn cảnh của Chế độ xem đường phố mặc định, hãy gọi
getStreetView()
trên đối tượng Map
. Xin lưu ý rằng nếu đặt thuộc tính streetView
của bản đồ một cách rõ ràng thành StreetViewPanorama
trong cấu trúc của riêng bạn, bạn sẽ ghi đè ảnh toàn cảnh mặc định.
Ví dụ sau đây cho thấy các điểm đánh dấu biểu thị nhiều vị trí xung quanh Astor Place, Thành phố New York. Chuyển màn hình sang Chế độ xem đường phố để hiển thị các điểm đánh dấu được chia sẻ hiển thị trong StreetViewPanorama
.
TypeScript
let panorama: google.maps.StreetViewPanorama; function initMap(): void { const astorPlace = { lat: 40.729884, lng: -73.990988 }; // Set up the map const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: astorPlace, zoom: 18, streetViewControl: false, } ); document .getElementById("toggle")! .addEventListener("click", toggleStreetView); // Set up the markers on the map const cafeMarker = new google.maps.Marker({ position: { lat: 40.730031, lng: -73.991428 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00", title: "Cafe", }); const bankMarker = new google.maps.Marker({ position: { lat: 40.729681, lng: -73.991138 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00", title: "Bank", }); const busMarker = new google.maps.Marker({ position: { lat: 40.729559, lng: -73.990741 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00", title: "Bus Stop", }); // We get the map's default panorama and set up some defaults. // Note that we don't yet set it visible. panorama = map.getStreetView()!; // TODO fix type panorama.setPosition(astorPlace); panorama.setPov( /** @type {google.maps.StreetViewPov} */ { heading: 265, pitch: 0, } ); } function toggleStreetView(): void { const toggle = panorama.getVisible(); if (toggle == false) { panorama.setVisible(true); } else { panorama.setVisible(false); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
let panorama; function initMap() { const astorPlace = { lat: 40.729884, lng: -73.990988 }; // Set up the map const map = new google.maps.Map(document.getElementById("map"), { center: astorPlace, zoom: 18, streetViewControl: false, }); document.getElementById("toggle").addEventListener("click", toggleStreetView); // Set up the markers on the map const cafeMarker = new google.maps.Marker({ position: { lat: 40.730031, lng: -73.991428 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00", title: "Cafe", }); const bankMarker = new google.maps.Marker({ position: { lat: 40.729681, lng: -73.991138 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00", title: "Bank", }); const busMarker = new google.maps.Marker({ position: { lat: 40.729559, lng: -73.990741 }, map, icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00", title: "Bus Stop", }); // We get the map's default panorama and set up some defaults. // Note that we don't yet set it visible. panorama = map.getStreetView(); // TODO fix type panorama.setPosition(astorPlace); panorama.setPov( /** @type {google.maps.StreetViewPov} */ { heading: 265, pitch: 0, }, ); } function toggleStreetView() { const toggle = panorama.getVisible(); if (toggle == false) { panorama.setVisible(true); } else { panorama.setVisible(false); } } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #floating-panel { position: absolute; top: 10px; left: 25%; z-index: 5; background-color: #fff; padding: 5px; border: 1px solid #999; text-align: center; font-family: "Roboto", "sans-serif"; line-height: 30px; padding-left: 10px; } #floating-panel { margin-left: -100px; }
HTML
<html> <head> <title>Overlays Within Street View</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="floating-panel"> <input type="button" value="Toggle Street View" id="toggle" /> </div> <div id="map"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
Thử mẫu
Sự kiện Chế độ xem đường phố
Khi di chuyển giữa Chế độ xem đường phố hoặc điều khiển hướng của chế độ xem này, bạn nên theo dõi một số sự kiện cho biết những thay đổi đối với trạng thái của StreetViewPanorama
:
pano_changed
sẽ kích hoạt bất cứ khi nào mã nhận dạng ảnh toàn cảnh riêng lẻ thay đổi. Sự kiện này không đảm bảo rằng mọi dữ liệu được liên kết trong ảnh toàn cảnh (chẳng hạn như các đường liên kết) cũng đã thay đổi vào thời điểm sự kiện này được kích hoạt; sự kiện này chỉ cho biết rằng mã nhận dạng ảnh toàn cảnh đã thay đổi. Lưu ý rằng mã nhận dạng ảnh toàn cảnh (bạn có thể dùng để tham chiếu ảnh toàn cảnh này) chỉ ổn định trong phiên trình duyệt hiện tại.position_changed
sẽ kích hoạt bất cứ khi nào vị trí cơ bản (LatLng
) của ảnh toàn cảnh thay đổi. Việc xoay ảnh toàn cảnh sẽ không kích hoạt sự kiện này. Xin lưu ý rằng bạn có thể thay đổi vị trí cơ bản của ảnh toàn cảnh mà không cần thay đổi mã ảnh toàn cảnh được liên kết, vì API sẽ tự động liên kết mã ảnh toàn cảnh gần nhất với vị trí của ảnh toàn cảnh.pov_changed
kích hoạt bất cứ khi nàoStreetViewPov
của Chế độ xem đường phố thay đổi. Xin lưu ý rằng sự kiện này có thể kích hoạt trong khi vị trí và mã nhận dạng ảnh toàn cảnh vẫn ổn định.links_changed
sẽ kích hoạt bất cứ khi nào đường liên kết của Chế độ xem đường phố thay đổi. Lưu ý rằng sự kiện này có thể kích hoạt không đồng bộ sau khi có sự thay đổi trong mã nhận dạng ảnh toàn cảnh được biểu thị thông quapano_changed
.visible_changed
sẽ kích hoạt bất cứ khi nào chế độ hiển thị của Chế độ xem đường phố thay đổi. Lưu ý rằng sự kiện này có thể kích hoạt không đồng bộ sau khi có sự thay đổi trong mã nhận dạng ảnh toàn cảnh được biểu thị thông quapano_changed
.
Đoạn mã sau minh hoạ cách xử lý những sự kiện này
để thu thập dữ liệu về StreetViewPanorama
cơ bản:
TypeScript
function initPano() { const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano") as HTMLElement, { position: { lat: 37.869, lng: -122.255 }, pov: { heading: 270, pitch: 0, }, visible: true, } ); panorama.addListener("pano_changed", () => { const panoCell = document.getElementById("pano-cell") as HTMLElement; panoCell.innerHTML = panorama.getPano(); }); panorama.addListener("links_changed", () => { const linksTable = document.getElementById("links_table") as HTMLElement; while (linksTable.hasChildNodes()) { linksTable.removeChild(linksTable.lastChild as ChildNode); } const links = panorama.getLinks(); for (const i in links) { const row = document.createElement("tr"); linksTable.appendChild(row); const labelCell = document.createElement("td"); labelCell.innerHTML = "<b>Link: " + i + "</b>"; const valueCell = document.createElement("td"); valueCell.innerHTML = links[i].description as string; linksTable.appendChild(labelCell); linksTable.appendChild(valueCell); } }); panorama.addListener("position_changed", () => { const positionCell = document.getElementById( "position-cell" ) as HTMLElement; (positionCell.firstChild as HTMLElement).nodeValue = panorama.getPosition() + ""; }); panorama.addListener("pov_changed", () => { const headingCell = document.getElementById("heading-cell") as HTMLElement; const pitchCell = document.getElementById("pitch-cell") as HTMLElement; (headingCell.firstChild as HTMLElement).nodeValue = panorama.getPov().heading + ""; (pitchCell.firstChild as HTMLElement).nodeValue = panorama.getPov().pitch + ""; }); } declare global { interface Window { initPano: () => void; } } window.initPano = initPano;
JavaScript
function initPano() { const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano"), { position: { lat: 37.869, lng: -122.255 }, pov: { heading: 270, pitch: 0, }, visible: true, }, ); panorama.addListener("pano_changed", () => { const panoCell = document.getElementById("pano-cell"); panoCell.innerHTML = panorama.getPano(); }); panorama.addListener("links_changed", () => { const linksTable = document.getElementById("links_table"); while (linksTable.hasChildNodes()) { linksTable.removeChild(linksTable.lastChild); } const links = panorama.getLinks(); for (const i in links) { const row = document.createElement("tr"); linksTable.appendChild(row); const labelCell = document.createElement("td"); labelCell.innerHTML = "<b>Link: " + i + "</b>"; const valueCell = document.createElement("td"); valueCell.innerHTML = links[i].description; linksTable.appendChild(labelCell); linksTable.appendChild(valueCell); } }); panorama.addListener("position_changed", () => { const positionCell = document.getElementById("position-cell"); positionCell.firstChild.nodeValue = panorama.getPosition() + ""; }); panorama.addListener("pov_changed", () => { const headingCell = document.getElementById("heading-cell"); const pitchCell = document.getElementById("pitch-cell"); headingCell.firstChild.nodeValue = panorama.getPov().heading + ""; pitchCell.firstChild.nodeValue = panorama.getPov().pitch + ""; }); } window.initPano = initPano;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #floating-panel { position: absolute; top: 10px; left: 25%; z-index: 5; background-color: #fff; padding: 5px; border: 1px solid #999; text-align: center; font-family: "Roboto", "sans-serif"; line-height: 30px; padding-left: 10px; } #pano { width: 50%; height: 100%; float: left; } #floating-panel { width: 45%; height: 100%; float: right; text-align: left; overflow: auto; position: static; border: 0px solid #999; }
HTML
<html> <head> <title>Street View Events</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="pano"></div> <div id="floating-panel"> <table> <tr> <td><b>Position</b></td> <td id="position-cell"> </td> </tr> <tr> <td><b>POV Heading</b></td> <td id="heading-cell">270</td> </tr> <tr> <td><b>POV Pitch</b></td> <td id="pitch-cell">0.0</td> </tr> <tr> <td><b>Pano ID</b></td> <td id="pano-cell"> </td> </tr> <table id="links_table"></table> </table> </div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly" defer ></script> </body> </html>
Thử mẫu
Chế độ điều khiển Chế độ xem đường phố
Khi hiển thị StreetViewPanorama
, nhiều chế độ điều khiển sẽ xuất hiện trên ảnh toàn cảnh theo mặc định. Bạn có thể bật hoặc tắt các chế độ kiểm soát này bằng cách đặt các trường thích hợp trong StreetViewPanoramaOptions
thành true
hoặc false
:
panControl
cung cấp cách xoay ảnh toàn cảnh. Chế độ điều khiển này xuất hiện theo mặc định dưới dạng một chế độ điều khiển xoay và la bàn tích hợp tiêu chuẩn. Bạn có thể thay đổi vị trí của chế độ điều khiển bằng cách cung cấpPanControlOptions
trong trườngpanControlOptions
.zoomControl
cung cấp cách thức để thu phóng trong hình ảnh. Theo mặc định, chế độ điều khiển này xuất hiện ở gần phía dưới cùng bên phải của ảnh toàn cảnh. Bạn có thể thay đổi giao diện của chế độ điều khiển bằng cách cung cấpZoomControlOptions
trong trườngzoomControlOptions
.addressControl
cung cấp một lớp phủ văn bản cho biết địa chỉ của vị trí được liên kết và cung cấp đường liên kết để mở vị trí đó trong Google Maps. Bạn có thể thay đổi giao diện của chế độ điều khiển bằng cách cung cấpStreetViewAddressControlOptions
trong trườngaddressControlOptions
.fullscreenControl
cung cấp tuỳ chọn mở Chế độ xem đường phố ở chế độ toàn màn hình. Bạn có thể thay đổi giao diện của chế độ điều khiển bằng cách cung cấpFullscreenControlOptions
trong trườngfullscreenControlOptions
.motionTrackingControl
cung cấp tuỳ chọn bật hoặc tắt tính năng theo dõi chuyển động trên thiết bị di động. Chế độ điều khiển này chỉ xuất hiện trên các thiết bị hỗ trợ sự kiện hướng thiết bị. Theo mặc định, chế độ điều khiển sẽ xuất hiện gần phía dưới cùng bên phải của ảnh toàn cảnh. Bạn có thể thay đổi vị trí của chế độ điều khiển này bằng cách cung cấpMotionTrackingControlOptions
. Để biết thêm thông tin, hãy xem phần theo dõi chuyển động.linksControl
cung cấp các mũi tên hướng dẫn trên hình ảnh để di chuyển đến hình ảnh toàn cảnh liền kề.- Điều khiển Đóng cho phép người dùng đóng trình xem Chế độ xem đường phố. Bạn có thể bật hoặc tắt chế độ điều khiển Đóng bằng cách đặt
enableCloseButton
thànhtrue
hoặcfalse
.
Ví dụ sau đây thay đổi các chế độ điều khiển hiển thị trong Chế độ xem đường phố được liên kết và xoá các đường liên kết của chế độ xem đó:
TypeScript
function initPano() { // Note: constructed panorama objects have visible: true // set by default. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map") as HTMLElement, { position: { lat: 42.345573, lng: -71.098326 }, addressControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER, }, linksControl: false, panControl: false, enableCloseButton: false, } ); } declare global { interface Window { initPano: () => void; } } window.initPano = initPano;
JavaScript
function initPano() { // Note: constructed panorama objects have visible: true // set by default. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map"), { position: { lat: 42.345573, lng: -71.098326 }, addressControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER, }, linksControl: false, panControl: false, enableCloseButton: false, }, ); } window.initPano = initPano;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>Street View Controls</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly" defer ></script> </body> </html>
Thử mẫu
Truy cập trực tiếp vào dữ liệu trong Chế độ xem đường phố
Bạn có thể dùng phương pháp lập trình để xác định tình trạng sẵn có của dữ liệu Chế độ xem đường phố hoặc trả về thông tin về các ảnh toàn cảnh cụ thể mà không cần thao tác trực tiếp với bản đồ/ảnh toàn cảnh. Bạn có thể thực hiện việc này bằng cách sử dụng đối tượng StreetViewService
. Đối tượng này cung cấp giao diện cho dữ liệu được lưu trữ trong dịch vụ Chế độ xem đường phố của Google.
Yêu cầu dịch vụ Chế độ xem đường phố
Bạn không thể truy cập vào dịch vụ Chế độ xem đường phố, vì API Google Maps cần thực hiện lệnh gọi đến một máy chủ bên ngoài. Do đó, bạn cần truyền phương thức callback để thực thi sau khi hoàn tất yêu cầu. Phương thức gọi lại này sẽ xử lý kết quả.
Bạn có thể bắt đầu yêu cầu đến StreetViewService
bằng StreetViewPanoRequest
hoặc StreetViewLocationRequest
.
Yêu cầu sử dụng StreetViewPanoRequest
sẽ trả về dữ liệu ảnh toàn cảnh với một mã tham chiếu giúp nhận dạng duy nhất ảnh toàn cảnh. Lưu ý rằng các mã nhận dạng tham chiếu này chỉ ổn định trong toàn bộ thời gian hình ảnh của ảnh toàn cảnh đó.
Yêu cầu sử dụng StreetViewLocationRequest
sẽ tìm kiếm dữ liệu toàn cảnh tại một vị trí cụ thể bằng cách sử dụng các tham số sau:
location
chỉ định vị trí (vĩ độ và kinh độ) để tìm kiếm ảnh toàn cảnh.preference
đặt lựa chọn ưu tiên về ảnh toàn cảnh mà bạn nên tìm thấy trong bán kính: vị trí gần vị trí được cung cấp nhất hoặc vị trí tốt nhất trong phạm vi bán kính.radius
đặt bán kính được chỉ định bằng mét để tìm ảnh toàn cảnh, căn giữa theo vĩ độ và kinh độ đã cho. Giá trị mặc định là 50 khi không được cung cấp.source
chỉ định nguồn của ảnh toàn cảnh để tìm kiếm. Có các giá trị hợp lệ như sau:default
sử dụng các nguồn mặc định cho Chế độ xem đường phố; các lượt tìm kiếm không bị giới hạn ở các nguồn cụ thể.outdoor
giới hạn số lượt tìm kiếm đối với các bộ sưu tập ngoài trời. Lưu ý rằng ảnh toàn cảnh ngoài trời có thể không tồn tại đối với vị trí được chỉ định.
Phản hồi về dịch vụ của Chế độ xem đường phố
Hàm getPanorama()
cần một hàm callback (gọi lại) để thực thi khi truy xuất kết quả từ dịch vụ Chế độ xem đường phố. Hàm callback này trả về một tập dữ liệu toàn cảnh trong một đối tượng StreetViewPanoramaData
và một mã StreetViewStatus
cho biết trạng thái của yêu cầu, theo thứ tự đó.
Thông số kỹ thuật của đối tượng StreetViewPanoramaData
chứa siêu dữ liệu về ảnh toàn cảnh của Chế độ xem đường phố ở dạng sau:
{ "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 } }
Hãy lưu ý rằng đối tượng dữ liệu này không phải là đối tượng StreetViewPanorama
. Để tạo đối tượng Chế độ xem đường phố bằng dữ liệu này, bạn cần tạo StreetViewPanorama
và gọi setPano()
, truyền vào đối tượng đó mã nhận dạng như được ghi chú trong trường location.pano
được trả về.
Mã status
có thể trả về một trong các giá trị sau:
OK
cho biết dịch vụ tìm thấy một ảnh toàn cảnh phù hợp.ZERO_RESULTS
cho biết dịch vụ không tìm thấy ảnh toàn cảnh phù hợp với tiêu chí đã đạt.UNKNOWN_ERROR
cho biết không thể xử lý yêu cầu Chế độ xem đường phố, mặc dù lý do chính xác chưa được xác định.
Mã sau đây sẽ tạo một StreetViewService
để phản hồi thao tác nhấp của người dùng trên bản đồ bằng cách tạo các điểm đánh dấu mà khi người dùng nhấp vào, thì hệ thống sẽ hiển thị StreetViewPanorama
của vị trí đó. Mã này sử dụng nội dung của StreetViewPanoramaData
do dịch vụ trả về.
TypeScript
/* * Click the map to set a new location for the Street View camera. */ let map: google.maps.Map; let panorama: google.maps.StreetViewPanorama; function initMap(): void { const berkeley = { lat: 37.869085, lng: -122.254775 }; const sv = new google.maps.StreetViewService(); panorama = new google.maps.StreetViewPanorama( document.getElementById("pano") as HTMLElement ); // Set up the map. map = new google.maps.Map(document.getElementById("map") as HTMLElement, { center: berkeley, zoom: 16, streetViewControl: false, }); // Set the initial Street View camera to the center of the map sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData); // Look for a nearby Street View panorama when the map is clicked. // getPanorama will return the nearest pano when the given // radius is 50 meters or less. map.addListener("click", (event) => { sv.getPanorama({ location: event.latLng, radius: 50 }) .then(processSVData) .catch((e) => console.error("Street View data not found for this location.") ); }); } function processSVData({ data }: google.maps.StreetViewResponse) { const location = data.location!; const marker = new google.maps.Marker({ position: location.latLng, map, title: location.description, }); panorama.setPano(location.pano as string); panorama.setPov({ heading: 270, pitch: 0, }); panorama.setVisible(true); marker.addListener("click", () => { const markerPanoID = location.pano; // Set the Pano to use the passed panoID. panorama.setPano(markerPanoID as string); panorama.setPov({ heading: 270, pitch: 0, }); panorama.setVisible(true); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
/* * Click the map to set a new location for the Street View camera. */ let map; let panorama; function initMap() { const berkeley = { lat: 37.869085, lng: -122.254775 }; const sv = new google.maps.StreetViewService(); panorama = new google.maps.StreetViewPanorama( document.getElementById("pano"), ); // Set up the map. map = new google.maps.Map(document.getElementById("map"), { center: berkeley, zoom: 16, streetViewControl: false, }); // Set the initial Street View camera to the center of the map sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData); // Look for a nearby Street View panorama when the map is clicked. // getPanorama will return the nearest pano when the given // radius is 50 meters or less. map.addListener("click", (event) => { sv.getPanorama({ location: event.latLng, radius: 50 }) .then(processSVData) .catch((e) => console.error("Street View data not found for this location."), ); }); } function processSVData({ data }) { const location = data.location; const marker = new google.maps.Marker({ position: location.latLng, map, title: location.description, }); panorama.setPano(location.pano); panorama.setPov({ heading: 270, pitch: 0, }); panorama.setVisible(true); marker.addListener("click", () => { const markerPanoID = location.pano; // Set the Pano to use the passed panoID. panorama.setPano(markerPanoID); panorama.setPov({ heading: 270, pitch: 0, }); panorama.setVisible(true); }); } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>Directly Accessing Street View Data</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map" style="width: 45%; height: 100%; float: left"></div> <div id="pano" style="width: 45%; height: 100%; float: left"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
Thử mẫu
Cung cấp ảnh toàn cảnh tuỳ chỉnh trong Chế độ xem đường phố
API JavaScript của Maps hỗ trợ hiển thị ảnh toàn cảnh tuỳ chỉnh trong đối tượng StreetViewPanorama
. Khi sử dụng ảnh toàn cảnh
tuỳ chỉnh, bạn có thể hiển thị không gian bên trong của các toà nhà, khung cảnh từ
các địa điểm ngắm cảnh hoặc bất cứ thứ gì trong trí tưởng tượng của bạn. Bạn thậm chí có thể liên kết các ảnh toàn cảnh tuỳ chỉnh này với các ảnh toàn cảnh hiện có trong Chế độ xem đường phố của Google.
Quy trình thiết lập một bộ hình ảnh toàn cảnh tuỳ chỉnh bao gồm các bước sau:
- Tạo hình ảnh toàn cảnh cơ sở cho từng ảnh toàn cảnh tuỳ chỉnh. Hình ảnh gốc này phải ở hình ảnh có độ phân giải cao nhất mà bạn muốn phân phát hình ảnh phóng to.
- (Không bắt buộc, nhưng nên dùng) Tạo một tập hợp các ô toàn cảnh ở các mức thu phóng khác nhau so với hình ảnh cơ bản.
- Tạo đường liên kết giữa các ảnh toàn cảnh tuỳ chỉnh.
- (Không bắt buộc) Chỉ định ảnh toàn cảnh "mục nhập" trong hình ảnh Chế độ xem đường phố hiện có của Google và tuỳ chỉnh các đường liên kết đến/từ tập hợp tuỳ chỉnh thành tập hợp tiêu chuẩn.
- Xác định siêu dữ liệu cho từng ảnh toàn cảnh trong một đối tượng
StreetViewPanoramaData
. - Triển khai một phương thức xác định dữ liệu và hình ảnh toàn cảnh tuỳ chỉnh, đồng thời chỉ định phương thức đó làm trình xử lý tuỳ chỉnh trong đối tượng
StreetViewPanorama
.
Các phần sau đây giải thích quy trình này.
Tạo ảnh toàn cảnh tùy chỉnh
Mỗi ảnh toàn cảnh của Chế độ xem đường phố là một hình ảnh hoặc một tập hợp hình ảnh
cho phép bạn xem toàn bộ 360 độ từ một vị trí duy nhất.
Đối tượng StreetViewPanorama
sử dụng hình ảnh tuân theo phép chiếu hình cầu toàn cảnh (Plate Carrees). Một phép chiếu như vậy có 360 độ khung hiển thị ngang (bao quanh toàn bộ) và 180 độ khung hiển thị dọc (từ thẳng lên đến thẳng xuống). Các trường hiển thị này sẽ tạo ra hình ảnh có tỷ lệ khung hình là 2:1. Dưới đây là ảnh toàn cảnh bao quát toàn bộ.
Bạn thường thu được ảnh toàn cảnh bằng cách chụp nhiều ảnh từ một vị trí và ghép các ảnh đó lại với nhau bằng phần mềm ảnh toàn cảnh. (Xem phần So sánh các ứng dụng ghép ảnh của Wikipedia để biết thêm thông tin.) Những hình ảnh như vậy phải có chung một quỹ tích "máy ảnh" để chụp từng ảnh toàn cảnh. Sau đó, ảnh toàn cảnh 360 độ thu được có thể xác định phép chiếu trên một hình cầu với hình ảnh được bao bọc theo bề mặt hai chiều của hình cầu.
Việc coi ảnh toàn cảnh là hình chiếu trên một hình cầu có hệ toạ độ thẳng là một lợi thế khi chia hình ảnh thành các thẻ thông tin trực tiếp và phân phát hình ảnh dựa trên toạ độ thẻ thông tin đã tính toán.
Tạo thẻ thông tin toàn cảnh tuỳ chỉnh
Chế độ xem đường phố cũng hỗ trợ nhiều mức độ chi tiết của hình ảnh thông qua việc sử dụng một nút điều khiển thu phóng, cho phép bạn phóng to và thu nhỏ từ chế độ xem mặc định. Nhìn chung, Chế độ xem đường phố cung cấp năm mức độ phân giải thu phóng cho mọi hình ảnh toàn cảnh cụ thể. Nếu bạn phải dựa vào một ảnh toàn cảnh để phân phát mọi mức thu phóng, thì một hình ảnh như vậy chắc chắn phải khá lớn và làm chậm đáng kể ứng dụng của bạn, hoặc có độ phân giải kém như vậy ở mức thu phóng cao hơn nên bạn sẽ phân phát được hình ảnh có độ phân giải kém. Tuy nhiên, may mắn thay, chúng ta có thể sử dụng một mẫu thiết kế tương tự dùng để phân phát các ô bản đồ của Google ở các mức thu phóng khác nhau nhằm cung cấp hình ảnh có độ phân giải thích hợp cho ảnh toàn cảnh ở mỗi mức thu phóng.
Khi tải lần đầu, theo mặc định, StreetViewPanorama
sẽ hiển thị một hình ảnh bao gồm 25% (90 độ cung) chiều rộng của ảnh toàn cảnh theo chiều ngang ở mức thu phóng 1. Khung hiển thị này tương ứng với trường nhìn thông thường của con người. Việc thu phóng từ chế độ xem mặc định này về cơ bản sẽ tạo ra một vòng cung rộng hơn, trong khi việc phóng to sẽ thu hẹp trường nhìn thành một vòng cung nhỏ hơn. StreetViewPanorama
tự động tính toán trường nhìn thích hợp cho mức thu phóng đã chọn, sau đó chọn hình ảnh phù hợp nhất với độ phân giải đó bằng cách chọn một tập hợp ô vừa với kích thước của trường nhìn ngang. Các trường sau đây của chế độ xem bản đồ tương ứng với mức thu phóng
của Chế độ xem đường phố:
Mức thu phóng của Chế độ xem đường phố | Trường xem (độ) |
---|---|
0 | 180 |
1 (mặc định) | 90 |
2 | 45 |
3 | 22.5 |
4 | 11.25 |
Xin lưu ý rằng kích thước của hình ảnh hiển thị trong Chế độ xem đường phố hoàn toàn phụ thuộc vào kích thước màn hình (chiều rộng) của vùng chứa Chế độ xem đường phố. Nếu bạn cung cấp một vùng chứa rộng hơn, thì dịch vụ vẫn sẽ cung cấp cùng một trường nhìn cho mọi mức thu phóng nhất định. Mặc dù vậy, dịch vụ này có thể chọn các thẻ thông tin phù hợp hơn với độ phân giải đó.
Vì mỗi ảnh toàn cảnh bao gồm một phép chiếu hình cầu toàn cảnh, nên việc tạo ô ảnh toàn cảnh tương đối dễ dàng. Vì phép chiếu cung cấp hình ảnh có tỷ lệ khung hình 2:1 nên các thẻ thông tin có tỷ lệ 2:1 sẽ dễ sử dụng hơn, mặc dù các ô vuông có thể mang lại hiệu suất tốt hơn trên bản đồ hình vuông (vì trường nhìn sẽ là hình vuông).
Đối với các ô 2:1, một hình ảnh bao gồm toàn bộ ảnh toàn cảnh đại diện cho toàn bộ ảnh toàn cảnh "thế giới" (hình ảnh cơ sở) ở mức thu phóng 0, trong đó mỗi mức thu phóng tăng dần cung cấp 4 ôzoomLevel. (Ví dụ: ở mức thu phóng 2, toàn bộ ảnh toàn cảnh bao gồm 16 ô.) Lưu ý: mức thu phóng trong ô xếp kề Chế độ xem đường phố không khớp trực tiếp với mức thu phóng như được cung cấp bằng cách sử dụng chế độ điều khiển Chế độ xem đường phố; thay vào đó, mức thu phóng của chế độ điều khiển Chế độ xem đường phố sẽ chọn một Trường chế độ xem (FoV), từ đó các ô thích hợp sẽ được chọn.
Nhìn chung, bạn nên đặt tên cho thẻ thông tin hình ảnh để có thể chọn thẻ thông tin theo phương thức lập trình. Lược đồ đặt tên như vậy được thảo luận dưới đây trong phần Xử lý yêu cầu ảnh toàn cảnh tuỳ chỉnh.
Xử lý yêu cầu ảnh toàn cảnh tuỳ chỉnh
Để sử dụng ảnh toàn cảnh tuỳ chỉnh, hãy gọi StreetViewPanorama.registerPanoProvider()
, chỉ định tên của phương thức của nhà cung cấp ảnh toàn cảnh tuỳ chỉnh. Phương thức của nhà cung cấp ảnh toàn cảnh phải trả về một đối tượng StreetViewPanoramaData
và có chữ ký sau:
Function(pano):StreetViewPanoramaData
StreetViewPanoramaData
là một đối tượng có dạng sau:
{ 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 ] }
Hiển thị ảnh toàn cảnh tùy chỉnh như sau:
- Đặt thuộc tính
StreetViewPanoramaOptions.pano
thành giá trị tuỳ chỉnh. - Gọi
StreetViewPanorama.registerPanoProvider()
để cung cấp hàm nhà cung cấp ảnh toàn cảnh tuỳ chỉnh. - Triển khai hàm nhà cung cấp ảnh toàn cảnh tuỳ chỉnh để xử lý giá trị
pano
được chỉ định. - Tạo một đối tượng
StreetViewPanoramaData
. - Đặt thuộc tính
StreetViewTileData.getTileUrl
thành tên của hàm nhà cung cấp thẻ thông tin tuỳ chỉnh mà bạn cung cấp. Ví dụ:getCustomPanoramaTileUrl
. - Triển khai hàm nhà cung cấp thẻ thông tin tuỳ chỉnh, như minh hoạ trong các mẫu dưới đây.
- Trả về đối tượng
StreetViewPanoramaData
.
Lưu ý: Đừng trực tiếp đặt position
trên StreetViewPanorama
khi bạn muốn hiển thị ảnh toàn cảnh tuỳ chỉnh, vì vị trí này sẽ hướng dẫn dịch vụ Chế độ xem đường phố yêu cầu hình ảnh Chế độ xem đường phố mặc định gần vị trí đó. Thay vào đó, hãy đặt vị trí này trong trường location.latLng
của đối tượng StreetViewPanoramaData
tuỳ chỉnh.
Ví dụ sau đây hiển thị một ảnh toàn cảnh tuỳ chỉnh của văn phòng Google Sydney. Xin lưu ý rằng ví dụ sau không sử dụng bản đồ hoặc hình ảnh mặc định trong Chế độ xem đường phố:
TypeScript
function initPano() { // Set up Street View and initially set it visible. Register the // custom panorama provider function. Set the StreetView to display // the custom panorama 'reception' which we check for below. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map") as HTMLElement, { pano: "reception", visible: true } ); panorama.registerPanoProvider(getCustomPanorama); } // Return a pano image given the panoID. function getCustomPanoramaTileUrl( pano: string, zoom: number, tileX: number, tileY: number ): string { return ( "https://developers.google.com/maps/documentation/javascript/examples/full/images/" + "panoReception1024-" + zoom + "-" + tileX + "-" + tileY + ".jpg" ); } // Construct the appropriate StreetViewPanoramaData given // the passed pano IDs. function getCustomPanorama(pano: string): google.maps.StreetViewPanoramaData { if (pano === "reception") { return { location: { pano: "reception", description: "Google Sydney - Reception", }, links: [], // The text for the copyright control. copyright: "Imagery (c) 2010 Google", // The definition of the tiles for this panorama. tiles: { tileSize: new google.maps.Size(1024, 512), worldSize: new google.maps.Size(2048, 1024), // The heading in degrees at the origin of the panorama // tile set. centerHeading: 105, getTileUrl: getCustomPanoramaTileUrl, }, }; } // @ts-ignore TODO fix typings return null; } declare global { interface Window { initPano: () => void; } } window.initPano = initPano;
JavaScript
function initPano() { // Set up Street View and initially set it visible. Register the // custom panorama provider function. Set the StreetView to display // the custom panorama 'reception' which we check for below. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map"), { pano: "reception", visible: true }, ); panorama.registerPanoProvider(getCustomPanorama); } // Return a pano image given the panoID. function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) { return ( "https://developers.google.com/maps/documentation/javascript/examples/full/images/" + "panoReception1024-" + zoom + "-" + tileX + "-" + tileY + ".jpg" ); } // Construct the appropriate StreetViewPanoramaData given // the passed pano IDs. function getCustomPanorama(pano) { if (pano === "reception") { return { location: { pano: "reception", description: "Google Sydney - Reception", }, links: [], // The text for the copyright control. copyright: "Imagery (c) 2010 Google", // The definition of the tiles for this panorama. tiles: { tileSize: new google.maps.Size(1024, 512), worldSize: new google.maps.Size(2048, 1024), // The heading in degrees at the origin of the panorama // tile set. centerHeading: 105, getTileUrl: getCustomPanoramaTileUrl, }, }; } // @ts-ignore TODO fix typings return null; } window.initPano = initPano;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>Custom Street View Panoramas</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly" defer ></script> </body> </html>
Thử mẫu
Trình cung cấp ảnh toàn cảnh tuỳ chỉnh sẽ trả về thẻ thông tin thích hợp dựa trên mã nhận dạng ảnh toàn cảnh, mức thu phóng và toạ độ thẻ thông tin toàn cảnh đã chuyển.
Vì việc lựa chọn hình ảnh phụ thuộc vào các giá trị được truyền này, nên bạn nên đặt tên cho những hình ảnh có thể chọn theo phương thức lập trình dựa trên các giá trị đã chuyển đó, chẳng hạn như pano_zoom_tileX_tileY.png
.
Ví dụ sau đây thêm một mũi tên khác vào hình ảnh, ngoài các mũi tên điều hướng mặc định của Chế độ xem đường phố, trỏ vào Google Sydney và liên kết đến hình ảnh tuỳ chỉnh:
TypeScript
let panorama: google.maps.StreetViewPanorama; // StreetViewPanoramaData of a panorama just outside the Google Sydney office. let outsideGoogle: google.maps.StreetViewPanoramaData; // StreetViewPanoramaData for a custom panorama: the Google Sydney reception. function getReceptionPanoramaData(): google.maps.StreetViewPanoramaData { return { location: { pano: "reception", // The ID for this custom panorama. description: "Google Sydney - Reception", latLng: new google.maps.LatLng(-33.86684, 151.19583), }, links: [ { heading: 195, description: "Exit", pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano, }, ], copyright: "Imagery (c) 2010 Google", tiles: { tileSize: new google.maps.Size(1024, 512), worldSize: new google.maps.Size(2048, 1024), centerHeading: 105, getTileUrl: function ( pano: string, zoom: number, tileX: number, tileY: number ): string { return ( "https://developers.google.com/maps/documentation/javascript/examples/full/images/" + "panoReception1024-" + zoom + "-" + tileX + "-" + tileY + ".jpg" ); }, }, }; } function initPanorama() { panorama = new google.maps.StreetViewPanorama( document.getElementById("street-view") as HTMLElement, { pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano } ); // Register a provider for the custom panorama. panorama.registerPanoProvider( (pano: string): google.maps.StreetViewPanoramaData => { if (pano === "reception") { return getReceptionPanoramaData(); } // @ts-ignore TODO fix typings return null; } ); // Add a link to our custom panorama from outside the Google Sydney office. panorama.addListener("links_changed", () => { if ( panorama.getPano() === (outsideGoogle.location as google.maps.StreetViewLocation).pano ) { panorama.getLinks().push({ description: "Google Sydney", heading: 25, pano: "reception", }); } }); } function initMap(): void { // Use the Street View service to find a pano ID on Pirrama Rd, outside the // Google office. new google.maps.StreetViewService() .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } }) .then(({ data }: google.maps.StreetViewResponse) => { outsideGoogle = data; initPanorama(); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
let panorama; // StreetViewPanoramaData of a panorama just outside the Google Sydney office. let outsideGoogle; // StreetViewPanoramaData for a custom panorama: the Google Sydney reception. function getReceptionPanoramaData() { return { location: { pano: "reception", description: "Google Sydney - Reception", latLng: new google.maps.LatLng(-33.86684, 151.19583), }, links: [ { heading: 195, description: "Exit", pano: outsideGoogle.location.pano, }, ], copyright: "Imagery (c) 2010 Google", tiles: { tileSize: new google.maps.Size(1024, 512), worldSize: new google.maps.Size(2048, 1024), centerHeading: 105, getTileUrl: function (pano, zoom, tileX, tileY) { return ( "https://developers.google.com/maps/documentation/javascript/examples/full/images/" + "panoReception1024-" + zoom + "-" + tileX + "-" + tileY + ".jpg" ); }, }, }; } function initPanorama() { panorama = new google.maps.StreetViewPanorama( document.getElementById("street-view"), { pano: outsideGoogle.location.pano }, ); // Register a provider for the custom panorama. panorama.registerPanoProvider((pano) => { if (pano === "reception") { return getReceptionPanoramaData(); } // @ts-ignore TODO fix typings return null; }); // Add a link to our custom panorama from outside the Google Sydney office. panorama.addListener("links_changed", () => { if (panorama.getPano() === outsideGoogle.location.pano) { panorama.getLinks().push({ description: "Google Sydney", heading: 25, pano: "reception", }); } }); } function initMap() { // Use the Street View service to find a pano ID on Pirrama Rd, outside the // Google office. new google.maps.StreetViewService() .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } }) .then(({ data }) => { outsideGoogle = data; initPanorama(); }); } window.initMap = initMap;
CSS
html, body { height: 100%; margin: 0; padding: 0; } #street-view { height: 100%; }
HTML
<html> <head> <title>Custom Street View Panorama Tiles</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="street-view"></div> <!-- The `defer` attribute causes the callback to execute after the full HTML document has been parsed. For non-blocking uses, avoiding race conditions, and consistent behavior across browsers, consider loading using Promises. See https://developers.google.com/maps/documentation/javascript/load-maps-js-api for more information. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>