UNPKG

@polygonjs/plugin-mapbox

Version:

Mapbox plugin for the 3D engine https://polygonjs.com

68 lines (67 loc) 2.62 kB
import { Vector3 } from "three"; import { Matrix4 } from "three"; import { CoreMapboxConstants } from "./Constants"; const Constants = CoreMapboxConstants; export class CoreMapboxUtils { static makePerspectiveMatrix(fovy, aspect, near, far) { const out = new Matrix4(); const f = 1 / Math.tan(fovy / 2); const nf = 1 / (near - far); const newMatrix = [f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) * nf, -1, 0, 0, 2 * far * near * nf, 0]; out.elements = newMatrix; return out; } static projectToWorld(lnglat) { const projected = [ -Constants.MERCATOR_A * lnglat[0] * Constants.DEG2RAD * Constants.PROJECTION_WORLD_SIZE, -Constants.MERCATOR_A * Math.log(Math.tan(Math.PI * 0.25 + 0.5 * lnglat[1] * Constants.DEG2RAD)) * Constants.PROJECTION_WORLD_SIZE ]; const pixelsPerMeter = this.projectedUnitsPerMeter(lnglat[1]); let height = lnglat[2]; if (height == null) { height = 0; } projected.push(height * pixelsPerMeter); return new Vector3(projected[0], projected[1], projected[2]); } static projectedUnitsPerMeter(latitude) { return Math.abs(Constants.WORLD_SIZE * (1 / Math.cos(latitude * Math.PI / 180)) / Constants.EARTH_CIRCUMFERENCE); } static fromLL(lon, lat) { const extent = 2003750834e-2; const x = lon * extent / 180; let y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * extent / 180; return [(x + extent) / (2 * extent), 1 - (y + extent) / (2 * extent)]; } static fromLLv(position) { const ll = this.fromLL(position.x, position.z); return new Vector3(ll[0], position.y, ll[1]); } static get_distance(latlng1, latlng2) { const R = 6371e3; const rad = Math.PI / 180, lat1 = latlng1.lat * rad, lat2 = latlng2.lat * rad, a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlng2.lng - latlng1.lng) * rad); const maxMeters = R * Math.acos(Math.min(a, 1)); return maxMeters; } static lnglat_to_tile_number(lng_deg, lat_deg, zoom) { const lat_rad = lat_deg / 180 * Math.PI; const n = 2 ** zoom; const x = Math.floor((lng_deg + 180) / 360 * n); const y = Math.floor((1 - Math.log(Math.tan(lat_rad) + 1 / Math.cos(lat_rad)) / Math.PI) / 2 * n); return { x, y }; } static tile_number_to_lnglat(xtile, ytile, zoom) { const n = 2 ** zoom; const lon_deg = xtile / n * 360 - 180; const lat_rad = Math.atan(Math.sinh(Math.PI * (1 - 2 * ytile / n))); const lat_deg = 180 * (lat_rad / Math.PI); return { lat: lat_deg, lng: lon_deg }; } }