Với WebGL Overlay View, bạn có thể thêm nội dung vào bản đồ bằng cách sử dụng trực tiếp WebGL hoặc các thư viện đồ hoạ phổ biến như Three.js. Lớp phủ WebGL cung cấp quyền truy cập trực tiếp vào cùng một ngữ cảnh kết xuất WebGL mà Nền tảng Google Maps dùng để kết xuất bản đồ cơ sở dạng vectơ. Việc sử dụng ngữ cảnh kết xuất dùng chung này mang lại nhiều lợi ích, chẳng hạn như độ che khuất theo chiều sâu với hình học toà nhà 3D và khả năng đồng bộ hoá nội dung 2D/3D với hoạt động kết xuất bản đồ cơ sở. Các đối tượng được kết xuất bằng WebGL Overlay View cũng có thể được liên kết với toạ độ vĩ độ/kinh độ, vì vậy, chúng sẽ di chuyển khi bạn kéo, thu phóng, xoay hoặc nghiêng bản đồ.
Yêu cầu
Để sử dụng Lớp phủ WebGL, bạn phải tải bản đồ bằng mã bản đồ có bản đồ vectơ được bật. Bạn nên bật chế độ nghiêng và xoay khi tạo mã bản đồ để cho phép kiểm soát hoàn toàn camera 3D. Xem thông tin tổng quan để biết chi tiết.
Thêm Chế độ xem lớp phủ WebGL
Để thêm lớp phủ vào bản đồ, hãy triển khai google.maps.WebGLOverlayView
, sau đó truyền phiên bản bản đồ bằng cách sử dụng setMap
:
// Create a map instance.
const map = new google.maps.Map(mapDiv, mapOptions);
// Create a WebGL Overlay View instance.
const webglOverlayView = new google.maps.WebGLOverlayView();
// Add the overlay to the map.
webglOverlayView.setMap(map);
Lifecycle hooks
WebGL Overlay View cung cấp một bộ các lệnh gọi được gọi vào nhiều thời điểm trong vòng đời của ngữ cảnh kết xuất WebGL của bản đồ cơ sở vectơ. Đây là các hook vòng đời mà bạn thiết lập, vẽ và tháo dỡ mọi thứ bạn muốn hiển thị trong lớp phủ.
onAdd()
được gọi khi lớp phủ được tạo. Sử dụng phương thức này để tìm nạp hoặc tạo cấu trúc dữ liệu trung gian trước khi lớp phủ được vẽ mà không yêu cầu quyền truy cập ngay vào ngữ cảnh kết xuất WebGL.onContextRestored({gl})
được gọi khi có sẵn ngữ cảnh kết xuất. Sử dụng hàm này để khởi tạo hoặc liên kết mọi trạng thái WebGL, chẳng hạn như chương trình đổ bóng, đối tượng vùng đệm GL, v.v.onContextRestored()
lấy một thực thểWebGLStateOptions
có một trường duy nhất:gl
là một đối tượng xử lý choWebGLRenderingContext
mà bản đồ cơ sở sử dụng.
onDraw({gl, transformer})
kết xuất cảnh trên bản đồ cơ sở. Các tham số choonDraw()
là đối tượngWebGLDrawOptions
, có hai trường:gl
là một đối tượng xử lý choWebGLRenderingContext
mà bản đồ cơ sở sử dụng.transformer
cung cấp các hàm trợ giúp để chuyển đổi từ toạ độ bản đồ sang ma trận chiếu mô hình-khung hiển thị. Bạn có thể dùng ma trận này để chuyển đổi toạ độ bản đồ sang không gian thế giới, không gian camera và không gian màn hình.
onContextLost()
được gọi khi ngữ cảnh kết xuất bị mất vì bất kỳ lý do nào và là nơi bạn nên dọn dẹp mọi trạng thái GL đã có từ trước vì trạng thái đó không còn cần thiết nữa.onStateUpdate({gl})
cập nhật trạng thái GL bên ngoài vòng lặp kết xuất và được gọi khirequestStateUpdate
được gọi. Phương thức này lấy một thực thểWebGLStateOptions
có một trường duy nhất:gl
là một đối tượng xử lý choWebGLRenderingContext
mà bản đồ cơ sở sử dụng.
onRemove()
được gọi khi lớp phủ bị xoá khỏi bản đồ bằngWebGLOverlayView.setMap(null)
và là nơi bạn nên xoá tất cả các đối tượng trung gian.
Ví dụ: sau đây là một cách triển khai cơ bản của tất cả các hook vòng đời:
const webglOverlayView = new google.maps.WebGLOverlayView();
webglOverlayView.onAdd = () => {
// Do setup that does not require access to rendering context.
}
webglOverlayView.onContextRestored = ({gl}) => {
// Do setup that requires access to rendering context before onDraw call.
}
webglOverlayView.onStateUpdate = ({gl}) => {
// Do GL state setup or updates outside of the render loop.
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Render objects.
}
webglOverlayView.onContextLost = () => {
// Clean up pre-existing GL state.
}
webglOverlayView.onRemove = () => {
// Remove all intermediate objects.
}
webglOverlayView.setMap(map);
Đặt lại trạng thái GL
Chế độ xem lớp phủ WebGL hiển thị ngữ cảnh kết xuất WebGL của bản đồ cơ sở. Vì lý do này, bạn cần phải đặt lại trạng thái GL về trạng thái ban đầu khi hoàn tất việc kết xuất các đối tượng. Việc không đặt lại trạng thái GL có thể dẫn đến xung đột trạng thái GL, khiến quá trình kết xuất cả bản đồ và mọi đối tượng mà bạn chỉ định đều không thành công.
Việc đặt lại trạng thái GL thường được xử lý trong lệnh gọi onDraw()
. Ví dụ: Three.js cung cấp một hàm trợ giúp giúp xoá mọi thay đổi đối với trạng thái GL:
webglOverlayView.onDraw = ({gl, transformer}) => {
// Specify an object to render.
renderer.render(scene, camera);
renderer.resetState();
}
Nếu bản đồ hoặc các đối tượng của bạn không kết xuất được, rất có thể trạng thái GL chưa được đặt lại.
Phép biến đổi toạ độ
Vị trí của một đối tượng trên bản đồ vectơ được chỉ định bằng cách cung cấp một tổ hợp gồm toạ độ vĩ độ và kinh độ, cũng như độ cao. Tuy nhiên, đồ hoạ 3D được chỉ định trong không gian thế giới, không gian camera hoặc không gian màn hình.
Để giúp bạn dễ dàng chuyển đổi toạ độ trên bản đồ sang những không gian thường dùng này, Chế độ xem lớp phủ WebGL cung cấp hàm trợ giúp coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr,
scalarArr)
trong lệnh gọi onDraw()
. Hàm này nhận các giá trị sau và trả về Float64Array
:
latLngAltitude
: Toạ độ vĩ độ/kinh độ/độ cao dưới dạngLatLngAltitude
hoặcLatLngAltitudeLiteral
.rotationArr
:Float32Array
của các góc xoay euler được chỉ định theo độ.scalarArr
:Float32Array
của các đại lượng vô hướng cần áp dụng cho trục chính.
Ví dụ: sau đây sử dụng fromLatLngAltitude()
để tạo ma trận chiếu camera trong Three.js:
const camera = new THREE.PerspectiveCamera();
const matrix = coordinateTransformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
Ví dụ:
Sau đây là một ví dụ đơn giản về cách sử dụng Three.js, một thư viện WebGL nguồn mở phổ biến, để đặt một đối tượng 3D trên bản đồ. Để xem hướng dẫn đầy đủ về cách sử dụng Chế độ xem lớp phủ WebGL để tạo ví dụ mà bạn thấy đang chạy ở đầu trang này, hãy thử Lớp học lập trình Xây dựng trải nghiệm bản đồ được tăng tốc bằng WebGL.
const webglOverlayView = new google.maps.WebGLOverlayView();
let scene, renderer, camera, loader;
webglOverlayView.onAdd = () => {
// Set up the Three.js scene.
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera();
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.75 ); // Soft white light.
scene.add(ambientLight);
// Load the 3D model with GLTF Loader from Three.js.
loader = new GLTFLoader();
loader.load("pin.gltf");
}
webglOverlayView.onContextRestored = ({gl}) => {
// Create the Three.js renderer, using the
// maps's WebGL rendering context.
renderer = new THREE.WebGLRenderer({
canvas: gl.canvas,
context: gl,
...gl.getContextAttributes(),
});
renderer.autoClear = false;
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Update camera matrix to ensure the model is georeferenced correctly on the map.
const matrix = transformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
// Request a redraw and render the scene.
webglOverlayView.requestRedraw();
renderer.render(scene, camera);
// Always reset the GL state.
renderer.resetState();
}
// Add the overlay to the map.
webglOverlayView.setMap(map);