cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
126 lines (125 loc) • 4.45 kB
JavaScript
import glmatrix from "../../../../claygl/src/glmatrix/index.mjs";
var mat4 = glmatrix.mat4;
var TILE_SIZE = 512;
var FOV = 0.6435011087932844;
var PI = Math.PI;
var WORLD_SCALE = 1 / 10;
function MapServiceCoordSys3D() {
this.width = 0;
this.height = 0;
this.altitudeScale = 1;
this.boxHeight = "auto";
this.altitudeExtent;
this.bearing = 0;
this.pitch = 0;
this.center = [0, 0];
this._origin;
this.zoom = 0;
this._initialZoom;
this.maxPitch = 60;
this.zoomOffset = 0;
}
MapServiceCoordSys3D.prototype = {
constructor: MapServiceCoordSys3D,
dimensions: ["lng", "lat", "alt"],
containPoint: function() {
},
setCameraOption: function(option) {
this.bearing = option.bearing;
this.pitch = option.pitch;
this.center = option.center;
this.zoom = option.zoom;
if (!this._origin) {
this._origin = this.projectOnTileWithScale(this.center, TILE_SIZE);
}
if (this._initialZoom == null) {
this._initialZoom = this.zoom;
}
this.updateTransform();
},
updateTransform: function() {
if (!this.height) {
return;
}
var cameraToCenterDistance = 0.5 / Math.tan(FOV / 2) * this.height * WORLD_SCALE;
var pitch = Math.max(Math.min(this.pitch, this.maxPitch), 0) / 180 * Math.PI;
var halfFov = FOV / 2;
var groundAngle = Math.PI / 2 + pitch;
var topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);
var furthestDistance = Math.cos(Math.PI / 2 - pitch) * topHalfSurfaceDistance + cameraToCenterDistance;
var farZ = furthestDistance * 1.1;
if (this.pitch > 50) {
farZ = 1e3;
}
var m = [];
mat4.perspective(m, FOV, this.width / this.height, 1, farZ);
this.viewGL.camera.projectionMatrix.setArray(m);
this.viewGL.camera.decomposeProjectionMatrix();
var m = mat4.identity([]);
var pt = this.dataToPoint(this.center);
mat4.scale(m, m, [1, -1, 1]);
mat4.translate(m, m, [0, 0, -cameraToCenterDistance]);
mat4.rotateX(m, m, pitch);
mat4.rotateZ(m, m, -this.bearing / 180 * Math.PI);
mat4.translate(m, m, [-pt[0] * this.getScale() * WORLD_SCALE, -pt[1] * this.getScale() * WORLD_SCALE, 0]);
this.viewGL.camera.viewMatrix.array = m;
var invertM = [];
mat4.invert(invertM, m);
this.viewGL.camera.worldTransform.array = invertM;
this.viewGL.camera.decomposeWorldTransform();
var worldSize = TILE_SIZE * this.getScale();
var verticalScale;
if (this.altitudeExtent && !isNaN(this.boxHeight)) {
var range = this.altitudeExtent[1] - this.altitudeExtent[0];
verticalScale = this.boxHeight / range * this.getScale() / Math.pow(2, this._initialZoom - this.zoomOffset);
} else {
verticalScale = worldSize / (2 * Math.PI * 6378e3 * Math.abs(Math.cos(this.center[1] * (Math.PI / 180)))) * this.altitudeScale * WORLD_SCALE;
}
this.viewGL.rootNode.scale.set(this.getScale() * WORLD_SCALE, this.getScale() * WORLD_SCALE, verticalScale);
},
getScale: function() {
return Math.pow(2, this.zoom - this.zoomOffset);
},
projectOnTile: function(data, out) {
return this.projectOnTileWithScale(data, this.getScale() * TILE_SIZE, out);
},
projectOnTileWithScale: function(data, scale, out) {
var lng = data[0];
var lat = data[1];
var lambda2 = lng * PI / 180;
var phi2 = lat * PI / 180;
var x = scale * (lambda2 + PI) / (2 * PI);
var y = scale * (PI - Math.log(Math.tan(PI / 4 + phi2 * 0.5))) / (2 * PI);
out = out || [];
out[0] = x;
out[1] = y;
return out;
},
unprojectFromTile: function(point, out) {
return this.unprojectOnTileWithScale(point, this.getScale() * TILE_SIZE, out);
},
unprojectOnTileWithScale: function(point, scale, out) {
var x = point[0];
var y = point[1];
var lambda2 = x / scale * (2 * PI) - PI;
var phi2 = 2 * (Math.atan(Math.exp(PI - y / scale * (2 * PI))) - PI / 4);
out = out || [];
out[0] = lambda2 * 180 / PI;
out[1] = phi2 * 180 / PI;
return out;
},
dataToPoint: function(data, out) {
out = this.projectOnTileWithScale(data, TILE_SIZE, out);
out[0] -= this._origin[0];
out[1] -= this._origin[1];
out[2] = !isNaN(data[2]) ? data[2] : 0;
if (!isNaN(data[2])) {
out[2] = data[2];
if (this.altitudeExtent) {
out[2] -= this.altitudeExtent[0];
}
}
return out;
}
};
export { MapServiceCoordSys3D as default };