UNPKG

@itwin/core-frontend

Version:
116 lines 4.79 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { Logger } from "@itwin/core-bentley"; import { Cartographic } from "@itwin/core-common"; import { GrowableXYZArray, LineString3d, Loop, Point3dArray, RegionOps } from "@itwin/core-geometry"; import { FeatureGeometryBaseRenderer, WebMercator } from "../../../../tile/internal"; const loggerCategory = "MapLayerImageryProvider.FeatureGraphicsRenderer"; /** Feature geometry renderer implementation that will "render" a list of [GraphicPrimitive]($frontend) * This renderer initial objective is to read geometries when a call to [[MapLayerImageryProvider.getFeatureInfo]] is performed. * @internal */ export class FeatureGraphicsRenderer extends FeatureGeometryBaseRenderer { hasSymbologyRenderer() { return false; } _scratchPointsArray = new GrowableXYZArray(); _scratchPaths = []; _graphics = []; _viewport; _crs; constructor(props) { super(); this._viewport = props.viewport; this._crs = props.crs; } moveGraphics() { const graphics = this._graphics; this._graphics = []; return graphics; } beginPath() { this._scratchPointsArray.clear(); this._scratchPaths = []; } closePath() { if (this._scratchPointsArray.length > 0) { this._scratchPaths.push(this._scratchPointsArray.getArray()); this._scratchPointsArray.clear(); } } async lineTo(x, y) { this._scratchPointsArray.push({ x, y, z: 0 }); } async moveTo(x, y) { if (this._scratchPointsArray.length > 0) { this._scratchPaths.push(this._scratchPointsArray.getArray()); this._scratchPointsArray.clear(); } this._scratchPointsArray.push({ x, y, z: 0 }); } async fill() { if (this._scratchPaths.length > 0) { const loops = []; const pathPromises = []; for (const points of this._scratchPaths) { pathPromises.push(this.toSpatial(points)); } const pathsArray = await Promise.all(pathPromises); for (const pointsArray of pathsArray) { loops.push(Loop.create(LineString3d.create(pointsArray))); } const mergedLoops = RegionOps.constructAllXYRegionLoops(loops); for (const loop of mergedLoops) { for (const negativeLoop of loop.negativeAreaLoops) { this._graphics.push({ type: "loop", loop: negativeLoop }); } } this._scratchPaths = []; } } async stroke() { if (this._scratchPointsArray.length > 0) { this._scratchPaths.push(this._scratchPointsArray.getArray()); this._scratchPointsArray.clear(); } const pathPromises = []; for (const geoPt of this._scratchPaths) { pathPromises.push(this.toSpatial(geoPt)); } const reprojectedPaths = await Promise.all(pathPromises); for (const path of reprojectedPaths) { this._graphics.push({ type: "linestring", points: Point3dArray.clonePoint3dArray(path) }); } this._scratchPaths = []; } drawPoint(x, y) { this._scratchPointsArray.push({ x, y, z: 0 }); } async finishPoints() { if (this._scratchPointsArray.length > 0) { // Backend reprojection const pointsArray = this._scratchPointsArray.getArray(); try { const spatialPoints = await this.toSpatial(pointsArray); this._graphics.push({ type: "pointstring", points: spatialPoints }); } catch { Logger.logError(loggerCategory, "FeatureGraphicsRenderer: Could not reproject points"); } this._scratchPointsArray.clear(); } } async toSpatial(geoPoints) { const bgMapGeom = this._viewport.displayStyle.getBackgroundMapGeometry(); if (bgMapGeom) { const cartoPts = geoPoints.map((pt) => Cartographic.fromDegrees({ longitude: this._crs === "webMercator" ? WebMercator.getEPSG4326Lon(pt.x) : pt.x, latitude: this._crs === "webMercator" ? WebMercator.getEPSG4326Lat(pt.y) : pt.y, height: pt.z, })); return bgMapGeom.cartographicToDbFromWgs84Gcs(cartoPts); } return []; } } //# sourceMappingURL=FeatureGraphicsRenderer.js.map