首页 > 其他分享 >TerrainProviderEdit

TerrainProviderEdit

时间:2023-08-29 16:46:59浏览次数:28  
标签:const TerrainProviderEdit tileRectangle Cesium turf data Math

import {     Request,     TerrainData,     Rectangle } from 'cesium'; import * as turf from '@turf/turf'; import {     Feature,     Polygon } from '@turf/turf'; const MAX_SHORT = 32767; interface ModelEdit {     polygon: Feature < Polygon > ;     polygonTriangles: Feature < Polygon > [];     // TIN algorithm result on polygon } export class TerrainProviderEdit extends Cesium.CesiumTerrainProvider {     private modelEdits: ModelEdit[] = [];     constructor({         url,         modelEdits     }: {         url: string;modelEdits: ModelEdit[]     }) {         super({             url         });         this.modelEdits = modelEdits;     }     requestTileGeometry(x: number, y: number, level: number, request: Request): Promise < TerrainData > | undefined {         const promise = super.requestTileGeometry(x, y, level, request);         if (!promise || this.modelEdits.length === 0) {             return promise;         }         const tileRectangle: Rectangle = this.tilingScheme.tileXYToRectangle(x, y, level);         const tilePolygon = GeoUtils.rectangleToPolygon(tileRectangle);         // Create turf polygon from tile rectangle         const relevantEdits = this.modelEdits.filter(edit => turf.booleanOverlap(edit.polygon, tilePolygon) || turf.booleanContains(edit.polygon, tilePolygon));         if (relevantEdits.length === 0) {             return promise;         }         return promise.then((data: TerrainData) => this.modifyTerrainTile(data, tileRectangle, relevantEdits));     }     private modifyTerrainTile(terrainData: TerrainData, tileRectangle: Rectangle, modelEdits: ModelEdit[]) {         const data = terrainData as any;         const minimumHeight = data._minimumHeight;         const maximumHeight = data._maximumHeight;         const quantizedVertices: Uint16Array = data._quantizedVertices;         const vertexCount = quantizedVertices.length / 3;         const positions: number[][] = [];         for (let i = 0; i < vertexCount; i++) {             const rawU = quantizedVertices[i];             const rawV = quantizedVertices[i + vertexCount];             const rawH = quantizedVertices[i + vertexCount * 2];             const u = rawU / MAX_SHORT;             const v = rawV / MAX_SHORT;             const longitude = Cesium.Math.toDegrees(Cesium.Math.lerp(tileRectangle.west, tileRectangle.east, u));             const latitude = Cesium.Math.toDegrees(Cesium.Math.lerp(tileRectangle.south, tileRectangle.north, v));             let height = Cesium.Math.lerp(minimumHeight, maximumHeight, rawH / MAX_SHORT);             const currentPoint = turf.point([longitude, latitude]);             const relevantEdit = modelEdits.find(edit => turf.booleanPointInPolygon(currentPoint, edit.polygon));             if (relevantEdit) {                 const relevantTriangle = relevantEdit.polygonTriangles.find(triangle => turf.booleanPointInPolygon(currentPoint, triangle));                 if (relevantTriangle) {                     height = turf.planepoint(currentPoint, relevantTriangle);                 }             }             positions.push([longitude, latitude, height]);         } // TODO: split mesh triangles that are crossing the user polygon's perimiter and recreate mesh         const heights = positions.map(p => p[2]);         const newMinHeight = Math.min(...heights);         const newMaxHeight = Math.max(...heights);         const newQuantizedVertices = new Uint16Array(positions.length * 3);         positions.forEach((p, i) => {             const lonRad = Cesium.Math.toRadians(p[0]);             newQuantizedVertices[i] = Math.round(Cesium.Math.lerp(MAX_SHORT, 0, (lonRad - tileRectangle.east) / (tileRectangle.west - tileRectangle.east)));             const latRad = Cesium.Math.toRadians(p[1]);             newQuantizedVertices[i + positions.length] = Math.round(Cesium.Math.lerp(MAX_SHORT, 0, (latRad - tileRectangle.north) / (tileRectangle.south - tileRectangle.north)));             const relativeHeight = Math.round(Cesium.Math.lerp(0, MAX_SHORT, (p[2] - newMinHeight) / (newMaxHeight - newMinHeight)));             newQuantizedVertices[i + positions.length * 2] = relativeHeight;         });         data._minimumHeight = newMinHeight;         data._maximumHeight = newMaxHeight;         data._quantizedVertices = newQuantizedVertices;         return data as TerrainData;     } }

标签:const,TerrainProviderEdit,tileRectangle,Cesium,turf,data,Math
From: https://www.cnblogs.com/zany-hui/p/17665228.html

相关文章