UNPKG

@deck.gl/core

Version:

deck.gl core library

92 lines 4.08 kB
// deck.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors /** * Projection utils * TODO: move to Viewport class? */ import { COORDINATE_SYSTEM } from "../../lib/constants.js"; import { getOffsetOrigin } from "./viewport-uniforms.js"; import WebMercatorViewport from "../../viewports/web-mercator-viewport.js"; import { vec3, vec4 } from '@math.gl/core'; import { addMetersToLngLat } from '@math.gl/web-mercator'; const DEFAULT_COORDINATE_ORIGIN = [0, 0, 0]; // In project.glsl, offset modes calculate z differently from LNG_LAT mode. // offset modes apply the y adjustment (unitsPerMeter2) when projecting z // LNG_LAT mode only use the linear scale. function lngLatZToWorldPosition(lngLatZ, viewport, offsetMode = false) { const p = viewport.projectPosition(lngLatZ); // TODO - avoid using instanceof if (offsetMode && viewport instanceof WebMercatorViewport) { const [longitude, latitude, z = 0] = lngLatZ; const distanceScales = viewport.getDistanceScales([longitude, latitude]); p[2] = z * distanceScales.unitsPerMeter[2]; } return p; } function normalizeParameters(opts) { const { viewport, modelMatrix, coordinateOrigin } = opts; let { coordinateSystem, fromCoordinateSystem, fromCoordinateOrigin } = opts; if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) { coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN; } if (fromCoordinateSystem === undefined) { fromCoordinateSystem = coordinateSystem; } if (fromCoordinateOrigin === undefined) { fromCoordinateOrigin = coordinateOrigin; } return { viewport, coordinateSystem, coordinateOrigin, modelMatrix, fromCoordinateSystem, fromCoordinateOrigin }; } /** Get the common space position from world coordinates in the given coordinate system */ export function getWorldPosition(position, { viewport, modelMatrix, coordinateSystem, coordinateOrigin, offsetMode }) { let [x, y, z = 0] = position; if (modelMatrix) { [x, y, z] = vec4.transformMat4([], [x, y, z, 1.0], modelMatrix); } switch (coordinateSystem) { case COORDINATE_SYSTEM.LNGLAT: return lngLatZToWorldPosition([x, y, z], viewport, offsetMode); case COORDINATE_SYSTEM.LNGLAT_OFFSETS: return lngLatZToWorldPosition([x + coordinateOrigin[0], y + coordinateOrigin[1], z + (coordinateOrigin[2] || 0)], viewport, offsetMode); case COORDINATE_SYSTEM.METER_OFFSETS: return lngLatZToWorldPosition(addMetersToLngLat(coordinateOrigin, [x, y, z]), viewport, offsetMode); case COORDINATE_SYSTEM.CARTESIAN: default: return viewport.isGeospatial ? [x + coordinateOrigin[0], y + coordinateOrigin[1], z + coordinateOrigin[2]] : viewport.projectPosition([x, y, z]); } } /** * Equivalent to project_position in project.glsl * projects a user supplied position to world position directly with or without * a reference coordinate system */ export function projectPosition(position, params) { const { viewport, coordinateSystem, coordinateOrigin, modelMatrix, fromCoordinateSystem, fromCoordinateOrigin } = normalizeParameters(params); const { autoOffset = true } = params; const { geospatialOrigin = DEFAULT_COORDINATE_ORIGIN, shaderCoordinateOrigin = DEFAULT_COORDINATE_ORIGIN, offsetMode = false } = autoOffset ? getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin) : {}; const worldPosition = getWorldPosition(position, { viewport, modelMatrix, coordinateSystem: fromCoordinateSystem, coordinateOrigin: fromCoordinateOrigin, offsetMode }); if (offsetMode) { const positionCommonSpace = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin); vec3.sub(worldPosition, worldPosition, positionCommonSpace); } return worldPosition; } //# sourceMappingURL=project-functions.js.map