Вы можете добавлять контент на карты в наложениях WebGL, используя API WebGL или популярные графические библиотеки, такие как Three.js. Такие наложения обеспечивают прямой доступ к контексту визуализации WebGL, который платформа Google Карт использует для отрисовки векторной базовой карты. Общий контекст визуализации позволяет отрисовывать перекрывающиеся в глубине трехмерные здания и синхронизировать показ 2D/3D-контента с отрисовкой базовой карты. Объекты в наложениях WebGL также можно привязать к географическим координатам, чтобы закрепить их на определенном месте при перетаскивании, масштабировании, панорамировании или наклоне карты.
Требования
Для работы с режимом просмотра WebGL необходимо загрузить векторную карту с присвоенным ей идентификатором. Мы настоятельно рекомендуем включить функции наклона и ориентации при создании идентификатора карты, чтобы обеспечить полноценное управление 3D-камерой. Подробнее...
Как добавить наложение WebGL
Чтобы добавить наложение на карту, реализуйте метод google.maps.WebGLOverlayView
и передайте ему свой экземпляр карты с помощью 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);
Обработчики жизненного цикла
С наложениями WebGL можно использовать ряд обработчиков, которые вызываются в разных точках цикла отрисовки в WebGL контекста векторной базовой карты. Такие обработчики вызываются при настройке, нанесении на карту и удалении отрисовываемой в наложении информации.
onAdd()
– вызывается при создании наложения. Используйте этот обработчик для извлечения или создания промежуточных структур данных, которые не требуют немедленного доступа к контексту визуализации WebGL, перед отрисовкой наложения.onContextRestored({gl})
– вызывается, когда становится доступен контекст визуализации. Используйте этот обработчик для инициализации или привязки любого состояния WebGL (шейдеров, объектов буфера GL и т. д.).onContextRestored()
принимает экземпляр классаWebGLStateOptions
, содержащий одно поле:gl
– дескрипторWebGLRenderingContext
в базовой карте.
onDraw({gl, transformer})
– отрисовывает сцену базовой карты. ПараметрыonDraw()
задаются в объектеWebGLDrawOptions
c двумя полями:gl
– дескрипторWebGLRenderingContext
в базовой карте.transformer
– вспомогательные функции для преобразования координат карты через матрицу "модель-вид-проекция" в объекты пространства мира, камеры или экрана.
onContextLost()
– вызывается, когда контекст визуализации потерян. Очищает все предыдущие состояния графической библиотеки, поскольку они больше не потребуются.onStateUpdate({gl})
– меняет состояние графической библиотеки вне цикла отрисовки. Вызывается при вызовеrequestStateUpdate
и принимает экземпляр классаWebGLStateOptions
, содержащий одно поле:gl
– дескрипторWebGLRenderingContext
в базовой карте.
onRemove()
– вызывается при удалении наложения с карты с помощью методаWebGLOverlayView.setMap(null)
и очищает все промежуточные объекты.
Ниже приведен пример базовой реализации всех обработчиков жизненного цикла.
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);
Сброс состояния графической библиотеки
Наложение WebGL предоставляет контекст графической библиотеки WebGL для визуализации базовой карты. Поэтому по окончании отрисовки объектов состояние графической библиотеки важно вернуть к исходному. В противном случае это может вызвать конфликт состояний графической библиотеки и привести к сбою отрисовки карты и любых заданных на ней объектов.
Сброс состояния графической библиотеки обычно выполняется в обработчике onDraw()
. Например, в Three.js предусмотрена вспомогательная функция, которая сбрасывает все изменения в состоянии библиотеки:
webglOverlayView.onDraw = ({gl, transformer}) => {
// Specify an object to render.
renderer.render(scene, camera);
renderer.resetState();
}
Если ваша карта или объекты на ней не отображаются, весьма вероятно, что состояние графической библиотеки не было сброшено.
Преобразования координат
Положение объекта на векторной карте определяется комбинацией координат широты, долготы и высоты. В то же время положение объектов 3D-графики задается в пространстве мира, камеры или экрана.
Чтобы упростить преобразование координат карты в координаты этих пространств, в наложении WebGL предусмотрена вспомогательная функция coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr,
scalarArr)
в обработчике onDraw()
. Она принимает следующие объекты и возвращает в ответ массив Float64Array
:
latLngAltitude
– координаты широты/долготы/высоты в виде объектаLatLngAltitude
илиLatLngAltitudeLiteral
;rotationArr
– массивFloat32Array
с углами Эйлера, задающими ориентацию в градусах;scalarArr
–Float32Array
массив скалярных значений по главной оси.
В примере ниже метод fromLatLngAltitude()
используется для создания матрицы проекций камеры в 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);
Пример
Ниже приведен простой пример использования Three.js, популярной библиотеки WebGL с открытым исходным кодом, для размещения 3D-объекта на карте. Если вы хотите узнать во всех подробностях, как была создана карта, которую вы видите вверху этой страницы, выполните практическую работу по созданию карт с 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);