@itwin/core-frontend
Version:
iTwin.js frontend components
148 lines • 7.08 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ViewGlobalLocationConstants = void 0;
exports.metersToRange = metersToRange;
exports.queryTerrainElevationOffset = queryTerrainElevationOffset;
exports.areaToEyeHeight = areaToEyeHeight;
exports.areaToEyeHeightFromGcs = areaToEyeHeightFromGcs;
exports.rangeToCartographicArea = rangeToCartographicArea;
exports.eyeToCartographicOnGlobe = eyeToCartographicOnGlobe;
exports.eyeToCartographicOnGlobeFromGcs = eyeToCartographicOnGlobeFromGcs;
exports.viewGlobalLocation = viewGlobalLocation;
const core_common_1 = require("@itwin/core-common");
const internal_1 = require("./tile/internal");
const ViewState_1 = require("./ViewState");
/** @internal */
class ViewGlobalLocationConstants {
static birdHeightAboveEarthInMeters = 713.0;
static satelliteHeightAboveEarthInMeters = 402336.0 * 24;
static largestEarthArc = 20037500.0; // distance from point on earth to opposite point in meters
static birdPitchAngleRadians = 0.0; // Angle.piOver4Radians;
static maximumDistanceToDrive = 96560.6; // The distance in meters that we will "drive" instead of fly to a destination (60 miles)
}
exports.ViewGlobalLocationConstants = ViewGlobalLocationConstants;
/** Converts a distance in meters to some range (smaller distances result in lower number; longer distances result in larger number)
* Uses 500 for minimum output and 3000 for maximum output, unless either are specified.
* Uses [[ViewGlobalLocationConstants.satelliteHeightAboveEarthInMeters]] as maximum input meters unless specified.
* A good use of this is to convert meters to some transition duration.
* @internal
*/
function metersToRange(inputMeters, minimumOutput = 500, maximumOutput = 3000, maximumInputMeters = ViewGlobalLocationConstants.satelliteHeightAboveEarthInMeters) {
let output;
if (inputMeters <= 0)
output = minimumOutput;
else if (inputMeters >= maximumInputMeters)
output = maximumOutput;
else {
const quickLerp = (start, end, amt) => {
return (1 - amt) * start + amt * end;
};
output = quickLerp(minimumOutput, maximumOutput, inputMeters / maximumInputMeters);
}
return output;
}
/** Queries the actual elevation of a cartographic point on the globe (using Bing elevation services)
* @public
* @extensions
*/
async function queryTerrainElevationOffset(viewport, carto) {
const bingElevationProvider = new internal_1.BingElevationProvider();
if (viewport && viewport.view instanceof ViewState_1.ViewState3d && viewport.iModel.isGeoLocated) {
const view3d = viewport.view;
if (view3d.displayStyle.displayTerrain) {
const elevationOffset = await bingElevationProvider.getHeight(carto, view3d.globeMode === core_common_1.GlobeMode.Ellipsoid);
if (elevationOffset !== undefined)
return elevationOffset;
}
}
return 0;
}
function _areaToEyeHeight(view3d, ne, sw, offset = 0) {
if (ne === undefined || sw === undefined)
return 0;
const diagonal = ne.distance(sw);
view3d.camera.validateLens();
const td = Math.tan(view3d.camera.getLensAngle().radians / 2.0);
return 0 !== td ? (diagonal / (2 * td) + offset) : offset;
}
/** Converts a cartographic area on the globe to an ideal eye height to view that area.
* Offset in meters, which defaults to 0, is applied to final eye height.
* @internal
*/
function areaToEyeHeight(view3d, area, offset = 0) {
const ne = view3d.cartographicToRoot(area.northeast);
const sw = view3d.cartographicToRoot(area.southwest);
return _areaToEyeHeight(view3d, ne, sw, offset);
}
/** Converts a cartographic area on the globe to an ideal eye height to view that area using the GCS.
* Offset in meters, which defaults to 0, is applied to final eye height.
* @internal
*/
async function areaToEyeHeightFromGcs(view3d, area, offset = 0) {
const corners = await view3d.cartographicToRootUsingGcs([area.northeast, area.southwest]);
if (!corners)
return 0;
return _areaToEyeHeight(view3d, corners[0], corners[1], offset);
}
/** Converts a root range (often project extents) to a cartographic area.
* @internal
*/
function rangeToCartographicArea(view3d, range) {
const low = view3d.rootToCartographic(range.low);
const high = view3d.rootToCartographic(range.high);
if (low === undefined || high === undefined)
return undefined;
return low.latitude < high.latitude ? { northeast: high, southwest: low } : { northeast: low, southwest: high };
}
/** Converts the eye of the camera to a cartographic location on the globe as if it was at height 0.
* If preserveHeight is set to true, then height will remain untouched.
* @internal
*/
function eyeToCartographicOnGlobe(viewport, preserveHeight = false) {
if (!(viewport.view instanceof ViewState_1.ViewState3d) || !viewport.iModel.isGeoLocated)
return undefined;
const view3d = viewport.view;
const eyePointCartographic = view3d.rootToCartographic(view3d.getEyeOrOrthographicViewPoint());
if (eyePointCartographic !== undefined) {
if (!preserveHeight)
eyePointCartographic.height = 0.0;
return eyePointCartographic;
}
return undefined;
}
/** Converts the eye of the camera to a cartographic location on the globe as if it was at height 0 using the GCS.
* If preserveHeight is set to true, then height will remain untouched.
* @internal
*/
async function eyeToCartographicOnGlobeFromGcs(viewport, preserveHeight = false) {
if (!(viewport.view instanceof ViewState_1.ViewState3d) || !viewport.iModel.isGeoLocated)
return undefined;
const view3d = viewport.view;
const eyePointCartographic = await view3d.rootToCartographicFromGcs(view3d.getEyeOrOrthographicViewPoint());
if (eyePointCartographic !== undefined) {
if (!preserveHeight)
eyePointCartographic.height = 0.0;
return eyePointCartographic;
}
return undefined;
}
/** @internal */
function viewGlobalLocation(viewport, doAnimate, eyeHeight = ViewGlobalLocationConstants.birdHeightAboveEarthInMeters, pitchAngleRadians = 0, location) {
if (!(viewport.view instanceof ViewState_1.ViewState3d))
return 0;
const before = viewport.getFrustum();
const view3d = viewport.view;
const transitionDistance = view3d.lookAtGlobalLocation(eyeHeight, pitchAngleRadians, location);
viewport.synchWithView();
if (doAnimate)
viewport.animateToCurrent(before, { animationTime: metersToRange(transitionDistance) });
return transitionDistance;
}
//# sourceMappingURL=ViewGlobalLocation.js.map
;