UNPKG

vue-cesium

Version:
244 lines (239 loc) 10.3 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var lodashUnified = require('lodash-unified'); var prettifyCoordinates = require('./prettifyCoordinates.js'); var prettifyProjection = require('./prettifyProjection.js'); var EarthGravityModel1996 = require('./EarthGravityModel1996.js'); "use strict"; class MouseCoords { constructor(options) { const { Cartographic, knockout } = Cesium; const gridFileUrl = options.gridFileUrl; gridFileUrl && (this.geoidModel = new EarthGravityModel1996["default"](gridFileUrl)); this.proj4Projection = options.proj4Projection; this.projectionUnits = options.projectionUnits; this.proj4longlat = options.proj4longlat; this.lastHeightSamplePosition = new Cartographic(); this.accurateSamplingDebounceTime = 250; this.tileRequestInFlight = void 0; this.elevation = ""; this.utmZone = ""; this.latitude = ""; this.longitude = ""; this.north = ""; this.east = ""; this.useProjection = false; this.debounceSampleAccurateHeight = lodashUnified.debounce(this.sampleAccurateHeight, this.accurateSamplingDebounceTime); this.decimal = options.decimal || 5; this.rangeType = options.rangeType || 0; knockout.track(this, ["elevation", "utmZone", "latitude", "longitude", "north", "east", "useProjection"]); } toggleUseProjection() { this.useProjection = !this.useProjection; } updateCoordinatesFromCesium(viewer, position) { const { Cartographic, defined, EllipsoidTerrainProvider, Intersections2D, SceneMode } = Cesium; const scene = viewer.scene; const camera = scene.camera; const pickRay = camera.getPickRay(position); const globe = scene.globe; const pickedTriangle = globe.pickTriangle(pickRay, scene); if (defined(pickedTriangle)) { const ellipsoid = globe.ellipsoid; const v0 = ellipsoid.cartesianToCartographic(pickedTriangle.v0); const v1 = ellipsoid.cartesianToCartographic(pickedTriangle.v1); const v2 = ellipsoid.cartesianToCartographic(pickedTriangle.v2); const intersection = ellipsoid.cartesianToCartographic( scene.mode === SceneMode.SCENE3D ? pickedTriangle.intersection : scene.globe.pick(pickRay, scene) ); let errorBar; if (globe.terrainProvider instanceof EllipsoidTerrainProvider) { intersection.height = void 0; } else { const barycentric = Intersections2D.computeBarycentricCoordinates( intersection.longitude, intersection.latitude, v0.longitude, v0.latitude, v1.longitude, v1.latitude, v2.longitude, v2.latitude ); if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { const height = barycentric.x * v0.height + barycentric.y * v1.height + barycentric.z * v2.height; intersection.height = height; } const geometricError = globe.terrainProvider.getLevelMaximumGeometricError(pickedTriangle.tile.level); const approximateHeight = intersection.height; const minHeight = Math.max(pickedTriangle.tile.data.tileBoundingRegion.minimumHeight, approximateHeight - geometricError); const maxHeight = Math.min(pickedTriangle.tile.data.tileBoundingRegion.maximumHeight, approximateHeight + geometricError); const minHeightGeoid = minHeight - (this.geoidModel ? this.geoidModel.minimumHeight : 0); const maxHeightGeoid = maxHeight + (this.geoidModel ? this.geoidModel.maximumHeight : 0); errorBar = Math.max(Math.abs(approximateHeight - minHeightGeoid), Math.abs(maxHeightGeoid - approximateHeight)); } Cartographic.clone(intersection, this.lastHeightSamplePosition); const terrainProvider = globe.terrainProvider; this.cartographicToFields(intersection, errorBar); if (!(terrainProvider instanceof EllipsoidTerrainProvider)) { this.debounceSampleAccurateHeight(terrainProvider, intersection); } } else { this.elevation = ""; this.utmZone = ""; this.latitude = ""; this.longitude = ""; this.north = ""; this.east = ""; } } cartographicToFields(coordinates, errorBar) { const { Math: CesiumMath } = Cesium; const latitude = CesiumMath.toDegrees(coordinates.latitude); const longitude = CesiumMath.toDegrees(coordinates.longitude); if (this.useProjection) { const prettyProjection = prettifyProjection["default"](longitude, latitude, this.proj4Projection, this.proj4longlat, this.projectionUnits); this.utmZone = prettyProjection.utmZone; this.north = prettyProjection.north; this.east = prettyProjection.east; } const prettyCoordinate = prettifyCoordinates["default"](longitude, latitude, { height: coordinates.height, errorBar, decimal: this.decimal, rangeType: this.rangeType }); this.latitude = prettyCoordinate.latitude; this.longitude = prettyCoordinate.longitude; this.elevation = prettyCoordinate.elevation; } sampleAccurateHeight(terrainProvider, position) { const { Cartographic, sampleTerrainMostDetailed } = Cesium; if (this.tileRequestInFlight) { this.debounceSampleAccurateHeight.cancel(); this.debounceSampleAccurateHeight(terrainProvider, position); return; } const positionWithHeight = Cartographic.clone(position); const geoidHeightPromise = this.geoidModel ? this.geoidModel.getHeight(position.longitude, position.latitude) : void 0; const terrainPromise = sampleTerrainMostDetailed(terrainProvider, [positionWithHeight]); this.tileRequestInFlight = Promise.all([geoidHeightPromise, terrainPromise]).then((result) => { const geoidHeight = result[0] || 0; this.tileRequestInFlight = void 0; if (Cartographic.equals(position, this.lastHeightSamplePosition)) { position.height = positionWithHeight.height - geoidHeight; this.cartographicToFields(position); } else { } }).catch(() => { this.tileRequestInFlight = void 0; }); } } const scratchArray = []; const scratchSphereIntersectionResult = { start: 0, stop: 0 }; const scratchV0 = {}; const scratchV1 = {}; const scratchV2 = {}; function extendForMouseCoords() { const { Globe, GlobeSurfaceTile, BoundingSphere, defaultValue, Cartesian3, defined, DeveloperError, IntersectionTests, SceneMode } = Cesium; Globe.prototype.pickTriangle = Globe.prototype.pickTriangle || function(ray, scene, cullBackFaces, result) { if (!defined(ray)) { throw new DeveloperError("ray is required"); } if (!defined(scene)) { throw new DeveloperError("scene is required"); } cullBackFaces = defaultValue(cullBackFaces, true); const mode = scene.mode; const projection = scene.mapProjection; const sphereIntersections = scratchArray; sphereIntersections.length = 0; const tilesToRender = this._surface._tilesToRender; let length = tilesToRender.length; let tile; let i; for (i = 0; i < length; ++i) { tile = tilesToRender[i]; const surfaceTile = tile.data; if (!defined(surfaceTile)) { continue; } const boundingVolume = surfaceTile.pickBoundingSphere; if (mode !== SceneMode.SCENE3D) { BoundingSphere.fromRectangleWithHeights2D(tile.rectangle, projection, surfaceTile.minimumHeight, surfaceTile.maximumHeight, boundingVolume); Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); } else { BoundingSphere.clone(surfaceTile.boundingSphere3D, boundingVolume); } const boundingSphereIntersection = IntersectionTests.raySphere(ray, boundingVolume, scratchSphereIntersectionResult); if (defined(boundingSphereIntersection)) { sphereIntersections.push(tile); } } sphereIntersections.sort(createComparePickTileFunction(ray.origin)); let intersection; length = sphereIntersections.length; for (i = 0; i < length; ++i) { intersection = sphereIntersections[i].data.pickTriangle(ray, scene.mode, scene.mapProjection, cullBackFaces, result); if (defined(intersection)) { intersection.tile = sphereIntersections[i]; break; } } return intersection; }; GlobeSurfaceTile.prototype.pickTriangle = GlobeSurfaceTile.prototype.pickTriangle || function(ray, mode, projection, cullBackFaces) { const mesh = this.renderedMesh; if (!defined(mesh)) { return void 0; } const vertices = mesh.vertices; const indices = mesh.indices; const encoding = mesh.encoding; const length = indices.length; for (let i = 0; i < length; i += 3) { const i0 = indices[i]; const i1 = indices[i + 1]; const i2 = indices[i + 2]; const v0 = getPosition(encoding, mode, projection, vertices, i0, scratchV0); const v1 = getPosition(encoding, mode, projection, vertices, i1, scratchV1); const v2 = getPosition(encoding, mode, projection, vertices, i2, scratchV2); const intersection = IntersectionTests.rayTriangle(ray, v0, v1, v2, cullBackFaces, new Cartesian3()); if (defined(intersection)) { return { intersection, v0, v1, v2 }; } } return void 0; }; } function createComparePickTileFunction(rayOrigin) { const { BoundingSphere } = Cesium; return function(a, b) { const aDist = BoundingSphere.distanceSquaredTo(a.data.pickBoundingSphere, rayOrigin); const bDist = BoundingSphere.distanceSquaredTo(b.data.pickBoundingSphere, rayOrigin); return aDist - bDist; }; } function getPosition(encoding, mode, projection, vertices, index, result) { encoding.decodePosition(vertices, index, result); const { Cartesian3, defined, SceneMode } = Cesium; if (defined(mode) && mode !== SceneMode.SCENE3D) { const ellipsoid = projection.ellipsoid; const positionCart = ellipsoid.cartesianToCartographic(result); projection.project(positionCart, result); Cartesian3.fromElements(result.z, result.x, result.y, result); } return result; } exports["default"] = MouseCoords; exports.extendForMouseCoords = extendForMouseCoords; //# sourceMappingURL=MouseCoords.js.map