From 997118a6d2c00f1a88e2601ddd05abce651ccf9f Mon Sep 17 00:00:00 2001 From: ghx <2654687615@qq.com> Date: Wed, 29 Oct 2025 10:07:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=96=E9=9D=A2=E5=88=86=E6=9E=90=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../general/CzmESProfileAnalysis/index.ts | 86 +++++++++++ .../src/CzmObjects/general/index.ts | 1 + .../ESObjects/general/ESProfileAnalysis.ts | 137 ++++++++++++++++++ .../earthsdk3/src/ESObjects/general/index.ts | 1 + 4 files changed, 225 insertions(+) create mode 100644 earthsdk/earthsdk3-cesium/src/CzmObjects/general/CzmESProfileAnalysis/index.ts create mode 100644 earthsdk/earthsdk3/src/ESObjects/general/ESProfileAnalysis.ts diff --git a/earthsdk/earthsdk3-cesium/src/CzmObjects/general/CzmESProfileAnalysis/index.ts b/earthsdk/earthsdk3-cesium/src/CzmObjects/general/CzmESProfileAnalysis/index.ts new file mode 100644 index 00000000..7da780e4 --- /dev/null +++ b/earthsdk/earthsdk3-cesium/src/CzmObjects/general/CzmESProfileAnalysis/index.ts @@ -0,0 +1,86 @@ +import { ESProfileAnalysis } from "earthsdk3"; +import { CzmESGeoVector, CzmPolyline } from "../../../CzmObjects"; +import { ESCesiumViewer } from "../../../ESCesiumViewer"; +import { bind, createNextAnimateFrameEvent, track } from "earthsdk3"; +import * as Cesium from 'cesium'; +import * as turf from '@turf/turf'; + +export class CzmESProfileAnalysis extends CzmESGeoVector { + static readonly type = this.register("ESCesiumViewer", ESProfileAnalysis.type, this); + private _geoPolyline; + get geoPolyline() { return this._geoPolyline; } + constructor(sceneObject: T, czmViewer: ESCesiumViewer) { + super(sceneObject, czmViewer); + this._geoPolyline = this.disposeVar(new CzmPolyline(czmViewer, sceneObject.id)); + const viewer = czmViewer.viewer; + if (!viewer) { + console.warn(`viewer is undefined!`); + return; + } + const geoPolyline = this._geoPolyline; + this.dispose(track([geoPolyline, 'allowPicking'], [sceneObject, 'allowPicking'])); + this.dispose(bind([geoPolyline, 'positions'], [sceneObject, 'points'])); + this.dispose(track([geoPolyline, 'width'], [sceneObject, 'strokeWidth'])); + this.dispose(track([geoPolyline, 'color'], [sceneObject, 'strokeColor'])); + this.dispose(track([geoPolyline, 'ground'], [sceneObject, 'strokeGround'])); + // 剖面数据 + this.dispose(track([geoPolyline, 'chartsData'], [sceneObject, 'chartsData'])); + // 插值 + this.dispose(track([geoPolyline, 'step'], [sceneObject, 'step'])); + + { + const updateProp = () => { + geoPolyline.show = sceneObject.show && sceneObject.stroked; + } + updateProp(); + const updateEvent = this.disposeVar(createNextAnimateFrameEvent( + sceneObject.showChanged, + sceneObject.strokedChanged, + )); + this.dispose(updateEvent.disposableOn(updateProp)); + // 编辑结束后, 通过points数组和传入的step以及属性turf的方法计算剖面数据 + this.ad(sceneObject.editingChanged.don((newVal) => { + let arr = sceneObject.points?.map(v => ([v[0], v[1]])) + let arr2 = [] as any[]; + let arr3 = [] as any[]; + let step = sceneObject.step ?? 100; + + arr?.forEach((ele, index) => { + + for (var i = 0; i < step; ++i) { + + if (index < arr.length - 1) { + let offset = i / (step - 1); + + let startx = arr[index][0] + let starty = arr[index][1] + let endx = arr[index + 1][0] + let endy = arr[index + 1][1] + + var lon = Cesium.Math.lerp(startx, endx, offset) as any; + var lat = Cesium.Math.lerp(starty, endy, offset) as any; + + var cartographic = Cesium.Cartographic.fromDegrees(lon, lat); + var posi = new Cesium.Cartographic(cartographic.longitude, cartographic.latitude) + var height = viewer.scene.globe.getHeight(posi) + + arr2.push([lon, lat]) + + var length = 0 + if (arr2.length > 1) { + var line = turf.lineString(arr2); + length = turf.length(line, { units: 'miles' }); + } + arr3.push([lon, lat, height, length]) + } + } + + }) + + sceneObject.chartsData = arr3 + })) + + } + } + +} diff --git a/earthsdk/earthsdk3-cesium/src/CzmObjects/general/index.ts b/earthsdk/earthsdk3-cesium/src/CzmObjects/general/index.ts index ed3ad86f..df5d34ce 100644 --- a/earthsdk/earthsdk3-cesium/src/CzmObjects/general/index.ts +++ b/earthsdk/earthsdk3-cesium/src/CzmObjects/general/index.ts @@ -21,6 +21,7 @@ export * from './CzmESGeoDiv'; export * from './CzmESGeoDivTextPoi'; export * from './CzmESGeoJson'; export * from './CzmESGeoLineString'; +export * from './CzmESProfileAnalysis'; export * from './CzmESGeoPolygon'; export * from './CzmESGeoRectangle'; export * from './CzmESGeoSmoothPolygon'; diff --git a/earthsdk/earthsdk3/src/ESObjects/general/ESProfileAnalysis.ts b/earthsdk/earthsdk3/src/ESObjects/general/ESProfileAnalysis.ts new file mode 100644 index 00000000..df000c06 --- /dev/null +++ b/earthsdk/earthsdk3/src/ESObjects/general/ESProfileAnalysis.ts @@ -0,0 +1,137 @@ +import { react, reactJson, UniteChanged } from "../../xbsj-base"; +import { ESJEditingBindModeType, ESJEditingMode, ESJStrokeStyle, NumberProperty } from "../../ESJTypes"; +import { ESGeoVector } from "../base"; +import { ESTextLabel } from "./ESTextLabel"; + + +/** + * ESProfileAnalysis 类用于表示和剖面分析。 + * 该类继承自 ESGeoVector,提供了地理折线的特定属性和方法。 + * 主要功能包括计算折线的距离、支持特定的编辑模式,以及定义折线的样式属性、以及根据传入的插值计算剖面数据 + * + * 核心功能或关键方法: + * - 计算折线的距离:通过 `distance` 属性获取折线的距离值。 + * - 支持编辑模式:通过 `supportEditingModes` 静态属性定义支持的编辑模式。 + * - 定义样式属性:通过 `defaults` 静态属性定义折线的默认样式。 + * - 获取 ES 属性:通过 `getESProperties` 方法获取包含坐标和样式属性的对象。 + * - 获取属性:通过 `getProperties` 方法获取包含父类属性和计算相关属性的数组。 + * - 获取echarts剖面数据: 通过传入step属性和points, 计算出坡面数据的数组 + * + * 使用示例: + * + * 构造函数参数: + * - `id`:可选参数,实例的 ID。 + * + * 特殊的使用限制或潜在的副作用: + * - 无特殊的使用限制或潜在的副作用。 + */ +export class ESProfileAnalysis extends ESGeoVector { + static override readonly createDefaultProps = () => ({ + ...ESGeoVector.createDefaultProps(), + /**线样式是否生效 默认 为true */ + stroked: true, + // 剖面分析返回给ecahrts渲染的数据 + chartsData: [] as any[], + // 剖面分析的插值 + step: 100, + /**线样式 */ + strokeStyle: reactJson({ + width: 1, + widthType: 'screen', + color: [1, 1, 1, 1], + material: '', + materialParams: {}, + // 剖面默认贴地 + ground: true, + }), + }); + /** + * 静态属性,用于注册 ESProfileAnalysis 类。 + * 包含类型名称、类本身、中文名称、标签和描述信息。 + */ + static override readonly type: string = this.register('ESProfileAnalysis', this, { chsName: '剖面分析', tags: ['ESObjects', '_ES_Impl_Cesium', '_ES_Impl_UE'], description: "剖面分析" }); + /** + * 私有属性,存储折线的距离,使用 react 函数初始化值为 0。 + */ + private _distance = this.dv(react(0)); + + /** + * 获取折线的距离值。 + */ + get distance() { return this._distance.value; } + + /** + * 获取距离值变化的事件对象。 + */ + get distanceChanged() { return this._distance.changed; } + + /** + * 静态属性,重写支持的编辑模式,包含 ESGeoVector 支持的模式以及新增的 LineStringAppend 和 LineStringInsert 模式。 + */ + static override supportEditingModes = [ + ...ESGeoVector.supportEditingModes, + ESJEditingMode.LineStringAppend, + ESJEditingMode.LineStringInsert + ]; + + /** + * 重写编辑绑定模式,设置为 'lineString'。 + */ + override editingBindMode: ESJEditingBindModeType = 'lineString'; + /** + * 重写获取 ES 属性的方法,返回包含坐标和样式属性的对象。 + * @returns 包含 ES 属性的对象。 + */ + override getESProperties() { + const properties = { ...super.getESProperties() }; + return { + ...properties, + coordinate: [ + ...properties.coordinate, + new NumberProperty([this, 'distance'], '长度', 0, false, true,), + ], + }; + }; + /** + * 构造函数,初始化 ESProfileAnalysis 实例。 + * @param id - 可选参数,实例的 ID。 + */ + constructor(id?: string) { + super(id); + const update = () => { + this._distance.value = this.getDistance() ?? 0; + + } + update(); + this.d(this.pointsChanged.don(update)); + // 监听编辑模式的结束,创建起点终点标识 + this.d(this.editingChanged.don(editing => { + if (editing === false) { + if (this.points && this.points?.length > 1) { + const start = this.dv(new ESTextLabel()); + start.fontSize = 18 + start.color = [1, 1, 1, 1] + start.text = '起点' + start.position = this.points?.[0] + this.d(this.components.disposableAdd(start)); + const end = this.dv(new ESTextLabel()); + end.fontSize = 18 + end.color = [1, 1, 1, 1] + end.text = '终点' + end.position = this.points?.[this.points.length - 1] + this.d(this.components.disposableAdd(end)); + } + } + })) + // 监听坡面数据的改变 + this.d(this.chartsDataChanged.don(chartsData => { + console.log(chartsData,'chartsData') + })); + + + } +} +/** + * 定义 ESProfileAnalysis 接口,继承 UniteChanged 类型,泛型为 createDefaultProps 方法返回值的类型。 + */ +export interface ESProfileAnalysis extends UniteChanged> { } diff --git a/earthsdk/earthsdk3/src/ESObjects/general/index.ts b/earthsdk/earthsdk3/src/ESObjects/general/index.ts index 39dc0fd5..011841dd 100644 --- a/earthsdk/earthsdk3/src/ESObjects/general/index.ts +++ b/earthsdk/earthsdk3/src/ESObjects/general/index.ts @@ -19,6 +19,7 @@ export * from './ESFireParticleSystem'; export * from './ESForestTileset'; export * from './ESGeoDiv'; export * from './ESGeoLineString'; +export * from './ESProfileAnalysis'; export * from './ESGeoPolygon'; export * from './ESGeoRectangle'; export * from './ESGltfModel'; -- Gitee