UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

151 lines (124 loc) 5.64 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var THREE = _interopRequireWildcard(require("three")); var _Coordinates = _interopRequireDefault(require("../../Geographic/Coordinates")); var _OBB2 = _interopRequireDefault(require("../../../Renderer/OBB")); var _Extent = _interopRequireDefault(require("../../Geographic/Extent")); var PI_OV_FOUR = Math.PI / 4; var INV_TWO_PI = 1.0 / (Math.PI * 2); var axisZ = new THREE.Vector3(0, 0, 1); var axisY = new THREE.Vector3(0, 1, 0); var quatToAlignLongitude = new THREE.Quaternion(); var quatToAlignLatitude = new THREE.Quaternion(); var quatNormalToZ = new THREE.Quaternion(); function WGS84ToOneSubY(latitude) { return 1.0 - (0.5 - Math.log(Math.tan(PI_OV_FOUR + THREE.Math.degToRad(latitude) * 0.5)) * INV_TWO_PI); } var BuilderEllipsoidTile = /*#__PURE__*/ function () { function BuilderEllipsoidTile() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; (0, _classCallCheck2["default"])(this, BuilderEllipsoidTile); this.tmp = { coords: [new _Coordinates["default"]('EPSG:4326', 0, 0), new _Coordinates["default"]('EPSG:4326', 0, 0)], position: new THREE.Vector3(), dimension: new THREE.Vector2() }; this.projection = options.projection; // Order projection on tiles this.uvCount = options.uvCount; this.computeUvs = [// Normalized coordinates (from degree) on the entire tile // EPSG:4326 function () {}, // Float row coordinate from Pseudo mercator coordinates // EPSG:3857 function (params) { var t = WGS84ToOneSubY(params.projected.latitude) * params.nbRow; return (!isFinite(t) ? 0 : t) - params.deltaUV1; }]; } // prepare params // init projected object -> params.projected (0, _createClass2["default"])(BuilderEllipsoidTile, [{ key: "prepare", value: function prepare(params) { params.nbRow = Math.pow(2, params.level + 1.0); var st1 = WGS84ToOneSubY(params.extent.south); if (!isFinite(st1)) { st1 = 0; } var sizeTexture = 1.0 / params.nbRow; var start = st1 % sizeTexture; params.deltaUV1 = (st1 - start) * params.nbRow; // transformation to align tile's normal to z axis params.quatNormalToZ = quatNormalToZ.setFromAxisAngle(axisY, -(Math.PI * 0.5 - THREE.Math.degToRad(params.extent.center().latitude))); // let's avoid building too much temp objects params.projected = { longitude: 0, latitude: 0 }; params.extent.dimensions(this.tmp.dimension); } // get center tile in cartesian 3D }, { key: "center", value: function center(extent) { return extent.center(this.tmp.coords[0]).as(this.projection, this.tmp.coords[1]).toVector3(); } // get position 3D cartesian }, { key: "vertexPosition", value: function vertexPosition(params) { this.tmp.coords[0].setFromValues(params.projected.longitude, params.projected.latitude); this.tmp.coords[0].as(this.projection, this.tmp.coords[1]).toVector3(this.tmp.position); return this.tmp.position; } // get normal for last vertex }, { key: "vertexNormal", value: function vertexNormal() { return this.tmp.coords[1].geodesicNormal; } // coord u tile to projected }, { key: "uProjecte", value: function uProjecte(u, params) { params.projected.longitude = params.extent.west + u * this.tmp.dimension.x; } // coord v tile to projected }, { key: "vProjecte", value: function vProjecte(v, params) { params.projected.latitude = params.extent.south + v * this.tmp.dimension.y; } }, { key: "computeSharableExtent", value: function computeSharableExtent(extent) { // Compute sharable extent to pool the geometries // the geometry in common extent is identical to the existing input // with a transformation (translation, rotation) // TODO: It should be possible to use equatorial plan symetrie, // but we should be reverse UV on tile // Common geometry is looking for only on longitude var sizeLongitude = Math.abs(extent.west - extent.east) / 2; var sharableExtent = new _Extent["default"](extent.crs, -sizeLongitude, sizeLongitude, extent.south, extent.north); // compute rotation to transform tile to position it on ellipsoid // this transformation take into account the transformation of the parents var rotLon = THREE.Math.degToRad(extent.west - sharableExtent.west); var rotLat = THREE.Math.degToRad(90 - extent.center(this.tmp.coords[0]).latitude); quatToAlignLongitude.setFromAxisAngle(axisZ, rotLon); quatToAlignLatitude.setFromAxisAngle(axisY, rotLat); quatToAlignLongitude.multiply(quatToAlignLatitude); return { sharableExtent: sharableExtent, quaternion: quatToAlignLongitude.clone(), position: this.center(extent) }; } // use for region for adaptation boundingVolume }, { key: "OBB", value: function OBB(boundingBox) { return new _OBB2["default"](boundingBox.min, boundingBox.max); } }]); return BuilderEllipsoidTile; }(); var _default = BuilderEllipsoidTile; exports["default"] = _default;