Maps JavaScript API cung cấp hai cách triển khai bản đồ: đường quét và vectơ. Bản đồ raster tải bản đồ dưới dạng lưới các ô hình ảnh raster dựa trên pixel, do phía máy chủ Google Maps Platform tạo, sau đó phân phát đến ứng dụng web của bạn. Bản đồ vectơ bao gồm các ô dựa trên vectơ, được vẽ tại thời điểm tải ở phía máy khách bằng WebGL, một công nghệ web cho phép trình duyệt truy cập vào GPU trên thiết bị của người dùng để kết xuất đồ hoạ 2D và 3D.
Bản đồ vectơ là cùng một bản đồ Google mà người dùng của bạn đã quen sử dụng và mang lại một số lợi thế so với bản đồ ô điểm ảnh mặc định, đáng chú ý nhất là độ sắc nét của hình ảnh dựa trên vectơ và việc bổ sung các toà nhà 3D ở mức thu phóng gần. Bản đồ vectơ hỗ trợ các tính năng sau:
- Điều khiển độ nghiêng và hướng theo phương thức lập trình
- Điều khiển máy ảnh nâng cao
- Thu phóng từng phần để thu phóng mượt mà hơn
Đối với bản đồ được tải bằng phần tử
divvà JavaScript, loại kết xuất mặc định làgoogle.maps.RenderingType.RASTER.Đối với bản đồ được tải bằng phần tử
gmp-map, loại kết xuất mặc định làgoogle.maps.RenderingType.VECTOR, có bật chế độ điều khiển độ nghiêng và hướng.
Độ nghiêng và xoay
Bạn có thể đặt độ nghiêng và độ xoay (hướng) trên bản đồ vectơ bằng cách thêm các thuộc tính heading và tilt khi khởi chạy bản đồ, đồng thời gọi các phương thức setTilt và setHeading trên bản đồ. Ví dụ sau đây thêm một số nút vào bản đồ để cho thấy việc điều chỉnh độ nghiêng và hướng theo phương thức lập trình với mức tăng 20 độ.
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: { lat: 37.7893719, lng: -122.3942, }, zoom: 16, heading: 320, tilt: 47.5, mapId: "90f87356969d889c", } ); const buttons: [string, string, number, google.maps.ControlPosition][] = [ ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER], ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER], ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER], ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER], ]; buttons.forEach(([text, mode, amount, position]) => { const controlDiv = document.createElement("div"); const controlUI = document.createElement("button"); controlUI.classList.add("ui-button"); controlUI.innerText = `${text}`; controlUI.addEventListener("click", () => { adjustMap(mode, amount); }); controlDiv.appendChild(controlUI); map.controls[position].push(controlDiv); }); const adjustMap = function (mode: string, amount: number) { switch (mode) { case "tilt": map.setTilt(map.getTilt()! + amount); break; case "rotate": map.setHeading(map.getHeading()! + amount); break; default: break; } }; } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 37.7893719, lng: -122.3942, }, zoom: 16, heading: 320, tilt: 47.5, mapId: "90f87356969d889c", }); const buttons = [ ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER], ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER], ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER], ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER], ]; buttons.forEach(([text, mode, amount, position]) => { const controlDiv = document.createElement("div"); const controlUI = document.createElement("button"); controlUI.classList.add("ui-button"); controlUI.innerText = `${text}`; controlUI.addEventListener("click", () => { adjustMap(mode, amount); }); controlDiv.appendChild(controlUI); map.controls[position].push(controlDiv); }); const adjustMap = function (mode, amount) { switch (mode) { case "tilt": map.setTilt(map.getTilt() + amount); break; case "rotate": map.setHeading(map.getHeading() + amount); break; default: break; } }; } 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; } .ui-button { background-color: #fff; border: 0; border-radius: 2px; box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3); margin: 10px; padding: 0 0.5em; font: 400 18px Roboto, Arial, sans-serif; overflow: hidden; height: 40px; cursor: pointer; } .ui-button:hover { background: rgb(235, 235, 235); }
HTML
<html>
<head>
<title>Tilt and Rotation</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
defer
></script>
</body>
</html>Sử dụng cử chỉ chuột và bàn phím
Nếu bạn đã bật các hoạt động tương tác của người dùng về độ nghiêng và độ xoay (hướng) (theo phương thức lập trình hoặc trong Google Cloud Console), thì người dùng có thể điều chỉnh độ nghiêng và độ xoay bằng chuột và bàn phím:
- Sử dụng chuột, giữ phím Shift, sau đó kéo chuột lên và xuống để điều chỉnh độ nghiêng, sang phải và sang trái để điều chỉnh hướng.
- Khi sử dụng bàn phím, hãy giữ phím Shift, sau đó dùng phím mũi tên lên và mũi tên xuống để điều chỉnh độ nghiêng, đồng thời dùng phím mũi tên phải và mũi tên trái để điều chỉnh hướng.
Điều chỉnh độ nghiêng và hướng theo phương thức lập trình
Sử dụng các phương thức setTilt() và setHeading() để điều chỉnh độ nghiêng và hướng trên bản đồ vectơ theo phương thức lập trình. Hướng là hướng mà camera đang hướng tới, tính theo độ theo chiều kim đồng hồ bắt đầu từ hướng bắc, vì vậy, map.setHeading(90) sẽ xoay bản đồ sao cho hướng đông hướng lên trên. Góc nghiêng được đo từ thiên đỉnh, vì vậy, map.setTilt(0) là nhìn thẳng xuống, trong khi map.setTilt(45) sẽ cho ra chế độ xem xiên.
- Gọi
setTilt()để đặt góc nghiêng của bản đồ. Sử dụnggetTilt()để lấy giá trị độ nghiêng hiện tại. - Gọi
setHeading()để đặt hướng của bản đồ. Sử dụnggetHeading()để lấy giá trị hướng hiện tại.
Để thay đổi tâm bản đồ trong khi vẫn giữ nguyên độ nghiêng và hướng, hãy sử dụng map.setCenter() hoặc map.panBy().
Xin lưu ý rằng phạm vi góc có thể sử dụng sẽ thay đổi tuỳ theo mức thu phóng hiện tại. Các giá trị nằm ngoài phạm vi này sẽ được giới hạn trong phạm vi cho phép.
Bạn cũng có thể sử dụng phương thức moveCamera để thay đổi hướng, độ nghiêng, tâm và mức thu phóng theo phương thức lập trình.
Tìm hiểu thêm.
Tác động đến các phương thức khác
Khi bạn áp dụng độ nghiêng hoặc độ xoay cho bản đồ, hành vi của các phương thức khác trong API JavaScript của Maps sẽ bị ảnh hưởng:
map.getBounds()luôn trả về hộp giới hạn nhỏ nhất bao gồm vùng hiển thị; khi áp dụng độ nghiêng, giới hạn được trả về có thể đại diện cho một vùng lớn hơn vùng hiển thị của khung nhìn trên bản đồ.map.fitBounds()sẽ đặt lại độ nghiêng và hướng về 0 trước khi điều chỉnh cho vừa với ranh giới.map.panToBounds()sẽ đặt lại độ nghiêng và hướng về 0 trước khi kéo ranh giới.map.setTilt()chấp nhận mọi giá trị, nhưng hạn chế độ nghiêng tối đa dựa trên mức thu phóng hiện tại của bản đồ.map.setHeading()chấp nhận mọi giá trị và sẽ sửa đổi giá trị đó cho phù hợp với phạm vi[0, 360].
Điều khiển camera
Sử dụng hàm map.moveCamera() để cập nhật cùng lúc mọi tổ hợp thuộc tính của camera. map.moveCamera() chấp nhận một tham số duy nhất chứa
tất cả thuộc tính của máy ảnh cần cập nhật. Ví dụ sau đây cho thấy cách gọi map.moveCamera() để đặt center, zoom, heading và tilt cùng một lúc:
map.moveCamera({
center: new google.maps.LatLng(37.7893719, -122.3942),
zoom: 16,
heading: 320,
tilt: 47.5
});
Bạn có thể tạo ảnh động cho các thuộc tính của camera bằng cách gọi map.moveCamera() bằng một vòng lặp ảnh động, như minh hoạ dưới đây:
const degreesPerSecond = 3;
function animateCamera(time) {
// Update the heading, leave everything else as-is.
map.moveCamera({
heading: (time / 1000) * degreesPerSecond
});
requestAnimationFrame(animateCamera);
}
// Start the animation.
requestAnimationFrame(animateCamera);
Vị trí camera
Chế độ xem bản đồ được mô phỏng như một máy ảnh nhìn xuống mặt phẳng. Vị trí của camera (và việc hiển thị của bản đồ) được xác định bởi các thuộc tính sau: nhắm mục tiêu (vĩ độ/kinh độ của địa điểm), đeo, nghiêng và thu phóng.
Mục tiêu (vị trí)
Mục tiêu của camera là vị trí của tâm bản đồ, được chỉ định dưới dạng toạ độ vĩ độ và kinh độ.
Vĩ độ có thể nằm trong khoảng từ -85 đến 85 độ. Các giá trị nằm ngoài phạm vi này sẽ được giới hạn ở giá trị gần nhất trong phạm vi này. Ví dụ: nếu bạn chỉ định vĩ độ là 100, thì giá trị sẽ được đặt thành 85. Kinh độ nằm trong khoảng từ -180 đến 180 độ. Các giá trị nằm ngoài phạm vi này sẽ được điều chỉnh để nằm trong phạm vi (-180, 180). Ví dụ: 480, 840 và 1200 đều sẽ được gói thành 120 độ.Góc phương vị (hướng)
Góc phương vị của camera chỉ định hướng la bàn, được đo bằng độ từ hướng bắc thực, tương ứng với cạnh trên của bản đồ. Nếu bạn vẽ một đường thẳng đứng từ tâm bản đồ đến cạnh trên của bản đồ, thì góc phương vị sẽ tương ứng với hướng của camera (đo bằng độ) so với hướng bắc thực.
Góc phương vị bằng 0 có nghĩa là phần trên cùng của bản đồ chỉ về hướng chính bắc. Giá trị góc phương vị 90 có nghĩa là đỉnh của bản đồ hướng về phía đông (90 độ trên la bàn). Giá trị 180 có nghĩa là phần trên cùng của bản đồ hướng về phía nam.
API Maps cho phép bạn thay đổi hướng của bản đồ. Ví dụ: người lái xe ô tô thường xoay bản đồ đường đi cho phù hợp với hướng di chuyển của họ, trong khi người đi bộ đường dài sử dụng bản đồ và la bàn thường định hướng bản đồ sao cho đường thẳng đứng hướng về phía bắc.
Độ nghiêng (góc xem)
Độ nghiêng xác định vị trí của camera trên một cung tròn ngay phía trên vị trí trung tâm của bản đồ, được đo bằng độ từ thiên để (hướng chỉ thẳng xuống dưới camera). Giá trị 0 tương ứng với camera hướng thẳng xuống. Giá trị lớn hơn 0 tương ứng với máy ảnh được nghiêng về phía đường chân trời theo số độ được chỉ định. Khi bạn thay đổi góc xem, bản đồ sẽ xuất hiện theo phối cảnh, trong đó các đối tượng ở xa sẽ xuất hiện nhỏ hơn và các đối tượng ở gần sẽ xuất hiện lớn hơn. Hình minh hoạ sau đây cho thấy điều này.
Trong các hình ảnh bên dưới, góc nhìn là 0 độ. Hình ảnh đầu tiên cho thấy sơ đồ của việc này; vị trí 1 là vị trí của camera và vị trí 2 là vị trí hiện tại trên bản đồ. Bản đồ kết quả được hiển thị bên dưới.
|
|
Trong các hình ảnh bên dưới, góc xem là 45 độ. Hãy lưu ý rằng máy ảnh di chuyển nửa chừng dọc theo một cung giữa vị trí thẳng trên đầu (0 độ) và mặt đất (90 độ), đến vị trí 3. Máy ảnh vẫn hướng vào điểm trung tâm của bản đồ, nhưng khu vực được biểu thị bằng đường thẳng ở vị trí 4 hiện đã hiển thị.
|
|
Bản đồ trong ảnh chụp màn hình này vẫn được căn giữa tại cùng một điểm như trong bản đồ gốc, nhưng có nhiều tính năng hơn xuất hiện ở đầu bản đồ. Khi bạn tăng góc vượt quá 45 độ, các đối tượng giữa camera và vị trí bản đồ sẽ xuất hiện lớn hơn theo tỷ lệ, trong khi các đối tượng nằm ngoài vị trí bản đồ sẽ xuất hiện nhỏ hơn theo tỷ lệ, tạo ra hiệu ứng ba chiều.
Zoom (thu phóng)
Mức thu phóng của camera xác định tỷ lệ của bản đồ. Ở mức thu phóng lớn hơn, bạn có thể thấy nhiều chi tiết hơn trên màn hình, trong khi ở mức thu phóng nhỏ hơn, bạn có thể thấy nhiều khu vực hơn trên màn hình.
Mức thu phóng không cần phải là số nguyên. Phạm vi mức thu phóng mà bản đồ cho phép phụ thuộc vào một số yếu tố, bao gồm mục tiêu, loại bản đồ và kích thước màn hình. Mọi số nằm ngoài phạm vi này sẽ được chuyển đổi thành giá trị hợp lệ gần nhất tiếp theo, có thể là mức thu phóng tối thiểu hoặc mức thu phóng tối đa. Danh sách sau đây cho biết mức độ chi tiết gần đúng mà bạn có thể thấy ở mỗi mức thu phóng:
- 1: Thế giới
- 5: Lục địa/đại lục
- 10: Thành phố
- 15: Đường phố
- 20: Toà nhà
|
|
|
Thu phóng từng phần
Bản đồ vectơ hỗ trợ tính năng thu phóng phân số, cho phép bạn thu phóng bằng các giá trị phân số thay vì số nguyên. Mặc dù cả bản đồ raster và bản đồ vectơ đều hỗ trợ tính năng thu phóng phân số, nhưng tính năng thu phóng phân số được bật theo mặc định cho bản đồ vectơ và tắt theo mặc định cho bản đồ raster. Sử dụng tuỳ chọn bản đồ isFractionalZoomEnabled để bật và tắt tính năng thu phóng phân số.
Ví dụ sau đây cho thấy cách bật tính năng thu phóng phân số khi khởi chạy bản đồ:
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8,
isFractionalZoomEnabled: true
});
Bạn cũng có thể bật và tắt tính năng thu phóng từng phần bằng cách đặt tuỳ chọn bản đồ isFractionalZoomEnabled như minh hoạ dưới đây:
// Using map.set
map.set('isFractionalZoomEnabled', true);
// Using map.setOptions
map.setOptions({isFractionalZoomEnabled: true});
Bạn có thể đặt trình nghe để phát hiện xem tính năng thu phóng phân số có được bật hay không; điều này hữu ích nhất nếu bạn chưa đặt rõ ràng isFractionalZoomEnabled thành true hoặc false. Mã ví dụ sau đây kiểm tra xem tính năng thu phóng từng phần có được bật hay không:
map.addListener('isfractionalzoomenabled_changed', () => {
const isFractionalZoomEnabled = map.get('isFractionalZoomEnabled');
if (isFractionalZoomEnabled === false) {
console.log('not using fractional zoom');
} else if (isFractionalZoomEnabled === true) {
console.log('using fractional zoom');
} else {
console.log('map not done initializing yet');
}
});