import type { IActivityHandler } from "@vertigis/workflow"; import Point from "@arcgis/core/geometry/Point"; import Multipoint from "@arcgis/core/geometry/Multipoint"; import Polyline from "@arcgis/core/geometry/Polyline"; import Polygon from "@arcgis/core/geometry/Polygon"; import ElevationLayer from "@arcgis/core/layers/ElevationLayer"; import { Geometry } from "@arcgis/core/geometry"; import { SpatialReference } from "esri/geometry"; /** An interface that defines the inputs of the activity. */ interface DrapGeometryInputs { /** * @displayName Input Geometry * @description The 2D geometry to be converted to 3D. * @required */ inputGeometry: Point | Multipoint | Polyline | Polygon; /** * @displayName Elevation Service URL * @description The URL of the elevation service to be used for draping. * @required */ elevationServiceUrl: string; } /** An interface that defines the outputs of the activity. */ interface DrapGeometryOutputs { /** * @description The 3D geometry result. */ result: Point | Multipoint | Polyline | Polygon; } /** * @displayName Drap Geometry * @category Geocortex * @description Convert 2D Geometry to 3D using an elevation service. V3 */ export default class DrapGeometryActivity implements IActivityHandler { /** Perform the execution logic of the activity. */ async execute(inputs: DrapGeometryInputs): Promise { // Create an ElevationLayer using the provided URL const elevationLayer = new ElevationLayer({ url: inputs.elevationServiceUrl }); // Function to process Polyline and Polygon geometries const processPolyline = async (polyline: Polyline, sp : SpatialReference): Promise => { const polylineClone = polyline.clone(); polylineClone.hasZ = false; polylineClone.spatialReference = sp const result = await elevationLayer.queryElevation(polylineClone); return result.geometry as Polyline; }; let geometry3D: Geometry; // Handle different types of geometry if (inputs.inputGeometry instanceof Point) { const pointClone = inputs.inputGeometry.clone(); pointClone.hasZ = false; pointClone.spatialReference = inputs.inputGeometry.spatialReference console.log('Point is :', elevationLayer) const result = await elevationLayer.queryElevation(pointClone); geometry3D = result.geometry; } else if (inputs.inputGeometry instanceof Multipoint) { const multipointClone = inputs.inputGeometry.clone(); multipointClone.hasZ = false; multipointClone.spatialReference = inputs.inputGeometry.spatialReference const result = await elevationLayer.queryElevation(multipointClone); geometry3D = result.geometry; } else if (inputs.inputGeometry instanceof Polyline) { geometry3D = await processPolyline(inputs.inputGeometry,inputs.inputGeometry.spatialReference); } else if (inputs.inputGeometry instanceof Polygon) { // Process each ring of the Polygon const rings = inputs.inputGeometry.rings; const lines = rings.map(ring => new Polyline({ paths: [ring], spatialReference: inputs.inputGeometry.spatialReference })); const processedLines = await Promise.all(lines.map(line => processPolyline(line, inputs.inputGeometry.spatialReference))); // Reconstruct the Polygon with the elevated lines const elevatedRings = processedLines.map(line => line.paths[0]); geometry3D = new Polygon({ rings: elevatedRings, spatialReference:inputs.inputGeometry.spatialReference }); } else { throw new Error("Unsupported geometry type. The input geometry must be a Point, Multipoint, Polyline, or Polygon."); } // Return the 3D geometry result return { result: geometry3D }; } }