UNPKG

@loaders.gl/tiles

Version:

Common components for different tiles loaders.

86 lines (85 loc) 4.1 kB
// loaders.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { Vector3 } from '@math.gl/core'; import { BoundingSphere, OrientedBoundingBox } from '@math.gl/culling'; import { Ellipsoid } from '@math.gl/geospatial'; const WGS84_RADIUS_X = 6378137.0; const WGS84_RADIUS_Y = 6378137.0; const WGS84_RADIUS_Z = 6356752.3142451793; const scratchVector = new Vector3(); /** * Calculate appropriate zoom value for a particular boundingVolume * @param boundingVolume - the instance of bounding volume * @param cartorgraphicCenter - cartographic center of the bounding volume * @returns {number} - zoom value */ export function getZoomFromBoundingVolume(boundingVolume, cartorgraphicCenter) { if (boundingVolume instanceof OrientedBoundingBox) { // OrientedBoundingBox const { halfAxes } = boundingVolume; const obbSize = getObbSize(halfAxes); // Use WGS84_RADIUS_Z to allign with BoundingSphere algorithm // Add the tile elevation value for correct zooming to elevated tiles return Math.log2(WGS84_RADIUS_Z / (obbSize + cartorgraphicCenter[2])); } else if (boundingVolume instanceof BoundingSphere) { // BoundingSphere const { radius } = boundingVolume; // Add the tile elevation value for correct zooming to elevated tiles return Math.log2(WGS84_RADIUS_Z / (radius + cartorgraphicCenter[2])); } else if (boundingVolume.width && boundingVolume.height) { // BoundingRectangle const { width, height } = boundingVolume; const zoomX = Math.log2(WGS84_RADIUS_X / width); const zoomY = Math.log2(WGS84_RADIUS_Y / height); return (zoomX + zoomY) / 2; } return 1; } /** * Calculate initial zoom for the tileset from 3D `fullExtent` defined in * the tileset metadata * @param fullExtent - 3D extent of the tileset * @param fullExtent.xmin - minimal longitude in decimal degrees * @param fullExtent.xmax - maximal longitude in decimal degrees * @param fullExtent.ymin - minimal latitude in decimal degrees * @param fullExtent.ymax - maximal latitude in decimal degrees * @param fullExtent.zmin - minimal elevation in meters * @param fullExtent.zmax - maximal elevation in meters * @param cartorgraphicCenter - tileset center in cartographic coordinate system * @param cartesianCenter - tileset center in cartesian coordinate system * @returns - initial zoom for the tileset */ export function getZoomFromFullExtent(fullExtent, cartorgraphicCenter, cartesianCenter) { Ellipsoid.WGS84.cartographicToCartesian([fullExtent.xmax, fullExtent.ymax, fullExtent.zmax], scratchVector); const extentSize = Math.sqrt(Math.pow(scratchVector[0] - cartesianCenter[0], 2) + Math.pow(scratchVector[1] - cartesianCenter[1], 2) + Math.pow(scratchVector[2] - cartesianCenter[2], 2)); return Math.log2(WGS84_RADIUS_Z / (extentSize + cartorgraphicCenter[2])); } /** * Calculate initial zoom for the tileset from 2D `extent` defined in * the tileset metadata * @param extent - 2D extent of the tileset. It is array of 4 elements [xmin, ymin, xmax, ymax] * @param extent[0] - minimal longitude in decimal degrees * @param extent[1] - minimal latitude in decimal degrees * @param extent[2] - maximal longitude in decimal degrees * @param extent[3] - maximal latitude in decimal degrees * @param cartorgraphicCenter - tileset center in cartographic coordinate system * @param cartesianCenter - tileset center in cartesian coordinate system * @returns - initial zoom for the tileset */ export function getZoomFromExtent(extent, cartorgraphicCenter, cartesianCenter) { const [xmin, ymin, xmax, ymax] = extent; return getZoomFromFullExtent({ xmin, xmax, ymin, ymax, zmin: 0, zmax: 0 }, cartorgraphicCenter, cartesianCenter); } function getObbSize(halfAxes) { halfAxes.getColumn(0, scratchVector); const axeY = halfAxes.getColumn(1); const axeZ = halfAxes.getColumn(2); const farthestVertex = scratchVector.add(axeY).add(axeZ); const size = farthestVertex.len(); return size; }