UNPKG

@itwin/core-frontend

Version:
111 lines 4.74 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Views */ import { assert } from "@itwin/core-bentley"; import { Point2d, Range1d } from "@itwin/core-geometry"; import { Cartographic } from "@itwin/core-common"; import { GeographicTilingScheme } from "./tile/internal"; let instance; /** * A collection of functions for approximating terrain height * @internal */ export class ApproximateTerrainHeights { static maxLevel = 6; globalHeightRange = Range1d.createXX(-400, 90000); // Dead Sea to Mount Everest. _terrainHeights; _scratchCorners = [Cartographic.createZero(), Cartographic.createZero(), Cartographic.createZero(), Cartographic.createZero()]; _tilingScheme = new GeographicTilingScheme(2, 1, true); // Y at top... ? _scratchTileXY = Point2d.createZero(); static get instance() { if (undefined === instance) instance = new ApproximateTerrainHeights(); return instance; } /** * Initializes the minimum and maximum terrain heights. * @return {Promise} */ async initialize() { if (!this._terrainHeights) { const { terrainHeightsPropsString } = await import("./ApproximateTerrainHeightsProps"); this._terrainHeights = JSON.parse(terrainHeightsPropsString); } } getTileHeightRange(quadId, result) { result = Range1d.createFrom(this.globalHeightRange, result); if (undefined === this._terrainHeights) return result; // Not initialized. let level = quadId.level, column = quadId.column, row = quadId.row; if (level > 6) { column = column >> (level - 6); row = row >> quadId.row >> ((level - 6)); level = 6; } const key = `${level}-${column}-${row}`; const heights = this._terrainHeights[key]; assert(undefined !== heights); result.low = heights[0]; result.high = heights[1]; return result; } getMinimumMaximumHeights(rectangle, result) { result = Range1d.createFrom(this.globalHeightRange, result); if (undefined === this._terrainHeights) return result; // Not initialized. const xyLevel = this._getTileXYLevel(rectangle); if (undefined !== xyLevel) { const key = `${xyLevel.level}-${xyLevel.x}-${xyLevel.y}`; const heights = this._terrainHeights[key]; assert(undefined !== heights); if (undefined !== heights) { result.low = heights[0]; result.high = heights[1]; } } return result; } _getTileXYLevel(rectangle) { Cartographic.fromRadians({ longitude: rectangle.low.x, latitude: rectangle.high.y, height: 0.0 }, this._scratchCorners[0]); Cartographic.fromRadians({ longitude: rectangle.high.x, latitude: rectangle.high.y, height: 0.0 }, this._scratchCorners[1]); Cartographic.fromRadians({ longitude: rectangle.low.x, latitude: rectangle.low.y, height: 0.0 }, this._scratchCorners[2]); Cartographic.fromRadians({ longitude: rectangle.high.x, latitude: rectangle.low.y, height: 0.0 }, this._scratchCorners[3]); // Determine which tile the bounding rectangle is in let lastLevelX = 0, lastLevelY = 0; let currentX = 0, currentY = 0; const maxLevel = ApproximateTerrainHeights.maxLevel; let i; for (i = 0; i <= maxLevel; ++i) { let failed = false; for (let j = 0; j < 4; ++j) { const corner = this._scratchCorners[j]; this._tilingScheme.cartographicToTileXY(corner, i, this._scratchTileXY); if (j === 0) { currentX = this._scratchTileXY.x; currentY = this._scratchTileXY.y; } else if (currentX !== this._scratchTileXY.x || currentY !== this._scratchTileXY.y) { failed = true; break; } } if (failed) break; lastLevelX = currentX; lastLevelY = currentY; } if (i === 0) { return undefined; } return { x: lastLevelX, y: lastLevelY, level: (i > maxLevel) ? maxLevel : (i - 1), }; } } //# sourceMappingURL=ApproximateTerrainHeights.js.map