@polygonjs/plugin-mapbox
Version:
Mapbox plugin for the 3D engine https://polygonjs.com
68 lines (67 loc) • 2.62 kB
JavaScript
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
};
}
}