cesium-xs-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/cesium-xs-sdk.cjs.js +7387 -0
- package/dist/cesium-xs-sdk.cjs.js.map +1 -0
- package/dist/cesium-xs-sdk.esm.js +7383 -0
- package/dist/cesium-xs-sdk.esm.js.map +1 -0
- package/dist/cesium-xs-sdk.umd.js +2 -0
- package/dist/cesium-xs-sdk.umd.js.map +1 -0
- package/package.json +78 -0
- package/src/core/Config.js +176 -0
- package/src/core/ModuleManager.js +157 -0
- package/src/index.d.ts +358 -0
- package/src/index.js +59 -0
- package/src/modules/EditorModule.js +370 -0
- package/src/modules/EventModule.js +211 -0
- package/src/modules/GraphicModule.js +1037 -0
- package/src/modules/PlotGraphicType.js +43 -0
- package/src/modules/SceneModule.js +600 -0
- package/src/modules/tools/BaseTool.js +155 -0
- package/src/modules/tools/DeleteTool.js +252 -0
- package/src/modules/tools/DrawTool.js +961 -0
- package/src/modules/tools/EditTool.js +1585 -0
- package/src/modules/tools/SelectTool.js +526 -0
- package/src/react.d.ts +18 -0
- package/src/react.js +49 -0
- package/src/utils/CoordinateUtil.js +63 -0
- package/src/utils/GeoCalcUtil.js +95 -0
- package/src/utils/PlotGeometryUtil.js +1134 -0
- package/src/vue.d.ts +18 -0
- package/src/vue.js +76 -0
- package/src/vue2.d.ts +20 -0
- package/src/vue2.js +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cesium-xs-sdk.umd.js","sources":["../src/core/Config.js","../src/modules/SceneModule.js","../src/utils/PlotGeometryUtil.js","../src/modules/PlotGraphicType.js","../src/modules/GraphicModule.js","../src/modules/EventModule.js","../src/modules/tools/BaseTool.js","../src/modules/tools/DrawTool.js","../src/modules/tools/EditTool.js","../src/modules/tools/SelectTool.js","../src/modules/tools/DeleteTool.js","../src/modules/EditorModule.js","../src/core/ModuleManager.js","../src/utils/GeoCalcUtil.js","../src/index.js","../src/utils/CoordinateUtil.js"],"sourcesContent":["/**\r\n * 全局配置类(对应平台 Application 单件)\r\n * 管理 Cesium Token、默认参数、模块开关\r\n */\r\nexport class Config {\r\n static instance = null;\r\n // 单例模式\r\n static getInstance() {\r\n if (!this.instance) {\r\n this.instance = new Config();\r\n }\r\n return this.instance;\r\n }\r\n\r\n constructor() {\r\n // 默认配置(对齐平台参数规范)\r\n this.config = {\r\n cesiumToken: '', // Cesium Ion Token\r\n // 场景默认参数\r\n scene: {\r\n animation: false,\r\n timeline: false,\r\n baseLayerPicker: false,\r\n fullscreenButton: false,\r\n geocoder: false,\r\n homeButton: false,\r\n infoBox: false,\r\n sceneModePicker: false,\r\n selectionIndicator: false,\r\n navigationHelpButton: false,\r\n navigationInstructionsInitiallyVisible: false,\r\n depthTestAgainstTerrain: true, // 默认开启深度检测\r\n },\r\n // 图元默认样式:延迟到 getConfig 时再构造,避免在 Cesium 未加载/未 mock 时崩溃\r\n // (对 SSR 和单元测试更友好)\r\n };\r\n }\r\n\r\n /**\r\n * 构造图元默认样式(延迟初始化)\r\n * @private\r\n */\r\n #getGraphicDefaults() {\r\n if (typeof Cesium === 'undefined') {\r\n return {};\r\n }\r\n\r\n const withAlpha = (color, alpha) => {\r\n if (color && typeof color.withAlpha === 'function') {\r\n return color.withAlpha(alpha);\r\n }\r\n return color;\r\n };\r\n\r\n return {\r\n point: { pixelSize: 8, color: Cesium.Color.RED },\r\n line: { width: 2, material: Cesium.Color.BLUE },\r\n polygon: { color: withAlpha(Cesium.Color.GREEN, 0.5) },\r\n plot: {\r\n polygon: {\r\n color: withAlpha(Cesium.Color.BLUE, 0.5),\r\n outlineColor: Cesium.Color.BLUE,\r\n outlineWidth: 2\r\n },\r\n line: {\r\n material: Cesium.Color.BLUE,\r\n width: 2\r\n }\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 设置全局配置(参数化配置)\r\n * @param {Object} options 配置项(支持部分覆盖)\r\n * @example\r\n * Config.getInstance().setConfig({\r\n * cesiumToken: 'your-token',\r\n * scene: { terrainProvider: await Cesium.createWorldTerrainAsync() }\r\n * });\r\n */\r\n setConfig(options) {\r\n for (const k in options) {\r\n // 1. 标量/数组/null -> 直接覆盖\r\n if (\r\n typeof options[k] !== 'object' ||\r\n Array.isArray(options[k]) ||\r\n options[k] === null\r\n ) {\r\n this.config[k] = options[k];\r\n continue;\r\n }\r\n\r\n // 2. scene -> 深度缺省合并\r\n if (k === 'scene') {\r\n this.config.scene = this.config.scene || {};\r\n this.#defaultsDeep(this.config.scene, options.scene);\r\n continue;\r\n }\r\n\r\n // 3. 其他对象 -> 浅层缺省(或按需改成深度)\r\n this.config[k] = this.config[k] || {};\r\n this.#defaultsShallow(this.config[k], options[k]);\r\n }\r\n\r\n console.log('config', this.config);\r\n\r\n\r\n // Token 同步\r\n if (options.cesiumToken) {\r\n Cesium.Ion.defaultAccessToken = options.cesiumToken;\r\n }\r\n }\r\n\r\n /**\r\n * 获取全局配置\r\n * @returns {Object} 完整配置\r\n */\r\n getConfig() {\r\n const graphicDefaults = this.#getGraphicDefaults();\r\n const userGraphic = this.config.graphic || {};\r\n\r\n // 深度合并 plot,避免用户只传 polygon 时丢失 line 默认样式\r\n const plot = userGraphic.plot\r\n ? { ...graphicDefaults.plot, ...userGraphic.plot }\r\n : graphicDefaults.plot;\r\n\r\n return {\r\n ...this.config,\r\n graphic: {\r\n ...graphicDefaults,\r\n ...userGraphic,\r\n plot\r\n }\r\n };\r\n }\r\n\r\n #defaultsDeep(target, src) {\r\n for (const k in src) {\r\n const sv = src[k];\r\n const tv = target[k];\r\n\r\n // 1. 非对象 || 数组 || null -> 直接补缺失\r\n if (typeof sv !== 'object' || Array.isArray(sv) || sv === null) {\r\n if (!Object.prototype.hasOwnProperty.call(target, k)) {\r\n target[k] = sv;\r\n }\r\n continue;\r\n }\r\n\r\n // 2. 特殊类实例(Promise、TerrainProvider…)-> 整棵补缺失,不展开\r\n if (\r\n sv instanceof Promise ||\r\n (sv.constructor && sv.constructor.name !== 'Object') // 普通 Object 字面量才继续\r\n ) {\r\n if (!Object.prototype.hasOwnProperty.call(target, k)) {\r\n target[k] = sv;\r\n }\r\n continue;\r\n }\r\n\r\n // 3. 普通对象 -> 递归\r\n target[k] = tv || {};\r\n this.#defaultsDeep(target[k], sv);\r\n }\r\n }\r\n\r\n /* 浅层缺省工具 */\r\n #defaultsShallow(target, src) {\r\n for (const k in src) {\r\n if (!Object.prototype.hasOwnProperty.call(target, k)) {\r\n target[k] = src[k];\r\n }\r\n }\r\n }\r\n}","import { Config } from '../core/Config.js';\r\n\r\n/**\r\n * 图层类型枚举\r\n * @readonly\r\n * @enum {string}\r\n */\r\nexport const LayerType = Object.freeze({\r\n /** XYZ 瓦片服务 */\r\n XYZ: 'xyz',\r\n /** WMTS 瓦片服务 */\r\n WMTS: 'wmts',\r\n /** WMS 动态地图服务 */\r\n WMS: 'wms',\r\n /** TMS 瓦片服务 */\r\n TMS: 'tms',\r\n /** 单张图片 */\r\n SINGLE_IMAGE: 'single_image',\r\n /** 地形数据 */\r\n TERRAIN: 'terrain',\r\n /** 3D Tiles 模型数据集 */\r\n '3DTILES': '3dtiles'\r\n});\r\n\r\n\r\n// ========== 私有工厂函数(文件内部) ==========\r\n\r\n/**\r\n * 根据 URL 自动推断图层类型\r\n * @param {string} url 服务地址\r\n * @returns {string} LayerType 值\r\n */\r\nfunction autoDetectType(url) {\r\n const u = url.toLowerCase();\r\n\r\n // 1. 3DTiles — 以 .json 结尾或包含 3dtiles/3d_tiles\r\n if (/\\.json(?:[?#]|$)/.test(u) || u.includes('3dtiles') || u.includes('3d_tiles')) {\r\n return LayerType['3DTILES'];\r\n }\r\n\r\n // 2. 地形 — 包含 terrain / dem / gdem / 水深 / elevation 关键词\r\n if (/\\/(?:terrain|dem|gdem|水深|elevation|ele)(\\/|$)/.test(u) || /[?&#]terrain=/.test(u)) {\r\n return LayerType.TERRAIN;\r\n }\r\n\r\n // 3. WMTS — 包含 wmts 关键词 或 TileMatrixSet 参数\r\n if (u.includes('wmts') || u.includes('tilematrixset')) {\r\n return LayerType.WMTS;\r\n }\r\n\r\n // 4. WMS — 包含 wms 关键词 或 GetMap 请求参数\r\n if (u.includes('wms') || u.includes('getmap') || u.includes('request=getmap')) {\r\n return LayerType.WMS;\r\n }\r\n\r\n // 5. TMS — 包含 tms 关键词 或 {-y} 反转瓦片\r\n if (u.includes('tms') || u.includes('{-y}')) {\r\n return LayerType.TMS;\r\n }\r\n\r\n // 6. XYZ — URL 模板包含 {z} {x} {y}\r\n if (/\\{[xyz]\\}/.test(u)) {\r\n return LayerType.XYZ;\r\n }\r\n\r\n // 7. 单张影像 — 有常见图片后缀且无瓦片模板\r\n if (/\\.(?:png|jpe?g|tiff?|gif|bmp|img)(?:[?#]|$)/.test(u)) {\r\n return LayerType.SINGLE_IMAGE;\r\n }\r\n\r\n // 默认按 XYZ 处理(最常见的瓦片格式)\r\n return LayerType.XYZ;\r\n}\r\n\r\n/**\r\n * 根据类型创建对应的 Cesium Provider\r\n * @param {string} type LayerType 值\r\n * @param {string} url 服务地址\r\n * @param {Object} opts 用户传入的配置\r\n * @returns {Object} Cesium Provider 实例\r\n */\r\nfunction createProviderByType(type, url, opts) {\r\n switch (type) {\r\n case LayerType.XYZ:\r\n case LayerType.TMS:\r\n // XYZ / TMS 均使用 UrlTemplateImageryProvider\r\n return new Cesium.UrlTemplateImageryProvider({ url, ...opts });\r\n\r\n case LayerType.WMTS:\r\n return new Cesium.WebMapTileServiceImageryProvider({\r\n url,\r\n layer: opts.layer,\r\n style: opts.style || 'default',\r\n format: opts.format || 'image/jpeg',\r\n tileMatrixSetID: opts.tileMatrixSetID || 'EPSG:4326',\r\n ...opts\r\n });\r\n\r\n case LayerType.WMS:\r\n return new Cesium.WebMapServiceImageryProvider({\r\n url,\r\n layers: opts.layers || '',\r\n parameters: { transparent: true, format: 'image/png', ...opts.parameters },\r\n ...opts\r\n });\r\n\r\n case LayerType.SINGLE_IMAGE:\r\n return new Cesium.SingleTileImageryProvider({\r\n url,\r\n rectangle: opts.extent ? Cesium.Rectangle.fromDegrees(...opts.extent) : undefined,\r\n credit: opts.credit || '',\r\n ...opts\r\n });\r\n\r\n case LayerType.TERRAIN:\r\n // fromUrl 返回 Promise,由 addProviderToViewer 统一 await\r\n return Cesium.CesiumTerrainProvider.fromUrl(url, {\r\n requestWaterMask: opts.requestWaterMask ?? false,\r\n requestVertexNormals: opts.requestVertexNormals ?? false,\r\n ...opts\r\n });\r\n\r\n case LayerType['3DTILES']:\r\n return new Cesium.Cesium3DTileset({\r\n url,\r\n maximumScreenSpaceError: opts.maximumScreenSpaceError ?? 16,\r\n maximumMemoryUsage: opts.maximumMemoryUsage ?? 512,\r\n ...opts\r\n });\r\n\r\n default:\r\n throw new Error(`SceneModule: 不支持的图层类型 \"${type}\",可用值: ${Object.values(LayerType).join(', ')}`);\r\n }\r\n}\r\n\r\n/**\r\n * 将 Provider 添加到 Viewer 并返回句柄\r\n * terrain 类型返回 provider 自身(不是 layer)\r\n * 3dtiles 类型返回 tileset\r\n * 其余返回 ImageryLayer\r\n * @param {string} type LayerType\r\n * @param {Object} viewer Cesium.Viewer\r\n * @param {Object} providerType Cesium Provider\r\n * @param {boolean} visible 是否可见\r\n * @returns {Object} layer/tileset/provider\r\n */\r\nasync function addProviderToViewer(type, viewer, providerType, visible) {\r\n if (type === LayerType.TERRAIN) {\r\n const provider = await providerType\r\n viewer.terrainProvider = provider;\r\n return provider;\r\n }\r\n if (type === LayerType['3DTILES']) {\r\n const tileset = viewer.scene.primitives.add(providerType);\r\n tileset.show = visible ?? true;\r\n return tileset;\r\n }\r\n const layer = viewer.imageryLayers.addImageryProvider(providerType);\r\n layer.show = visible ?? true;\r\n return layer;\r\n}\r\n\r\n\r\n// ========== 图层包装器 ==========\r\n\r\n/**\r\n * 影像图层包装器\r\n */\r\nclass ImageryLayerWrapper {\r\n constructor(sceneModule, layer, layerId) {\r\n this._layer = layer;\r\n this._sceneModule = sceneModule;\r\n this._layerId = layerId;\r\n this._pickable = true;\r\n this._eventEnabled = true;\r\n }\r\n\r\n setVisible(visible) {\r\n this._layer.show = visible;\r\n return this;\r\n }\r\n\r\n setAlpha(alpha) {\r\n this._layer.alpha = alpha;\r\n return this;\r\n }\r\n\r\n setBrightness(brightness) {\r\n this._layer.brightness = brightness;\r\n return this;\r\n }\r\n\r\n setContrast(contrast) {\r\n this._layer.contrast = contrast;\r\n return this;\r\n }\r\n\r\n setHue(hue) {\r\n this._layer.hue = hue;\r\n return this;\r\n }\r\n\r\n setSaturation(saturation) {\r\n this._layer.saturation = saturation;\r\n return this;\r\n }\r\n\r\n setGamma(gamma) {\r\n this._layer.gamma = gamma;\r\n return this;\r\n }\r\n\r\n enableEdit(enabled) {\r\n this._pickable = enabled;\r\n return this;\r\n }\r\n\r\n enableEvent(enabled) {\r\n this._eventEnabled = enabled;\r\n if (this._layer.imageryProvider && this._layer.imageryProvider.enablePickFeatures) {\r\n this._layer.imageryProvider.enablePickFeatures = enabled;\r\n }\r\n return this;\r\n }\r\n\r\n getExtent() {\r\n const provider = this._layer.imageryProvider;\r\n if (provider && provider.rectangle) {\r\n const rect = provider.rectangle;\r\n return {\r\n west: Cesium.Math.toDegrees(rect.west),\r\n south: Cesium.Math.toDegrees(rect.south),\r\n east: Cesium.Math.toDegrees(rect.east),\r\n north: Cesium.Math.toDegrees(rect.north)\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n getRange() {\r\n const provider = this._layer.imageryProvider;\r\n return {\r\n minLevel: provider.minimumLevel || 0,\r\n maxLevel: provider.maximumLevel || 18\r\n };\r\n }\r\n\r\n getLayer() {\r\n return this._layer;\r\n }\r\n\r\n remove() {\r\n this._sceneModule.removeLayer(this._layerId);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 地形图层包装器\r\n */\r\nclass TerrainLayerWrapper {\r\n constructor(sceneModule, provider, layerId) {\r\n this._provider = provider;\r\n this._sceneModule = sceneModule;\r\n this._layerId = layerId;\r\n this._visible = true;\r\n }\r\n\r\n setVisible(visible) {\r\n this._visible = visible;\r\n return this;\r\n }\r\n\r\n getExtent() {\r\n if (this._provider.rectangle) {\r\n const rect = this._provider.rectangle;\r\n return {\r\n west: Cesium.Math.toDegrees(rect.west),\r\n south: Cesium.Math.toDegrees(rect.south),\r\n east: Cesium.Math.toDegrees(rect.east),\r\n north: Cesium.Math.toDegrees(rect.north)\r\n };\r\n }\r\n return { west: -180, south: -85, east: 180, north: 85 };\r\n }\r\n\r\n getProvider() {\r\n return this._provider;\r\n }\r\n\r\n remove() {\r\n this._sceneModule.removeLayer(this._layerId);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 3DTiles 图层包装器\r\n */\r\nclass TilesetLayerWrapper {\r\n constructor(sceneModule, tileset, layerId) {\r\n this._tileset = tileset;\r\n this._sceneModule = sceneModule;\r\n this._layerId = layerId;\r\n }\r\n\r\n setVisible(visible) {\r\n this._tileset.show = visible;\r\n return this;\r\n }\r\n\r\n setStyle(style) {\r\n this._tileset.style = style;\r\n return this;\r\n }\r\n\r\n getExtent() {\r\n if (this._tileset.boundingSphere) {\r\n const bs = this._tileset.boundingSphere;\r\n const cartographic = Cesium.Cartographic.fromCartesian(bs.center);\r\n const rect = this._tileset.rectangle;\r\n if (rect) {\r\n return {\r\n west: Cesium.Math.toDegrees(rect.west),\r\n south: Cesium.Math.toDegrees(rect.south),\r\n east: Cesium.Math.toDegrees(rect.east),\r\n north: Cesium.Math.toDegrees(rect.north),\r\n center: [\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude)\r\n ]\r\n };\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n locateTo() {\r\n return this._sceneModule.viewer.zoomTo(this._tileset);\r\n }\r\n\r\n getTileset() {\r\n return this._tileset;\r\n }\r\n\r\n remove() {\r\n this._sceneModule.removeLayer(this._layerId);\r\n return this;\r\n }\r\n}\r\n\r\n\r\n// ========== SceneModule ==========\r\n\r\n/**\r\n * 场景+图层管理模块\r\n */\r\nexport class SceneModule {\r\n constructor(viewer) {\r\n this.viewer = viewer;\r\n this.config = Config.getInstance().getConfig();\r\n this.layerMap = new Map(); // 图层缓存(ID -> Wrapper 实例)\r\n }\r\n\r\n // ========== 坐标转换 ==========\r\n\r\n lonLatToWorld(lon, lat, height = 0) {\r\n return Cesium.Cartesian3.fromDegrees(lon, lat, height);\r\n }\r\n\r\n worldToLonLat(cartesian) {\r\n const cartographic = Cesium.Cartographic.fromCartesian(cartesian);\r\n return [\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude),\r\n cartographic.height\r\n ];\r\n }\r\n\r\n screenToWorld(x, y) {\r\n const screenPosition = new Cesium.Cartesian2(x, y);\r\n if (this.viewer.scene.pickPositionSupported) {\r\n const precisePosition = this.viewer.scene.pickPosition(screenPosition);\r\n if (precisePosition) return precisePosition;\r\n }\r\n const ray = this.viewer.camera.getPickRay(screenPosition);\r\n const globePosition = this.viewer.scene.globe.pick(ray, this.viewer.scene);\r\n if (globePosition) return globePosition;\r\n return this.viewer.camera.pickEllipsoid(screenPosition, Cesium.Ellipsoid.WGS84);\r\n }\r\n\r\n worldToScreen(cartesian) {\r\n return this.viewer.scene.cartesianToCanvasCoordinates(cartesian);\r\n }\r\n\r\n screenToLonLat(x, y) {\r\n const worldCoord = this.screenToWorld(x, y);\r\n return worldCoord ? this.worldToLonLat(worldCoord) : null;\r\n }\r\n\r\n lonLatToScreen(lon, lat, height = 0) {\r\n const worldCoord = this.lonLatToWorld(lon, lat, height);\r\n return this.worldToScreen(worldCoord);\r\n }\r\n\r\n lonLatToCartographic(lon, lat, height = 0) {\r\n return new Cesium.Cartographic(Cesium.Math.toRadians(lon), Cesium.Math.toRadians(lat), height);\r\n }\r\n\r\n cartographicToLonLat(cartographic) {\r\n return [\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude),\r\n cartographic.height\r\n ];\r\n }\r\n\r\n // ========== 统一图层工厂 ==========\r\n\r\n /**\r\n * 通用图层创建工厂(自动从 URL 推断类型)\r\n * @param {string} url 服务地址\r\n * @param {Object} [options={}] 配置选项\r\n * @param {string} [options.type] 强制指定图层类型,见 {@link LayerType},不提供则自动推断\r\n * @param {string} [options.layerId] 图层唯一 ID,不提供则自动生成\r\n * @param {boolean} [options.visible=true] 是否可见\r\n * @param {number} [options.minimumLevel=0] 最小层级\r\n * @param {number} [options.maximumLevel=18] 最大层级\r\n * @param {string} [options.credit=''] 版权信息\r\n * @param {Array<number>} [options.extent] 范围 [west, south, east, north](单张影像用)\r\n * @param {string} [options.layer] WMTS 层名\r\n * @param {string} [options.style] WMTS 样式\r\n * @param {string} [options.format] WMTS 格式\r\n * @param {string} [options.tileMatrixSetID] WMTS 瓦片矩阵集\r\n * @param {string} [options.layers] WMS 图层名\r\n * @param {Object} [options.parameters] WMS 额外参数\r\n * @param {boolean} [options.requestWaterMask] 地形请求水面遮罩\r\n * @param {boolean} [options.requestVertexNormals] 地形请求顶点法线\r\n * @param {number} [options.maximumScreenSpaceError] 3DTiles 最大屏幕空间误差\r\n * @param {number} [options.maximumMemoryUsage] 3DTiles 最大内存占用(MB)\r\n * @param {boolean} [options.autoLocate=true] 3DTiles 创建后自动定位\r\n * @returns {ImageryLayerWrapper|TerrainLayerWrapper|TilesetLayerWrapper} 图层包装器\r\n * @example\r\n * // 自动推断类型(推荐)\r\n * sceneModule.createLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { layerId: 'osm' });\r\n * sceneModule.createLayer('https://example.com/tileset.json');\r\n * sceneModule.createLayer('https://example.com/terrain');\r\n *\r\n * // 显式指定类型(覆盖自动推断)\r\n * sceneModule.createLayer('https://example.com/wmts', { type: LayerType.WMTS, layer: 'vec' });\r\n */\r\n async createLayer(url, options = {}) {\r\n const type = options.type ?? autoDetectType(url);\r\n const layerId = options.layerId || `${type}_${Date.now()}`;\r\n\r\n if (this.layerMap.has(layerId)) {\r\n console.warn(`图层 ${layerId} 已存在`);\r\n return this.layerMap.get(layerId);\r\n }\r\n\r\n const visible = options.visible !== false;\r\n const provider = createProviderByType(type, url, options);\r\n const layerOrEntity = await addProviderToViewer(type, this.viewer, provider, visible);\r\n const wrapper = this.#wrapLayer(type, layerOrEntity, layerId);\r\n\r\n // 3DTiles 自动定位(readyPromise 已移除,改用 initialTilesLoaded 一次性事件)\r\n if (type === LayerType['3DTILES'] && options.autoLocate !== false) {\r\n const removeListener = layerOrEntity.initialTilesLoaded.addEventListener(() => {\r\n removeListener();\r\n this.viewer.zoomTo(layerOrEntity);\r\n });\r\n }\r\n\r\n this.layerMap.set(layerId, wrapper);\r\n console.log(`${type} 图层 ${layerId} 创建成功`);\r\n return wrapper;\r\n }\r\n\r\n /** 根据类型实例化对应包装器 */\r\n #wrapLayer(type, layerOrEntity, layerId) {\r\n if (type === LayerType.TERRAIN) {\r\n return new TerrainLayerWrapper(this, layerOrEntity, layerId);\r\n }\r\n if (type === LayerType['3DTILES']) {\r\n return new TilesetLayerWrapper(this, layerOrEntity, layerId);\r\n }\r\n return new ImageryLayerWrapper(this, layerOrEntity, layerId);\r\n }\r\n\r\n // ========== 图层管理 ==========\r\n\r\n /**\r\n * 删除图层\r\n * @param {string} layerId 图层 ID\r\n * @returns {boolean} 是否删除成功\r\n */\r\n removeLayer(layerId) {\r\n if (!this.layerMap.has(layerId)) {\r\n console.warn(`图层 ${layerId} 不存在`);\r\n return false;\r\n }\r\n\r\n const layer = this.layerMap.get(layerId);\r\n\r\n if (layer instanceof ImageryLayerWrapper) {\r\n this.viewer.imageryLayers.remove(layer.getLayer());\r\n } else if (layer instanceof TerrainLayerWrapper) {\r\n // 地形无法直接删除,重置为默认椭球地形\r\n this.viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider();\r\n } else if (layer instanceof TilesetLayerWrapper) {\r\n this.viewer.scene.primitives.remove(layer.getTileset());\r\n }\r\n\r\n this.layerMap.delete(layerId);\r\n return true;\r\n }\r\n\r\n /**\r\n * 获取图层\r\n * @param {string} layerId 图层 ID\r\n * @returns {ImageryLayerWrapper|TerrainLayerWrapper|TilesetLayerWrapper|undefined}\r\n */\r\n getLayer(layerId) {\r\n return this.layerMap.get(layerId);\r\n }\r\n\r\n // ========== 场景定位 ==========\r\n\r\n /**\r\n * 相机飞到指定经纬度\r\n * @param {Object} params 飞行参数\r\n * @param {number} params.lon 经度\r\n * @param {number} params.lat 纬度\r\n * @param {number} [params.height=2000] 相机高度\r\n * @param {number} [params.heading=0] 偏航角\r\n * @param {number} [params.pitch=-90] 俯仰角\r\n * @param {number} [params.roll=0] 翻滚角\r\n * @param {number} [params.duration=3.0] 飞行时长(秒)\r\n * @returns {Promise<boolean>}\r\n */\r\n flyToLonLat(params = {}) {\r\n const {\r\n lon, lat,\r\n height = 2000,\r\n heading = 0,\r\n pitch = -90,\r\n roll = 0,\r\n duration = 3.0\r\n } = params;\r\n\r\n if (!Cesium.defined(lon) || !Cesium.defined(lat)) {\r\n console.warn('flyToLonLat: 必须提供 lon、lat');\r\n return Promise.resolve(false);\r\n }\r\n\r\n return this.viewer.camera.flyTo({\r\n destination: Cesium.Cartesian3.fromDegrees(lon, lat, height),\r\n orientation: {\r\n heading: Cesium.Math.toRadians(heading),\r\n pitch: Cesium.Math.toRadians(pitch),\r\n roll: Cesium.Math.toRadians(roll)\r\n },\r\n duration\r\n });\r\n }\r\n\r\n /**\r\n * 设置相机视角(立即跳转,无飞行动画)\r\n * @param {Object} params\r\n * @param {number} params.lon 经度\r\n * @param {number} params.lat 纬度\r\n * @param {number} [params.height=500] 相机高度\r\n * @param {number} [params.heading=0] 偏航角(默认北向)\r\n * @param {number} [params.pitch=-90] 俯仰角(默认俯视)\r\n * @param {number} [params.roll=0] 翻滚角\r\n */\r\n setView(params = {}) {\r\n const {\r\n lon, lat,\r\n height = 500,\r\n heading = 0,\r\n pitch = -90,\r\n roll = 0\r\n } = params;\r\n\r\n if (!Cesium.defined(lon) || !Cesium.defined(lat)) {\r\n console.warn('setView: 必须提供 lon、lat');\r\n return;\r\n }\r\n\r\n this.viewer.camera.setView({\r\n destination: Cesium.Cartesian3.fromDegrees(lon, lat, height),\r\n orientation: {\r\n heading: Cesium.Math.toRadians(heading),\r\n pitch: Cesium.Math.toRadians(pitch),\r\n roll: Cesium.Math.toRadians(roll)\r\n }\r\n });\r\n }\r\n}\r\n","/**\r\n * 标绘几何算法工具\r\n * 移植自 cesium-plot-js 的几何生成能力\r\n *\r\n * 设计约定:\r\n * - 输入控制点:[lon, lat] 或 [lon, lat, height]\r\n * - 算法内部在经纬度平面上运算(与插件保持一致)\r\n * - 输出:[[lon, lat, height], ...] 或 Cesium.Cartesian3[]\r\n *\r\n * 注意:标绘算法内部使用平面距离计算,不要替换为 GeoCalcUtil.calcDistance\r\n */\r\nexport class PlotGeometryUtil {\r\n // ==================== 常量 ====================\r\n\r\n static FITTING_COUNT = 100;\r\n static ZERO_TOLERANCE = 0.0001;\r\n\r\n // ==================== 基础平面几何工具 ====================\r\n\r\n /**\r\n * 平面距离计算\r\n * 将经纬度视为平面坐标计算两点距离\r\n */\r\n static mathDistance(p1, p2) {\r\n return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);\r\n }\r\n\r\n /**\r\n * 计算点集合的总距离(平面)\r\n */\r\n static wholeDistance(points) {\r\n let distance = 0;\r\n if (!points || !Array.isArray(points) || points.length === 0) return distance;\r\n for (let i = 0; i < points.length - 1; i++) {\r\n distance += this.mathDistance(points[i], points[i + 1]);\r\n }\r\n return distance;\r\n }\r\n\r\n /**\r\n * 获取基础长度(插件算法中用于计算箭头尺寸)\r\n */\r\n static getBaseLength(points) {\r\n return this.wholeDistance(points) ** 0.99;\r\n }\r\n\r\n /**\r\n * 求两个坐标的中点\r\n */\r\n static mid(p1, p2) {\r\n return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];\r\n }\r\n\r\n /**\r\n * 获取方位角(弧度)\r\n * 将经纬度视为平面坐标计算方向\r\n */\r\n static getAzimuth(startPoint, endPoint) {\r\n const distance = this.mathDistance(startPoint, endPoint);\r\n if (distance === 0) return 0;\r\n\r\n const angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / distance);\r\n\r\n if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {\r\n return angle + Math.PI;\r\n }\r\n if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {\r\n return Math.PI * 2 - angle;\r\n }\r\n if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {\r\n return angle;\r\n }\r\n return Math.PI - angle;\r\n }\r\n\r\n /**\r\n * 获取三点夹角(∠ABC)\r\n */\r\n static getAngleOfThreePoints(pntA, pntB, pntC) {\r\n const angle = this.getAzimuth(pntB, pntA) - this.getAzimuth(pntB, pntC);\r\n return angle < 0 ? angle + Math.PI * 2 : angle;\r\n }\r\n\r\n /**\r\n * 判断三点是否顺时针\r\n */\r\n static isClockWise(pnt1, pnt2, pnt3) {\r\n return (pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]);\r\n }\r\n\r\n /**\r\n * 根据起止点和旋转方向求取第三个点\r\n * @param {Array} startPnt 起点 [lon, lat]\r\n * @param {Array} endPnt 终点 [lon, lat]\r\n * @param {number} angle 旋转角(弧度)\r\n * @param {number} distance 距离\r\n * @param {boolean} clockWise 是否顺时针\r\n * @returns {[number, number]}\r\n */\r\n static getThirdPoint(startPnt, endPnt, angle, distance, clockWise) {\r\n const azimuth = this.getAzimuth(startPnt, endPnt);\r\n const alpha = clockWise ? azimuth + angle : azimuth - angle;\r\n const dx = distance * Math.cos(alpha);\r\n const dy = distance * Math.sin(alpha);\r\n return [endPnt[0] + dx, endPnt[1] + dy];\r\n }\r\n\r\n /**\r\n * 插值圆弧点(经纬度平面)\r\n * @param {Array} center 圆心 [lon, lat]\r\n * @param {number} radius 半径(经纬度平面距离)\r\n * @param {number} startAngle 起始角(弧度)\r\n * @param {number} endAngle 结束角(弧度)\r\n * @param {number} segments 分段数\r\n * @returns {Array[]}\r\n */\r\n static getArcPoints(center, radius, startAngle, endAngle, segments = 100) {\r\n let angleDiff = endAngle - startAngle;\r\n angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff;\r\n\r\n const points = [];\r\n for (let i = 0; i <= segments; i++) {\r\n const angle = startAngle + (angleDiff * i) / segments;\r\n const x = center[0] + radius * Math.cos(angle);\r\n const y = center[1] + radius * Math.sin(angle);\r\n points.push([x, y]);\r\n }\r\n return points;\r\n }\r\n\r\n /**\r\n * 计算两点球面距离(米)\r\n * 与 _getPointAtBearingAndDistance 使用同一地球半径,保证扇形圆弧闭合一致\r\n * @param {Array} p1 [lon, lat]\r\n * @param {Array} p2 [lon, lat]\r\n * @returns {number}\r\n */\r\n static _calcSphericalDistance(p1, p2) {\r\n const earthRadius = 6371000;\r\n const radPerDeg = Math.PI / 180;\r\n const [lon1, lat1] = [p1[0] * radPerDeg, p1[1] * radPerDeg];\r\n const [lon2, lat2] = [p2[0] * radPerDeg, p2[1] * radPerDeg];\r\n const dLat = lat2 - lat1;\r\n const dLon = lon2 - lon1;\r\n const a = Math.sin(dLat / 2) ** 2 +\r\n Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n return earthRadius * c;\r\n }\r\n\r\n /**\r\n * 计算真实地理方位角(弧度)\r\n * 采用与 _getPointAtBearingAndDistance 一致的约定:0=正东,逆时针增大\r\n * @param {Array} from 起点 [lon, lat]\r\n * @param {Array} to 终点 [lon, lat]\r\n * @returns {number} 方位角 [0, 2π)\r\n */\r\n static _getBearing(from, to) {\r\n const radPerDeg = Math.PI / 180;\r\n const lon1 = from[0] * radPerDeg;\r\n const lat1 = from[1] * radPerDeg;\r\n const lon2 = to[0] * radPerDeg;\r\n const lat2 = to[1] * radPerDeg;\r\n\r\n const dLon = lon2 - lon1;\r\n const y = Math.sin(dLon) * Math.cos(lat2);\r\n const x = Math.cos(lat1) * Math.sin(lat2) -\r\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);\r\n\r\n // 标准球面前进方位角:0=正北,顺时针增大\r\n let standardBearing = Math.atan2(y, x);\r\n if (standardBearing < 0) standardBearing += Math.PI * 2;\r\n\r\n // 转换为本 SDK 约定:0=正东,逆时针增大\r\n let angle = Math.PI / 2 - standardBearing;\r\n if (angle < 0) angle += Math.PI * 2;\r\n if (angle > Math.PI * 2 - 1e-12) angle = 0;\r\n return angle;\r\n }\r\n\r\n /**\r\n * 按真实地理方位角和距离求目标点(球面直接解法)\r\n * 约定:0=正东,逆时针增大\r\n * @param {Array} center 圆心 [lon, lat]\r\n * @param {number} distanceMeters 距离(米)\r\n * @param {number} angle 方位角(弧度)\r\n * @returns {[number, number]}\r\n */\r\n static _getPointAtBearingAndDistance(center, distanceMeters, angle) {\r\n const earthRadius = 6371000;\r\n const radPerDeg = Math.PI / 180;\r\n const lon1 = center[0] * radPerDeg;\r\n const lat1 = center[1] * radPerDeg;\r\n const angularDistance = distanceMeters / earthRadius;\r\n\r\n // 转换回标准球面前进方位角:0=正北,顺时针增大\r\n const bearing = Math.PI / 2 - angle;\r\n\r\n const lat2 = Math.asin(\r\n Math.sin(lat1) * Math.cos(angularDistance) +\r\n Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(bearing)\r\n );\r\n const lon2 = lon1 + Math.atan2(\r\n Math.sin(bearing) * Math.sin(angularDistance) * Math.cos(lat1),\r\n Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2)\r\n );\r\n\r\n return [lon2 / radPerDeg, lat2 / radPerDeg];\r\n }\r\n\r\n /**\r\n * 在两个端点之间沿真实地理圆弧插值\r\n * 精确包含 startPoint 和 endPoint,避免端点漂移\r\n * @param {Array} center 圆心 [lon, lat]\r\n * @param {Array} startPoint 起点 [lon, lat]\r\n * @param {Array} endPoint 终点 [lon, lat]\r\n * @param {number} radiusMeters 半径(米)\r\n * @param {number} segments 分段数\r\n * @returns {Array[]}\r\n */\r\n static _getGeoArcPointsBetween(center, startPoint, endPoint, radiusMeters, segments = 100) {\r\n const startAngle = this._getBearing(center, startPoint);\r\n const endAngle = this._getBearing(center, endPoint);\r\n\r\n let angleDiff = endAngle - startAngle;\r\n angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff;\r\n\r\n const points = [startPoint];\r\n for (let i = 1; i < segments; i++) {\r\n const angle = startAngle + (angleDiff * i) / segments;\r\n points.push(this._getPointAtBearingAndDistance(center, radiusMeters, angle));\r\n }\r\n points.push(endPoint);\r\n return points;\r\n }\r\n\r\n // ==================== 坐标转换工具 ====================\r\n\r\n /**\r\n * 提取经纬度(忽略高度)\r\n */\r\n static toLonLat(point) {\r\n return [point[0], point[1]];\r\n }\r\n\r\n /**\r\n * 将结果点数组统一转为 [lon, lat, height] 格式\r\n */\r\n static toPositions(points, height = 0) {\r\n return points.map(p => [p[0], p[1], height]);\r\n }\r\n\r\n /**\r\n * 去除多边形轮廓中的相邻重复点,并显式闭合首尾\r\n * 用于修复 Cesium polyline/polygon 因零长度边导致的连线异常\r\n * @param {Array[]} points [lon, lat] 或 [lon, lat, height] 数组\r\n * @returns {Array[]}\r\n */\r\n static _closePolygonPoints(points) {\r\n if (!points || points.length === 0) return points;\r\n const result = [points[0]];\r\n for (let i = 1; i < points.length; i++) {\r\n const prev = result[result.length - 1];\r\n const curr = points[i];\r\n if (prev[0] !== curr[0] || prev[1] !== curr[1]) {\r\n result.push(curr);\r\n }\r\n }\r\n if (result.length > 1) {\r\n const first = result[0];\r\n const last = result[result.length - 1];\r\n if (first[0] !== last[0] || first[1] !== last[1]) {\r\n result.push(first);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * 将 [lon, lat, height] 数组转为 Cesium.Cartesian3 数组\r\n */\r\n static toCartesian3Array(points) {\r\n const flat = [];\r\n for (const p of points) {\r\n flat.push(p[0], p[1], p[2] || 0);\r\n }\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(flat);\r\n }\r\n\r\n // ==================== 曲线/插值工具(复合箭头、曲线标绘需要)====================\r\n\r\n /**\r\n * 线性插值\r\n */\r\n static getPointOnLine(t, startPnt, endPnt) {\r\n return [\r\n startPnt[0] + t * (endPnt[0] - startPnt[0]),\r\n startPnt[1] + t * (endPnt[1] - startPnt[1])\r\n ];\r\n }\r\n\r\n /**\r\n * 三次贝塞尔曲线求值\r\n */\r\n static getCubicValue(t, startPnt, cPnt1, cPnt2, endPnt) {\r\n t = Math.max(Math.min(t, 1), 0);\r\n const tp = 1 - t;\r\n const t2 = t * t;\r\n const t3 = t2 * t;\r\n const tp2 = tp * tp;\r\n const tp3 = tp2 * tp;\r\n return [\r\n tp3 * startPnt[0] + 3 * tp2 * t * cPnt1[0] + 3 * tp * t2 * cPnt2[0] + t3 * endPnt[0],\r\n tp3 * startPnt[1] + 3 * tp2 * t * cPnt1[1] + 3 * tp * t2 * cPnt2[1] + t3 * endPnt[1]\r\n ];\r\n }\r\n\r\n /**\r\n * 计算三点的法线及角平分线上的两个控制点\r\n */\r\n static getBisectorNormals(t, pnt1, pnt2, pnt3) {\r\n const normal = this.getNormal(pnt1, pnt2, pnt3);\r\n const dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1]);\r\n const uX = normal[0] / dist;\r\n const uY = normal[1] / dist;\r\n const d1 = this.mathDistance(pnt1, pnt2);\r\n const d2 = this.mathDistance(pnt2, pnt3);\r\n let bisectorNormalRight, bisectorNormalLeft;\r\n\r\n if (dist > this.ZERO_TOLERANCE) {\r\n if (this.isClockWise(pnt1, pnt2, pnt3)) {\r\n let dt = t * d1;\r\n let x = pnt2[0] - dt * uY;\r\n let y = pnt2[1] + dt * uX;\r\n bisectorNormalRight = [x, y];\r\n dt = t * d2;\r\n x = pnt2[0] + dt * uY;\r\n y = pnt2[1] - dt * uX;\r\n bisectorNormalLeft = [x, y];\r\n } else {\r\n let dt = t * d1;\r\n let x = pnt2[0] + dt * uY;\r\n let y = pnt2[1] - dt * uX;\r\n bisectorNormalRight = [x, y];\r\n dt = t * d2;\r\n x = pnt2[0] - dt * uY;\r\n y = pnt2[1] + dt * uX;\r\n bisectorNormalLeft = [x, y];\r\n }\r\n } else {\r\n let x = pnt2[0] + t * (pnt1[0] - pnt2[0]);\r\n let y = pnt2[1] + t * (pnt1[1] - pnt2[1]);\r\n bisectorNormalRight = [x, y];\r\n x = pnt2[0] + t * (pnt3[0] - pnt2[0]);\r\n y = pnt2[1] + t * (pnt3[1] - pnt2[1]);\r\n bisectorNormalLeft = [x, y];\r\n }\r\n return [bisectorNormalRight, bisectorNormalLeft];\r\n }\r\n\r\n /**\r\n * 获取三点的内切法线方向\r\n */\r\n static getNormal(pnt1, pnt2, pnt3) {\r\n let dX1 = pnt1[0] - pnt2[0];\r\n let dY1 = pnt1[1] - pnt2[1];\r\n const d1 = Math.sqrt(dX1 * dX1 + dY1 * dY1);\r\n dX1 /= d1;\r\n dY1 /= d1;\r\n let dX2 = pnt3[0] - pnt2[0];\r\n let dY2 = pnt3[1] - pnt2[1];\r\n const d2 = Math.sqrt(dX2 * dX2 + dY2 * dY2);\r\n dX2 /= d2;\r\n dY2 /= d2;\r\n return [dX1 + dX2, dY1 + dY2];\r\n }\r\n\r\n /**\r\n * 获取左侧第一个控制点(用于曲线插值)\r\n */\r\n static getLeftMostControlPoint(controlPoints, t) {\r\n const [pnt1, pnt2, pnt3] = [controlPoints[0], controlPoints[1], controlPoints[2]];\r\n const pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3);\r\n const normalRight = pnts[0];\r\n const normal = this.getNormal(pnt1, pnt2, pnt3);\r\n const dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1]);\r\n let controlX, controlY;\r\n if (dist > this.ZERO_TOLERANCE) {\r\n const mid = this.mid(pnt1, pnt2);\r\n const pX = pnt1[0] - mid[0];\r\n const pY = pnt1[1] - mid[1];\r\n const d1 = this.mathDistance(pnt1, pnt2);\r\n const n = 2.0 / d1;\r\n const nX = -n * pY;\r\n const nY = n * pX;\r\n const a11 = nX * nX - nY * nY;\r\n const a12 = 2 * nX * nY;\r\n const a22 = nY * nY - nX * nX;\r\n const dX = normalRight[0] - mid[0];\r\n const dY = normalRight[1] - mid[1];\r\n controlX = mid[0] + a11 * dX + a12 * dY;\r\n controlY = mid[1] + a12 * dX + a22 * dY;\r\n } else {\r\n controlX = pnt1[0] + t * (pnt2[0] - pnt1[0]);\r\n controlY = pnt1[1] + t * (pnt2[1] - pnt1[1]);\r\n }\r\n return [controlX, controlY];\r\n }\r\n\r\n /**\r\n * 获取右侧最后一个控制点(用于曲线插值)\r\n */\r\n static getRightMostControlPoint(controlPoints, t) {\r\n const count = controlPoints.length;\r\n const pnt1 = controlPoints[count - 3];\r\n const pnt2 = controlPoints[count - 2];\r\n const pnt3 = controlPoints[count - 1];\r\n const pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3);\r\n const normalLeft = pnts[1];\r\n const normal = this.getNormal(pnt1, pnt2, pnt3);\r\n const dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1]);\r\n let controlX, controlY;\r\n if (dist > this.ZERO_TOLERANCE) {\r\n const mid = this.mid(pnt2, pnt3);\r\n const pX = pnt3[0] - mid[0];\r\n const pY = pnt3[1] - mid[1];\r\n const d1 = this.mathDistance(pnt2, pnt3);\r\n const n = 2.0 / d1;\r\n const nX = -n * pY;\r\n const nY = n * pX;\r\n const a11 = nX * nX - nY * nY;\r\n const a12 = 2 * nX * nY;\r\n const a22 = nY * nY - nX * nX;\r\n const dX = normalLeft[0] - mid[0];\r\n const dY = normalLeft[1] - mid[1];\r\n controlX = mid[0] + a11 * dX + a12 * dY;\r\n controlY = mid[1] + a12 * dX + a22 * dY;\r\n } else {\r\n controlX = pnt3[0] + t * (pnt2[0] - pnt3[0]);\r\n controlY = pnt3[1] + t * (pnt2[1] - pnt3[1]);\r\n }\r\n return [controlX, controlY];\r\n }\r\n\r\n /**\r\n * 曲线插值(用于 CurvedArrow / Curve)\r\n * @param {number} t 张力系数\r\n * @param {Array[]} controlPoints 控制点数组\r\n */\r\n static getCurvePoints(t, controlPoints) {\r\n if (!controlPoints || controlPoints.length < 3) {\r\n return controlPoints ? controlPoints.slice() : [];\r\n }\r\n\r\n const leftControl = this.getLeftMostControlPoint(controlPoints, t);\r\n const normals = [leftControl];\r\n let pnt1, pnt2, pnt3;\r\n for (let i = 0; i < controlPoints.length - 2; i++) {\r\n pnt1 = controlPoints[i];\r\n pnt2 = controlPoints[i + 1];\r\n pnt3 = controlPoints[i + 2];\r\n const normalPoints = this.getBisectorNormals(t, pnt1, pnt2, pnt3);\r\n normals.push(...normalPoints);\r\n }\r\n const rightControl = this.getRightMostControlPoint(controlPoints, t);\r\n if (rightControl) {\r\n normals.push(rightControl);\r\n }\r\n\r\n const points = [];\r\n for (let i = 0; i < controlPoints.length - 1; i++) {\r\n pnt1 = controlPoints[i];\r\n pnt2 = controlPoints[i + 1];\r\n points.push(pnt1);\r\n for (let j = 0; j < this.FITTING_COUNT; j++) {\r\n const pnt = this.getCubicValue(\r\n j / this.FITTING_COUNT,\r\n pnt1,\r\n normals[i * 2],\r\n normals[i * 2 + 1],\r\n pnt2\r\n );\r\n points.push(pnt);\r\n }\r\n points.push(pnt2);\r\n }\r\n return points;\r\n }\r\n\r\n /**\r\n * 贝塞尔曲线插值\r\n */\r\n static getBezierPoints(points) {\r\n if (!points || points.length <= 2) return points;\r\n const bezierPoints = [];\r\n const n = points.length - 1;\r\n for (let t = 0; t <= 1; t += 0.01) {\r\n let x = 0, y = 0;\r\n for (let index = 0; index <= n; index++) {\r\n const factor = this.getBinomialFactor(n, index);\r\n const a = t ** index;\r\n const b = (1 - t) ** (n - index);\r\n x += factor * a * b * points[index][0];\r\n y += factor * a * b * points[index][1];\r\n }\r\n bezierPoints.push([x, y]);\r\n }\r\n bezierPoints.push(points[n]);\r\n return bezierPoints;\r\n }\r\n\r\n static getFactorial(n) {\r\n let result = 1;\r\n for (let i = 1; i <= n; i++) {\r\n result *= i;\r\n }\r\n return result;\r\n }\r\n\r\n static getBinomialFactor(n, index) {\r\n return this.getFactorial(n) / (this.getFactorial(index) * this.getFactorial(n - index));\r\n }\r\n\r\n /**\r\n * 二次 B 样条插值\r\n */\r\n static getQBSplinePoints(points) {\r\n if (!points || points.length <= 2) return points;\r\n const n = 2;\r\n const bSplinePoints = [];\r\n const m = points.length - n - 1;\r\n bSplinePoints.push(points[0]);\r\n for (let i = 0; i <= m; i++) {\r\n for (let t = 0; t <= 1; t += 0.05) {\r\n let x = 0, y = 0;\r\n for (let k = 0; k <= n; k++) {\r\n const factor = this.getQuadricBSplineFactor(k, t);\r\n x += factor * points[i + k][0];\r\n y += factor * points[i + k][1];\r\n }\r\n bSplinePoints.push([x, y]);\r\n }\r\n }\r\n bSplinePoints.push(points[points.length - 1]);\r\n return bSplinePoints;\r\n }\r\n\r\n static getQuadricBSplineFactor(k, t) {\r\n if (k === 0) return (t - 1) ** 2 / 2;\r\n if (k === 1) return (-2 * t ** 2 + 2 * t + 1) / 2;\r\n if (k === 2) return t ** 2 / 2;\r\n return 0;\r\n }\r\n\r\n // ==================== 标绘图元生成 ====================\r\n\r\n /**\r\n * 直箭头(FineArrow)\r\n * 控制点:2 个 [起点, 终点]\r\n */\r\n static createFineArrow(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const [p1, p2] = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n const tailWidthFactor = options.tailWidthFactor ?? 0.1;\r\n const neckWidthFactor = options.neckWidthFactor ?? 0.2;\r\n const headWidthFactor = options.headWidthFactor ?? 0.25;\r\n const headAngle = options.headAngle ?? Math.PI / 8.5;\r\n const neckAngle = options.neckAngle ?? Math.PI / 13;\r\n\r\n const len = this.getBaseLength([p1, p2]);\r\n const tailWidth = len * tailWidthFactor;\r\n const neckWidth = len * neckWidthFactor;\r\n const headWidth = len * headWidthFactor;\r\n\r\n const tailLeft = this.getThirdPoint(p2, p1, Math.PI / 2, tailWidth, true);\r\n const tailRight = this.getThirdPoint(p2, p1, Math.PI / 2, tailWidth, false);\r\n const headLeft = this.getThirdPoint(p1, p2, headAngle, headWidth, false);\r\n const headRight = this.getThirdPoint(p1, p2, headAngle, headWidth, true);\r\n const neckLeft = this.getThirdPoint(p1, p2, neckAngle, neckWidth, false);\r\n const neckRight = this.getThirdPoint(p1, p2, neckAngle, neckWidth, true);\r\n\r\n const outlinePoints = [\r\n tailLeft, neckLeft, headLeft, p2, headRight, neckRight, tailRight, p1\r\n ];\r\n\r\n return this.toPositions(outlinePoints, height);\r\n }\r\n\r\n /**\r\n * 突击方向(AssaultDirection)\r\n * 继承直箭头逻辑,仅系数不同,整体长度拉长 1.5 倍\r\n * 控制点:2 个 [起点, 终点]\r\n */\r\n static createAssaultDirection(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const [p1, p2] = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n const tailWidthFactor = options.tailWidthFactor ?? 0.08;\r\n const neckWidthFactor = options.neckWidthFactor ?? 0.1;\r\n const headWidthFactor = options.headWidthFactor ?? 0.13;\r\n const headAngle = options.headAngle ?? Math.PI / 4;\r\n const neckAngle = options.neckAngle ?? Math.PI * 0.17741;\r\n\r\n const len = this.getBaseLength([p1, p2]) * 1.5;\r\n const tailWidth = len * tailWidthFactor;\r\n const neckWidth = len * neckWidthFactor;\r\n const headWidth = len * headWidthFactor;\r\n\r\n const tailLeft = this.getThirdPoint(p2, p1, Math.PI / 2, tailWidth, true);\r\n const tailRight = this.getThirdPoint(p2, p1, Math.PI / 2, tailWidth, false);\r\n const headLeft = this.getThirdPoint(p1, p2, headAngle, headWidth, false);\r\n const headRight = this.getThirdPoint(p1, p2, headAngle, headWidth, true);\r\n const neckLeft = this.getThirdPoint(p1, p2, neckAngle, neckWidth, false);\r\n const neckRight = this.getThirdPoint(p1, p2, neckAngle, neckWidth, true);\r\n\r\n return this.toPositions([\r\n tailLeft, neckLeft, headLeft, p2, headRight, neckRight, tailRight, p1\r\n ], height);\r\n }\r\n\r\n /**\r\n * 细直箭头(StraightArrow)\r\n * 控制点:2 个 [起点, 终点]\r\n * 输出:线型\r\n */\r\n static createStraightArrow(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const [p1, p2] = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n const arrowLengthScale = options.arrowLengthScale ?? 5;\r\n const maxArrowLength = options.maxArrowLength ?? 3000000;\r\n\r\n const distance = this.mathDistance(p1, p2);\r\n let len = distance / arrowLengthScale;\r\n len = Math.min(len, maxArrowLength);\r\n\r\n const leftPnt = this.getThirdPoint(p1, p2, Math.PI / 6, len / 2, false);\r\n const rightPnt = this.getThirdPoint(p1, p2, Math.PI / 6, len / 2, true);\r\n\r\n return this.toPositions([p1, p2, leftPnt, p2, rightPnt], height);\r\n }\r\n\r\n /**\r\n * 三角形(Triangle)\r\n * 控制点:3 个\r\n */\r\n static createTriangle(points) {\r\n if (!points || points.length < 3) return [];\r\n return points.slice(0, 3).map(p => [p[0], p[1], p[2] || 0]);\r\n }\r\n\r\n /**\r\n * 扇形(Sector)\r\n * 控制点:3 个 [圆心, 起始点, 结束点]\r\n * 使用球面真实地理圆,保证圆弧经过两个半径控制点\r\n */\r\n static createSector(points) {\r\n if (!points || points.length < 3) return [];\r\n\r\n const [center, pnt2, pnt3] = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n // 使用球面距离作为半径,与圆弧插值函数保持一致\r\n const radius = this._calcSphericalDistance(pnt2, center);\r\n\r\n // 弧线精确经过两个控制点,避免端点漂移\r\n const arcPoints = this._getGeoArcPointsBetween(center, pnt2, pnt3, radius);\r\n arcPoints.push(center);\r\n\r\n return this.toPositions(arcPoints, height);\r\n }\r\n\r\n /**\r\n * 椭圆(Ellipse)\r\n * 控制点:3 个 [center, majorEnd, minorEnd]\r\n */\r\n static createEllipse(points) {\r\n if (!points || points.length < 3) return [];\r\n\r\n const controlPoints = points.slice(0, 3);\r\n const [center, majorEnd, minorEnd] = controlPoints.map(p => this.toLonLat(p));\r\n const height = controlPoints[0][2] || 0;\r\n\r\n const majorVec = [majorEnd[0] - center[0], majorEnd[1] - center[1]];\r\n const minorVec = [minorEnd[0] - center[0], minorEnd[1] - center[1]];\r\n\r\n const ellipsePoints = [];\r\n for (let i = 0; i <= 100; i++) {\r\n const angle = (Math.PI * 2 * i) / 100;\r\n const x = center[0] + majorVec[0] * Math.cos(angle) + minorVec[0] * Math.sin(angle);\r\n const y = center[1] + majorVec[1] * Math.cos(angle) + minorVec[1] * Math.sin(angle);\r\n ellipsePoints.push([x, y]);\r\n }\r\n\r\n return this.toPositions(ellipsePoints, height);\r\n }\r\n\r\n // ==================== 复合箭头图元 ====================\r\n\r\n /**\r\n * 通用箭头头部点\r\n * @param {Array[]} points 控制点数组\r\n * @param {object} options 箭头系数\r\n * @returns {Array[]} [neckLeft, headLeft, headPnt, headRight, neckRight]\r\n */\r\n static _getAttackArrowHeadPoints(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n const headHeightFactor = options.headHeightFactor ?? 0.18;\r\n const headWidthFactor = options.headWidthFactor ?? 0.3;\r\n const neckHeightFactor = options.neckHeightFactor ?? 0.85;\r\n const neckWidthFactor = options.neckWidthFactor ?? 0.15;\r\n const headTailFactor = options.headTailFactor ?? 0.8;\r\n\r\n const len = this.getBaseLength(points);\r\n let headHeight = len * headHeightFactor;\r\n const headPnt = points[points.length - 1];\r\n const len2 = this.mathDistance(headPnt, points[points.length - 2]);\r\n const tailWidth = this.mathDistance(options.tailLeft, options.tailRight);\r\n if (headHeight > tailWidth * headTailFactor) {\r\n headHeight = tailWidth * headTailFactor;\r\n }\r\n const headWidth = headHeight * headWidthFactor;\r\n const neckWidth = headHeight * neckWidthFactor;\r\n headHeight = Math.min(headHeight, len2);\r\n const neckHeight = headHeight * neckHeightFactor;\r\n\r\n const headEndPnt = this.getThirdPoint(points[points.length - 2], headPnt, 0, headHeight, true);\r\n const neckEndPnt = this.getThirdPoint(points[points.length - 2], headPnt, 0, neckHeight, true);\r\n const headLeft = this.getThirdPoint(headPnt, headEndPnt, Math.PI / 2, headWidth, false);\r\n const headRight = this.getThirdPoint(headPnt, headEndPnt, Math.PI / 2, headWidth, true);\r\n const neckLeft = this.getThirdPoint(headPnt, neckEndPnt, Math.PI / 2, neckWidth, false);\r\n const neckRight = this.getThirdPoint(headPnt, neckEndPnt, Math.PI / 2, neckWidth, true);\r\n return [neckLeft, headLeft, headPnt, headRight, neckRight];\r\n }\r\n\r\n /**\r\n * 通用箭头躯干点\r\n * @param {Array[]} points 骨骼点\r\n * @param {Array} neckLeft\r\n * @param {Array} neckRight\r\n * @param {number} tailWidthFactor\r\n */\r\n static _getAttackArrowBodyPoints(points, neckLeft, neckRight, tailWidthFactor) {\r\n const allLen = this.wholeDistance(points);\r\n const len = this.getBaseLength(points);\r\n const tailWidth = len * tailWidthFactor;\r\n const neckWidth = this.mathDistance(neckLeft, neckRight);\r\n const widthDif = (tailWidth - neckWidth) / 2;\r\n let tempLen = 0;\r\n const leftBodyPnts = [];\r\n const rightBodyPnts = [];\r\n for (let i = 1; i < points.length - 1; i++) {\r\n const angle = this.getAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2;\r\n tempLen += this.mathDistance(points[i - 1], points[i]);\r\n const w = (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle);\r\n const left = this.getThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true);\r\n const right = this.getThirdPoint(points[i - 1], points[i], angle, w, false);\r\n leftBodyPnts.push(left);\r\n rightBodyPnts.push(right);\r\n }\r\n return leftBodyPnts.concat(rightBodyPnts);\r\n }\r\n\r\n /**\r\n * 获取燕尾/集结箭头的尾部点\r\n */\r\n static _getSquadTailPoints(points, tailWidthFactor, swallowTailFactor = 0) {\r\n const allLen = this.getBaseLength(points);\r\n const tailWidth = allLen * tailWidthFactor;\r\n const tailLeft = this.getThirdPoint(points[1], points[0], Math.PI / 2, tailWidth, false);\r\n const tailRight = this.getThirdPoint(points[1], points[0], Math.PI / 2, tailWidth, true);\r\n if (swallowTailFactor > 0) {\r\n const len = tailWidth * swallowTailFactor;\r\n const swallowTailPnt = this.getThirdPoint(points[1], points[0], 0, len, true);\r\n return [tailLeft, swallowTailPnt, tailRight];\r\n }\r\n return [tailLeft, tailRight];\r\n }\r\n\r\n /**\r\n * 攻击箭头(AttackArrow)\r\n * 控制点:≥3 个 [tailLeft, tailRight, bone..., head]\r\n */\r\n static createAttackArrow(points, options = {}) {\r\n if (!points || points.length < 3) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n let [tailLeft, tailRight] = [lnglatPoints[0], lnglatPoints[1]];\r\n if (this.isClockWise(lnglatPoints[0], lnglatPoints[1], lnglatPoints[2])) {\r\n tailLeft = lnglatPoints[1];\r\n tailRight = lnglatPoints[0];\r\n }\r\n\r\n const midTail = this.mid(tailLeft, tailRight);\r\n const bonePnts = [midTail].concat(lnglatPoints.slice(2));\r\n const headPnts = this._getAttackArrowHeadPoints(bonePnts, {\r\n ...options,\r\n tailLeft,\r\n tailRight\r\n });\r\n if (!headPnts || headPnts.length === 0) return this.toPositions(lnglatPoints, height);\r\n\r\n const [neckLeft, neckRight] = [headPnts[0], headPnts[4]];\r\n const tailWidthFactor = this.mathDistance(tailLeft, tailRight) / this.getBaseLength(bonePnts);\r\n const bodyPnts = this._getAttackArrowBodyPoints(bonePnts, neckLeft, neckRight, tailWidthFactor);\r\n const count = bodyPnts.length;\r\n let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2));\r\n leftPnts.push(neckLeft);\r\n let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count));\r\n rightPnts.push(neckRight);\r\n leftPnts = this.getQBSplinePoints(leftPnts);\r\n rightPnts = this.getQBSplinePoints(rightPnts);\r\n const result = this._closePolygonPoints(leftPnts.concat(headPnts, rightPnts.reverse()));\r\n return this.toPositions(result, height);\r\n }\r\n\r\n /**\r\n * 燕尾攻击箭头(SwallowtailAttackArrow)\r\n * 控制点:≥3 个\r\n */\r\n static createSwallowtailAttackArrow(points, options = {}) {\r\n if (!points || points.length < 3) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n let [tailLeft, tailRight] = [lnglatPoints[0], lnglatPoints[1]];\r\n if (this.isClockWise(lnglatPoints[0], lnglatPoints[1], lnglatPoints[2])) {\r\n tailLeft = lnglatPoints[1];\r\n tailRight = lnglatPoints[0];\r\n }\r\n\r\n const midTail = this.mid(tailLeft, tailRight);\r\n const bonePnts = [midTail].concat(lnglatPoints.slice(2));\r\n const headPnts = this._getAttackArrowHeadPoints(bonePnts, {\r\n ...options,\r\n tailLeft,\r\n tailRight\r\n });\r\n if (!headPnts || headPnts.length === 0) return this.toPositions(lnglatPoints, height);\r\n\r\n const [neckLeft, neckRight] = [headPnts[0], headPnts[4]];\r\n const tailWidthFactor = options.tailWidthFactor ?? 0.1;\r\n const swallowTailFactor = options.swallowTailFactor ?? 1;\r\n const allLen = this.getBaseLength(bonePnts);\r\n const tailWidth = this.mathDistance(tailLeft, tailRight);\r\n const len = allLen * tailWidthFactor * swallowTailFactor;\r\n const swallowTailPnt = this.getThirdPoint(bonePnts[1], bonePnts[0], 0, len, true);\r\n const factor = tailWidth / allLen;\r\n const bodyPnts = this._getAttackArrowBodyPoints(bonePnts, neckLeft, neckRight, factor);\r\n const count = bodyPnts.length;\r\n let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2));\r\n leftPnts.push(neckLeft);\r\n let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count));\r\n rightPnts.push(neckRight);\r\n leftPnts = this.getQBSplinePoints(leftPnts);\r\n rightPnts = this.getQBSplinePoints(rightPnts);\r\n const result = this._closePolygonPoints(leftPnts.concat(headPnts, rightPnts.reverse(), [swallowTailPnt, leftPnts[0]]));\r\n return this.toPositions(result, height);\r\n }\r\n\r\n /**\r\n * 集结箭头(SquadCombat)\r\n * 控制点:≥2 个 [tailBase, bone..., head]\r\n */\r\n static createSquadCombat(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n const tailWidthFactor = options.tailWidthFactor ?? 0.1;\r\n const tailPnts = this._getSquadTailPoints(lnglatPoints, tailWidthFactor);\r\n const headPnts = this._getAttackArrowHeadPoints(lnglatPoints, {\r\n ...options,\r\n tailLeft: tailPnts[0],\r\n tailRight: tailPnts[1]\r\n });\r\n if (!headPnts || headPnts.length === 0) return this.toPositions(lnglatPoints, height);\r\n\r\n const [neckLeft, neckRight] = [headPnts[0], headPnts[4]];\r\n const bodyPnts = this._getAttackArrowBodyPoints(lnglatPoints, neckLeft, neckRight, tailWidthFactor);\r\n const count = bodyPnts.length;\r\n let leftPnts = [tailPnts[0]].concat(bodyPnts.slice(0, count / 2));\r\n leftPnts.push(neckLeft);\r\n let rightPnts = [tailPnts[1]].concat(bodyPnts.slice(count / 2, count));\r\n rightPnts.push(neckRight);\r\n leftPnts = this.getQBSplinePoints(leftPnts);\r\n rightPnts = this.getQBSplinePoints(rightPnts);\r\n const result = this._closePolygonPoints(leftPnts.concat(headPnts, rightPnts.reverse()));\r\n return this.toPositions(result, height);\r\n }\r\n\r\n /**\r\n * 燕尾集结箭头(SwallowtailSquadCombat)\r\n * 控制点:≥2 个\r\n */\r\n static createSwallowtailSquadCombat(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n const tailWidthFactor = options.tailWidthFactor ?? 0.1;\r\n const swallowTailFactor = options.swallowTailFactor ?? 1;\r\n const tailPnts = this._getSquadTailPoints(lnglatPoints, tailWidthFactor, swallowTailFactor);\r\n const headPnts = this._getAttackArrowHeadPoints(lnglatPoints, {\r\n ...options,\r\n tailLeft: tailPnts[0],\r\n tailRight: tailPnts[2]\r\n });\r\n if (!headPnts || headPnts.length === 0) return this.toPositions(lnglatPoints, height);\r\n\r\n const [neckLeft, neckRight] = [headPnts[0], headPnts[4]];\r\n const bodyPnts = this._getAttackArrowBodyPoints(lnglatPoints, neckLeft, neckRight, tailWidthFactor);\r\n const count = bodyPnts.length;\r\n let leftPnts = [tailPnts[0]].concat(bodyPnts.slice(0, count / 2));\r\n leftPnts.push(neckLeft);\r\n let rightPnts = [tailPnts[2]].concat(bodyPnts.slice(count / 2, count));\r\n rightPnts.push(neckRight);\r\n leftPnts = this.getQBSplinePoints(leftPnts);\r\n rightPnts = this.getQBSplinePoints(rightPnts);\r\n const result = this._closePolygonPoints(leftPnts.concat(headPnts, rightPnts.reverse(), [tailPnts[1], leftPnts[0]]));\r\n return this.toPositions(result, height);\r\n }\r\n\r\n /**\r\n * 双箭头(DoubleArrow)\r\n * 控制点:3~5 个\r\n * - 3 点:自动生成临时第四点和对称连接点\r\n * - 4 点:第四点作为临时控制点\r\n * - 5 点:第四点作为临时控制点,第五点作为连接点\r\n */\r\n static createDoubleArrow(points, options = {}) {\r\n if (!points || points.length < 3) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n const [pnt1, pnt2, pnt3] = lnglatPoints;\r\n const count = lnglatPoints.length;\r\n\r\n let tempPoint4;\r\n let connPoint;\r\n if (count === 3) {\r\n tempPoint4 = this._getDoubleArrowTempPoint4(pnt1, pnt2, pnt3);\r\n connPoint = this.mid(pnt1, pnt2);\r\n } else if (count === 4) {\r\n tempPoint4 = lnglatPoints[3];\r\n connPoint = this.mid(pnt1, pnt2);\r\n } else {\r\n tempPoint4 = lnglatPoints[3];\r\n connPoint = lnglatPoints[4];\r\n }\r\n\r\n const headHeightFactor = options.headHeightFactor ?? 0.25;\r\n const headWidthFactor = options.headWidthFactor ?? 0.3;\r\n const neckHeightFactor = options.neckHeightFactor ?? 0.85;\r\n const neckWidthFactor = options.neckWidthFactor ?? 0.15;\r\n\r\n const isClockWise = this.isClockWise(pnt1, pnt2, pnt3);\r\n let leftArrowPnts, rightArrowPnts;\r\n if (isClockWise) {\r\n leftArrowPnts = this._getDoubleArrowPoints(pnt1, connPoint, tempPoint4, false, options);\r\n rightArrowPnts = this._getDoubleArrowPoints(connPoint, pnt2, pnt3, true, options);\r\n } else {\r\n leftArrowPnts = this._getDoubleArrowPoints(pnt2, connPoint, pnt3, false, options);\r\n rightArrowPnts = this._getDoubleArrowPoints(connPoint, pnt1, tempPoint4, true, options);\r\n }\r\n\r\n const m = leftArrowPnts.length;\r\n const t = (m - 5) / 2;\r\n const llBodyPnts = leftArrowPnts.slice(0, t);\r\n const lArrowPnts = leftArrowPnts.slice(t, t + 5);\r\n let lrBodyPnts = leftArrowPnts.slice(t + 5, m);\r\n let rlBodyPnts = rightArrowPnts.slice(0, t);\r\n const rArrowPnts = rightArrowPnts.slice(t, t + 5);\r\n const rrBodyPnts = rightArrowPnts.slice(t + 5, m);\r\n\r\n rlBodyPnts = this.getBezierPoints(rlBodyPnts);\r\n const bodyPnts = this.getBezierPoints(rrBodyPnts.concat(llBodyPnts.slice(1)));\r\n lrBodyPnts = this.getBezierPoints(lrBodyPnts);\r\n const result = this._closePolygonPoints(rlBodyPnts.concat(rArrowPnts, bodyPnts, lArrowPnts, lrBodyPnts));\r\n return this.toPositions(result, height);\r\n }\r\n\r\n static _getDoubleArrowTempPoint4(linePnt1, linePnt2, point) {\r\n const midPnt = this.mid(linePnt1, linePnt2);\r\n const len = this.mathDistance(midPnt, point);\r\n const angle = this.getAngleOfThreePoints(linePnt1, midPnt, point);\r\n let symPnt = [0, 0];\r\n let distance1, distance2, mid;\r\n if (angle < Math.PI / 2) {\r\n distance1 = len * Math.sin(angle);\r\n distance2 = len * Math.cos(angle);\r\n mid = this.getThirdPoint(linePnt1, midPnt, Math.PI / 2, distance1, false);\r\n symPnt = this.getThirdPoint(midPnt, mid, Math.PI / 2, distance2, true);\r\n } else if (angle < Math.PI) {\r\n distance1 = len * Math.sin(Math.PI - angle);\r\n distance2 = len * Math.cos(Math.PI - angle);\r\n mid = this.getThirdPoint(linePnt1, midPnt, Math.PI / 2, distance1, false);\r\n symPnt = this.getThirdPoint(midPnt, mid, Math.PI / 2, distance2, false);\r\n } else if (angle < Math.PI * 1.5) {\r\n distance1 = len * Math.sin(angle - Math.PI);\r\n distance2 = len * Math.cos(angle - Math.PI);\r\n mid = this.getThirdPoint(linePnt1, midPnt, Math.PI / 2, distance1, true);\r\n symPnt = this.getThirdPoint(midPnt, mid, Math.PI / 2, distance2, true);\r\n } else {\r\n distance1 = len * Math.sin(Math.PI * 2 - angle);\r\n distance2 = len * Math.cos(Math.PI * 2 - angle);\r\n mid = this.getThirdPoint(linePnt1, midPnt, Math.PI / 2, distance1, true);\r\n symPnt = this.getThirdPoint(midPnt, mid, Math.PI / 2, distance2, false);\r\n }\r\n return symPnt;\r\n }\r\n\r\n static _getDoubleArrowPoints(pnt1, pnt2, pnt3, clockWise, options = {}) {\r\n const headHeightFactor = options.headHeightFactor ?? 0.25;\r\n const headWidthFactor = options.headWidthFactor ?? 0.3;\r\n const neckHeightFactor = options.neckHeightFactor ?? 0.85;\r\n const neckWidthFactor = options.neckWidthFactor ?? 0.15;\r\n\r\n const midPnt = this.mid(pnt1, pnt2);\r\n const len = this.mathDistance(midPnt, pnt3);\r\n let midPnt1 = this.getThirdPoint(pnt3, midPnt, 0, len * 0.3, true);\r\n let midPnt2 = this.getThirdPoint(pnt3, midPnt, 0, len * 0.5, true);\r\n midPnt1 = this.getThirdPoint(midPnt, midPnt1, Math.PI / 2, len / 5, clockWise);\r\n midPnt2 = this.getThirdPoint(midPnt, midPnt2, Math.PI / 2, len / 4, clockWise);\r\n const points = [midPnt, midPnt1, midPnt2, pnt3];\r\n const arrowPnts = this._getDoubleArrowHeadPoints(points, options);\r\n if (!arrowPnts || arrowPnts.length === 0) return [];\r\n\r\n const neckLeftPoint = arrowPnts[0];\r\n const neckRightPoint = arrowPnts[4];\r\n const tailWidthFactor = this.mathDistance(pnt1, pnt2) / this.getBaseLength(points) / 2;\r\n const bodyPnts = this._getAttackArrowBodyPoints(points, neckLeftPoint, neckRightPoint, tailWidthFactor);\r\n const n = bodyPnts.length;\r\n let lPoints = bodyPnts.slice(0, n / 2);\r\n let rPoints = bodyPnts.slice(n / 2, n);\r\n lPoints.push(neckLeftPoint);\r\n rPoints.push(neckRightPoint);\r\n lPoints = lPoints.reverse();\r\n lPoints.push(pnt2);\r\n rPoints = rPoints.reverse();\r\n rPoints.push(pnt1);\r\n return lPoints.reverse().concat(arrowPnts, rPoints);\r\n }\r\n\r\n static _getDoubleArrowHeadPoints(points, options = {}) {\r\n const len = this.getBaseLength(points);\r\n const headHeight = len * (options.headHeightFactor ?? 0.25);\r\n const headPnt = points[points.length - 1];\r\n const headWidth = headHeight * (options.headWidthFactor ?? 0.3);\r\n const neckWidth = headHeight * (options.neckWidthFactor ?? 0.15);\r\n const neckHeight = headHeight * (options.neckHeightFactor ?? 0.85);\r\n const headEndPnt = this.getThirdPoint(points[points.length - 2], headPnt, 0, headHeight, true);\r\n const neckEndPnt = this.getThirdPoint(points[points.length - 2], headPnt, 0, neckHeight, true);\r\n const headLeft = this.getThirdPoint(headPnt, headEndPnt, Math.PI / 2, headWidth, false);\r\n const headRight = this.getThirdPoint(headPnt, headEndPnt, Math.PI / 2, headWidth, true);\r\n const neckLeft = this.getThirdPoint(headPnt, neckEndPnt, Math.PI / 2, neckWidth, false);\r\n const neckRight = this.getThirdPoint(headPnt, neckEndPnt, Math.PI / 2, neckWidth, true);\r\n return [neckLeft, headLeft, headPnt, headRight, neckRight];\r\n }\r\n\r\n /**\r\n * 曲线箭头(CurvedArrow)\r\n * 控制点:≥2 个;2 个点时退化为细直箭头\r\n */\r\n static createCurvedArrow(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n if (points.length === 2) {\r\n return this.createStraightArrow(points, options);\r\n }\r\n\r\n const t = options.t ?? 0.3;\r\n const arrowLengthScale = options.arrowLengthScale ?? 5;\r\n const maxArrowLength = options.maxArrowLength ?? 3000000;\r\n\r\n const curvePoints = this.getCurvePoints(t, lnglatPoints);\r\n const pnt1 = lnglatPoints[lnglatPoints.length - 2];\r\n const pnt2 = lnglatPoints[lnglatPoints.length - 1];\r\n const distance = this.wholeDistance(lnglatPoints);\r\n let len = distance / arrowLengthScale;\r\n len = Math.min(len, maxArrowLength);\r\n const leftPnt = this.getThirdPoint(\r\n curvePoints[curvePoints.length - 2],\r\n curvePoints[curvePoints.length - 1],\r\n Math.PI / 6,\r\n len / 2,\r\n false\r\n );\r\n const rightPnt = this.getThirdPoint(\r\n curvePoints[curvePoints.length - 2],\r\n curvePoints[curvePoints.length - 1],\r\n Math.PI / 6,\r\n len / 2,\r\n true\r\n );\r\n const result = curvePoints.concat([leftPnt, pnt2, rightPnt]);\r\n return this.toPositions(result, height);\r\n }\r\n\r\n /**\r\n * 曲线(Curve)\r\n * 控制点:≥2 个;2 个点时退化为直线\r\n */\r\n static createCurve(points, options = {}) {\r\n if (!points || points.length < 2) return [];\r\n\r\n const lnglatPoints = points.map(p => this.toLonLat(p));\r\n const height = points[0][2] || 0;\r\n\r\n // 2 个点时直接连成直线,避免曲线插值算法因点数不足报错\r\n if (points.length === 2) {\r\n return this.toPositions(lnglatPoints, height);\r\n }\r\n\r\n const t = options.t ?? 0.3;\r\n const curvePoints = this.getCurvePoints(t, lnglatPoints);\r\n return this.toPositions(curvePoints, height);\r\n }\r\n}\r\n","/**\r\n * 标绘图元类型枚举\r\n * 对应 cesium-plot-js 支持的军事标绘类型\r\n */\r\nexport const PlotGraphicType = {\r\n // 面型标绘\r\n TRIANGLE: 'triangle',\r\n SECTOR: 'sector',\r\n ELLIPSE: 'ellipse',\r\n FINE_ARROW: 'fineArrow',\r\n ASSAULT_DIRECTION: 'assaultDirection',\r\n ATTACK_ARROW: 'attackArrow',\r\n SWALLOWTAIL_ATTACK_ARROW: 'swallowtailAttackArrow',\r\n SQUAD_COMBAT: 'squadCombat',\r\n SWALLOWTAIL_SQUAD_COMBAT: 'swallowtailSquadCombat',\r\n DOUBLE_ARROW: 'doubleArrow',\r\n\r\n // 线型标绘\r\n STRAIGHT_ARROW: 'straightArrow',\r\n CURVED_ARROW: 'curvedArrow',\r\n CURVE: 'curve'\r\n};\r\n\r\n/**\r\n * 标绘图元分类\r\n */\r\nexport const PlotGraphicCategory = {\r\n POLYGON: 'polygon',\r\n LINE: 'line'\r\n};\r\n\r\n/**\r\n * 判断标绘类型是否为线型\r\n * @param {string} plotType PlotGraphicType\r\n * @returns {boolean}\r\n */\r\nexport function isLinePlotType(plotType) {\r\n return [\r\n PlotGraphicType.STRAIGHT_ARROW,\r\n PlotGraphicType.CURVED_ARROW,\r\n PlotGraphicType.CURVE\r\n ].includes(plotType);\r\n}\r\n","import { Config } from '../core/Config.js';\r\nimport { PlotGeometryUtil } from '../utils/PlotGeometryUtil.js';\r\nimport { PlotGraphicType, isLinePlotType } from './PlotGraphicType.js';\r\n\r\n/**\r\n * 点图元包装器\r\n */\r\nclass PointWrapper {\r\n constructor(graphicModule, entity) {\r\n this._entity = entity;\r\n this._graphicModule = graphicModule;\r\n }\r\n\r\n setPosition(coords) {\r\n this._entity.position = Cesium.Cartesian3.fromDegrees(...coords);\r\n return this;\r\n }\r\n\r\n setColor(color) {\r\n this._entity.point.color = color;\r\n return this;\r\n }\r\n\r\n setPixelSize(size) {\r\n this._entity.point.pixelSize = size;\r\n return this;\r\n }\r\n\r\n setVisible(visible) {\r\n this._entity.show = visible;\r\n return this;\r\n }\r\n\r\n setHeightReference(ref) {\r\n this._entity.point.heightReference = ref;\r\n return this;\r\n }\r\n\r\n setDisableDepthTestDistance(distance) {\r\n this._entity.point.disableDepthTestDistance = distance;\r\n return this;\r\n }\r\n\r\n\r\n setOutlineColor(color) {\r\n this._entity.point.outlineColor = color;\r\n return this;\r\n }\r\n\r\n setOutlineWidth(width) {\r\n this._entity.point.outlineWidth = width;\r\n return this;\r\n }\r\n\r\n setName(name) {\r\n this._entity.id = name;\r\n return this;\r\n }\r\n\r\n // 名称标签相关\r\n setNameVisible(visible) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.show = visible;\r\n return this;\r\n }\r\n\r\n setText(text, options = {}) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.text = text;\r\n\r\n // 应用配置选项\r\n this._entity.label.disableDepthTestDistance = options.disableDepthTestDistance ?? Number.POSITIVE_INFINITY;\r\n this._entity.label.verticalOrigin = options.verticalOrigin ?? Cesium.VerticalOrigin.BOTTOM;\r\n this._entity.label.eyeOffset = options.eyeOffset ?? new Cesium.Cartesian3(0, 0, -10);\r\n this._entity.label.heightReference = options.heightReference ?? Cesium.HeightReference.RELATIVE_TO_GROUND;\r\n\r\n return this;\r\n }\r\n\r\n setFont(font) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.font = font;\r\n return this;\r\n }\r\n\r\n setTextColor(color) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.fillColor = color;\r\n return this;\r\n }\r\n\r\n setTextOutlineColor(color) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.outlineColor = color;\r\n return this;\r\n }\r\n\r\n setTextOutlineWidth(width) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.outlineWidth = width;\r\n return this;\r\n }\r\n\r\n setAlignType(alignType) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n // alignType: 0=CENTER, 1=LEFT, 2=RIGHT, 3=TOP, 4=BOTTOM\r\n const horizontalOrigins = [Cesium.HorizontalOrigin.CENTER, Cesium.HorizontalOrigin.LEFT, Cesium.HorizontalOrigin.RIGHT];\r\n const verticalOrigins = [Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.TOP, Cesium.VerticalOrigin.BOTTOM];\r\n this._entity.label.horizontalOrigin = horizontalOrigins[alignType] || Cesium.HorizontalOrigin.CENTER;\r\n this._entity.label.verticalOrigin = verticalOrigins[alignType] || Cesium.VerticalOrigin.CENTER;\r\n return this;\r\n }\r\n\r\n setTextPixelOffset(offset) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.pixelOffset = offset;\r\n return this;\r\n }\r\n\r\n setTextScale(scale) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.scale = scale;\r\n return this;\r\n }\r\n\r\n remove() {\r\n this._graphicModule.removeGraphic(this._entity.id);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 线图元包装器\r\n */\r\nclass LineWrapper {\r\n constructor(graphicModule, entity) {\r\n this._entity = entity;\r\n this._graphicModule = graphicModule;\r\n }\r\n\r\n setPositions(coords) {\r\n this._entity.polyline.positions = Cesium.Cartesian3.fromDegreesArrayHeights(\r\n coords.flatMap(coord => [coord[0], coord[1], coord[2] || 0])\r\n );\r\n return this;\r\n }\r\n\r\n setColor(color) {\r\n this._entity.polyline.material = color;\r\n return this;\r\n }\r\n\r\n setWidth(width) {\r\n this._entity.polyline.width = width;\r\n return this;\r\n }\r\n\r\n setMaterial(material) {\r\n this._entity.polyline.material = material;\r\n return this;\r\n }\r\n\r\n setVisible(visible) {\r\n this._entity.show = visible;\r\n return this;\r\n }\r\n\r\n setClampToGround(clamp) {\r\n this._entity.polyline.clampToGround = clamp;\r\n return this;\r\n }\r\n\r\n setName(name) {\r\n this._entity.id = name;\r\n return this;\r\n }\r\n\r\n /**\r\n * 在图元上附加标签,标签位置随几何变化自动更新\r\n * @param {string} text 标签文字\r\n * @param {object} options 标签样式 { font, color, outlineColor, outlineWidth, pixelOffset, horizontalOrigin, verticalOrigin }\r\n * @returns {LineWrapper}\r\n */\r\n setLabel(text, options = {}) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.text = text;\r\n this._entity.label.font = options.font || '14px Microsoft YaHei';\r\n this._entity.label.fillColor = options.color || Cesium.Color.WHITE;\r\n this._entity.label.outlineColor = options.outlineColor || Cesium.Color.BLACK;\r\n this._entity.label.outlineWidth = options.outlineWidth ?? 1;\r\n this._entity.label.show = true;\r\n this._entity.label.pixelOffset = options.pixelOffset || new Cesium.Cartesian2(0, -10);\r\n this._entity.label.horizontalOrigin = options.horizontalOrigin ?? Cesium.HorizontalOrigin.CENTER;\r\n this._entity.label.verticalOrigin = options.verticalOrigin ?? Cesium.VerticalOrigin.BOTTOM;\r\n\r\n // 使用 CallbackProperty 动态计算标签锚点,随编辑/平移自动更新\r\n const self = this;\r\n this._entity.position = new Cesium.CallbackProperty(function () {\r\n const anchor = self._computeLabelAnchor();\r\n return Cesium.Cartesian3.fromDegrees(anchor[0], anchor[1], anchor[2] || 0);\r\n }, false);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * 计算标签锚点 [lon, lat, height]\r\n * 标绘图元使用控制点重心,普通线图元使用顶点平均\r\n * @private\r\n */\r\n _computeLabelAnchor() {\r\n if (this._entity._isPlotGraphic && this._entity._controlPoints?.length) {\r\n const cps = this._entity._controlPoints;\r\n let x = 0, y = 0, z = 0;\r\n cps.forEach(cp => {\r\n x += cp[0];\r\n y += cp[1];\r\n z += cp[2] || 0;\r\n });\r\n return [x / cps.length, y / cps.length, z / cps.length];\r\n }\r\n\r\n const positions = this._entity.polyline?.positions?.getValue(Cesium.JulianDate.now());\r\n if (positions && positions.length > 0) {\r\n let lon = 0, lat = 0, height = 0;\r\n positions.forEach(p => {\r\n const c = Cesium.Cartographic.fromCartesian(p);\r\n lon += Cesium.Math.toDegrees(c.longitude);\r\n lat += Cesium.Math.toDegrees(c.latitude);\r\n height += c.height || 0;\r\n });\r\n const count = positions.length;\r\n return [lon / count, lat / count, height / count];\r\n }\r\n\r\n return [0, 0, 0];\r\n }\r\n\r\n /**\r\n * 设置为参数化标绘图元\r\n * @param {string} plotType PlotGraphicType\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n * @param {object} options 标绘参数\r\n * @returns {LineWrapper}\r\n */\r\n setPlotType(plotType, controlPoints, options = {}) {\r\n this._entity._isPlotGraphic = true;\r\n this._entity._plotType = plotType;\r\n this._entity._controlPoints = JSON.parse(JSON.stringify(controlPoints));\r\n\r\n const factoryName = `create${this._capitalizePlotType(plotType)}`;\r\n if (!PlotGeometryUtil[factoryName]) {\r\n console.warn(`未知标绘类型: ${plotType}`);\r\n return this;\r\n }\r\n\r\n const positions = PlotGeometryUtil[factoryName](controlPoints, options);\r\n this.setPositions(positions);\r\n return this;\r\n }\r\n\r\n /**\r\n * 更新标绘图元控制点并重算几何\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n * @param {object} options 标绘参数\r\n * @returns {LineWrapper}\r\n */\r\n setControlPoints(controlPoints, options = {}) {\r\n if (!this._entity._isPlotGraphic) {\r\n console.warn('非标绘图元,请使用 setPositions');\r\n return this;\r\n }\r\n return this.setPlotType(this._entity._plotType, controlPoints, options);\r\n }\r\n\r\n /**\r\n * 将标绘类型名转为工厂方法名\r\n * @private\r\n */\r\n _capitalizePlotType(plotType) {\r\n return plotType\r\n .replace(/-([a-z])/g, (g) => g[1].toUpperCase())\r\n .replace(/^./, s => s.toUpperCase());\r\n }\r\n\r\n remove() {\r\n this._graphicModule.removeGraphic(this._entity.id);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 面图元包装器\r\n */\r\nclass PolygonWrapper {\r\n constructor(graphicModule, entity) {\r\n this._entity = entity;\r\n this._graphicModule = graphicModule;\r\n }\r\n\r\n setPositions(coords) {\r\n this._entity.polygon.hierarchy = new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(\r\n coords.flatMap(coord => [coord[0], coord[1], coord[2] || 0])\r\n )\r\n );\r\n return this;\r\n }\r\n\r\n setColor(color) {\r\n this._entity.polygon.material = color;\r\n return this;\r\n }\r\n\r\n setOutlineColor(color) {\r\n this._entity.polygon.outlineColor = color;\r\n return this;\r\n }\r\n\r\n setOutlineWidth(width) {\r\n this._entity.polygon.outlineWidth = width;\r\n return this;\r\n }\r\n\r\n setVisible(visible) {\r\n this._entity.show = visible;\r\n return this;\r\n }\r\n\r\n setClampToGround(clamp) {\r\n this._entity.polygon.clampToGround = clamp;\r\n return this;\r\n }\r\n\r\n setHeightReference(ref) {\r\n this._entity.polygon.heightReference = ref;\r\n return this;\r\n }\r\n\r\n setName(name) {\r\n this._entity.id = name;\r\n return this;\r\n }\r\n\r\n /**\r\n * 在图元上附加标签,标签位置随几何变化自动更新\r\n * @param {string} text 标签文字\r\n * @param {object} options 标签样式 { font, color, outlineColor, outlineWidth, pixelOffset, horizontalOrigin, verticalOrigin }\r\n * @returns {PolygonWrapper}\r\n */\r\n setLabel(text, options = {}) {\r\n if (!this._entity.label) {\r\n this._entity.label = new Cesium.LabelGraphics();\r\n }\r\n this._entity.label.text = text;\r\n this._entity.label.font = options.font || '14px Microsoft YaHei';\r\n this._entity.label.fillColor = options.color || Cesium.Color.WHITE;\r\n this._entity.label.outlineColor = options.outlineColor || Cesium.Color.BLACK;\r\n this._entity.label.outlineWidth = options.outlineWidth ?? 1;\r\n this._entity.label.show = true;\r\n this._entity.label.pixelOffset = options.pixelOffset || new Cesium.Cartesian2(0, -10);\r\n this._entity.label.horizontalOrigin = options.horizontalOrigin ?? Cesium.HorizontalOrigin.CENTER;\r\n this._entity.label.verticalOrigin = options.verticalOrigin ?? Cesium.VerticalOrigin.BOTTOM;\r\n\r\n // 使用 CallbackProperty 动态计算标签锚点,随编辑/平移自动更新\r\n const self = this;\r\n this._entity.position = new Cesium.CallbackProperty(function () {\r\n const anchor = self._computeLabelAnchor();\r\n return Cesium.Cartesian3.fromDegrees(anchor[0], anchor[1], anchor[2] || 0);\r\n }, false);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * 计算标签锚点 [lon, lat, height]\r\n * 扇形固定在圆心,其他标绘使用控制点重心,普通面图元使用顶点重心\r\n * @private\r\n */\r\n _computeLabelAnchor() {\r\n if (this._entity._isPlotGraphic && this._entity._controlPoints?.length) {\r\n const cps = this._entity._controlPoints;\r\n if (this._entity._plotType === PlotGraphicType.SECTOR ||\r\n this._entity._plotType === PlotGraphicType.ELLIPSE) {\r\n return cps[0];\r\n }\r\n let x = 0, y = 0, z = 0;\r\n cps.forEach(cp => {\r\n x += cp[0];\r\n y += cp[1];\r\n z += cp[2] || 0;\r\n });\r\n return [x / cps.length, y / cps.length, z / cps.length];\r\n }\r\n\r\n const hierarchy = this._entity.polygon?.hierarchy?.getValue(Cesium.JulianDate.now());\r\n if (hierarchy && hierarchy.positions && hierarchy.positions.length > 0) {\r\n let lon = 0, lat = 0, height = 0;\r\n hierarchy.positions.forEach(p => {\r\n const c = Cesium.Cartographic.fromCartesian(p);\r\n lon += Cesium.Math.toDegrees(c.longitude);\r\n lat += Cesium.Math.toDegrees(c.latitude);\r\n height += c.height || 0;\r\n });\r\n const count = hierarchy.positions.length;\r\n return [lon / count, lat / count, height / count];\r\n }\r\n\r\n return [0, 0, 0];\r\n }\r\n\r\n /**\r\n * 设置为参数化标绘图元\r\n * @param {string} plotType PlotGraphicType\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n * @param {object} options 标绘参数\r\n * @returns {PolygonWrapper}\r\n */\r\n setPlotType(plotType, controlPoints, options = {}) {\r\n this._entity._isPlotGraphic = true;\r\n this._entity._plotType = plotType;\r\n this._entity._controlPoints = JSON.parse(JSON.stringify(controlPoints));\r\n\r\n const factoryName = `create${this._capitalizePlotType(plotType)}`;\r\n if (!PlotGeometryUtil[factoryName]) {\r\n console.warn(`未知标绘类型: ${plotType}`);\r\n return this;\r\n }\r\n\r\n const positions = PlotGeometryUtil[factoryName](controlPoints, options);\r\n this.setPositions(positions);\r\n return this;\r\n }\r\n\r\n /**\r\n * 更新标绘图元控制点并重算几何\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n * @param {object} options 标绘参数\r\n * @returns {PolygonWrapper}\r\n */\r\n setControlPoints(controlPoints, options = {}) {\r\n if (!this._entity._isPlotGraphic) {\r\n console.warn('非标绘图元,请使用 setPositions');\r\n return this;\r\n }\r\n return this.setPlotType(this._entity._plotType, controlPoints, options);\r\n }\r\n\r\n /**\r\n * 将标绘类型名转为工厂方法名\r\n * @private\r\n */\r\n _capitalizePlotType(plotType) {\r\n return plotType\r\n .replace(/-([a-z])/g, (g) => g[1].toUpperCase())\r\n .replace(/^./, s => s.toUpperCase());\r\n }\r\n\r\n remove() {\r\n this._graphicModule.removeGraphic(this._entity.id);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 模型图元包装器\r\n */\r\nclass ModelWrapper {\r\n constructor(graphicModule, entity) {\r\n this._entity = entity;\r\n this._graphicModule = graphicModule;\r\n }\r\n\r\n setPosition(coords) {\r\n this._entity.position = Cesium.Cartesian3.fromDegrees(...coords);\r\n return this;\r\n }\r\n\r\n setUrl(url) {\r\n this._entity.model.uri = url;\r\n return this;\r\n }\r\n\r\n setScale(scale) {\r\n this._entity.model.scale = scale;\r\n return this;\r\n }\r\n\r\n setMinimumPixelSize(size) {\r\n this._entity.model.minimumPixelSize = size;\r\n return this;\r\n }\r\n\r\n setVisible(visible) {\r\n this._entity.show = visible;\r\n return this;\r\n }\r\n\r\n setColor(color) {\r\n this._entity.model.color = color;\r\n return this;\r\n }\r\n\r\n setName(name) {\r\n this._entity.id = name;\r\n return this;\r\n }\r\n\r\n remove() {\r\n this._graphicModule.removeGraphic(this._entity.id);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 文本图元包装器\r\n */\r\nclass TextWrapper {\r\n constructor(graphicModule, entity) {\r\n this._entity = entity;\r\n this._graphicModule = graphicModule;\r\n }\r\n\r\n setPosition(coords) {\r\n this._entity.position = Cesium.Cartesian3.fromDegrees(...coords);\r\n return this;\r\n }\r\n\r\n setText(text) {\r\n this._entity.label.text = text;\r\n\r\n return this;\r\n }\r\n\r\n setFont(font) {\r\n this._entity.label.font = font;\r\n return this;\r\n }\r\n\r\n setColor(color) {\r\n this._entity.label.fillColor = color;\r\n return this;\r\n }\r\n\r\n setOutlineColor(color) {\r\n this._entity.label.outlineColor = color;\r\n return this;\r\n }\r\n\r\n setOutlineWidth(width) {\r\n this._entity.label.outlineWidth = width;\r\n return this;\r\n }\r\n\r\n setVisible(visible) {\r\n this._entity.show = visible;\r\n return this;\r\n }\r\n\r\n setPixelOffset(offset) {\r\n this._entity.label.pixelOffset = offset;\r\n return this;\r\n }\r\n\r\n setScale(scale) {\r\n this._entity.label.scale = scale;\r\n return this;\r\n }\r\n\r\n setAlignType(alignType) {\r\n const horizontalOrigins = [Cesium.HorizontalOrigin.CENTER, Cesium.HorizontalOrigin.LEFT, Cesium.HorizontalOrigin.RIGHT];\r\n const verticalOrigins = [Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.CENTER, Cesium.VerticalOrigin.TOP, Cesium.VerticalOrigin.BOTTOM];\r\n this._entity.label.horizontalOrigin = horizontalOrigins[alignType] || Cesium.HorizontalOrigin.CENTER;\r\n this._entity.label.verticalOrigin = verticalOrigins[alignType] || Cesium.VerticalOrigin.CENTER;\r\n return this;\r\n }\r\n\r\n setName(name) {\r\n this._entity.id = name;\r\n return this;\r\n }\r\n\r\n remove() {\r\n this._graphicModule.removeGraphic(this._entity.id);\r\n return this;\r\n }\r\n}\r\n\r\n/**\r\n * 图元模块(对应平台 IGraphicModule)\r\n * 职责:点/线/面/模型的参数化创建、编辑、销毁\r\n */\r\nexport class GraphicModule {\r\n constructor(viewer) {\r\n this.viewer = viewer;\r\n this.config = Config.getInstance().getConfig();\r\n this.graphicMap = new Map(); // 图元缓存(ID -> 实体实例)\r\n this.wrapperMap = new Map(); // 包装器缓存(ID -> Wrapper 实例)\r\n }\r\n\r\n /**\r\n * 创建点图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @returns {PointWrapper} 点图元包装器\r\n */\r\n createPoint(graphicId) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const defaultStyle = this.config.graphic?.point || { pixelSize: 8, color: Cesium.Color.RED };\r\n\r\n const entityOptions = {\r\n id: graphicId,\r\n position: Cesium.Cartesian3.fromDegrees(0, 0, 0),\r\n point: {\r\n ...defaultStyle,\r\n outlineColor: Cesium.Color.WHITE,\r\n outlineWidth: 1\r\n }\r\n };\r\n\r\n const entity = this.viewer.entities.add(entityOptions);\r\n this.graphicMap.set(graphicId, entity);\r\n\r\n const wrapper = new PointWrapper(this, entity);\r\n this.wrapperMap.set(graphicId, wrapper);\r\n console.log(`点图元 ${graphicId} 创建成功`);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建点图元(旧方法别名,建议迁移到 createPoint)\r\n * @deprecated\r\n */\r\n CreatePoint(graphicId) {\r\n return this.createPoint(graphicId);\r\n }\r\n\r\n /**\r\n * 创建线图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @returns {LineWrapper} 线图元包装器\r\n */\r\n createLine(graphicId) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const defaultStyle = this.config.graphic?.line || { width: 2, material: Cesium.Color.BLUE };\r\n\r\n const entityOptions = {\r\n id: graphicId,\r\n polyline: {\r\n positions: Cesium.Cartesian3.fromDegreesArrayHeights([]),\r\n clampToGround: true,\r\n ...defaultStyle\r\n }\r\n };\r\n\r\n const entity = this.viewer.entities.add(entityOptions);\r\n this.graphicMap.set(graphicId, entity);\r\n\r\n const wrapper = new LineWrapper(this, entity);\r\n this.wrapperMap.set(graphicId, wrapper);\r\n console.log(`线图元 ${graphicId} 创建成功`);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建线图元(旧方法别名,建议迁移到 createLine)\r\n * @deprecated\r\n */\r\n CreateLine(graphicId) {\r\n return this.createLine(graphicId);\r\n }\r\n\r\n /**\r\n * 创建面图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @returns {PolygonWrapper} 面图元包装器\r\n */\r\n createPolygon(graphicId) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const defaultStyle = this.config.graphic?.polygon || { color: Cesium.Color.GREEN.withAlpha(0.5) };\r\n\r\n const entityOptions = {\r\n id: graphicId,\r\n polygon: {\r\n hierarchy: new Cesium.PolygonHierarchy([]),\r\n clampToGround: true,\r\n outlineColor: Cesium.Color.WHITE,\r\n outlineWidth: 1,\r\n ...defaultStyle\r\n }\r\n };\r\n\r\n const entity = this.viewer.entities.add(entityOptions);\r\n this.graphicMap.set(graphicId, entity);\r\n\r\n const wrapper = new PolygonWrapper(this, entity);\r\n this.wrapperMap.set(graphicId, wrapper);\r\n console.log(`面图元 ${graphicId} 创建成功`);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建面图元(旧方法别名,建议迁移到 createPolygon)\r\n * @deprecated\r\n */\r\n CreatePolygon(graphicId) {\r\n return this.createPolygon(graphicId);\r\n }\r\n\r\n /**\r\n * 创建模型图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @returns {ModelWrapper} 模型图元包装器\r\n */\r\n createModel(graphicId) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const entityOptions = {\r\n id: graphicId,\r\n position: Cesium.Cartesian3.fromDegrees(0, 0, 0),\r\n model: {\r\n uri: \"\",\r\n scale: 1.0,\r\n minimumPixelSize: 128\r\n }\r\n };\r\n\r\n const entity = this.viewer.entities.add(entityOptions);\r\n this.graphicMap.set(graphicId, entity);\r\n\r\n const wrapper = new ModelWrapper(this, entity);\r\n this.wrapperMap.set(graphicId, wrapper);\r\n console.log(`模型图元 ${graphicId} 创建成功`);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建模型图元(旧方法别名,建议迁移到 createModel)\r\n * @deprecated\r\n */\r\n CreateModel(graphicId) {\r\n return this.createModel(graphicId);\r\n }\r\n\r\n /**\r\n * 创建文本图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @returns {TextWrapper} 文本图元包装器\r\n */\r\n createText(graphicId) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const entityOptions = {\r\n id: graphicId,\r\n position: Cesium.Cartesian3.fromDegrees(0, 0, 0),\r\n label: {\r\n text: \"\",\r\n font: \"16px Microsoft YaHei\",\r\n fillColor: Cesium.Color.WHITE,\r\n outlineColor: Cesium.Color.BLACK,\r\n outlineWidth: 2,\r\n style: Cesium.LabelStyle.FILL_AND_OUTLINE,\r\n verticalOrigin: Cesium.VerticalOrigin.BOTTOM,\r\n horizontalOrigin: Cesium.HorizontalOrigin.CENTER\r\n }\r\n };\r\n\r\n const entity = this.viewer.entities.add(entityOptions);\r\n this.graphicMap.set(graphicId, entity);\r\n\r\n const wrapper = new TextWrapper(this, entity);\r\n this.wrapperMap.set(graphicId, wrapper);\r\n console.log(`文本图元 ${graphicId} 创建成功`);\r\n\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建文本图元(旧方法别名,建议迁移到 createText)\r\n * @deprecated\r\n */\r\n CreateText(graphicId) {\r\n return this.createText(graphicId);\r\n }\r\n\r\n /**\r\n * 创建参数化标绘图元\r\n * @param {string} graphicId 图元唯一ID\r\n * @param {string} plotType PlotGraphicType\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n * @returns {PolygonWrapper|LineWrapper} 图元包装器\r\n */\r\n createPlotGraphic(graphicId, plotType, controlPoints = []) {\r\n if (this.wrapperMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 已存在`);\r\n return this.wrapperMap.get(graphicId);\r\n }\r\n\r\n const isLine = isLinePlotType(plotType);\r\n const wrapper = isLine\r\n ? this.createLine(graphicId)\r\n : this.createPolygon(graphicId);\r\n\r\n if (controlPoints.length > 0) {\r\n const options = this._getPlotOptions(plotType);\r\n wrapper.setPlotType(plotType, controlPoints, options);\r\n } else {\r\n wrapper._entity._isPlotGraphic = true;\r\n wrapper._entity._plotType = plotType;\r\n wrapper._entity._controlPoints = [];\r\n }\r\n\r\n console.log(`标绘图元 ${graphicId}(${plotType})创建成功`);\r\n return wrapper;\r\n }\r\n\r\n /**\r\n * 创建直箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点\r\n * @returns {PolygonWrapper}\r\n */\r\n createFineArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.FINE_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建突击方向箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点\r\n * @returns {PolygonWrapper}\r\n */\r\n createAssaultDirection(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.ASSAULT_DIRECTION, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建细直箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点\r\n * @returns {LineWrapper}\r\n */\r\n createStraightArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.STRAIGHT_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建三角形\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点\r\n * @returns {PolygonWrapper}\r\n */\r\n createTriangle(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.TRIANGLE, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建扇形\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} center 圆心 [lon, lat, height]\r\n * @param {number} radius 半径(米)\r\n * @param {number} startAngle 起始角度(度,0=正东,逆时针增大)\r\n * @param {number} endAngle 结束角度(度)\r\n * @returns {PolygonWrapper}\r\n */\r\n createSector(graphicId, center, radius, startAngle, endAngle) {\r\n // 转换为三点控制点,与内部编辑逻辑保持一致\r\n const startAngleRad = (startAngle || 0) * Math.PI / 180;\r\n const endAngleRad = (endAngle === undefined ? 90 : endAngle) * Math.PI / 180;\r\n const pnt2 = PlotGeometryUtil._getPointAtBearingAndDistance(center, radius, startAngleRad);\r\n const pnt3 = PlotGeometryUtil._getPointAtBearingAndDistance(center, radius, endAngleRad);\r\n const controlPoints = [center, pnt2, pnt3];\r\n\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.SECTOR, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建椭圆\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,3 点 [center, majorEnd, minorEnd]\r\n * @returns {PolygonWrapper}\r\n */\r\n createEllipse(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.ELLIPSE, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建攻击箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥3 点\r\n * @returns {PolygonWrapper}\r\n */\r\n createAttackArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.ATTACK_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建燕尾攻击箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥3 点\r\n * @returns {PolygonWrapper}\r\n */\r\n createSwallowtailAttackArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.SWALLOWTAIL_ATTACK_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建集结箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥2 点\r\n * @returns {PolygonWrapper}\r\n */\r\n createSquadCombat(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.SQUAD_COMBAT, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建燕尾集结箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥2 点\r\n * @returns {PolygonWrapper}\r\n */\r\n createSwallowtailSquadCombat(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.SWALLOWTAIL_SQUAD_COMBAT, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建双箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,3~5 点\r\n * @returns {PolygonWrapper}\r\n */\r\n createDoubleArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.DOUBLE_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建曲线箭头\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥2 点\r\n * @returns {LineWrapper}\r\n */\r\n createCurvedArrow(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.CURVED_ARROW, controlPoints);\r\n }\r\n\r\n /**\r\n * 创建曲线\r\n * @param {string} graphicId 图元ID\r\n * @param {Array} controlPoints 控制点,≥2 点\r\n * @returns {LineWrapper}\r\n */\r\n createCurve(graphicId, controlPoints = []) {\r\n return this.createPlotGraphic(graphicId, PlotGraphicType.CURVE, controlPoints);\r\n }\r\n\r\n /**\r\n * 获取标绘类型默认参数\r\n * 当前返回空对象,算法参数使用 PlotGeometryUtil 内部默认值\r\n * 后续可扩展为从 Config 读取各标绘类型的算法参数\r\n * @private\r\n */\r\n _getPlotOptions(plotType) {\r\n const plotConfig = this.config.graphic?.plot;\r\n if (!plotConfig) return {};\r\n // 当前仅支持按线/面读取通用样式,算法参数暂不提供配置\r\n return {};\r\n }\r\n\r\n /**\r\n * 删除图元\r\n * @param {string} graphicId 图元ID\r\n * @returns {boolean} 是否删除成功\r\n */\r\n removeGraphic(graphicId) {\r\n if (!this.graphicMap.has(graphicId)) {\r\n console.warn(`图元 ${graphicId} 不存在`);\r\n return false;\r\n }\r\n\r\n const entity = this.graphicMap.get(graphicId);\r\n this.viewer.entities.remove(entity);\r\n this.graphicMap.delete(graphicId);\r\n this.wrapperMap.delete(graphicId);\r\n return true;\r\n }\r\n\r\n /**\r\n * 获取图元\r\n * @param {string} graphicId 图元ID\r\n * @returns {Cesium.Entity|undefined} 图元实体\r\n */\r\n getGraphic(graphicId) {\r\n return this.graphicMap.get(graphicId);\r\n }\r\n}\r\n","import { Config } from '../core/Config.js';\r\n\r\n/**\r\n * 事件模块(对应平台 IEventModule)\r\n * 职责:注册/注销鼠标、键盘、场景事件观察者\r\n */\r\nexport class EventModule {\r\n constructor(viewer) {\r\n this.viewer = viewer;\r\n this.config = Config.getInstance().getConfig();\r\n this.observers = new Map(); // 观察者缓存(事件类型 -> 回调列表)\r\n this.handlers = {}; // Cesium 事件处理器缓存\r\n }\r\n\r\n /**\r\n * 注册事件观察者(对齐平台 Observer 模式)\r\n * @param {string} eventType 事件类型\r\n * - mouse:click/move/down/up\r\n * - keyboard:keyup/keydown\r\n * - scene:load/change/zoom\r\n * @param {Function} callback 回调函数\r\n * @returns {string} 观察者ID(用于注销)\r\n * @example\r\n * // 注册鼠标点击事件\r\n * const observerId = eventModule.registerObserver('mouse:click', (position, entity) => {\r\n * console.log('点击位置:', position, '点击实体:', entity);\r\n * });\r\n */\r\n registerObserver(eventType, callback) {\r\n const observerId = `obs-${Date.now()}-${Math.random().toString(36).slice(2)}`;\r\n const [baseType, subType] = eventType.split(':');\r\n\r\n // 初始化观察者列表\r\n if (!this.observers.has(eventType)) {\r\n this.observers.set(eventType, new Map());\r\n // 创建 Cesium 事件处理器\r\n this.createEventHandler(baseType, subType);\r\n }\r\n\r\n // 存储观察者\r\n this.observers.get(eventType).set(observerId, callback);\r\n return observerId;\r\n }\r\n\r\n /**\r\n * 注销事件观察者\r\n * @param {string} eventType 事件类型\r\n * @param {string} observerId 观察者ID\r\n * @returns {boolean} 是否注销成功\r\n */\r\n unregisterObserver(eventType, observerId) {\r\n if (!this.observers.has(eventType)) return false;\r\n const typeObservers = this.observers.get(eventType);\r\n if (!typeObservers.has(observerId)) return false;\r\n\r\n typeObservers.delete(observerId);\r\n // 无观察者时销毁事件处理器\r\n if (typeObservers.size === 0) {\r\n this.destroyEventHandler(eventType);\r\n this.observers.delete(eventType);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * 注销所有事件观察者\r\n */\r\n unregisterAllObservers() {\r\n // 按处理器类型安全销毁\r\n Object.keys(this.handlers).forEach(eventKey => {\r\n const handler = this.handlers[eventKey];\r\n if (!handler) return;\r\n\r\n // 判断事件类型:mouse 处理器是 ScreenSpaceEventHandler;\r\n // scene 处理器是 addEventListener 返回的移除函数;\r\n // keyboard 处理器是 document 事件监听器,需通过存储的引用移除。\r\n const [baseType] = eventKey.split(':');\r\n if (baseType === 'mouse' && typeof handler.destroy === 'function') {\r\n handler.destroy();\r\n } else if (baseType === 'scene' && typeof handler === 'function') {\r\n handler();\r\n } else if (baseType === 'keyboard') {\r\n const subType = eventKey.split(':')[1];\r\n document.removeEventListener(subType, handler);\r\n }\r\n });\r\n this.handlers = {};\r\n this.observers.clear();\r\n }\r\n\r\n // ========== 内部方法:创建 Cesium 事件处理器 ==========\r\n createEventHandler(baseType, subType) {\r\n const eventKey = `${baseType}:${subType}`;\r\n if (this.handlers[eventKey]) return;\r\n\r\n switch (baseType) {\r\n // 鼠标事件\r\n case 'mouse':\r\n this.handlers[eventKey] = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);\r\n // 绑定鼠标事件\r\n const mouseEventType = this.getCesiumMouseEventType(subType);\r\n this.handlers[eventKey].setInputAction((movement) => {\r\n // 获取点击位置和实体\r\n const screenPos = movement.position || movement.endPosition;\r\n if (!screenPos) return;\r\n\r\n let position = null;\r\n let lngLat = null;\r\n\r\n try {\r\n position = this.viewer.scene.pickPosition(screenPos);\r\n } catch (e) {\r\n // pickPosition 可能在无效情况下抛出异常\r\n console.warn('获取点击位置失败:', e);\r\n }\r\n\r\n const pickedEntity = this.viewer.scene.pick(screenPos);\r\n\r\n if (position) {\r\n const cartographic = Cesium.Cartographic.fromCartesian(position);\r\n lngLat = [\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude),\r\n cartographic.height\r\n ];\r\n }\r\n\r\n // 触发所有观察者回调\r\n this.observers.get(eventKey).forEach(callback => {\r\n callback(lngLat, pickedEntity ? pickedEntity.id : null, movement);\r\n });\r\n }, mouseEventType);\r\n break;\r\n // 场景事件\r\n case 'scene':\r\n if (subType === 'load') {\r\n // 一次性加载事件:第一次 postRender 触发后自动移除\r\n let removeListener = null;\r\n const listener = () => {\r\n if (removeListener) {\r\n removeListener();\r\n removeListener = null;\r\n }\r\n this.observers.get(eventKey)?.forEach(callback => callback());\r\n };\r\n removeListener = this.viewer.scene.postRender.addEventListener(listener);\r\n this.handlers[eventKey] = removeListener;\r\n } else if (subType === 'zoom') {\r\n this.handlers[eventKey] = this.viewer.camera.changed.addEventListener(() => {\r\n const zoomLevel = this.getZoomLevel();\r\n this.observers.get(eventKey).forEach(callback => callback(zoomLevel));\r\n });\r\n }\r\n break;\r\n // 键盘事件\r\n case 'keyboard':\r\n this.handlers[eventKey] = (e) => {\r\n if (e.type === subType) {\r\n this.observers.get(eventKey).forEach(callback => callback(e));\r\n }\r\n };\r\n document.addEventListener(subType, this.handlers[eventKey]);\r\n break;\r\n }\r\n }\r\n\r\n // ========== 内部方法:销毁事件处理器 ==========\r\n destroyEventHandler(eventType) {\r\n const [baseType, subType] = eventType.split(':');\r\n const eventKey = eventType;\r\n\r\n if (!this.handlers[eventKey]) return;\r\n if (baseType === 'mouse') {\r\n this.handlers[eventKey].destroy();\r\n } else if (baseType === 'scene') {\r\n // scene 事件返回的是移除函数\r\n if (typeof this.handlers[eventKey] === 'function') {\r\n this.handlers[eventKey]();\r\n }\r\n } else if (baseType === 'keyboard') {\r\n document.removeEventListener(subType, this.handlers[eventKey]);\r\n }\r\n delete this.handlers[eventKey];\r\n }\r\n\r\n // ========== 工具方法:映射 Cesium 鼠标事件类型 ==========\r\n getCesiumMouseEventType(subType) {\r\n switch (subType) {\r\n case 'click': return Cesium.ScreenSpaceEventType.LEFT_CLICK;\r\n case 'rightclick': return Cesium.ScreenSpaceEventType.RIGHT_CLICK;\r\n case 'move': return Cesium.ScreenSpaceEventType.MOUSE_MOVE;\r\n case 'down': return Cesium.ScreenSpaceEventType.LEFT_DOWN;\r\n case 'up': return Cesium.ScreenSpaceEventType.LEFT_UP;\r\n default: return Cesium.ScreenSpaceEventType.LEFT_CLICK;\r\n }\r\n }\r\n\r\n // ========== 工具方法:获取场景缩放级别 ==========\r\n getZoomLevel() {\r\n const camera = this.viewer.camera;\r\n const positionCartographic = camera.positionCartographic;\r\n const positionCartesian = Cesium.Cartesian3.fromRadians(\r\n positionCartographic.longitude,\r\n positionCartographic.latitude,\r\n positionCartographic.height\r\n );\r\n const distance = Cesium.Cartesian3.distance(camera.position, positionCartesian);\r\n // 映射为 0-20 级缩放(类似地图瓦片级别)\r\n return Math.floor(Math.log2(6378137 * 2 * Math.PI / distance)) + 1;\r\n }\r\n}","/**\n * 工具基类\n * 所有编辑工具的抽象基类\n */\nexport class BaseTool {\n constructor(editorModule, options = {}) {\n this._editor = editorModule;\n this._viewer = editorModule.viewer;\n this._graphicModule = editorModule.graphicModule;\n this._eventModule = editorModule.eventModule;\n this._options = options;\n this._isActive = false;\n this._handlers = []; // 注册的事件处理器 ID\n }\n\n /**\n * 激活工具\n */\n activate() {\n if (this._isActive) return;\n this._isActive = true;\n this.onActivate();\n }\n\n /**\n * 停用工具\n */\n deactivate() {\n if (!this._isActive) return;\n this._isActive = false;\n this.onDeactivate();\n this.clearHandlers();\n }\n\n /**\n * 激活时的回调,子类重写\n */\n onActivate() { }\n\n /**\n * 停用时的回调,子类重写\n */\n onDeactivate() { }\n\n /**\n * 注册事件观察者\n * @param {string} eventType 事件类型\n * @param {Function} callback 回调函数\n * @returns {string} 观察者 ID\n */\n registerObserver(eventType, callback) {\n const observerId = this._eventModule.registerObserver(eventType, (lngLat, entity, movement) => {\n // mouse:move 事件没有 lngLat,直接传递 movement 对象\n if (eventType === 'mouse:move') {\n callback(movement);\n } else {\n callback(lngLat, entity, movement);\n }\n });\n this._handlers.push({ eventType, observerId });\n return observerId;\n }\n\n /**\n * 清除所有已注册的事件处理器\n */\n clearHandlers() {\n this._handlers.forEach(({ eventType, observerId }) => {\n this._eventModule.unregisterObserver(eventType, observerId);\n });\n this._handlers = [];\n }\n\n /**\n * 获取屏幕坐标对应的地理坐标\n * @param {object} screenPos 屏幕坐标 {x, y}\n * @returns {Array} 经纬度高度 [lon, lat, height]\n */\n screenToLonLat(screenPos) {\n if (!screenPos || screenPos.x == null || screenPos.y == null) return null;\n\n let cartesian = null;\n\n // 优先尝试拾取地形/物体表面位置\n try {\n cartesian = this._viewer.scene.pickPosition(screenPos);\n } catch (e) {\n // ignore\n }\n\n // 如果拾取失败(空白区域),fallback 到椭球体表面\n if (!cartesian) {\n cartesian = this._viewer.camera.pickEllipsoid(\n new Cesium.Cartesian3(screenPos.x, screenPos.y),\n this._viewer.scene.globe.ellipsoid\n );\n }\n\n if (!cartesian) return null;\n\n const cartographic = Cesium.Cartographic.fromCartesian(cartesian);\n return [\n Cesium.Math.toDegrees(cartographic.longitude),\n Cesium.Math.toDegrees(cartographic.latitude),\n cartographic.height\n ];\n }\n\n /**\n * 获取地形高度\n * @param {Array} lonLat 经纬度 [lon, lat]\n * @returns {Promise<number>} 地形高度\n */\n async getTerrainHeight(lonLat) {\n const cartographic = Cesium.Cartographic.fromDegrees(lonLat[0], lonLat[1]);\n const result = await Cesium.sampleTerrainMostDetailed(\n this._viewer.terrainProvider,\n [cartographic]\n );\n return result[0].height;\n }\n\n /**\n * 创建临时图元(不被 GraphicModule 管理,工具内部使用)\n * @param {string} id 临时 ID\n * @param {object} options 图元配置\n * @returns {Cesium.Entity}\n */\n createTempEntity(id, options) {\n const entity = this._viewer.entities.add({\n id: `${id}`,\n ...options\n });\n return entity;\n }\n\n /**\n * 移除临时图元\n * @param {Cesium.Entity} entity\n */\n removeTempEntity(entity) {\n if (entity) {\n this._viewer.entities.remove(entity);\n }\n }\n\n /**\n * 获取唯一 ID\n * @param {string} prefix 前缀\n * @returns {string}\n */\n generateId(prefix = 'tool') {\n return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n","import { BaseTool } from './BaseTool.js';\r\nimport { PlotGeometryUtil } from '../../utils/PlotGeometryUtil.js';\r\nimport { PlotGraphicType, isLinePlotType } from '../PlotGraphicType.js';\r\n\r\n/**\r\n * 绘制类型枚举\r\n */\r\nexport const DrawType = {\r\n POINT: 'point',\r\n LINE: 'line',\r\n POLYGON: 'polygon',\r\n RECTANGLE: 'rectangle',\r\n CIRCLE: 'circle',\r\n\r\n // 标绘类型\r\n TRIANGLE: 'triangle',\r\n SECTOR: 'sector',\r\n ELLIPSE: 'ellipse',\r\n FINE_ARROW: 'fineArrow',\r\n ASSAULT_DIRECTION: 'assaultDirection',\r\n STRAIGHT_ARROW: 'straightArrow',\r\n ATTACK_ARROW: 'attackArrow',\r\n SWALLOWTAIL_ATTACK_ARROW: 'swallowtailAttackArrow',\r\n SQUAD_COMBAT: 'squadCombat',\r\n SWALLOWTAIL_SQUAD_COMBAT: 'swallowtailSquadCombat',\r\n DOUBLE_ARROW: 'doubleArrow',\r\n CURVED_ARROW: 'curvedArrow',\r\n CURVE: 'curve'\r\n};\r\n\r\n/**\r\n * 标绘绘制配置表\r\n * 描述每种标绘类型的:渲染类型、最少点数、完成触发方式、对应 PlotGraphicType\r\n * 注:当前仅配置已实现的标绘类型,后续随算法实现逐步放开\r\n */\r\nconst PLOT_DRAW_CONFIG = {\r\n [DrawType.TRIANGLE]: {\r\n category: 'polygon',\r\n minPoints: 3,\r\n finishOnCount: 3,\r\n plotType: PlotGraphicType.TRIANGLE\r\n },\r\n [DrawType.SECTOR]: {\r\n category: 'polygon',\r\n minPoints: 3,\r\n finishOnCount: 3,\r\n plotType: PlotGraphicType.SECTOR\r\n },\r\n [DrawType.ELLIPSE]: {\r\n category: 'polygon',\r\n minPoints: 3,\r\n finishOnCount: 3,\r\n plotType: PlotGraphicType.ELLIPSE\r\n },\r\n [DrawType.FINE_ARROW]: {\r\n category: 'polygon',\r\n minPoints: 2,\r\n finishOnCount: 2,\r\n plotType: PlotGraphicType.FINE_ARROW\r\n },\r\n [DrawType.ASSAULT_DIRECTION]: {\r\n category: 'polygon',\r\n minPoints: 2,\r\n finishOnCount: 2,\r\n plotType: PlotGraphicType.ASSAULT_DIRECTION\r\n },\r\n [DrawType.STRAIGHT_ARROW]: {\r\n category: 'line',\r\n minPoints: 2,\r\n finishOnCount: 2,\r\n plotType: PlotGraphicType.STRAIGHT_ARROW\r\n },\r\n [DrawType.ATTACK_ARROW]: {\r\n category: 'polygon',\r\n minPoints: 3,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.ATTACK_ARROW\r\n },\r\n [DrawType.SWALLOWTAIL_ATTACK_ARROW]: {\r\n category: 'polygon',\r\n minPoints: 3,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.SWALLOWTAIL_ATTACK_ARROW\r\n },\r\n [DrawType.SQUAD_COMBAT]: {\r\n category: 'polygon',\r\n minPoints: 2,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.SQUAD_COMBAT\r\n },\r\n [DrawType.SWALLOWTAIL_SQUAD_COMBAT]: {\r\n category: 'polygon',\r\n minPoints: 2,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.SWALLOWTAIL_SQUAD_COMBAT\r\n },\r\n [DrawType.DOUBLE_ARROW]: {\r\n category: 'polygon',\r\n minPoints: 4,\r\n finishOnCount: 4,\r\n plotType: PlotGraphicType.DOUBLE_ARROW\r\n },\r\n [DrawType.CURVED_ARROW]: {\r\n category: 'line',\r\n minPoints: 2,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.CURVED_ARROW\r\n },\r\n [DrawType.CURVE]: {\r\n category: 'line',\r\n minPoints: 2,\r\n finishOnDoubleClick: true,\r\n plotType: PlotGraphicType.CURVE\r\n }\r\n};\r\n\r\n/**\r\n * 绘制工具\r\n * 支持点、线、面、矩形、圆的交互式绘制\r\n */\r\nexport class DrawTool extends BaseTool {\r\n constructor(editorModule, options = {}) {\r\n super(editorModule, options);\r\n this._drawType = options.drawType || DrawType.POINT;\r\n this._tempEntities = []; // 临时图元(辅助点等)\r\n this._tempPositions = []; // 用户点击的位置数组\r\n this._isDrawing = false; // 是否正在绘制\r\n this._startPos = null; // 起始位置(用于矩形、圆)\r\n this._mouseMoveHandler = null;\r\n this._clickCount = 0;\r\n // 预览线/面实体(单独保存,避免每次重建)\r\n this._previewLine = null;\r\n this._previewPolygon = null;\r\n this._previewRect = null;\r\n this._previewCircle = null;\r\n this._previewPlot = null; // 标绘图元预览\r\n this._currentMousePos = null; // 当前鼠标位置\r\n }\r\n\r\n /**\r\n * 设置绘制类型\r\n * @param {string} type 绘制类型 DrawType\r\n */\r\n setDrawType(type) {\r\n this._drawType = type;\r\n return this;\r\n }\r\n\r\n /**\r\n * 获取绘制类型\r\n */\r\n getDrawType() {\r\n return this._drawType;\r\n }\r\n\r\n onActivate() {\r\n // 注册鼠标事件\r\n this.registerObserver('mouse:click', this._onClick.bind(this));\r\n this.registerObserver('mouse:move', this._onMove.bind(this));\r\n this.registerObserver('mouse:rightclick', this._onRightClick.bind(this));\r\n this.registerObserver('keyboard:keydown', this._onKeyDown.bind(this));\r\n }\r\n\r\n onDeactivate() {\r\n this.clearTempEntities();\r\n this._isDrawing = false;\r\n this._tempPositions = [];\r\n this._clickCount = 0;\r\n this._currentMousePos = null;\r\n this._startPos = null;\r\n this._previewPlot = null;\r\n }\r\n\r\n _onClick(lngLat, entity, movement) {\r\n // lngLat 已经是经纬度数组 [lon, lat, height]\r\n if (!lngLat) return;\r\n\r\n // 优先处理标绘类型\r\n const plotConfig = PLOT_DRAW_CONFIG[this._drawType];\r\n if (plotConfig) {\r\n this._handlePlotClick(lngLat, plotConfig);\r\n return;\r\n }\r\n\r\n switch (this._drawType) {\r\n case DrawType.POINT:\r\n this._drawPoint(lngLat);\r\n break;\r\n case DrawType.LINE:\r\n this._handleLineClick(lngLat);\r\n break;\r\n case DrawType.POLYGON:\r\n this._handlePolygonClick(lngLat);\r\n break;\r\n case DrawType.RECTANGLE:\r\n this._handleRectangleClick(lngLat);\r\n break;\r\n case DrawType.CIRCLE:\r\n this._handleCircleClick(lngLat);\r\n break;\r\n }\r\n }\r\n\r\n _onMove(data) {\r\n // mouse:move 事件的 movement 对象使用 endPosition\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n const lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });\r\n if (!lonLat) return;\r\n\r\n this._currentMousePos = lonLat;\r\n\r\n if (this._drawType === DrawType.POINT) return;\r\n\r\n // 标绘类型预览\r\n const plotConfig = PLOT_DRAW_CONFIG[this._drawType];\r\n if (plotConfig) {\r\n if (this._isDrawing && this._tempPositions.length >= plotConfig.minPoints - 1) {\r\n this._updatePlotPreview(plotConfig, lonLat);\r\n }\r\n return;\r\n }\r\n\r\n if (this._isDrawing) {\r\n if (this._drawType === DrawType.LINE) {\r\n this._updateTempLine(lonLat);\r\n } else if (this._drawType === DrawType.POLYGON) {\r\n this._updateTempPolygon(lonLat);\r\n }\r\n }\r\n\r\n if (this._startPos) {\r\n this._updateRectOrCirclePreview(lonLat);\r\n }\r\n }\r\n\r\n _onKeyDown(data) {\r\n // ESC 取消绘制\r\n if (data.key === 'Escape') {\r\n this.cancelDrawing();\r\n }\r\n // Enter 完成当前绘制(线、面、标绘)\r\n if (data.key === 'Enter') {\r\n const plotConfig = PLOT_DRAW_CONFIG[this._drawType];\r\n if (plotConfig && this._isDrawing && this._tempPositions.length >= plotConfig.minPoints) {\r\n this._finishPlotDrawing(plotConfig);\r\n return;\r\n }\r\n this.finishDrawing();\r\n }\r\n // Backspace 删除上一个点(用于线、面、标绘)\r\n if (data.key === 'Backspace' && this._isDrawing && this._tempPositions.length > 0) {\r\n const plotConfig = PLOT_DRAW_CONFIG[this._drawType];\r\n if (plotConfig) {\r\n this._tempPositions.pop();\r\n const lastTemp = this._tempEntities.pop();\r\n if (lastTemp) {\r\n this.removeTempEntity(lastTemp);\r\n }\r\n this._updatePlotPreview(plotConfig);\r\n return;\r\n }\r\n\r\n this._tempPositions.pop();\r\n // 删除对应的临时辅助点\r\n const lastTemp = this._tempEntities.pop();\r\n if (lastTemp) {\r\n this.removeTempEntity(lastTemp);\r\n }\r\n this._updateTempPositions();\r\n }\r\n }\r\n\r\n _onRightClick(_lngLat, _entity, _movement) {\r\n // 右键结束绘制(用于线、面、标绘)\r\n if (this._isDrawing) {\r\n const plotConfig = PLOT_DRAW_CONFIG[this._drawType];\r\n if (plotConfig && this._tempPositions.length >= plotConfig.minPoints) {\r\n this._finishPlotDrawing(plotConfig);\r\n return;\r\n }\r\n this.finishDrawing();\r\n }\r\n }\r\n\r\n _drawPoint(lonLat) {\r\n const id = this.generateId('point');\r\n this._graphicModule.CreatePoint(id)\r\n .setPosition(lonLat)\r\n .setColor(Cesium.Color.RED)\r\n .setPixelSize(10);\r\n\r\n this._emitGraphicCreated('point', id);\r\n }\r\n\r\n _handleLineClick(lonLat) {\r\n this._tempPositions.push(lonLat);\r\n this._isDrawing = true;\r\n\r\n // 创建辅助点\r\n const tempPoint = this.createTempEntity(this.generateId('temp_point'), {\r\n position: Cesium.Cartesian3.fromDegrees(...lonLat),\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 8\r\n }\r\n });\r\n this._tempEntities.push(tempPoint);\r\n\r\n // 如果已经有至少2个点,创建或更新临时线\r\n if (this._tempPositions.length >= 2) {\r\n this._updateTempLine();\r\n }\r\n\r\n this._emitDrawProgress('line', this._tempPositions.slice());\r\n }\r\n\r\n _handlePolygonClick(lonLat) {\r\n this._tempPositions.push(lonLat);\r\n this._isDrawing = true;\r\n\r\n // 创建辅助点\r\n const tempPoint = this.createTempEntity(this.generateId('temp_point'), {\r\n position: Cesium.Cartesian3.fromDegrees(...lonLat),\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 8\r\n }\r\n });\r\n this._tempEntities.push(tempPoint);\r\n\r\n // 如果已经有至少3个点,显示临时面\r\n if (this._tempPositions.length >= 3) {\r\n this._updateTempPolygon();\r\n }\r\n\r\n this._emitDrawProgress('polygon', this._tempPositions.slice());\r\n }\r\n\r\n _handleRectangleClick(lonLat) {\r\n if (!this._startPos) {\r\n // 第一次点击:设置起始点\r\n this._startPos = lonLat;\r\n // 创建起始点标记\r\n const startMarker = this.createTempEntity(this.generateId('temp_start'), {\r\n position: Cesium.Cartesian3.fromDegrees(...lonLat),\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 10\r\n }\r\n });\r\n this._tempEntities.push(startMarker);\r\n } else {\r\n // 第二次点击:完成矩形\r\n this._finishRectangle(lonLat);\r\n }\r\n }\r\n\r\n _handleCircleClick(lonLat) {\r\n if (!this._startPos) {\r\n this._startPos = lonLat;\r\n const startMarker = this.createTempEntity(this.generateId('temp_start'), {\r\n position: Cesium.Cartesian3.fromDegrees(...lonLat),\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 10\r\n }\r\n });\r\n this._tempEntities.push(startMarker);\r\n } else {\r\n this._finishCircle(lonLat);\r\n }\r\n }\r\n\r\n _updateTempLine(mousePos) {\r\n // 构建预览线位置:已有位置 + 鼠标当前位置(跟随鼠标)\r\n const previewPositions = [...this._tempPositions];\r\n if (mousePos) {\r\n previewPositions.push(mousePos);\r\n }\r\n\r\n // 计算 Cartesian3 数组\r\n const flatCoords = [];\r\n for (const c of previewPositions) {\r\n flatCoords.push(c[0], c[1], c[2] || 0);\r\n }\r\n const cartesians = Cesium.Cartesian3.fromDegreesArrayHeights(flatCoords);\r\n\r\n if (!this._previewLine) {\r\n // 首次创建预览线\r\n this._previewLine = this.createTempEntity(this.generateId('temp_line'), {\r\n polyline: {\r\n positions: cartesians,\r\n material: Cesium.Color.YELLOW,\r\n width: 2\r\n }\r\n });\r\n this._tempEntities.push(this._previewLine);\r\n } else {\r\n // 直接更新位置属性,避免重建实体\r\n // this._previewLine.polyline.positions = cartesians;\r\n this._previewLine.polyline.positions = new Cesium.CallbackProperty(() => {\r\n return cartesians;\r\n }, false);\r\n }\r\n }\r\n\r\n _updateTempPolygon(mousePos) {\r\n if (this._tempPositions.length < 3) return;\r\n\r\n // 构建预览多边形:已有位置 + 鼠标当前位置 \r\n const previewPositions = [...this._tempPositions];\r\n if (mousePos) {\r\n previewPositions.push(mousePos);\r\n }\r\n // previewPositions.push(this._tempPositions[0]); // 闭合\r\n\r\n const flatCoords = [];\r\n for (const c of previewPositions) {\r\n flatCoords.push(c[0], c[1], c[2] || 0);\r\n }\r\n const cartesians = Cesium.Cartesian3.fromDegreesArrayHeights(flatCoords);\r\n\r\n if (!this._previewPolygon) {\r\n // 首次创建预览面\r\n this._previewPolygon = this.createTempEntity(this.generateId('temp_polygon'), {\r\n polygon: {\r\n hierarchy: new Cesium.PolygonHierarchy(cartesians),\r\n material: Cesium.Color.YELLOW.withAlpha(0.5),\r\n outline: false,\r\n outlineColor: Cesium.Color.YELLOW,\r\n }\r\n });\r\n this._tempEntities.push(this._previewPolygon);\r\n } else {\r\n // 直接更新层级,避免重建实体,使用 CallbackProperty 防止闪烁\r\n this._previewPolygon.polygon.hierarchy = new Cesium.CallbackProperty(() => {\r\n return new Cesium.PolygonHierarchy(cartesians);\r\n }, false);\r\n }\r\n }\r\n\r\n _updateRectOrCirclePreview(currentLonLat) {\r\n if (!this._startPos) return;\r\n\r\n if (this._drawType === DrawType.RECTANGLE) {\r\n this._updateRectPreview(currentLonLat);\r\n } else if (this._drawType === DrawType.CIRCLE) {\r\n this._updateCirclePreview(currentLonLat);\r\n }\r\n }\r\n\r\n _updateRectPreview(currentLonLat) {\r\n const corner1 = this._startPos;\r\n const corner2 = currentLonLat;\r\n\r\n // 计算矩形四个角\r\n const positions = [\r\n [corner1[0], corner1[1]],\r\n [corner2[0], corner1[1]],\r\n [corner2[0], corner2[1]],\r\n [corner1[0], corner2[1]],\r\n [corner1[0], corner1[1]]\r\n ];\r\n\r\n const flatCoords = [];\r\n for (const c of positions) {\r\n flatCoords.push(c[0], c[1], 0);\r\n }\r\n const cartesians = Cesium.Cartesian3.fromDegreesArrayHeights(flatCoords);\r\n\r\n if (!this._previewRect) {\r\n this._previewRect = this.createTempEntity(this.generateId('temp_rect'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(() => cartesians, false),\r\n material: Cesium.Color.YELLOW.withAlpha(0.7),\r\n width: 2\r\n },\r\n polygon: {\r\n hierarchy: new Cesium.CallbackProperty(() => new Cesium.PolygonHierarchy(cartesians), false),\r\n material: Cesium.Color.YELLOW.withAlpha(0.2),\r\n outline: false\r\n }\r\n });\r\n this._previewRect._isPreview = true;\r\n this._tempEntities.push(this._previewRect);\r\n } else {\r\n // 直接更新位置属性\r\n this._previewRect.polyline.positions = new Cesium.CallbackProperty(() => {\r\n const c1 = this._startPos;\r\n const c2 = this._currentMousePos;\r\n if (!c1 || !c2) return cartesians;\r\n const pos = [\r\n [c1[0], c1[1]],\r\n [c2[0], c1[1]],\r\n [c2[0], c2[1]],\r\n [c1[0], c2[1]],\r\n [c1[0], c1[1]]\r\n ];\r\n const flat = [];\r\n for (const p of pos) {\r\n flat.push(p[0], p[1], 0);\r\n }\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(flat);\r\n }, false);\r\n this._previewRect.polygon.hierarchy = new Cesium.CallbackProperty(() => {\r\n const c1 = this._startPos;\r\n const c2 = this._currentMousePos;\r\n if (!c1 || !c2) return new Cesium.PolygonHierarchy(cartesians);\r\n const pos = [\r\n [c1[0], c1[1]],\r\n [c2[0], c1[1]],\r\n [c2[0], c2[1]],\r\n [c1[0], c2[1]],\r\n [c1[0], c1[1]]\r\n ];\r\n const flat = [];\r\n for (const p of pos) {\r\n flat.push(p[0], p[1], 0);\r\n }\r\n return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(flat));\r\n }, false);\r\n }\r\n }\r\n\r\n _updateCirclePreview(currentLonLat) {\r\n const center = this._startPos;\r\n const radius = this._calcDistance(center, currentLonLat);\r\n const segments = 64;\r\n\r\n if (!this._previewCircle) {\r\n this._previewCircle = this.createTempEntity(this.generateId('temp_circle'), {\r\n polygon: {\r\n hierarchy: new Cesium.CallbackProperty(() => {\r\n const positions = this._generateCirclePositions(center, radius, segments);\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(flat));\r\n }, false),\r\n material: Cesium.Color.YELLOW.withAlpha(0.2),\r\n outline: false // 地形贴合时不支持 outline,设为 false 避免警告\r\n }\r\n });\r\n this._previewCircle._isPreview = true;\r\n this._tempEntities.push(this._previewCircle);\r\n } else {\r\n // 直接更新\r\n this._previewCircle.polygon.hierarchy = new Cesium.CallbackProperty(() => {\r\n const r = this._calcDistance(this._startPos, this._currentMousePos);\r\n const pos = this._generateCirclePositions(this._startPos, r, 64);\r\n const flat = pos.flatMap(c => [c[0], c[1], 0]);\r\n return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(flat));\r\n }, false);\r\n }\r\n }\r\n\r\n _finishRectangle(corner2) {\r\n const corner1 = this._startPos;\r\n const positions = [\r\n [corner1[0], corner1[1]],\r\n [corner2[0], corner1[1]],\r\n [corner2[0], corner2[1]],\r\n [corner1[0], corner2[1]]\r\n ];\r\n\r\n const id = this.generateId('rectangle');\r\n const entity = this._graphicModule.CreatePolygon(id)\r\n .setPositions(positions)\r\n .setColor(Cesium.Color.BLUE.withAlpha(0.5))\r\n .setOutlineColor(Cesium.Color.BLUE)\r\n .setOutlineWidth(2)\r\n .setHeightReference(Cesium.HeightReference.NONE);\r\n\r\n this.clearTempEntities();\r\n this._startPos = null;\r\n this._emitGraphicCreated('rectangle', id);\r\n }\r\n\r\n _finishCircle(edgeLonLat) {\r\n const center = this._startPos;\r\n const radius = this._calcDistance(center, edgeLonLat);\r\n const positions = this._generateCirclePositions(center, radius, 64);\r\n\r\n const id = this.generateId('circle');\r\n console.log('创建圆:', { center, radius, edgeLonLat, positionsCount: positions.length });\r\n\r\n // 创建圆并标记为圆形\r\n const wrapper = this._graphicModule.CreatePolygon(id);\r\n wrapper.setPositions(positions)\r\n .setColor(Cesium.Color.BLUE.withAlpha(0.5))\r\n .setOutlineColor(Cesium.Color.BLUE)\r\n .setOutlineWidth(2);\r\n\r\n // 给 entity 添加圆形标记(用于 EditTool 特殊处理)\r\n const entity = wrapper._entity;\r\n entity._isCircle = true;\r\n entity._circleCenter = center; // [lon, lat]\r\n entity._circleRadius = radius; // 米\r\n\r\n this.clearTempEntities();\r\n this._startPos = null;\r\n this._currentMousePos = null;\r\n this._emitGraphicCreated('circle', id);\r\n }\r\n\r\n _generateCirclePositions(center, radius, segments) {\r\n const [lon, lat] = center;\r\n const positions = [];\r\n const radPerDeg = Math.PI / 180;\r\n\r\n // 当前纬度的经度米数(随纬度变化)\r\n const metersPerLonDeg = 111320 * Math.cos(lat * radPerDeg);\r\n const metersPerLatDeg = 110540; // 纬度方向相对固定\r\n\r\n for (let i = 0; i <= segments; i++) {\r\n const angle = (i / segments) * Math.PI * 2;\r\n\r\n // 东向和北向偏移(米)→ 转换为度\r\n const dLon = (radius * Math.cos(angle) / metersPerLonDeg);\r\n const dLat = (radius * Math.sin(angle) / metersPerLatDeg);\r\n\r\n positions.push([lon + dLon, lat + dLat]);\r\n }\r\n\r\n return positions;\r\n }\r\n\r\n _calcDistance(coord1, coord2) {\r\n const earthRadius = 6371000; // 米\r\n const [lon1, lat1] = coord1.map(d => d * Math.PI / 180);\r\n const [lon2, lat2] = coord2.map(d => d * Math.PI / 180);\r\n\r\n const dLat = lat2 - lat1;\r\n const dLon = lon2 - lon1;\r\n\r\n const a = Math.sin(dLat / 2) ** 2 +\r\n Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n\r\n return earthRadius * c;\r\n }\r\n\r\n /**\r\n * 将椭圆控制点中的短轴端点投影到与长轴垂直的直线上\r\n * @param {Array} points [center, majorEnd, minorEndOrMouse]\r\n * @returns {Array} [center, majorEnd, projectedMinorEnd]\r\n */\r\n _normalizeEllipseControlPoints(points) {\r\n if (!points || points.length < 3) return points;\r\n\r\n const center = points[0];\r\n const majorEnd = points[1];\r\n const rawMinor = points[2];\r\n\r\n const major = [majorEnd[0] - center[0], majorEnd[1] - center[1]];\r\n const majorLen = Math.hypot(major[0], major[1]);\r\n if (majorLen === 0) return points;\r\n\r\n const ux = major[0] / majorLen;\r\n const uy = major[1] / majorLen;\r\n // 长轴逆时针旋转 90° 得到短轴方向\r\n const perpUx = -uy;\r\n const perpUy = ux;\r\n\r\n const mouseVec = [rawMinor[0] - center[0], rawMinor[1] - center[1]];\r\n const projectedLen = mouseVec[0] * perpUx + mouseVec[1] * perpUy;\r\n\r\n return [\r\n center,\r\n majorEnd,\r\n [center[0] + perpUx * projectedLen, center[1] + perpUy * projectedLen, center[2] || 0]\r\n ];\r\n }\r\n\r\n // ==================== 标绘类型绘制方法 ====================\r\n\r\n /**\r\n * 处理标绘类型点击事件\r\n * @param {Array} lngLat [lon, lat, height]\r\n * @param {object} config 标绘配置\r\n */\r\n _handlePlotClick(lngLat, config) {\r\n this._tempPositions.push(lngLat);\r\n this._isDrawing = true;\r\n\r\n // 创建辅助点\r\n const tempPoint = this.createTempEntity(this.generateId('temp_point'), {\r\n position: Cesium.Cartesian3.fromDegrees(...lngLat),\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 8\r\n }\r\n });\r\n this._tempEntities.push(tempPoint);\r\n\r\n // 更新预览\r\n if (this._tempPositions.length >= config.minPoints) {\r\n this._updatePlotPreview(config);\r\n }\r\n\r\n this._emitDrawProgress(config.plotType, this._tempPositions.slice());\r\n\r\n // 判断是否完成绘制\r\n if (config.finishOnCount && this._tempPositions.length >= config.finishOnCount) {\r\n this._finishPlotDrawing(config);\r\n return;\r\n }\r\n\r\n // 点数达到最小值后可以右键/Enter 结束(用于双击结束的类型)\r\n if (config.finishOnDoubleClick && this._tempPositions.length >= config.minPoints) {\r\n // 不自动完成,等待右键/Enter/双击\r\n console.log(`标绘 ${config.plotType} 已达到最小点数,可右键或按 Enter 完成`);\r\n }\r\n }\r\n\r\n /**\r\n * 更新标绘图元预览\r\n * @param {object} config 标绘配置\r\n * @param {Array} mousePos 当前鼠标位置 [lon, lat, height]\r\n */\r\n _updatePlotPreview(config, mousePos) {\r\n const isEllipse = config.plotType === PlotGraphicType.ELLIPSE;\r\n const normalizeForEllipse = (pts) => isEllipse ? this._normalizeEllipseControlPoints(pts) : pts;\r\n\r\n const previewPositions = [...this._tempPositions];\r\n if (mousePos) {\r\n previewPositions.push(mousePos);\r\n }\r\n\r\n if (previewPositions.length < config.minPoints) return;\r\n\r\n const factoryName = `create${this._capitalizePlotType(config.plotType)}`;\r\n if (!PlotGeometryUtil[factoryName]) {\r\n console.warn(`未知标绘类型: ${config.plotType}`);\r\n return;\r\n }\r\n\r\n const geometryPositions = normalizeForEllipse(previewPositions);\r\n const positions = PlotGeometryUtil[factoryName](geometryPositions);\r\n const isLine = config.category === 'line';\r\n const flatCoords = [];\r\n for (const c of positions) {\r\n flatCoords.push(c[0], c[1], c[2] || 0);\r\n }\r\n const cartesians = Cesium.Cartesian3.fromDegreesArrayHeights(flatCoords);\r\n\r\n if (!this._previewPlot) {\r\n if (isLine) {\r\n this._previewPlot = this.createTempEntity(this.generateId('temp_plot'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(() => cartesians, false),\r\n material: Cesium.Color.YELLOW,\r\n width: 2\r\n }\r\n });\r\n } else {\r\n this._previewPlot = this.createTempEntity(this.generateId('temp_plot'), {\r\n polygon: {\r\n hierarchy: new Cesium.CallbackProperty(() => new Cesium.PolygonHierarchy(cartesians), false),\r\n material: Cesium.Color.YELLOW.withAlpha(0.3),\r\n outline: false\r\n },\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(() => [...cartesians, cartesians[0]], false),\r\n material: Cesium.Color.YELLOW,\r\n width: 1\r\n }\r\n });\r\n }\r\n this._previewPlot._isPreview = true;\r\n this._tempEntities.push(this._previewPlot);\r\n } else {\r\n const self = this;\r\n if (isLine) {\r\n this._previewPlot.polyline.positions = new Cesium.CallbackProperty(() => {\r\n const dynamicPositions = [...self._tempPositions];\r\n if (self._currentMousePos) {\r\n dynamicPositions.push(self._currentMousePos);\r\n }\r\n if (dynamicPositions.length < config.minPoints) return [];\r\n const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));\r\n const flat = [];\r\n for (const c of pos) {\r\n flat.push(c[0], c[1], c[2] || 0);\r\n }\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(flat);\r\n }, false);\r\n } else {\r\n this._previewPlot.polygon.hierarchy = new Cesium.CallbackProperty(() => {\r\n const dynamicPositions = [...self._tempPositions];\r\n if (self._currentMousePos) {\r\n dynamicPositions.push(self._currentMousePos);\r\n }\r\n if (dynamicPositions.length < config.minPoints) return new Cesium.PolygonHierarchy([]);\r\n const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));\r\n const flat = [];\r\n for (const c of pos) {\r\n flat.push(c[0], c[1], c[2] || 0);\r\n }\r\n return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(flat));\r\n }, false);\r\n this._previewPlot.polyline.positions = new Cesium.CallbackProperty(() => {\r\n const dynamicPositions = [...self._tempPositions];\r\n if (self._currentMousePos) {\r\n dynamicPositions.push(self._currentMousePos);\r\n }\r\n if (dynamicPositions.length < config.minPoints) return [];\r\n const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));\r\n const flat = [];\r\n for (const c of pos) {\r\n flat.push(c[0], c[1], c[2] || 0);\r\n }\r\n const cart = Cesium.Cartesian3.fromDegreesArrayHeights(flat);\r\n return [...cart, cart[0]];\r\n }, false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 完成标绘图元绘制\r\n * @param {object} config 标绘配置\r\n */\r\n _finishPlotDrawing(config) {\r\n if (this._tempPositions.length < config.minPoints) return;\r\n\r\n const factoryName = `create${this._capitalizePlotType(config.plotType)}`;\r\n if (!PlotGeometryUtil[factoryName]) {\r\n console.warn(`未知标绘类型: ${config.plotType}`);\r\n return;\r\n }\r\n\r\n const id = this.generateId(config.plotType);\r\n const isLine = config.category === 'line';\r\n\r\n // 椭圆:将第三点击点投影到与长轴垂直的直线上\r\n const finalPositions = config.plotType === PlotGraphicType.ELLIPSE\r\n ? this._normalizeEllipseControlPoints(this._tempPositions)\r\n : this._tempPositions;\r\n\r\n // 创建标绘图元\r\n const wrapper = this._graphicModule.createPlotGraphic(\r\n id,\r\n config.plotType,\r\n finalPositions\r\n );\r\n\r\n // 应用默认样式\r\n if (isLine) {\r\n wrapper.setColor(Cesium.Color.BLUE).setWidth(2);\r\n } else {\r\n wrapper\r\n .setColor(Cesium.Color.BLUE.withAlpha(0.5))\r\n .setOutlineColor(Cesium.Color.BLUE)\r\n .setOutlineWidth(2);\r\n }\r\n\r\n this.clearTempEntities();\r\n this._startPos = null;\r\n this._currentMousePos = null;\r\n this._isDrawing = false;\r\n this._tempPositions = [];\r\n this._previewPlot = null;\r\n\r\n this._emitGraphicCreated(config.plotType, id);\r\n }\r\n\r\n /**\r\n * 将标绘类型名转为工厂方法名\r\n * @private\r\n */\r\n _capitalizePlotType(plotType) {\r\n return plotType\r\n .replace(/-([a-z])/g, (g) => g[1].toUpperCase())\r\n .replace(/^./, s => s.toUpperCase());\r\n }\r\n\r\n _updateTempPositions() {\r\n if (this._drawType === DrawType.LINE) {\r\n this._updateTempLine();\r\n } else if (this._drawType === DrawType.POLYGON) {\r\n this._updateTempPolygon();\r\n }\r\n }\r\n\r\n /**\r\n * 取消当前绘制\r\n */\r\n cancelDrawing() {\r\n this.clearTempEntities();\r\n this._tempPositions = [];\r\n this._isDrawing = false;\r\n this._clickCount = 0;\r\n this._startPos = null;\r\n this._currentMousePos = null;\r\n this._emitDrawCancel();\r\n }\r\n\r\n /**\r\n * 完成当前绘制(回车键触发)\r\n */\r\n finishDrawing() {\r\n if (this._drawType === DrawType.LINE && this._tempPositions.length >= 2) {\r\n const id = this.generateId('line');\r\n this._graphicModule.CreateLine(id)\r\n .setPositions(this._tempPositions)\r\n .setColor(Cesium.Color.BLUE)\r\n .setWidth(2);\r\n\r\n this._emitGraphicCreated('line', id);\r\n } else if (this._drawType === DrawType.POLYGON && this._tempPositions.length >= 3) {\r\n const positions = [...this._tempPositions, this._tempPositions[0]]; // 闭合\r\n const id = this.generateId('polygon');\r\n this._graphicModule.CreatePolygon(id)\r\n .setPositions(positions)\r\n .setColor(Cesium.Color.BLUE.withAlpha(0.5))\r\n .setOutlineColor(Cesium.Color.BLUE)\r\n\r\n this._emitGraphicCreated('polygon', id);\r\n }\r\n\r\n this.clearTempEntities();\r\n this._tempPositions = [];\r\n this._isDrawing = false;\r\n this._clickCount = 0;\r\n this._currentMousePos = null;\r\n }\r\n\r\n /**\r\n * 清除所有临时图元\r\n */\r\n clearTempEntities() {\r\n this._tempEntities.forEach(entity => {\r\n this.removeTempEntity(entity);\r\n });\r\n this._tempEntities = [];\r\n this._previewLine = null;\r\n this._previewPolygon = null;\r\n this._previewRect = null;\r\n this._previewCircle = null;\r\n this._previewPlot = null;\r\n }\r\n\r\n _emitGraphicCreated(type, id) {\r\n // 触发图元创建事件\r\n if (this._options.onGraphicCreated) {\r\n this._options.onGraphicCreated({ type, id });\r\n }\r\n }\r\n\r\n _emitDrawProgress(type, positions) {\r\n if (this._options.onDrawProgress) {\r\n this._options.onDrawProgress({ type, positions });\r\n }\r\n }\r\n\r\n _emitDrawCancel() {\r\n if (this._options.onDrawCancel) {\r\n this._options.onDrawCancel();\r\n }\r\n }\r\n}\r\n","import { BaseTool } from './BaseTool.js';\r\nimport { PlotGraphicType } from '../PlotGraphicType.js';\r\nimport { PlotGeometryUtil } from '../../utils/PlotGeometryUtil.js';\r\n\r\n/**\r\n * 编辑模式枚举\r\n */\r\nexport const EditMode = {\r\n VERTEX: 'vertex' // 顶点编辑模式(同时支持平移)\r\n};\r\n\r\n/**\r\n * 编辑工具\r\n * 支持选中图元的顶点编辑、平移、缩放\r\n */\r\nexport class EditTool extends BaseTool {\r\n // 静态常量\r\n static CLOSE_POINT_TOLERANCE = 0.001; // 闭合点检测容差(1毫米)\r\n static DEFAULT_PIXEL_SIZE = 12;\r\n static DEFAULT_OUTLINE_WIDTH = 2;\r\n static MOVE_THROTTLE_MS = 16; // 拖拽节流间隔(~60fps)\r\n\r\n constructor(editorModule, options = {}) {\r\n super(editorModule, options);\r\n this._editMode = options.editMode || EditMode.VERTEX;\r\n this._selectedEntity = null; // 当前选中的图元\r\n this._selectedEntityId = null;\r\n this._editHandles = []; // 编辑控制点\r\n this._positionOutline = null; // 位置辅助线\r\n this._polygonPreview = null; // 多边形预览\r\n this._tempEntities = []; // 临时图元(如包围盒)\r\n this._isDragging = false; // 是否正在拖拽\r\n this._dragHandle = null; // 当前拖拽的控制点\r\n this._originalPositions = null; // 原始位置(用于撤销)\r\n this._handleVertexIndices = null; // 控制点对应的实际顶点索引\r\n this._rectangleOriginalPositions = null; // 矩形原始顶点位置\r\n this._originalEnableInputs = true; // 原始相机控制状态\r\n this._lastMoveTime = 0; // 上次移动时间(用于节流)\r\n this._originalCircleCenter = null; // 圆形原始圆心\r\n this._originalCircleRadius = null; // 圆形原始半径\r\n this._originalEntityCenter = null; // 原始中心点(用于平移)\r\n this._radiusLine = null; // 半径线引用\r\n }\r\n\r\n /**\r\n * 设置编辑模式\r\n * @param {string} mode EditMode\r\n */\r\n setEditMode(mode) {\r\n this._editMode = mode;\r\n return this;\r\n }\r\n\r\n getEditMode() {\r\n return this._editMode;\r\n }\r\n\r\n /**\r\n * 手动选中图元进行编辑\r\n * @param {string} entityId 图元 ID\r\n */\r\n selectEntity(entityId) {\r\n const entity = this._graphicModule.getGraphic(entityId);\r\n if (entity) {\r\n this._selectEntity(entity);\r\n }\r\n }\r\n\r\n onActivate() {\r\n this.registerObserver('mouse:click', this._onClick.bind(this));\r\n this.registerObserver('mouse:move', this._onMove.bind(this));\r\n this.registerObserver('mouse:down', this._onMouseDown.bind(this));\r\n this.registerObserver('mouse:up', this._onMouseUp.bind(this));\r\n }\r\n\r\n onDeactivate() {\r\n this._deselectEntity();\r\n }\r\n\r\n _onClick(_lngLat, _entity, movement) {\r\n // movement.position 包含屏幕坐标 {x, y}\r\n const screenPos = movement.position || (movement && movement.endPosition);\r\n if (!screenPos) return;\r\n\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n console.log('EditTool _onClick:', { picked, screenPos });\r\n\r\n if (Cesium.defined(picked) && Cesium.defined(picked.id)) {\r\n const entityId = picked.id.id;\r\n console.log('EditTool picked entity:', entityId);\r\n\r\n // 忽略临时图元\r\n if (entityId && entityId.startsWith('__temp_')) {\r\n return;\r\n }\r\n\r\n // 忽略控制点(拖拽在 _onMouseDown 中处理)\r\n if (entityId && (entityId.startsWith('__edit_handle_') || entityId.includes('__edit_handle_'))) {\r\n return;\r\n }\r\n\r\n const entity = this._graphicModule.getGraphic(entityId);\r\n if (entity) {\r\n console.log('EditTool selecting entity');\r\n this._selectEntity(entity);\r\n } else {\r\n this._deselectEntity();\r\n }\r\n } else {\r\n // 点击空白处取消选择\r\n console.log('EditTool click on empty');\r\n this._deselectEntity();\r\n }\r\n }\r\n\r\n _onMouseDown(_lngLat, _entity, movement) {\r\n // movement 包含屏幕坐标 {position: {x, y}}\r\n const screenPos = movement && (movement.position || movement.endPosition);\r\n if (!screenPos) return;\r\n\r\n // 如果已经选中了图元,检查是否点击了控制点\r\n if (this._selectedEntity && !this._isDragging) {\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n if (Cesium.defined(picked) && Cesium.defined(picked.id)) {\r\n const entityId = picked.id.id;\r\n if (entityId && (entityId.startsWith('__edit_handle_') || entityId.includes('__edit_handle_'))) {\r\n // 直接在 _editHandles 中查找被点击的控制点\r\n const clickedHandle = this._editHandles.find(handle => handle.id === entityId);\r\n if (clickedHandle) {\r\n this._dragHandle = clickedHandle;\r\n this._isDragging = true;\r\n this._originalPositions = this._getEntityPositions(this._selectedEntity);\r\n // 禁用相机控制,防止拖拽时相机移动\r\n this._viewer.scene.screenSpaceCameraController.enableRotate = false;\r\n this._viewer.scene.screenSpaceCameraController.enableTranslate = false;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n _onMouseUp(_data) {\r\n if (this._isDragging) {\r\n this._isDragging = false;\r\n // 恢复相机控制\r\n this._viewer.scene.screenSpaceCameraController.enableRotate = true;\r\n this._viewer.scene.screenSpaceCameraController.enableTranslate = true;\r\n this._setCursorStyle('default');\r\n this._emitEditComplete();\r\n this._dragHandle = null;\r\n }\r\n }\r\n\r\n /**\r\n * 设置鼠标样式\r\n * @param {string} style CSS cursor 样式\r\n */\r\n _setCursorStyle(style) {\r\n if (this._viewer && this._viewer.canvas) {\r\n this._viewer.canvas.style.cursor = style;\r\n }\r\n }\r\n\r\n _onMove(data) {\r\n // _onMove receives movement object from BaseTool\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n\r\n // 非拖拽时做节流,避免 hover 检测过于频繁\r\n if (!this._isDragging) {\r\n const now = Date.now();\r\n if (now - this._lastMoveTime < EditTool.MOVE_THROTTLE_MS) return;\r\n this._lastMoveTime = now;\r\n\r\n // 检测是否悬停在控制点上\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n const isOverHandle = Cesium.defined(picked) && Cesium.defined(picked.id) &&\r\n picked.id.id && picked.id.id.startsWith('__edit_handle_');\r\n this._setCursorStyle(isOverHandle ? 'move' : 'default');\r\n }\r\n\r\n if (this._isDragging && this._dragHandle) {\r\n this._setCursorStyle('grabbing');\r\n\r\n // 拖拽时优先使用椭球面拾取,避免拾取到控制点句柄本身导致图元跟随滞后\r\n let lonLat = null;\r\n const cartesian = this._viewer.camera.pickEllipsoid(\r\n new Cesium.Cartesian2(screenPos.x, screenPos.y),\r\n this._viewer.scene.globe.ellipsoid\r\n );\r\n if (cartesian) {\r\n const c = Cesium.Cartographic.fromCartesian(cartesian);\r\n lonLat = [\r\n Cesium.Math.toDegrees(c.longitude),\r\n Cesium.Math.toDegrees(c.latitude),\r\n c.height || 0\r\n ];\r\n } else {\r\n lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });\r\n }\r\n\r\n if (lonLat) {\r\n this._updateEntityPosition(lonLat);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 平移标绘图元的所有控制点\r\n * @param {Cesium.Cartesian3} newAnchorCartesian 新锚点位置\r\n * @param {Cesium.Cartesian3} oldAnchorCartesian 旧锚点位置\r\n */\r\n _translatePlotControlPoints(newAnchorCartesian, oldAnchorCartesian) {\r\n const deltaX = newAnchorCartesian.x - oldAnchorCartesian.x;\r\n const deltaY = newAnchorCartesian.y - oldAnchorCartesian.y;\r\n const deltaZ = newAnchorCartesian.z - oldAnchorCartesian.z;\r\n\r\n const controlPoints = this._selectedEntity._controlPoints.map(cp => {\r\n const cpCart = Cesium.Cartesian3.fromDegrees(cp[0], cp[1], cp[2] || 0);\r\n const newCpCart = new Cesium.Cartesian3(\r\n cpCart.x + deltaX,\r\n cpCart.y + deltaY,\r\n cpCart.z + deltaZ\r\n );\r\n const newCpCarto = Cesium.Cartographic.fromCartesian(newCpCart);\r\n return [\r\n Cesium.Math.toDegrees(newCpCarto.longitude),\r\n Cesium.Math.toDegrees(newCpCarto.latitude),\r\n newCpCarto.height || 0\r\n ];\r\n });\r\n\r\n this._selectedEntity._controlPoints = controlPoints;\r\n\r\n // 更新包装器几何\r\n const wrapper = this._graphicModule.wrapperMap.get(this._selectedEntity.id);\r\n if (wrapper) {\r\n wrapper.setControlPoints(controlPoints);\r\n }\r\n\r\n // 更新所有控制点位置\r\n this._editHandles.forEach((handle) => {\r\n if (handle.id && handle.id.includes('center')) {\r\n // 扇形/椭圆:中心控制点固定在圆心/中心;其他类型使用重心\r\n const plotType = this._selectedEntity._plotType;\r\n const center = (plotType === PlotGraphicType.SECTOR || plotType === PlotGraphicType.ELLIPSE)\r\n ? controlPoints[0]\r\n : this._getPlotControlPointsCenter(controlPoints);\r\n handle.position = new Cesium.ConstantPositionProperty(\r\n this._clampPositionToGround(Cesium.Cartesian3.fromDegrees(center[0], center[1], center[2] || 0))\r\n );\r\n return;\r\n }\r\n // 按句柄 ID 解析真实控制点索引(扇形跳过了索引 0,不能直接使用 forEach 索引)\r\n const match = handle.id.match(/__edit_handle_(\\d+)$/);\r\n if (match) {\r\n const cpIndex = parseInt(match[1], 10);\r\n const cp = controlPoints[cpIndex];\r\n handle.position = new Cesium.ConstantPositionProperty(\r\n this._clampPositionToGround(Cesium.Cartesian3.fromDegrees(cp[0], cp[1], cp[2] || 0))\r\n );\r\n }\r\n });\r\n\r\n this._originalPositions = this._getEntityPositions(this._selectedEntity);\r\n }\r\n\r\n _selectEntity(entity) {\r\n // 先取消之前的选中\r\n this._deselectEntity();\r\n\r\n this._selectedEntity = entity;\r\n this._selectedEntityId = entity.id;\r\n\r\n // 创建编辑控制点\r\n this._createEditHandles();\r\n\r\n // 高亮选中图元\r\n this._highlightEntity(entity, true);\r\n\r\n this._emitSelect(entity.id);\r\n }\r\n\r\n _deselectEntity() {\r\n if (this._selectedEntity) {\r\n this._highlightEntity(this._selectedEntity, false);\r\n }\r\n\r\n this._clearEditHandles();\r\n this._selectedEntity = null;\r\n this._selectedEntityId = null;\r\n this._isDragging = false;\r\n this._dragHandle = null;\r\n // 确保取消选择时也恢复相机控制\r\n this._viewer.scene.screenSpaceCameraController.enableRotate = true;\r\n this._viewer.scene.screenSpaceCameraController.enableTranslate = true;\r\n }\r\n\r\n _createEditHandles() {\r\n this._clearEditHandles();\r\n\r\n // 标绘图元:显示控制点并重新生成几何\r\n if (this._selectedEntity && this._selectedEntity._isPlotGraphic) {\r\n this._createPlotControlHandles(this._selectedEntity);\r\n return;\r\n }\r\n\r\n const positions = this._getEditablePositions(this._selectedEntity);\r\n if (!positions || positions.length === 0) return;\r\n\r\n // 创建顶点编辑控制点\r\n this._createVertexHandles(positions);\r\n\r\n // 如果是多顶点图元(非圆形),创建中心控制点用于平移\r\n // 圆形在 _createVertexHandles 中已经创建了中心控制点\r\n if (positions.length > 1 && !this._isCircle(this._selectedEntity)) {\r\n this._createCenterHandleForVertexMode(positions);\r\n }\r\n }\r\n\r\n /**\r\n * 将位置转换为贴地位置(高度设为0)\r\n * @param {Cesium.Cartesian3} position \r\n * @returns {Cesium.Cartesian3}\r\n */\r\n _clampPositionToGround(position) {\r\n if (!position) return position;\r\n const cartographic = Cesium.Cartographic.fromCartesian(position);\r\n return Cesium.Cartesian3.fromDegrees(\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude),\r\n 0\r\n );\r\n }\r\n\r\n /**\r\n * 创建标绘图元的控制点\r\n * @param {Cesium.Entity} entity 标绘图元实体\r\n */\r\n _createPlotControlHandles(entity) {\r\n const controlPoints = entity._controlPoints || [];\r\n if (controlPoints.length === 0) return;\r\n\r\n // 扇形:圆心作为平移控制点,不创建黄色顶点句柄\r\n const plotType = entity._plotType;\r\n const isSector = plotType === PlotGraphicType.SECTOR;\r\n const isEllipse = plotType === PlotGraphicType.ELLIPSE;\r\n\r\n controlPoints.forEach((cp, index) => {\r\n if ((isSector || isEllipse) && index === 0) return; // 扇形/椭圆圆心/中心由中心控制点处理\r\n\r\n const clampedPos = this._clampPositionToGround(\r\n Cesium.Cartesian3.fromDegrees(cp[0], cp[1], cp[2] || 0)\r\n );\r\n const handle = this.createTempEntity(`__edit_handle_${index}`, {\r\n position: clampedPos,\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 12,\r\n outlineColor: Cesium.Color.RED,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND\r\n }\r\n });\r\n this._editHandles.push(handle);\r\n });\r\n\r\n // 显示轮廓辅助线\r\n if (controlPoints.length > 1) {\r\n this._createPlotPositionOutline();\r\n }\r\n\r\n // 椭圆:显示两条半轴辅助线\r\n if (isEllipse) {\r\n this._createEllipseAxisLines();\r\n }\r\n\r\n // 创建中心平移控制点\r\n if (controlPoints.length > 1) {\r\n if (isSector || isEllipse) {\r\n // 扇形/椭圆:中心点即为中心平移控制点\r\n this._createPlotCenterHandle(controlPoints, controlPoints[0]);\r\n } else {\r\n this._createPlotCenterHandle(controlPoints);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 创建标绘图元的中心平移控制点\r\n * @param {Array} controlPoints 控制点\r\n * @param {Array|null} centerPoint 指定中心点位置;为空时使用控制点重心\r\n */\r\n _createPlotCenterHandle(controlPoints, centerPoint = null) {\r\n const center = centerPoint || this._getPlotControlPointsCenter(controlPoints);\r\n if (!center) return;\r\n\r\n this._originalEntityCenter = this._clampPositionToGround(\r\n Cesium.Cartesian3.fromDegrees(center[0], center[1], center[2] || 0)\r\n );\r\n\r\n const handle = this.createTempEntity('__edit_handle_center_plot', {\r\n position: this._originalEntityCenter,\r\n point: {\r\n color: Cesium.Color.CYAN,\r\n pixelSize: 14,\r\n outlineColor: Cesium.Color.BLUE,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND\r\n }\r\n });\r\n this._editHandles.push(handle);\r\n }\r\n\r\n /**\r\n * 计算标绘控制点的中心点\r\n * @param {Array} controlPoints 控制点 [lon, lat, height][]\r\n */\r\n _getPlotControlPointsCenter(controlPoints) {\r\n if (!controlPoints || controlPoints.length === 0) return null;\r\n\r\n let x = 0, y = 0, z = 0;\r\n controlPoints.forEach(cp => {\r\n x += cp[0];\r\n y += cp[1];\r\n z += cp[2] || 0;\r\n });\r\n return [x / controlPoints.length, y / controlPoints.length, z / controlPoints.length];\r\n }\r\n\r\n /**\r\n * 创建标绘图元轮廓辅助线\r\n */\r\n _createPlotPositionOutline() {\r\n const self = this;\r\n const entity = this._selectedEntity;\r\n const isLine = Cesium.defined(entity.polyline);\r\n\r\n // 以下标绘图元的控制点连线会干扰真实几何,不绘制轮廓辅助线\r\n const skipOutlineTypes = new Set([\r\n PlotGraphicType.FINE_ARROW,\r\n PlotGraphicType.ASSAULT_DIRECTION,\r\n PlotGraphicType.ATTACK_ARROW,\r\n PlotGraphicType.SWALLOWTAIL_ATTACK_ARROW,\r\n PlotGraphicType.SQUAD_COMBAT,\r\n PlotGraphicType.SWALLOWTAIL_SQUAD_COMBAT,\r\n PlotGraphicType.DOUBLE_ARROW,\r\n PlotGraphicType.CURVED_ARROW,\r\n PlotGraphicType.CURVE\r\n ]);\r\n\r\n this._positionOutline = this.createTempEntity(this.generateId('temp_plot_outline'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(function () {\r\n const handles = self._editHandles;\r\n if (!handles || handles.length === 0) return [];\r\n\r\n const plotType = entity._plotType;\r\n if (skipOutlineTypes.has(plotType)) {\r\n return [];\r\n }\r\n\r\n // 扇形/椭圆:直接沿实际几何边界绘制辅助线\r\n if (plotType === PlotGraphicType.SECTOR || plotType === PlotGraphicType.ELLIPSE) {\r\n const hierarchy = entity.polygon?.hierarchy;\r\n let positions = null;\r\n if (hierarchy) {\r\n if (typeof hierarchy.getValue === 'function') {\r\n const value = hierarchy.getValue(Cesium.JulianDate.now());\r\n positions = value ? value.positions : null;\r\n } else if (hierarchy.positions) {\r\n positions = hierarchy.positions;\r\n }\r\n }\r\n if (positions && positions.length > 2) {\r\n // 复制并显式闭合,避免 polygon 顶点重复导致 polyline 退化\r\n const closed = positions.slice();\r\n closed.push(positions[0]);\r\n return closed;\r\n }\r\n return positions || [];\r\n }\r\n\r\n const degrees = [];\r\n handles.forEach(handle => {\r\n // 跳过中心平移控制点\r\n if (handle.id && handle.id.includes('center')) return;\r\n\r\n const pos = handle.position.getValue(Cesium.JulianDate.now());\r\n if (pos) {\r\n const c = Cesium.Cartographic.fromCartesian(pos);\r\n degrees.push(Cesium.Math.toDegrees(c.longitude));\r\n degrees.push(Cesium.Math.toDegrees(c.latitude));\r\n degrees.push(c.height || 0);\r\n }\r\n });\r\n\r\n if (degrees.length === 0) return [];\r\n\r\n const cartesians = Cesium.Cartesian3.fromDegreesArrayHeights(degrees);\r\n if (isLine) {\r\n return cartesians;\r\n }\r\n return [...cartesians, cartesians[0]];\r\n }, false),\r\n material: Cesium.Color.YELLOW,\r\n width: 2,\r\n clampToGround: true\r\n }\r\n });\r\n this._positionOutline._isPreview = true;\r\n this._tempEntities.push(this._positionOutline);\r\n }\r\n\r\n /**\r\n * 创建椭圆半轴辅助线(中心到长/短半轴端点)\r\n */\r\n _createEllipseAxisLines() {\r\n const self = this;\r\n const axisLine = this.createTempEntity(this.generateId('temp_ellipse_axis'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(function () {\r\n const entity = self._selectedEntity;\r\n const cps = entity?._controlPoints;\r\n if (!cps || cps.length < 3) return [];\r\n\r\n const center = Cesium.Cartesian3.fromDegrees(cps[0][0], cps[0][1], cps[0][2] || 0);\r\n const major = Cesium.Cartesian3.fromDegrees(cps[1][0], cps[1][1], cps[1][2] || 0);\r\n const minor = Cesium.Cartesian3.fromDegrees(cps[2][0], cps[2][1], cps[2][2] || 0);\r\n return [center, major, center, minor];\r\n }, false),\r\n material: Cesium.Color.YELLOW,\r\n width: 2,\r\n clampToGround: true\r\n }\r\n });\r\n axisLine._isPreview = true;\r\n this._tempEntities.push(axisLine);\r\n }\r\n\r\n /**\r\n * 创建顶点编辑控制点\r\n * @param {Array} positions 可编辑位置数组\r\n */\r\n _createVertexHandles(positions) {\r\n // 判断是否是矩形(4个顶点形成矩形)\r\n const isRectangle = Cesium.defined(this._selectedEntity.polygon) && positions.length === 4 &&\r\n this._isRectangle(positions);\r\n\r\n if (isRectangle) {\r\n this._rectangleOriginalPositions = positions.slice();\r\n\r\n const vertexIndices = [0, 1, 2, 3];\r\n\r\n vertexIndices.forEach((vertexIdx, handleIdx) => {\r\n // 修复:位置贴地\r\n const clampedPos = this._clampPositionToGround(positions[vertexIdx]);\r\n const handle = this.createTempEntity(`__edit_handle_${handleIdx}`, {\r\n position: clampedPos,\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 12,\r\n outlineColor: Cesium.Color.RED,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,\r\n }\r\n });\r\n this._editHandles.push(handle);\r\n });\r\n\r\n this._handleVertexIndices = [0, 1, 2, 3];\r\n } else if (this._isCircle(this._selectedEntity)) {\r\n const circleInfo = this._getCircleInfo(this._selectedEntity);\r\n if (!circleInfo) return;\r\n\r\n const { center, radius } = circleInfo;\r\n // 修复:圆心位置贴地\r\n const centerCartesian = Cesium.Cartesian3.fromDegrees(center[0], center[1], 0);\r\n const radiusPoint = this._getPointOnCircle(center, radius, 0);\r\n const radiusCartesian = Cesium.Cartesian3.fromDegrees(radiusPoint[0], radiusPoint[1], 0);\r\n\r\n // 圆心控制点(可平移)- 使用与其他类型不同的ID格式\r\n const centerHandle = this.createTempEntity('__edit_handle_center', {\r\n position: centerCartesian,\r\n point: {\r\n color: Cesium.Color.CYAN,\r\n pixelSize: 14,\r\n outlineColor: Cesium.Color.BLUE,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND\r\n }\r\n });\r\n this._editHandles.push(centerHandle);\r\n\r\n // 半径控制点\r\n const radiusHandle = this.createTempEntity('__edit_handle_radius', {\r\n position: radiusCartesian,\r\n point: {\r\n color: Cesium.Color.RED,\r\n pixelSize: 12,\r\n outlineColor: Cesium.Color.YELLOW,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND\r\n }\r\n });\r\n this._editHandles.push(radiusHandle);\r\n\r\n this._handleVertexIndices = ['center', 'radius'];\r\n this._originalCircleCenter = center;\r\n this._originalCircleRadius = radius;\r\n this._rectangleOriginalPositions = null;\r\n\r\n this._createCircleOutline();\r\n } else {\r\n this._rectangleOriginalPositions = null;\r\n this._handleVertexIndices = null;\r\n\r\n positions.forEach((pos, index) => {\r\n const clampedPos = this._clampPositionToGround(pos);\r\n const handle = this.createTempEntity(`__edit_handle_${index}`, {\r\n position: clampedPos,\r\n point: {\r\n color: Cesium.Color.YELLOW,\r\n pixelSize: 12,\r\n outlineColor: Cesium.Color.RED,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,\r\n }\r\n });\r\n this._editHandles.push(handle);\r\n });\r\n }\r\n\r\n if (positions.length > 1) {\r\n this._createPositionOutline();\r\n }\r\n }\r\n\r\n /**\r\n * 在 VERTEX 模式下创建中心控制点用于平移\r\n * @param {Array} positions 顶点位置数组\r\n */\r\n _createCenterHandleForVertexMode(positions) {\r\n const center = this._getEntityCenter(this._selectedEntity);\r\n if (!center) return;\r\n\r\n // 修复:中心点贴地\r\n const clampedCenter = this._clampPositionToGround(center);\r\n this._originalEntityCenter = clampedCenter;\r\n\r\n // 圆形特殊处理:保存圆心和半径用于 undo\r\n if (this._isCircle(this._selectedEntity)) {\r\n const circleInfo = this._getCircleInfo(this._selectedEntity);\r\n if (circleInfo) {\r\n this._originalCircleCenter = circleInfo.center.slice();\r\n this._originalCircleRadius = circleInfo.radius;\r\n }\r\n }\r\n\r\n // 创建中心控制点(使用不同的 ID 区分)\r\n const handle = this.createTempEntity('__edit_handle_center_vertex', {\r\n position: clampedCenter,\r\n point: {\r\n color: Cesium.Color.CYAN,\r\n pixelSize: 14,\r\n outlineColor: Cesium.Color.BLUE,\r\n outlineWidth: 2,\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n heightReference: Cesium.HeightReference.CLAMP_TO_GROUND\r\n }\r\n });\r\n this._editHandles.push(handle);\r\n }\r\n\r\n /**\r\n * 更新中心控制点位置(在顶点编辑后重新计算)\r\n */\r\n _updateCenterHandlePosition() {\r\n // 圆形不需要更新中心点,因为圆心就是中心\r\n if (this._isCircle(this._selectedEntity)) return;\r\n\r\n const centerHandle = this._editHandles.find(h => h.id && h.id.includes('center'));\r\n if (!centerHandle) return;\r\n\r\n // 重新计算当前几何中心\r\n const newCenter = this._getEntityCenter(this._selectedEntity);\r\n if (!newCenter) return;\r\n\r\n // 修复:中心点贴地\r\n const clampedCenter = this._clampPositionToGround(newCenter);\r\n\r\n // 更新中心控制点位置\r\n centerHandle.position = new Cesium.ConstantPositionProperty(clampedCenter);\r\n // 更新原始中心点缓存(用于下次平移计算)\r\n this._originalEntityCenter = clampedCenter;\r\n }\r\n\r\n _createPositionOutline() {\r\n // 从控制点获取位置,性能更好(避免每次从实体重新获取和转换)\r\n const self = this;\r\n const isPolyline = Cesium.defined(this._selectedEntity.polyline);\r\n\r\n this._positionOutline = this.createTempEntity(this.generateId('temp_outline'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(function () {\r\n // 从控制点获取位置(已被更新),排除中心控制点\r\n const handles = self._editHandles;\r\n if (!handles || handles.length === 0) return [];\r\n\r\n // 收集所有控制点的当前位置,排除中心控制点\r\n const degrees = [];\r\n handles.forEach(handle => {\r\n // 跳过所有中心控制点(用于平移)- 修复:统一使用 includes('center')\r\n if (handle.id && handle.id.includes('center')) return;\r\n\r\n const pos = handle.position.getValue(Cesium.JulianDate.now());\r\n if (pos) {\r\n const c = Cesium.Cartographic.fromCartesian(pos);\r\n degrees.push(Cesium.Math.toDegrees(c.longitude));\r\n degrees.push(Cesium.Math.toDegrees(c.latitude));\r\n degrees.push(c.height || 0);\r\n }\r\n });\r\n\r\n if (degrees.length === 0) return [];\r\n\r\n // 线不闭合,面需要闭合\r\n if (isPolyline) {\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(degrees);\r\n }\r\n // 闭合多边形(首尾点相同)\r\n return Cesium.Cartesian3.fromDegreesArrayHeights([...degrees, degrees[0], degrees[1], degrees[2] || 0]);\r\n }, false),\r\n material: Cesium.Color.YELLOW,\r\n width: 2,\r\n clampToGround: true\r\n }\r\n });\r\n this._positionOutline._isPreview = true;\r\n this._tempEntities.push(this._positionOutline);\r\n }\r\n\r\n _clearEditHandles() {\r\n this._editHandles.forEach(handle => {\r\n this.removeTempEntity(handle);\r\n });\r\n this._editHandles = [];\r\n this._positionOutline = null;\r\n this._polygonPreview = null;\r\n this._handleVertexIndices = null;\r\n this._rectangleOriginalPositions = null;\r\n this._originalCircleCenter = null;\r\n this._originalCircleRadius = null;\r\n this._originalEntityCenter = null;\r\n this._radiusLine = null;\r\n\r\n this._tempEntities.forEach(entity => {\r\n this.removeTempEntity(entity);\r\n });\r\n this._tempEntities = [];\r\n }\r\n\r\n _getEditablePositions(entity) {\r\n if (!entity) return [];\r\n\r\n if (Cesium.defined(entity.polyline) && Cesium.defined(entity.polyline.positions)) {\r\n return entity.polyline.positions.getValue(Cesium.JulianDate.now());\r\n }\r\n\r\n if (Cesium.defined(entity.polygon) && Cesium.defined(entity.polygon.hierarchy)) {\r\n const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now());\r\n if (hierarchy && hierarchy.positions) {\r\n let positions = hierarchy.positions;\r\n\r\n // ✅ 检查并移除闭合点(首尾相同)\r\n if (positions.length >= 2) {\r\n const first = positions[0];\r\n const last = positions[positions.length - 1];\r\n // 使用距离判断而不是精确相等(避免浮点误差)\r\n const distance = Cesium.Cartesian3.distance(first, last);\r\n if (distance < EditTool.CLOSE_POINT_TOLERANCE) {\r\n positions = positions.slice(0, -1); // 移除最后一个点\r\n }\r\n }\r\n\r\n return positions;\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.position)) {\r\n return [entity.position.getValue(Cesium.JulianDate.now())];\r\n }\r\n\r\n return [];\r\n }\r\n\r\n _getEntityPositions(entity) {\r\n return this._getEditablePositions(entity);\r\n }\r\n\r\n /**\r\n * 获取图元中心点\r\n */\r\n _getEntityCenter(entity) {\r\n const positions = this._getEditablePositions(entity);\r\n if (!positions || positions.length === 0) return null;\r\n\r\n let x = 0, y = 0, z = 0;\r\n positions.forEach(p => {\r\n x += p.x;\r\n y += p.y;\r\n z += p.z;\r\n });\r\n const count = positions.length;\r\n return new Cesium.Cartesian3(x / count, y / count, z / count);\r\n }\r\n\r\n /**\r\n * 平移整个图元\r\n * @param {Cesium.Cartesian3} newCenter 新中心点\r\n */\r\n _translateEntity(newCenter) {\r\n if (!this._selectedEntity || !this._originalEntityCenter) {\r\n console.log('Translate skipped: no entity or no original center', {\r\n hasEntity: !!this._selectedEntity,\r\n originalCenter: this._originalEntityCenter\r\n });\r\n return;\r\n }\r\n\r\n // 修复:新中心点贴地\r\n const clampedNewCenter = this._clampPositionToGround(newCenter);\r\n\r\n // 计算偏移量\r\n const deltaX = clampedNewCenter.x - this._originalEntityCenter.x;\r\n const deltaY = clampedNewCenter.y - this._originalEntityCenter.y;\r\n const deltaZ = clampedNewCenter.z - this._originalEntityCenter.z;\r\n\r\n // 计算真正的新中心位置(不是鼠标位置)\r\n const actualNewCenter = new Cesium.Cartesian3(\r\n this._originalEntityCenter.x + deltaX,\r\n this._originalEntityCenter.y + deltaY,\r\n this._originalEntityCenter.z + deltaZ\r\n );\r\n\r\n // 更新原始中心(用于下次平移计算)\r\n this._originalEntityCenter = actualNewCenter;\r\n\r\n // 更新中心控制点位置\r\n this._dragHandle.position = new Cesium.ConstantPositionProperty(actualNewCenter);\r\n\r\n if (Cesium.defined(this._selectedEntity.polyline)) {\r\n // 线图元:平移所有位置\r\n const newPositions = this._originalPositions.map(p => {\r\n const newPos = new Cesium.Cartesian3(p.x + deltaX, p.y + deltaY, p.z + deltaZ);\r\n // 修复:贴地\r\n return this._clampPositionToGround(newPos);\r\n });\r\n this._selectedEntity.polyline.positions = newPositions;\r\n \r\n // 修复:更新所有顶点控制点位置,同时更新中心控制点位置\r\n this._editHandles.forEach((handle) => {\r\n // 修复:统一使用 includes('center') 来判断中心控制点\r\n if (handle.id && handle.id.includes('center')) {\r\n // 中心控制点已经更新过了\r\n return;\r\n }\r\n // 找到对应的顶点索引\r\n const match = handle.id.match(/__edit_handle_(\\d+)$/);\r\n if (match) {\r\n const index = parseInt(match[1], 10);\r\n if (newPositions[index]) {\r\n handle.position = new Cesium.ConstantPositionProperty(newPositions[index]);\r\n }\r\n }\r\n });\r\n \r\n // 更新原始位置缓存\r\n this._originalPositions = newPositions;\r\n } else if (Cesium.defined(this._selectedEntity.polygon)) {\r\n if (this._isCircle(this._selectedEntity)) {\r\n // 圆形平移\r\n const oldCenter = this._selectedEntity._circleCenter; // [lon, lat]\r\n\r\n // 将旧的圆心经纬度转为 Cartesian3\r\n const oldCenterCartesian = Cesium.Cartesian3.fromDegrees(oldCenter[0], oldCenter[1], 0);\r\n\r\n // 应用偏移量计算新的 Cartesian3 位置\r\n const newCenterCartesian = new Cesium.Cartesian3(\r\n oldCenterCartesian.x + deltaX,\r\n oldCenterCartesian.y + deltaY,\r\n oldCenterCartesian.z + deltaZ\r\n );\r\n\r\n // 将新的 Cartesian3 转回经纬度\r\n const newCenterCartographic = Cesium.Cartographic.fromCartesian(newCenterCartesian);\r\n const newCenterLon = Cesium.Math.toDegrees(newCenterCartographic.longitude);\r\n const newCenterLat = Cesium.Math.toDegrees(newCenterCartographic.latitude);\r\n\r\n this._selectedEntity._circleCenter = [newCenterLon, newCenterLat];\r\n\r\n // 更新多边形顶点\r\n const positions = this._generateCirclePositions(\r\n this._selectedEntity._circleCenter,\r\n this._selectedEntity._circleRadius,\r\n 256\r\n );\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(flat)\r\n );\r\n\r\n // 更新圆心控制点位置\r\n const centerHandle = this._editHandles.find(h => h.id && h.id.includes('__edit_handle_center'));\r\n if (centerHandle) {\r\n centerHandle.position = new Cesium.ConstantPositionProperty(newCenterCartesian);\r\n }\r\n } else {\r\n // 普通多边形:平移所有顶点\r\n const newPositions = this._originalPositions.map(p => {\r\n const newPos = new Cesium.Cartesian3(p.x + deltaX, p.y + deltaY, p.z + deltaZ);\r\n // 修复:贴地\r\n return this._clampPositionToGround(newPos);\r\n });\r\n // 添加闭合点\r\n newPositions.push(newPositions[0].clone());\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(newPositions);\r\n \r\n // 修复:更新顶点控制点位置,使用更可靠的ID匹配\r\n this._editHandles.forEach((handle) => {\r\n // 修复:统一使用 includes('center') 来判断中心控制点\r\n if (handle.id && handle.id.includes('center')) {\r\n return;\r\n }\r\n // 提取数字索引\r\n const match = handle.id.match(/__edit_handle_(\\d+)$/);\r\n if (match) {\r\n const index = parseInt(match[1], 10);\r\n if (newPositions[index]) {\r\n handle.position = new Cesium.ConstantPositionProperty(newPositions[index]);\r\n }\r\n }\r\n });\r\n \r\n // 更新原始位置缓存\r\n this._originalPositions = newPositions.slice(0, -1);\r\n }\r\n } else if (Cesium.defined(this._selectedEntity.position)) {\r\n // 点/文本图元:平移位置\r\n this._selectedEntity.position = new Cesium.ConstantPositionProperty(actualNewCenter);\r\n this._originalPositions = [actualNewCenter];\r\n }\r\n }\r\n\r\n _isRectangle(positions) {\r\n if (positions.length !== 4) return false;\r\n\r\n const relativeTolerance = 0.001; // 0.1% 相对误差\r\n\r\n // 提取XY坐标(忽略Z)\r\n const xy = positions.map(p => ({ x: p.x, y: p.y }));\r\n\r\n const [v0, v1, v2, v3] = xy;\r\n\r\n // 计算XY平面上的距离\r\n const dist = (p1, p2) => Math.sqrt(\r\n Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)\r\n );\r\n\r\n const d01 = dist(v0, v1);\r\n const d12 = dist(v1, v2);\r\n const d23 = dist(v2, v3);\r\n const d30 = dist(v3, v0);\r\n const d02 = dist(v0, v2);\r\n const d13 = dist(v1, v3);\r\n\r\n const oppositeSidesEqual =\r\n Math.abs(d01 - d23) / Math.max(d01, d23) < relativeTolerance &&\r\n Math.abs(d12 - d30) / Math.max(d12, d30) < relativeTolerance;\r\n\r\n const diagonalsEqual = Math.abs(d02 - d13) / Math.max(d02, d13) < relativeTolerance;\r\n\r\n return oppositeSidesEqual && diagonalsEqual;\r\n }\r\n\r\n /**\r\n * 检测 entity 是否为圆\r\n */\r\n _isCircle(entity) {\r\n return entity && entity._isCircle === true;\r\n }\r\n\r\n /**\r\n * 获取圆的中心点和半径\r\n */\r\n _getCircleInfo(entity) {\r\n if (!this._isCircle(entity)) return null;\r\n return {\r\n center: entity._circleCenter, // [lon, lat]\r\n radius: entity._circleRadius // 米\r\n };\r\n }\r\n\r\n /**\r\n * 生成圆的多边形顶点(用于更新圆的形状)\r\n * @param {Array} center [lon, lat]\r\n * @param {number} radius 半径(米)\r\n * @param {number} segments 顶点数\r\n * @returns {Array} 经纬度数组\r\n */\r\n _generateCirclePositions(center, radius, segments = 256) {\r\n const [lon, lat] = center;\r\n const radPerDeg = Math.PI / 180;\r\n const positions = [];\r\n\r\n // 当前纬度的经度米数(随纬度变化)\r\n const metersPerLonDeg = 111320 * Math.cos(lat * radPerDeg);\r\n const metersPerLatDeg = 110540; // 纬度方向相对固定\r\n\r\n for (let i = 0; i <= segments; i++) {\r\n const angle = (i / segments) * Math.PI * 2;\r\n const dLon = (radius * Math.cos(angle) / metersPerLonDeg);\r\n const dLat = (radius * Math.sin(angle) / metersPerLatDeg);\r\n positions.push([lon + dLon, lat + dLat]);\r\n }\r\n\r\n return positions;\r\n }\r\n\r\n /**\r\n * 计算圆周上的点\r\n * @param {Array} center [lon, lat]\r\n * @param {number} radius 半径(米)\r\n * @param {number} angleRadians 角度(弧度)\r\n * @returns {Array} [lon, lat]\r\n */\r\n _getPointOnCircle(center, radius, angleRadians) {\r\n const [lon, lat] = center;\r\n const radPerDeg = Math.PI / 180;\r\n const metersPerLonDeg = 111320 * Math.cos(lat * radPerDeg);\r\n const metersPerLatDeg = 110540;\r\n\r\n const dLon = (radius * Math.cos(angleRadians) / metersPerLonDeg);\r\n const dLat = (radius * Math.sin(angleRadians) / metersPerLatDeg);\r\n return [lon + dLon, lat + dLat];\r\n }\r\n\r\n /**\r\n * 将 oldAxis 绕原点旋转到与 newAxis 垂直,并保持原长度和相对方向(顺/逆时针)\r\n * @param {Array} newAxis [dx, dy]\r\n * @param {Array} oldAxis [dx, dy]\r\n * @returns {Array} [rx, ry]\r\n */\r\n _rotatePerpendicular(newAxis, oldAxis) {\r\n const newLen = Math.hypot(newAxis[0], newAxis[1]);\r\n const oldLen = Math.hypot(oldAxis[0], oldAxis[1]);\r\n if (newLen === 0 || oldLen === 0) return [0, 0];\r\n\r\n const ux = newAxis[0] / newLen;\r\n const uy = newAxis[1] / newLen;\r\n\r\n // 叉积判断 oldAxis 在 newAxis 的左侧还是右侧\r\n const cross = newAxis[0] * oldAxis[1] - newAxis[1] * oldAxis[0];\r\n const sign = cross >= 0 ? 1 : -1;\r\n\r\n // 将 newAxis 旋转 ±90° 得到新的垂直方向,并保持 oldAxis 长度\r\n return [-sign * uy * oldLen, sign * ux * oldLen];\r\n }\r\n\r\n /**\r\n * 创建圆形辅助线\r\n */\r\n _createCircleOutline() {\r\n const self = this;\r\n\r\n // 圆周辅助线(黄色)\r\n this._positionOutline = this.createTempEntity(this.generateId('temp_circle_outline'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(function () {\r\n const circleInfo = self._getCircleInfo(self._selectedEntity);\r\n if (!circleInfo) return [];\r\n\r\n const { center, radius } = circleInfo;\r\n const positions = self._generateCirclePositions(center, radius, 256);\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(flat);\r\n }, false),\r\n material: Cesium.Color.YELLOW,\r\n width: 2,\r\n clampToGround: true\r\n }\r\n });\r\n this._positionOutline._isPreview = true;\r\n this._tempEntities.push(this._positionOutline);\r\n\r\n // 半径连线(红色,从圆心到编辑点)\r\n // 修复:正确获取半径控制点的位置\r\n this._radiusLine = this.createTempEntity(this.generateId('temp_radius_line'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(function () {\r\n const circleInfo = self._getCircleInfo(self._selectedEntity);\r\n if (!circleInfo) return [];\r\n\r\n const { center } = circleInfo;\r\n // 修复:通过ID查找半径控制点,而不是固定索引\r\n const radiusHandle = self._editHandles.find(h => h.id && h.id.includes('__edit_handle_radius'));\r\n if (!radiusHandle) return [];\r\n\r\n const radiusPos = radiusHandle.position.getValue(Cesium.JulianDate.now());\r\n if (!radiusPos) return [];\r\n\r\n const centerCart = Cesium.Cartesian3.fromDegrees(center[0], center[1], 0);\r\n return [centerCart, radiusPos];\r\n }, false),\r\n material: Cesium.Color.RED,\r\n width: 3,\r\n clampToGround: true\r\n }\r\n });\r\n this._radiusLine._isPreview = true;\r\n this._tempEntities.push(this._radiusLine);\r\n }\r\n\r\n /**\r\n * 计算两点之间的距离(米)\r\n * @param {Array} coord1 [lon, lat]\r\n * @param {Array} coord2 [lon, lat]\r\n * @returns {number} 距离(米)\r\n */\r\n _calcDistance(coord1, coord2) {\r\n const earthRadius = 6371000; // 米\r\n const [lon1, lat1] = coord1.map(d => d * Math.PI / 180);\r\n const [lon2, lat2] = coord2.map(d => d * Math.PI / 180);\r\n\r\n const dLat = lat2 - lat1;\r\n const dLon = lon2 - lon1;\r\n\r\n const a = Math.sin(dLat / 2) ** 2 +\r\n Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n\r\n return earthRadius * c;\r\n }\r\n\r\n /**\r\n * 计算矩形拖拽后的新顶点位置\r\n * @param {Cesium.Cartesian3} newPos - 拖拽的新位置\r\n * @param {Array} originalPositions - 原始4个顶点位置\r\n * @param {number} draggedIndex - 被拖拽的顶点索引 (0,1,2,3)\r\n * @returns {Array} 新的4个顶点位置数组\r\n */\r\n _computeRectangleNewPositions(newPos, originalPositions, draggedIndex) {\r\n // 对角顶点索引:0->2, 1->3, 2->0, 3->1\r\n const oppositeIndex = (draggedIndex + 2) % 4;\r\n const newP = Cesium.Cartographic.fromCartesian(newPos);\r\n const currentPos = originalPositions.map(p => Cesium.Cartographic.fromCartesian(p));\r\n const oppositePos = currentPos[oppositeIndex];\r\n\r\n const newPositions = new Array(4);\r\n newPositions[draggedIndex] = newPos; // 拖拽点为新位置\r\n newPositions[oppositeIndex] = originalPositions[oppositeIndex]; // 对角点固定\r\n\r\n // 计算相邻两个顶点\r\n // draggedIndex 的相邻顶点是 (draggedIndex + 1) % 4 和 (draggedIndex + 3) % 4\r\n const neighbor1 = (draggedIndex + 1) % 4;\r\n const neighbor2 = (draggedIndex + 3) % 4;\r\n\r\n // neighbor1 使用 newPos 的 longitude 和 opposite 的 latitude\r\n newPositions[neighbor1] = Cesium.Cartesian3.fromRadians(\r\n newP.longitude,\r\n oppositePos.latitude,\r\n oppositePos.height\r\n );\r\n\r\n // neighbor2 使用 opposite 的 longitude 和 newPos 的 latitude\r\n newPositions[neighbor2] = Cesium.Cartesian3.fromRadians(\r\n oppositePos.longitude,\r\n newP.latitude,\r\n oppositePos.height\r\n );\r\n\r\n return newPositions;\r\n }\r\n\r\n _updateEntityPosition(newLonLat) {\r\n if (!this._selectedEntity) return;\r\n\r\n const handleIndex = this._editHandles.indexOf(this._dragHandle);\r\n if (handleIndex === -1) return;\r\n\r\n // 修复:新位置贴地(高度设为0)\r\n const newCartesian = Cesium.Cartesian3.fromDegrees(newLonLat[0], newLonLat[1], 0);\r\n\r\n // 标绘图元:拖拽控制点重新生成几何\r\n if (this._selectedEntity._isPlotGraphic) {\r\n const handleId = this._dragHandle.id;\r\n\r\n // 拖拽中心控制点:平移整个标绘图元\r\n if (handleId && handleId.includes('center') && this._originalEntityCenter) {\r\n const clampedNewCenter = this._clampPositionToGround(newCartesian);\r\n this._translatePlotControlPoints(clampedNewCenter, this._originalEntityCenter);\r\n this._originalEntityCenter = clampedNewCenter;\r\n return;\r\n }\r\n\r\n const handleMatch = handleId.match(/__edit_handle_(\\d+)$/);\r\n if (!handleMatch) return;\r\n\r\n const index = parseInt(handleMatch[1], 10);\r\n const plotType = this._selectedEntity._plotType;\r\n\r\n // 扇形:拖拽圆心(索引0)时整体平移,保持两半径等长\r\n if (plotType === PlotGraphicType.SECTOR && index === 0) {\r\n const oldCenter = this._selectedEntity._controlPoints[0];\r\n const oldCenterCart = Cesium.Cartesian3.fromDegrees(oldCenter[0], oldCenter[1], oldCenter[2] || 0);\r\n const clampedNewCenter = this._clampPositionToGround(newCartesian);\r\n this._translatePlotControlPoints(clampedNewCenter, oldCenterCart);\r\n // 中心控制点固定在圆心\r\n this._originalEntityCenter = this._clampPositionToGround(\r\n Cesium.Cartesian3.fromDegrees(\r\n this._selectedEntity._controlPoints[0][0],\r\n this._selectedEntity._controlPoints[0][1],\r\n this._selectedEntity._controlPoints[0][2] || 0\r\n )\r\n );\r\n return;\r\n }\r\n\r\n const controlPoints = this._selectedEntity._controlPoints.map((cp, i) =>\r\n i === index ? [newLonLat[0], newLonLat[1], cp[2] || 0] : cp\r\n );\r\n\r\n // 扇形:两个半径控制点同步缩放,保持半径一致\r\n if (plotType === PlotGraphicType.SECTOR && index > 0) {\r\n const center = controlPoints[0];\r\n // 使用球面距离(米)作为新半径,与 createSector 保持一致\r\n const newRadius = PlotGeometryUtil._calcSphericalDistance(controlPoints[index], center);\r\n const otherIndex = index === 1 ? 2 : 1;\r\n const otherCp = controlPoints[otherIndex];\r\n // 保持另一个控制点的真实地理方位角,按新半径在球面圆上重新定位\r\n const otherBearing = PlotGeometryUtil._getBearing(center, otherCp);\r\n const newOtherPoint = PlotGeometryUtil._getPointAtBearingAndDistance(center, newRadius, otherBearing);\r\n controlPoints[otherIndex] = [newOtherPoint[0], newOtherPoint[1], otherCp[2] || 0];\r\n }\r\n\r\n // 椭圆:长短半轴端点控制,保持两轴垂直\r\n if (plotType === PlotGraphicType.ELLIPSE && (index === 1 || index === 2)) {\r\n const center = controlPoints[0];\r\n if (index === 1) {\r\n // 长轴端点移动:改变长轴长度/方向,短轴端点跟随旋转并保持长度\r\n const newMajor = [controlPoints[1][0] - center[0], controlPoints[1][1] - center[1]];\r\n const oldMinor = [\r\n this._selectedEntity._controlPoints[2][0] - center[0],\r\n this._selectedEntity._controlPoints[2][1] - center[1]\r\n ];\r\n const newMinor = this._rotatePerpendicular(newMajor, oldMinor);\r\n controlPoints[2] = [center[0] + newMinor[0], center[1] + newMinor[1], center[2] || 0];\r\n } else if (index === 2) {\r\n // 短轴端点移动:只改变短轴长度,投影到过中心且与长轴垂直的直线上\r\n const major = [controlPoints[1][0] - center[0], controlPoints[1][1] - center[1]];\r\n const majorLen = Math.hypot(major[0], major[1]);\r\n if (majorLen > 0) {\r\n const ux = major[0] / majorLen;\r\n const uy = major[1] / majorLen;\r\n // 长轴逆时针旋转 90° 得到垂直方向\r\n const perpUx = -uy;\r\n const perpUy = ux;\r\n const mouseVec = [newLonLat[0] - center[0], newLonLat[1] - center[1]];\r\n const projectedLen = mouseVec[0] * perpUx + mouseVec[1] * perpUy;\r\n controlPoints[2] = [\r\n center[0] + perpUx * projectedLen,\r\n center[1] + perpUy * projectedLen,\r\n center[2] || 0\r\n ];\r\n }\r\n }\r\n }\r\n\r\n // 更新控制点缓存\r\n this._selectedEntity._controlPoints = controlPoints;\r\n\r\n // 重新生成几何\r\n const wrapper = this._graphicModule.wrapperMap.get(this._selectedEntity.id);\r\n if (wrapper) {\r\n wrapper.setControlPoints(controlPoints);\r\n }\r\n\r\n // 更新控制点位置(不含中心控制点)\r\n this._editHandles.forEach((handle) => {\r\n if (handle.id && handle.id.includes('center')) return;\r\n // 按句柄 ID 解析真实控制点索引(扇形跳过了索引 0)\r\n const match = handle.id.match(/__edit_handle_(\\d+)$/);\r\n if (match) {\r\n const cpIndex = parseInt(match[1], 10);\r\n const cp = controlPoints[cpIndex];\r\n handle.position = new Cesium.ConstantPositionProperty(\r\n this._clampPositionToGround(Cesium.Cartesian3.fromDegrees(cp[0], cp[1], cp[2] || 0))\r\n );\r\n }\r\n });\r\n\r\n // 更新中心控制点位置\r\n const centerHandle = this._editHandles.find(h => h.id && h.id.includes('center'));\r\n if (centerHandle) {\r\n // 扇形/椭圆:中心控制点固定在中心;其他类型使用重心\r\n const newCenter = (plotType === PlotGraphicType.SECTOR || plotType === PlotGraphicType.ELLIPSE)\r\n ? controlPoints[0]\r\n : this._getPlotControlPointsCenter(controlPoints);\r\n centerHandle.position = new Cesium.ConstantPositionProperty(\r\n this._clampPositionToGround(Cesium.Cartesian3.fromDegrees(newCenter[0], newCenter[1], newCenter[2] || 0))\r\n );\r\n this._originalEntityCenter = this._clampPositionToGround(\r\n Cesium.Cartesian3.fromDegrees(newCenter[0], newCenter[1], newCenter[2] || 0)\r\n );\r\n }\r\n\r\n // 更新原始位置缓存\r\n this._originalPositions = this._getEntityPositions(this._selectedEntity);\r\n return;\r\n }\r\n\r\n const hierarchy = this._selectedEntity.polygon?.hierarchy?.getValue(Cesium.JulianDate.now());\r\n\r\n // 拖动中心控制点:平移整个图元\r\n // 修复:统一使用 includes('center') 来判断\r\n if (this._dragHandle.id && this._dragHandle.id.includes('center') && this._originalEntityCenter) {\r\n this._translateEntity(newCartesian);\r\n return;\r\n }\r\n\r\n // 矩形特殊情况:重新计算所有4个顶点\r\n // 确保是数字索引(矩形用 [0,1,2,3],圆用 ['center','radius'])\r\n if (this._handleVertexIndices &&\r\n Array.isArray(this._handleVertexIndices) &&\r\n typeof this._handleVertexIndices[0] === 'number' &&\r\n Cesium.defined(this._selectedEntity.polygon)) {\r\n if (!hierarchy || !hierarchy.positions || hierarchy.positions.length < 4) return;\r\n\r\n const draggedVertexIndex = this._handleVertexIndices[handleIndex];\r\n const newPositions = this._computeRectangleNewPositions(newCartesian, hierarchy.positions, draggedVertexIndex);\r\n\r\n // 修复:所有新位置贴地\r\n const clampedPositions = newPositions.map(pos => this._clampPositionToGround(pos));\r\n\r\n // 更新多边形\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(clampedPositions);\r\n\r\n // 更新所有控制点位置(使用 ConstantPositionProperty 确保正确更新)\r\n this._editHandles.forEach((handle, i) => {\r\n // 修复:跳过中心控制点\r\n if (handle.id && handle.id.includes('center')) return;\r\n handle.position = new Cesium.ConstantPositionProperty(clampedPositions[i]);\r\n });\r\n\r\n // 修复:顶点编辑后重新计算并更新中心控制点位置\r\n this._updateCenterHandlePosition();\r\n\r\n return;\r\n }\r\n\r\n // 圆形特殊情况:编辑半径或圆心\r\n if (this._handleVertexIndices &&\r\n Array.isArray(this._handleVertexIndices) &&\r\n this._isCircle(this._selectedEntity)) {\r\n\r\n const circleInfo = this._getCircleInfo(this._selectedEntity);\r\n if (!circleInfo) return;\r\n\r\n const handleId = this._dragHandle.id;\r\n\r\n // 拖拽圆心:平移整个圆\r\n if (handleId && handleId.includes('__edit_handle_center')) {\r\n // 计算新圆心\r\n const newCenterLonLat = newLonLat;\r\n\r\n // 更新圆心控制点位置\r\n this._dragHandle.position = newCartesian;\r\n\r\n // 更新圆的实体属性\r\n this._selectedEntity._circleCenter = newCenterLonLat;\r\n\r\n // 更新多边形顶点\r\n const positions = this._generateCirclePositions(newCenterLonLat, circleInfo.radius, 256);\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(flat)\r\n );\r\n\r\n // 更新半径控制点位置\r\n const radiusHandle = this._editHandles.find(h => h.id && h.id.includes('radius'));\r\n if (radiusHandle) {\r\n const radiusPoint = this._getPointOnCircle(newCenterLonLat, circleInfo.radius, 0);\r\n radiusHandle.position = new Cesium.ConstantPositionProperty(\r\n Cesium.Cartesian3.fromDegrees(radiusPoint[0], radiusPoint[1], 0)\r\n );\r\n }\r\n\r\n return;\r\n }\r\n\r\n // 拖拽半径:计算新半径\r\n let newRadius = this._calcDistance(circleInfo.center, newLonLat);\r\n // 更新半径控制点位置(在圆周上)\r\n const angle = Math.atan2(newLonLat[1] - circleInfo.center[1], newLonLat[0] - circleInfo.center[0]);\r\n const radiusPoint = this._getPointOnCircle(circleInfo.center, newRadius, angle);\r\n this._dragHandle.position = new Cesium.ConstantPositionProperty(\r\n Cesium.Cartesian3.fromDegrees(radiusPoint[0], radiusPoint[1], 0)\r\n );\r\n\r\n // 更新圆的实体属性\r\n this._selectedEntity._circleCenter = circleInfo.center;\r\n this._selectedEntity._circleRadius = newRadius;\r\n\r\n // 更新多边形顶点\r\n const positions = this._generateCirclePositions(circleInfo.center, newRadius, 256);\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(flat)\r\n );\r\n\r\n return;\r\n }\r\n\r\n if (Cesium.defined(this._selectedEntity.polyline)) {\r\n const positions = this._selectedEntity.polyline.positions.getValue(Cesium.JulianDate.now());\r\n if (positions && positions[handleIndex]) {\r\n // 直接修改数组元素触发更新\r\n positions[handleIndex] = newCartesian;\r\n this._selectedEntity.polyline.positions = positions;\r\n this._dragHandle.position = new Cesium.ConstantPositionProperty(newCartesian);\r\n \r\n // 修复:线编辑后重新计算并更新中心控制点位置\r\n this._updateCenterHandlePosition();\r\n }\r\n } else if (Cesium.defined(this._selectedEntity.polygon)) {\r\n // 获取当前实际顶点数(不包含闭合点)\r\n const actualVertexCount = this._editHandles.filter(h => !h.id.includes('center')).length;\r\n\r\n // 构建新位置数组\r\n const newPositions = [];\r\n let vertexIndex = 0;\r\n for (let i = 0; i < this._editHandles.length; i++) {\r\n const handle = this._editHandles[i];\r\n // 修复:跳过中心控制点\r\n if (handle.id && handle.id.includes('center')) continue;\r\n \r\n if (handle === this._dragHandle) {\r\n newPositions.push(newCartesian);\r\n } else {\r\n // 从控制点获取当前位置\r\n const pos = handle.position.getValue(Cesium.JulianDate.now());\r\n // 修复:确保位置贴地\r\n newPositions.push(this._clampPositionToGround(pos));\r\n }\r\n vertexIndex++;\r\n }\r\n\r\n // ✅ 添加闭合点\r\n newPositions.push(newPositions[0].clone());\r\n\r\n // 更新多边形\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(newPositions);\r\n\r\n // 更新控制点\r\n this._dragHandle.position = new Cesium.ConstantPositionProperty(newCartesian);\r\n \r\n // 修复:多边形编辑后重新计算并更新中心控制点位置\r\n this._updateCenterHandlePosition();\r\n\r\n return;\r\n } else if (Cesium.defined(this._selectedEntity.position)) {\r\n this._selectedEntity.position = new Cesium.ConstantPositionProperty(newCartesian);\r\n this._dragHandle.position = new Cesium.ConstantPositionProperty(newCartesian);\r\n }\r\n }\r\n\r\n _highlightEntity(entity, highlight) {\r\n if (!entity) return;\r\n\r\n if (Cesium.defined(entity.point)) {\r\n if (highlight) {\r\n entity.point.outlineColor = Cesium.Color.CYAN;\r\n entity.point.outlineWidth = 3;\r\n } else {\r\n entity.point.outlineColor = Cesium.Color.WHITE;\r\n entity.point.outlineWidth = 1;\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.polyline)) {\r\n if (highlight) {\r\n entity.polyline.material = Cesium.Color.CYAN;\r\n } else {\r\n entity.polyline.material = Cesium.Color.BLUE;\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.polygon)) {\r\n if (highlight) {\r\n entity.polygon.outlineColor = Cesium.Color.CYAN;\r\n } else {\r\n entity.polygon.outlineColor = Cesium.Color.WHITE;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取当前选中的图元 ID\r\n */\r\n getSelectedEntityId() {\r\n return this._selectedEntityId;\r\n }\r\n\r\n /**\r\n * 获取编辑前的原始位置(用于撤销)\r\n */\r\n getOriginalPositions() {\r\n return this._originalPositions;\r\n }\r\n\r\n /**\r\n * 撤销编辑,恢复原始位置\r\n */\r\n undo() {\r\n if (!this._selectedEntity) return;\r\n\r\n // 圆形特殊处理:恢复圆心和半径\r\n if (this._isCircle(this._selectedEntity) && this._originalCircleCenter && this._originalCircleRadius) {\r\n const center = this._originalCircleCenter;\r\n const radius = this._originalCircleRadius;\r\n\r\n // 恢复圆的实体属性\r\n this._selectedEntity._circleCenter = center;\r\n this._selectedEntity._circleRadius = radius;\r\n\r\n // 更新多边形顶点\r\n const positions = this._generateCirclePositions(center, radius, 256);\r\n const flat = positions.flatMap(c => [c[0], c[1], 0]);\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(flat)\r\n );\r\n\r\n this._createEditHandles();\r\n this._emitEditComplete();\r\n return;\r\n }\r\n\r\n // 优先使用矩形原始位置,其次使用一般原始位置\r\n const originalPositions = this._rectangleOriginalPositions || this._originalPositions;\r\n if (!originalPositions) return;\r\n\r\n // 拷贝一份避免直接修改原始数据\r\n const positionsCopy = originalPositions.map(p => p.clone ? p.clone() : p);\r\n\r\n if (Cesium.defined(this._selectedEntity.polyline)) {\r\n this._selectedEntity.polyline.positions = positionsCopy;\r\n } else if (Cesium.defined(this._selectedEntity.polygon)) {\r\n this._selectedEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(positionsCopy);\r\n }\r\n\r\n this._createEditHandles();\r\n this._emitEditComplete();\r\n }\r\n\r\n _emitSelect(entityId) {\r\n if (this._options.onSelect) {\r\n this._options.onSelect({ entityId });\r\n }\r\n }\r\n\r\n _emitEditComplete() {\r\n if (this._options.onEditComplete) {\r\n this._options.onEditComplete({\r\n entityId: this._selectedEntityId,\r\n positions: this._getEntityPositions(this._selectedEntity)\r\n });\r\n }\r\n }\r\n}","import { BaseTool } from './BaseTool.js';\r\n\r\n/**\r\n * 选择类型枚举\r\n */\r\nexport const SelectType = {\r\n POINT: 'point', // 点选\r\n RECTANGLE: 'rectangle', // 矩形框选\r\n CIRCLE: 'circle' // 圆形框选\r\n};\r\n\r\n/**\r\n * 选择工具\r\n * 支持点选和框选(矩形、圆形)\r\n */\r\nexport class SelectTool extends BaseTool {\r\n constructor(editorModule, options = {}) {\r\n super(editorModule, options);\r\n this._selectType = options.selectType || SelectType.POINT;\r\n this._isSelecting = false;\r\n this._startPos = null;\r\n this._tempEntities = [];\r\n this._selectedIds = new Set();\r\n this._selectionRect = null;\r\n this._originalStyles = new Map(); // 记录选中前的原始样式\r\n }\r\n\r\n /**\r\n * 设置选择类型\r\n * @param {string} type SelectType\r\n */\r\n setSelectType(type) {\r\n this._selectType = type;\r\n return this;\r\n }\r\n\r\n getSelectType() {\r\n return this._selectType;\r\n }\r\n\r\n onActivate() {\r\n this.registerObserver('mouse:click', this._onClick.bind(this));\r\n this.registerObserver('mouse:move', this._onMove.bind(this));\r\n this.registerObserver('mouse:down', this._onMouseDown.bind(this));\r\n this.registerObserver('mouse:up', this._onMouseUp.bind(this));\r\n }\r\n\r\n onDeactivate() {\r\n this._cancelSelection();\r\n this._clearSelectionRect();\r\n }\r\n\r\n _onMouseDown(data) {\r\n // mouse:down passes movement object from BaseTool\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n\r\n if (this._selectType !== SelectType.POINT) {\r\n const lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });\r\n if (lonLat) {\r\n this._startPos = lonLat;\r\n this._isSelecting = true;\r\n this._createSelectionStartMarker(lonLat);\r\n }\r\n }\r\n }\r\n\r\n _onMouseUp(data) {\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n\r\n if (this._isSelecting && this._startPos) {\r\n const lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });\r\n if (lonLat) {\r\n this._finishSelection(lonLat);\r\n }\r\n }\r\n }\r\n\r\n _onClick(_lngLat, _entity, movement) {\r\n if (this._selectType !== SelectType.POINT) return;\r\n\r\n const screenPos = movement.position || (movement && movement.endPosition);\r\n if (!screenPos) return;\r\n\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n\r\n if (Cesium.defined(picked) && Cesium.defined(picked.id)) {\r\n const entityId = picked.id.id;\r\n\r\n // 忽略临时图元\r\n if (entityId && entityId.startsWith('__temp_')) return;\r\n if (entityId && entityId.startsWith('__edit_handle_')) return;\r\n\r\n if (this._isSelected(entityId)) {\r\n this._deselect(entityId);\r\n } else {\r\n this._select(entityId);\r\n }\r\n } else {\r\n // 点击空白处,清除所有选择\r\n this._clearAllSelections();\r\n }\r\n }\r\n\r\n _onMove(data) {\r\n // mouse:move passes movement object from BaseTool\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n\r\n if (!this._isSelecting || !this._startPos) return;\r\n\r\n const lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });\r\n if (!lonLat) return;\r\n\r\n this._updateSelectionRectPreview(lonLat);\r\n\r\n // 实时框选\r\n if (this._selectType === SelectType.RECTANGLE) {\r\n const insideIds = this._getEntitiesInRectangle(this._startPos, lonLat);\r\n this._highlightEntitiesInSelection(insideIds);\r\n } else if (this._selectType === SelectType.CIRCLE) {\r\n const insideIds = this._getEntitiesInCircle(this._startPos, lonLat);\r\n this._highlightEntitiesInSelection(insideIds);\r\n }\r\n }\r\n\r\n _createSelectionStartMarker(pos) {\r\n const marker = this.createTempEntity(this.generateId('sel_start'), {\r\n position: Cesium.Cartesian3.fromDegrees(...pos),\r\n point: {\r\n color: Cesium.Color.GREEN,\r\n pixelSize: 10\r\n }\r\n });\r\n this._tempEntities.push(marker);\r\n }\r\n\r\n _updateSelectionRectPreview(currentPos) {\r\n if (this._selectType === SelectType.RECTANGLE) {\r\n this._updateRectPreview(currentPos);\r\n } else if (this._selectType === SelectType.CIRCLE) {\r\n this._updateCirclePreview(currentPos);\r\n }\r\n }\r\n\r\n _updateRectPreview(currentPos) {\r\n const corner1 = this._startPos;\r\n const corner2 = currentPos;\r\n\r\n if (!corner1 || !corner2) return;\r\n\r\n if (!this._selectionRect) {\r\n this._selectionRect = this.createTempEntity(this.generateId('sel_rect'), {\r\n polyline: {\r\n positions: new Cesium.CallbackProperty(() => {\r\n const pos = this._getRectPositions(corner1, corner2);\r\n return Cesium.Cartesian3.fromDegreesArrayHeights(pos.flatMap(c => [c[0], c[1], 0]));\r\n }, false),\r\n material: Cesium.Color.CYAN,\r\n width: 2\r\n },\r\n polygon: {\r\n hierarchy: new Cesium.CallbackProperty(() => {\r\n const pos = this._getRectPositions(corner1, corner2);\r\n return new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(pos.flatMap(c => [c[0], c[1], 0]))\r\n );\r\n }, false),\r\n material: Cesium.Color.CYAN.withAlpha(0.2),\r\n outline: false\r\n }\r\n });\r\n this._selectionRect._isPreview = true;\r\n this._tempEntities.push(this._selectionRect);\r\n }\r\n }\r\n\r\n _updateCirclePreview(currentPos) {\r\n const center = this._startPos;\r\n\r\n if (!center || !currentPos) return;\r\n\r\n if (!this._selectionRect) {\r\n this._selectionRect = this.createTempEntity(this.generateId('sel_circle'), {\r\n polygon: {\r\n hierarchy: new Cesium.CallbackProperty(() => {\r\n const radius = this._calcDistance(center, currentPos);\r\n const positions = this._generateCirclePositions(center, radius, 36);\r\n return new Cesium.PolygonHierarchy(\r\n Cesium.Cartesian3.fromDegreesArrayHeights(\r\n positions.flatMap(c => [c[0], c[1], 0])\r\n )\r\n );\r\n }, false),\r\n material: Cesium.Color.CYAN.withAlpha(0.2),\r\n outline: true,\r\n outlineColor: Cesium.Color.CYAN\r\n }\r\n });\r\n this._selectionRect._isPreview = true;\r\n this._tempEntities.push(this._selectionRect);\r\n }\r\n }\r\n\r\n _getRectPositions(corner1, corner2) {\r\n return [\r\n [corner1[0], corner1[1]],\r\n [corner2[0], corner1[1]],\r\n [corner2[0], corner2[1]],\r\n [corner1[0], corner2[1]],\r\n [corner1[0], corner1[1]]\r\n ];\r\n }\r\n\r\n _clearSelectionRect() {\r\n this._tempEntities.forEach(entity => {\r\n if (entity._isPreview) {\r\n this.removeTempEntity(entity);\r\n }\r\n });\r\n this._tempEntities = this._tempEntities.filter(e => !e._isPreview);\r\n this._selectionRect = null;\r\n }\r\n\r\n _finishSelection(endPos) {\r\n let selectedIds = [];\r\n\r\n if (this._selectType === SelectType.RECTANGLE) {\r\n selectedIds = this._getEntitiesInRectangle(this._startPos, endPos);\r\n } else if (this._selectType === SelectType.CIRCLE) {\r\n selectedIds = this._getEntitiesInCircle(this._startPos, endPos);\r\n }\r\n\r\n // 框选模式:选中框内所有图元\r\n selectedIds.forEach(id => {\r\n this._select(id, false); // 不触发事件\r\n });\r\n\r\n this._cancelSelection();\r\n this._emitSelectionComplete(Array.from(this._selectedIds));\r\n }\r\n\r\n _cancelSelection() {\r\n this._isSelecting = false;\r\n this._startPos = null;\r\n this._isSelecting = false;\r\n this._selectionRect = null;\r\n this._tempEntities.forEach(entity => {\r\n this.removeTempEntity(entity);\r\n });\r\n this._tempEntities = [];\r\n }\r\n\r\n _select(entityId, emitEvent = true) {\r\n if (this._selectedIds.has(entityId)) return;\r\n\r\n this._selectedIds.add(entityId);\r\n this._highlightEntity(entityId, true);\r\n\r\n if (emitEvent) {\r\n this._emitSelect(entityId);\r\n }\r\n }\r\n\r\n _deselect(entityId) {\r\n if (!this._selectedIds.has(entityId)) return;\r\n\r\n this._selectedIds.delete(entityId);\r\n this._highlightEntity(entityId, false);\r\n }\r\n\r\n _clearAllSelections() {\r\n this._selectedIds.forEach(id => {\r\n this._highlightEntity(id, false);\r\n });\r\n this._selectedIds.clear();\r\n this._emitSelectionChange([]);\r\n }\r\n\r\n _highlightEntity(entityId, highlight) {\r\n const entity = this._graphicModule.getGraphic(entityId);\r\n if (!entity) return;\r\n\r\n const styleKey = entityId;\r\n\r\n if (Cesium.defined(entity.point)) {\r\n if (highlight) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n point: {\r\n outlineColor: entity.point.outlineColor,\r\n outlineWidth: entity.point.outlineWidth\r\n }\r\n });\r\n }\r\n entity.point.outlineColor = Cesium.Color.YELLOW;\r\n entity.point.outlineWidth = 2;\r\n } else {\r\n const original = this._originalStyles.get(styleKey)?.point;\r\n if (original) {\r\n entity.point.outlineColor = original.outlineColor;\r\n entity.point.outlineWidth = original.outlineWidth;\r\n } else {\r\n entity.point.outlineColor = Cesium.Color.WHITE;\r\n entity.point.outlineWidth = 1;\r\n }\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.polyline)) {\r\n if (highlight) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n polyline: {\r\n material: entity.polyline.material\r\n }\r\n });\r\n }\r\n entity.polyline.material = Cesium.Color.CYAN;\r\n } else {\r\n const original = this._originalStyles.get(styleKey)?.polyline;\r\n entity.polyline.material = original?.material || Cesium.Color.BLUE;\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.polygon)) {\r\n if (highlight) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n polygon: {\r\n outlineColor: entity.polygon.outlineColor\r\n }\r\n });\r\n }\r\n entity.polygon.outlineColor = Cesium.Color.CYAN;\r\n } else {\r\n const original = this._originalStyles.get(styleKey)?.polygon;\r\n entity.polygon.outlineColor = original?.outlineColor || Cesium.Color.WHITE;\r\n }\r\n }\r\n\r\n if (!highlight) {\r\n this._originalStyles.delete(styleKey);\r\n }\r\n }\r\n\r\n _highlightEntitiesInSelection(entityIds) {\r\n // 先取消所有选择的高亮\r\n this._selectedIds.forEach(id => {\r\n if (!entityIds.includes(id)) {\r\n this._highlightEntity(id, false);\r\n this._selectedIds.delete(id);\r\n }\r\n });\r\n\r\n // 高亮框内图元\r\n entityIds.forEach(id => {\r\n if (!this._selectedIds.has(id)) {\r\n this._selectedIds.add(id);\r\n this._highlightEntity(id, true);\r\n }\r\n });\r\n }\r\n\r\n _getOriginalColor(entity) {\r\n // 已废弃:原始样式由 _originalStyles 统一维护\r\n return null;\r\n }\r\n\r\n _getEntitiesInRectangle(corner1, corner2) {\r\n const minLon = Math.min(corner1[0], corner2[0]);\r\n const maxLon = Math.max(corner1[0], corner2[0]);\r\n const minLat = Math.min(corner1[1], corner2[1]);\r\n const maxLat = Math.max(corner1[1], corner2[1]);\r\n\r\n const allIds = this._getAllGraphicIds();\r\n return this._filterEntitiesInBounds(allIds, minLon, maxLon, minLat, maxLat);\r\n }\r\n\r\n _getEntitiesInCircle(center, edge) {\r\n const radius = this._calcDistance(center, edge);\r\n const allIds = this._getAllGraphicIds();\r\n const result = [];\r\n\r\n allIds.forEach(id => {\r\n const entity = this._graphicModule.getGraphic(id);\r\n if (!entity) return;\r\n\r\n const entityPos = this._getEntityPosition(entity);\r\n if (!entityPos) return;\r\n\r\n const distance = this._calcDistance(center, entityPos);\r\n if (distance <= radius) {\r\n result.push(id);\r\n }\r\n });\r\n\r\n return result;\r\n }\r\n\r\n _getAllGraphicIds() {\r\n // 从 GraphicModule 获取所有图元 ID\r\n const ids = [];\r\n this._graphicModule.graphicMap.forEach((entity, id) => {\r\n if (!id.startsWith('__temp_') && !id.startsWith('__edit_handle_')) {\r\n ids.push(id);\r\n }\r\n });\r\n return ids;\r\n }\r\n\r\n _filterEntitiesInBounds(ids, minLon, maxLon, minLat, maxLat) {\r\n const result = [];\r\n\r\n ids.forEach(id => {\r\n const entity = this._graphicModule.getGraphic(id);\r\n if (!entity) return;\r\n\r\n const positions = this._getEntityPositions(entity);\r\n if (!positions || positions.length === 0) return;\r\n\r\n // 检查是否所有点都在范围内\r\n let allInBounds = true;\r\n for (const pos of positions) {\r\n const c = Cesium.Cartographic.fromCartesian(pos);\r\n const lon = Cesium.Math.toDegrees(c.longitude);\r\n const lat = Cesium.Math.toDegrees(c.latitude);\r\n\r\n if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) {\r\n allInBounds = false;\r\n break;\r\n }\r\n }\r\n\r\n if (allInBounds) {\r\n result.push(id);\r\n }\r\n });\r\n\r\n return result;\r\n }\r\n\r\n _getEntityPosition(entity) {\r\n if (Cesium.defined(entity.position)) {\r\n const pos = entity.position.getValue(Cesium.JulianDate.now());\r\n if (pos) {\r\n const c = Cesium.Cartographic.fromCartesian(pos);\r\n return [\r\n Cesium.Math.toDegrees(c.longitude),\r\n Cesium.Math.toDegrees(c.latitude)\r\n ];\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n _getEntityPositions(entity) {\r\n if (Cesium.defined(entity.polyline) && Cesium.defined(entity.polyline.positions)) {\r\n return entity.polyline.positions.getValue(Cesium.JulianDate.now());\r\n }\r\n if (Cesium.defined(entity.polygon) && Cesium.defined(entity.polygon.hierarchy)) {\r\n const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now());\r\n return hierarchy ? hierarchy.positions : [];\r\n }\r\n return [];\r\n }\r\n\r\n _calcDistance(coord1, coord2) {\r\n const earthRadius = 6371000;\r\n const [lon1, lat1] = coord1.map(d => d * Math.PI / 180);\r\n const [lon2, lat2] = coord2.map(d => d * Math.PI / 180);\r\n\r\n const dLat = lat2 - lat1;\r\n const dLon = lon2 - lon1;\r\n\r\n const a = Math.sin(dLat / 2) ** 2 +\r\n Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n\r\n return earthRadius * c;\r\n }\r\n\r\n _generateCirclePositions(center, radius, segments) {\r\n const positions = [];\r\n const [lon, lat] = center;\r\n const radPerDeg = Math.PI / 180;\r\n\r\n for (let i = 0; i <= segments; i++) {\r\n const angle = (i / segments) * Math.PI * 2;\r\n const dLon = (radius / 111320) * Math.cos(angle) / radPerDeg;\r\n const dLat = (radius / 110540) / radPerDeg;\r\n positions.push([lon + dLon, lat + dLat]);\r\n }\r\n return positions;\r\n }\r\n\r\n _isSelected(entityId) {\r\n return this._selectedIds.has(entityId);\r\n }\r\n\r\n /**\r\n * 获取当前所有选中的图元 ID\r\n */\r\n getSelectedIds() {\r\n return Array.from(this._selectedIds);\r\n }\r\n\r\n _emitSelect(entityId) {\r\n if (this._options.onSelect) {\r\n this._options.onSelect({ entityId });\r\n }\r\n }\r\n\r\n _emitSelectionChange(ids) {\r\n if (this._options.onSelectionChange) {\r\n this._options.onSelectionChange({ selectedIds: ids });\r\n }\r\n }\r\n\r\n _emitSelectionComplete(ids) {\r\n if (this._options.onSelectionComplete) {\r\n this._options.onSelectionComplete({ selectedIds: ids });\r\n }\r\n }\r\n}\r\n","import { BaseTool } from './BaseTool.js';\r\n\r\n/**\r\n * 删除模式枚举\r\n */\r\nexport const DeleteMode = {\r\n SINGLE: 'single', // 单个删除(点击删除)\r\n SELECTED: 'selected' // 删除已选择的图元\r\n};\r\n\r\n/**\r\n * 删除工具\r\n * 支持单个删除和批量删除已选择的图元\r\n */\r\nexport class DeleteTool extends BaseTool {\r\n constructor(editorModule, options = {}) {\r\n super(editorModule, options);\r\n this._deleteMode = options.deleteMode || DeleteMode.SINGLE;\r\n this._hoveredEntity = null;\r\n this._hoverEntity = null; // 悬停高亮\r\n this._originalStyles = new Map(); // 记录悬停前的原始样式\r\n }\r\n\r\n /**\r\n * 设置删除模式\r\n * @param {string} mode DeleteMode\r\n */\r\n setDeleteMode(mode) {\r\n this._deleteMode = mode;\r\n return this;\r\n }\r\n\r\n getDeleteMode() {\r\n return this._deleteMode;\r\n }\r\n\r\n onActivate() {\r\n this.registerObserver('mouse:click', this._onClick.bind(this));\r\n this.registerObserver('mouse:move', this._onMove.bind(this));\r\n }\r\n\r\n onDeactivate() {\r\n this._clearHoverHighlight();\r\n }\r\n\r\n _onClick(_lngLat, _entity, movement) {\r\n const screenPos = movement.position || (movement && movement.endPosition);\r\n if (!screenPos) return;\r\n\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n\r\n if (Cesium.defined(picked) && Cesium.defined(picked.id)) {\r\n const entityId = picked.id.id;\r\n\r\n // 忽略临时图元\r\n if (entityId && entityId.startsWith('__temp_')) return;\r\n if (entityId && entityId.startsWith('__edit_handle_')) return;\r\n\r\n // 忽略编辑器自身的控制点\r\n if (entityId && entityId.startsWith('__sel_')) return;\r\n\r\n if (this._deleteMode === DeleteMode.SINGLE) {\r\n this._deleteSingle(entityId);\r\n }\r\n }\r\n }\r\n\r\n _onMove(data) {\r\n const screenPos = data.position || data.endPosition;\r\n if (!screenPos) return;\r\n\r\n const picked = this._viewer.scene.pick({ x: screenPos.x, y: screenPos.y });\r\n\r\n let hoveredId = null;\r\n\r\n if (Cesium.defined(picked) && Cesium.defined(picked.id)) {\r\n const entityId = picked.id.id;\r\n if (!entityId.startsWith('__temp_') && !entityId.startsWith('__edit_handle_')) {\r\n hoveredId = entityId;\r\n }\r\n }\r\n\r\n if (hoveredId !== this._hoveredEntity) {\r\n this._clearHoverHighlight();\r\n this._hoveredEntity = hoveredId;\r\n\r\n if (hoveredId) {\r\n this._highlightAsDeletable(hoveredId);\r\n }\r\n }\r\n }\r\n\r\n _deleteSingle(entityId) {\r\n const entity = this._graphicModule.getGraphic(entityId);\r\n if (!entity) return;\r\n\r\n // 发送删除前事件(可撤销)\r\n this._emitBeforeDelete({\r\n entityId,\r\n entity: entity\r\n });\r\n\r\n // 执行删除\r\n this._graphicModule.removeGraphic(entityId);\r\n\r\n // 发送删除完成事件\r\n this._emitDelete({\r\n entityId\r\n });\r\n }\r\n\r\n /**\r\n * 删除多个图元\r\n * @param {string[]} entityIds 图元 ID 数组\r\n */\r\n deleteMultiple(entityIds) {\r\n const deleted = [];\r\n const failed = [];\r\n\r\n entityIds.forEach(id => {\r\n const success = this._graphicModule.removeGraphic(id);\r\n if (success) {\r\n deleted.push(id);\r\n } else {\r\n failed.push(id);\r\n }\r\n });\r\n\r\n this._emitDeleteMultiple({ deleted, failed });\r\n\r\n return { deleted, failed };\r\n }\r\n\r\n /**\r\n * 删除所有图元\r\n */\r\n deleteAll() {\r\n const allIds = [];\r\n this._graphicModule.graphicMap.forEach((entity, id) => {\r\n if (!id.startsWith('__temp_') && !id.startsWith('__edit_handle_')) {\r\n allIds.push(id);\r\n }\r\n });\r\n\r\n return this.deleteMultiple(allIds);\r\n }\r\n\r\n _highlightAsDeletable(entityId) {\r\n const entity = this._graphicModule.getGraphic(entityId);\r\n if (!entity) return;\r\n\r\n this._hoverEntity = entity;\r\n const styleKey = entityId;\r\n\r\n // 红色高亮表示可删除,先保存原始样式\r\n if (Cesium.defined(entity.point)) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n point: {\r\n outlineColor: entity.point.outlineColor,\r\n outlineWidth: entity.point.outlineWidth\r\n }\r\n });\r\n }\r\n entity.point.outlineColor = Cesium.Color.RED;\r\n entity.point.outlineWidth = 3;\r\n }\r\n\r\n if (Cesium.defined(entity.polyline)) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n polyline: {\r\n material: entity.polyline.material\r\n }\r\n });\r\n }\r\n entity.polyline.material = Cesium.Color.RED;\r\n }\r\n\r\n if (Cesium.defined(entity.polygon)) {\r\n if (!this._originalStyles.has(styleKey)) {\r\n this._originalStyles.set(styleKey, {\r\n polygon: {\r\n outlineColor: entity.polygon.outlineColor\r\n }\r\n });\r\n }\r\n entity.polygon.outlineColor = Cesium.Color.RED;\r\n }\r\n\r\n // 更改鼠标样式\r\n if (this._viewer.container) {\r\n this._viewer.container.style.cursor = 'pointer';\r\n }\r\n }\r\n\r\n _clearHoverHighlight() {\r\n if (!this._hoverEntity) return;\r\n\r\n const entity = this._hoverEntity;\r\n const styleKey = this._hoveredEntity;\r\n const original = styleKey ? this._originalStyles.get(styleKey) : null;\r\n\r\n // 恢复原始样式\r\n if (Cesium.defined(entity.point)) {\r\n if (original?.point) {\r\n entity.point.outlineColor = original.point.outlineColor;\r\n entity.point.outlineWidth = original.point.outlineWidth;\r\n } else {\r\n entity.point.outlineColor = Cesium.Color.WHITE;\r\n entity.point.outlineWidth = 1;\r\n }\r\n }\r\n\r\n if (Cesium.defined(entity.polyline)) {\r\n entity.polyline.material = original?.polyline?.material || Cesium.Color.BLUE;\r\n }\r\n\r\n if (Cesium.defined(entity.polygon)) {\r\n entity.polygon.outlineColor = original?.polygon?.outlineColor || Cesium.Color.WHITE;\r\n }\r\n\r\n // 恢复鼠标样式\r\n if (this._viewer.container) {\r\n this._viewer.container.style.cursor = 'default';\r\n }\r\n\r\n if (styleKey) {\r\n this._originalStyles.delete(styleKey);\r\n }\r\n this._hoverEntity = null;\r\n this._hoveredEntity = null;\r\n }\r\n\r\n _emitBeforeDelete(data) {\r\n if (this._options.onBeforeDelete) {\r\n this._options.onBeforeDelete(data);\r\n }\r\n }\r\n\r\n _emitDelete(data) {\r\n if (this._options.onDelete) {\r\n this._options.onDelete(data);\r\n }\r\n }\r\n\r\n _emitDeleteMultiple(data) {\r\n if (this._options.onDeleteMultiple) {\r\n this._options.onDeleteMultiple(data);\r\n }\r\n }\r\n}\r\n","import { Config } from '../core/Config.js';\r\nimport { DrawTool, DrawType } from './tools/DrawTool.js';\r\nimport { EditTool, EditMode } from './tools/EditTool.js';\r\nimport { SelectTool, SelectType } from './tools/SelectTool.js';\r\nimport { DeleteTool, DeleteMode } from './tools/DeleteTool.js';\r\n\r\n/**\r\n * 工具名称枚举\r\n */\r\nexport const ToolName = {\r\n DRAW: 'draw',\r\n EDIT: 'edit',\r\n SELECT: 'select',\r\n DELETE: 'delete'\r\n};\r\n\r\n/**\r\n * 编辑器模块\r\n * 负责工具的注册、切换、激活管理\r\n */\r\nexport class EditorModule {\r\n constructor(viewer, options = {}) {\r\n this.viewer = viewer;\r\n this.config = Config.getInstance().getConfig();\r\n this.graphicModule = null; // 依赖注入\r\n this.eventModule = null; // 依赖注入\r\n this.toolMap = new Map(); // 工具缓存\r\n this.currentTool = null; // 当前激活的工具\r\n this.currentToolName = null;\r\n this._isActive = false;\r\n }\r\n\r\n /**\r\n * 设置依赖模块\r\n * @param {object} deps 依赖模块 { graphicModule, eventModule }\r\n */\r\n setDependencies(deps) {\r\n this.graphicModule = deps.graphicModule;\r\n this.eventModule = deps.eventModule;\r\n return this;\r\n }\r\n\r\n /**\r\n * 初始化编辑器,注册所有内置工具\r\n */\r\n init() {\r\n // 注册内置工具\r\n this.registerTool(ToolName.DRAW, new DrawTool(this));\r\n this.registerTool(ToolName.EDIT, new EditTool(this));\r\n this.registerTool(ToolName.SELECT, new SelectTool(this));\r\n this.registerTool(ToolName.DELETE, new DeleteTool(this));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * 注册工具\r\n * @param {string} name 工具名称\r\n * @param {BaseTool} tool 工具实例\r\n * @returns {EditorModule}\r\n */\r\n registerTool(name, tool) {\r\n this.toolMap.set(name, tool);\r\n return this;\r\n }\r\n\r\n /**\r\n * 获取工具\r\n * @param {string} name 工具名称\r\n * @returns {BaseTool|undefined}\r\n */\r\n getTool(name) {\r\n return this.toolMap.get(name);\r\n }\r\n\r\n /**\r\n * 获取当前激活的工具\r\n * @returns {BaseTool|null}\r\n */\r\n getCurrentTool() {\r\n return this.currentTool;\r\n }\r\n\r\n /**\r\n * 获取当前激活的工具名称\r\n * @returns {string|null}\r\n */\r\n getCurrentToolName() {\r\n return this.currentToolName;\r\n }\r\n\r\n /**\r\n * 激活指定工具\r\n * @param {string} name 工具名称\r\n * @returns {EditorModule}\r\n */\r\n activateTool(name) {\r\n const tool = this.toolMap.get(name);\r\n if (!tool) {\r\n console.warn(`工具 ${name} 未注册`);\r\n return this;\r\n }\r\n\r\n // 停用当前工具\r\n if (this.currentTool) {\r\n this.currentTool.deactivate();\r\n }\r\n\r\n // 激活新工具\r\n this.currentTool = tool;\r\n this.currentToolName = name;\r\n this.currentTool.activate();\r\n this._isActive = true;\r\n\r\n console.log(`工具 ${name} 已激活`);\r\n return this;\r\n }\r\n\r\n /**\r\n * 停用当前工具\r\n * @returns {EditorModule}\r\n */\r\n deactivateTool() {\r\n if (this.currentTool) {\r\n this.currentTool.deactivate();\r\n }\r\n this.currentTool = null;\r\n this.currentToolName = null;\r\n this._isActive = false;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * 激活绘制工具并设置类型\r\n * @param {string} type 绘制类型 DrawType\r\n * @returns {EditorModule}\r\n */\r\n activateDrawTool(type = DrawType.POINT) {\r\n const drawTool = this.toolMap.get(ToolName.DRAW);\r\n if (drawTool) {\r\n drawTool.setDrawType(type);\r\n }\r\n return this.activateTool(ToolName.DRAW);\r\n }\r\n\r\n /**\r\n * 激活选择工具并设置类型\r\n * @param {string} type 选择类型 SelectType\r\n * @returns {EditorModule}\r\n */\r\n activateSelectTool(type = SelectType.POINT) {\r\n const selectTool = this.toolMap.get(ToolName.SELECT);\r\n if (selectTool) {\r\n selectTool.setSelectType(type);\r\n }\r\n return this.activateTool(ToolName.SELECT);\r\n }\r\n\r\n /**\r\n * 激活编辑工具并设置模式\r\n * @param {string} mode 编辑模式 EditMode\r\n * @returns {EditorModule}\r\n */\r\n activateEditTool(mode = EditMode.VERTEX) {\r\n const editTool = this.toolMap.get(ToolName.EDIT);\r\n if (editTool) {\r\n editTool.setEditMode(mode);\r\n }\r\n return this.activateTool(ToolName.EDIT);\r\n }\r\n\r\n /**\r\n * 激活删除工具并设置模式\r\n * @param {string} mode 删除模式 DeleteMode\r\n * @returns {EditorModule}\r\n */\r\n activateDeleteTool(mode = DeleteMode.SINGLE) {\r\n const deleteTool = this.toolMap.get(ToolName.DELETE);\r\n if (deleteTool) {\r\n deleteTool.setDeleteMode(mode);\r\n }\r\n return this.activateTool(ToolName.DELETE);\r\n }\r\n\r\n /**\r\n * 获取绘制工具(快捷方法)\r\n * @returns {DrawTool}\r\n */\r\n getDrawTool() {\r\n return this.toolMap.get(ToolName.DRAW);\r\n }\r\n\r\n /**\r\n * 获取选择工具(快捷方法)\r\n * @returns {SelectTool}\r\n */\r\n getSelectTool() {\r\n return this.toolMap.get(ToolName.SELECT);\r\n }\r\n\r\n /**\r\n * 获取编辑工具(快捷方法)\r\n * @returns {EditTool}\r\n */\r\n getEditTool() {\r\n return this.toolMap.get(ToolName.EDIT);\r\n }\r\n\r\n /**\r\n * 获取删除工具(快捷方法)\r\n * @returns {DeleteTool}\r\n */\r\n getDeleteTool() {\r\n return this.toolMap.get(ToolName.DELETE);\r\n }\r\n\r\n // ========== 公开回调 setter ==========\r\n\r\n /**\r\n * 设置绘制完成回调\r\n * @param {Function} callback\r\n */\r\n onDrawComplete(callback) {\r\n this.getDrawTool()._options.onGraphicCreated = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置绘制进度回调\r\n * @param {Function} callback\r\n */\r\n onDrawProgress(callback) {\r\n this.getDrawTool()._options.onDrawProgress = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置绘制取消回调\r\n * @param {Function} callback\r\n */\r\n onDrawCancel(callback) {\r\n this.getDrawTool()._options.onDrawCancel = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置编辑完成回调\r\n * @param {Function} callback\r\n */\r\n onEditComplete(callback) {\r\n this.getEditTool()._options.onEditComplete = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置编辑选中回调\r\n * @param {Function} callback\r\n */\r\n onEditSelect(callback) {\r\n this.getEditTool()._options.onSelect = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置选择回调\r\n * @param {Function} callback\r\n */\r\n onSelect(callback) {\r\n this.getSelectTool()._options.onSelect = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置选择变化回调\r\n * @param {Function} callback\r\n */\r\n onSelectionChange(callback) {\r\n this.getSelectTool()._options.onSelectionChange = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置框选完成回调\r\n * @param {Function} callback\r\n */\r\n onSelectionComplete(callback) {\r\n this.getSelectTool()._options.onSelectionComplete = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置删除前回调\r\n * @param {Function} callback\r\n */\r\n onBeforeDelete(callback) {\r\n this.getDeleteTool()._options.onBeforeDelete = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置删除完成回调\r\n * @param {Function} callback\r\n */\r\n onDelete(callback) {\r\n this.getDeleteTool()._options.onDelete = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 设置批量删除完成回调\r\n * @param {Function} callback\r\n */\r\n onDeleteMultiple(callback) {\r\n this.getDeleteTool()._options.onDeleteMultiple = callback;\r\n return this;\r\n }\r\n\r\n /**\r\n * 获取所有已选择的图元 ID(需要先使用选择工具)\r\n * @returns {string[]}\r\n */\r\n getSelectedIds() {\r\n const selectTool = this.getSelectTool();\r\n if (selectTool) {\r\n return selectTool.getSelectedIds();\r\n }\r\n return [];\r\n }\r\n\r\n /**\r\n * 删除所有已选择的图元\r\n * @returns {object} { deleted, failed }\r\n */\r\n deleteSelected() {\r\n const selectTool = this.getSelectTool();\r\n if (selectTool) {\r\n const ids = selectTool.getSelectedIds();\r\n const deleteTool = this.getDeleteTool();\r\n if (deleteTool) {\r\n return deleteTool.deleteMultiple(ids);\r\n }\r\n }\r\n return { deleted: [], failed: [] };\r\n }\r\n\r\n /**\r\n * 检查编辑器是否处于激活状态\r\n * @returns {boolean}\r\n */\r\n isActive() {\r\n return this._isActive;\r\n }\r\n\r\n /**\r\n * 销毁编辑器\r\n */\r\n destroy() {\r\n this.deactivateTool();\r\n this.toolMap.clear();\r\n this.graphicModule = null;\r\n this.eventModule = null;\r\n }\r\n}\r\n\r\n// 导出工具类型枚举\r\nexport { DrawType } from './tools/DrawTool.js';\r\nexport { EditMode } from './tools/EditTool.js';\r\nexport { SelectType } from './tools/SelectTool.js';\r\nexport { DeleteMode } from './tools/DeleteTool.js';\r\n","/**\r\n * 模块管理器(对应平台 GetModule 逻辑)\r\n * 统一管理场景、图元、事件模块的实例\r\n */\r\nimport { SceneModule } from '../modules/SceneModule.js';\r\nimport { GraphicModule } from '../modules/GraphicModule.js';\r\nimport { EventModule } from '../modules/EventModule.js';\r\nimport { EditorModule } from '../modules/EditorModule.js';\r\nimport { Config } from './Config.js';\r\n\r\nexport class ModuleManager {\r\n static instance = null;\r\n static getInstance() {\r\n if (!this.instance) {\r\n this.instance = new ModuleManager();\r\n }\r\n return this.instance;\r\n }\r\n\r\n constructor() {\r\n this.modules = new Map(); // 模块缓存\r\n this.cesiumViewer = null; // Cesium Viewer 实例(全局唯一)\r\n }\r\n\r\n /**\r\n * 初始化 Cesium 核心实例(插件初始化逻辑)\r\n * @param {string|HTMLElement} container 容器ID/元素\r\n * @returns {Cesium.Viewer} Cesium 实例\r\n */\r\n initViewer(container) {\r\n if (this.cesiumViewer) return this.cesiumViewer;\r\n const config = Config.getInstance().getConfig();\r\n\r\n this.cesiumViewer = new Cesium.Viewer(container, config.scene);\r\n // 隐藏版权信息(可选,对齐平台界面规范)\r\n const creditContainer = this.cesiumViewer.cesiumWidget?.creditContainer;\r\n if (creditContainer) {\r\n creditContainer.style.display = 'none';\r\n }\r\n\r\n // 初始化所有模块(注入 Viewer 实例)\r\n this.registerModule('SceneModule', new SceneModule(this.cesiumViewer));\r\n this.registerModule('GraphicModule', new GraphicModule(this.cesiumViewer));\r\n this.registerModule('EventModule', new EventModule(this.cesiumViewer));\r\n\r\n // 初始化编辑器模块(依赖其他模块)\r\n const editorModule = new EditorModule(this.cesiumViewer);\r\n editorModule.setDependencies({\r\n graphicModule: this.getModule('GraphicModule'),\r\n eventModule: this.getModule('EventModule')\r\n }).init();\r\n this.registerModule('EditorModule', editorModule);\r\n\r\n return this.cesiumViewer;\r\n }\r\n\r\n /**\r\n * 获取模块实例(对应平台 GetModule 函数)\r\n * @param {string} moduleName 模块名称(SceneModule/GraphicModule/EventModule)\r\n * @returns {Object} 模块实例\r\n */\r\n getModule(moduleName) {\r\n if (!this.modules.has(moduleName)) {\r\n throw new Error(`模块 ${moduleName} 未注册,请先初始化 Viewer`);\r\n }\r\n return this.modules.get(moduleName);\r\n }\r\n\r\n /**\r\n * Cesium Viewer 快捷访问\r\n * @returns {Cesium.Viewer}\r\n */\r\n get viewer() {\r\n return this.cesiumViewer;\r\n }\r\n\r\n /**\r\n * 场景模块快捷访问\r\n * @returns {SceneModule}\r\n */\r\n get sceneModule() {\r\n return this.getModule('SceneModule');\r\n }\r\n\r\n /**\r\n * 图元模块快捷访问\r\n * @returns {GraphicModule}\r\n */\r\n get graphicModule() {\r\n return this.getModule('GraphicModule');\r\n }\r\n\r\n /**\r\n * 事件模块快捷访问\r\n * @returns {EventModule}\r\n */\r\n get eventModule() {\r\n return this.getModule('EventModule');\r\n }\r\n\r\n /**\r\n * 编辑器模块快捷访问\r\n * @returns {EditorModule}\r\n */\r\n get editorModule() {\r\n return this.getModule('EditorModule');\r\n }\r\n\r\n /**\r\n * 注册模块(内部使用)\r\n * @param {string} moduleName 模块名称\r\n * @param {Object} moduleInstance 模块实例\r\n */\r\n registerModule(moduleName, moduleInstance) {\r\n this.modules.set(moduleName, moduleInstance);\r\n }\r\n\r\n /**\r\n * 销毁实例(对应平台插件 Destroy 逻辑)\r\n */\r\n destroy() {\r\n if (this.cesiumViewer) {\r\n // 先通知各模块释放资源\r\n try {\r\n const eventModule = this.modules.get('EventModule');\r\n if (eventModule && typeof eventModule.unregisterAllObservers === 'function') {\r\n eventModule.unregisterAllObservers();\r\n }\r\n } catch (e) {\r\n console.warn('EventModule 注销失败:', e);\r\n }\r\n\r\n try {\r\n const editorModule = this.modules.get('EditorModule');\r\n if (editorModule && typeof editorModule.destroy === 'function') {\r\n editorModule.destroy();\r\n }\r\n } catch (e) {\r\n console.warn('EditorModule 销毁失败:', e);\r\n }\r\n\r\n this.cesiumViewer.destroy();\r\n this.cesiumViewer = null;\r\n this.modules.clear();\r\n }\r\n }\r\n\r\n /**\r\n * 重置 ModuleManager 单例(用于完全重新初始化)\r\n */\r\n static reset() {\r\n if (ModuleManager.instance) {\r\n ModuleManager.instance.destroy();\r\n ModuleManager.instance = null;\r\n }\r\n }\r\n}","/**\r\n * 地理计算工具(距离、面积、高程)\r\n */\r\nexport class GeoCalcUtil {\r\n /**\r\n * 计算两点地理坐标距离(米)\r\n * @param {Array<number>} point1 [lng, lat, height]\r\n * @param {Array<number>} point2 [lng, lat, height]\r\n * @returns {number} 距离\r\n */\r\n static calcDistance(point1, point2) {\r\n const coord1 = Cesium.Cartesian3.fromDegrees(...point1);\r\n const coord2 = Cesium.Cartesian3.fromDegrees(...point2);\r\n return Cesium.Cartesian3.distance(coord1, coord2);\r\n }\r\n\r\n /**\r\n * 计算多边形面积(平方米)\r\n * 使用球面多边形面积公式(基于 Cesium 几何顶点)\r\n * @param {Array<Array<number>>} points 地理坐标点集 [lon, lat, height?]\r\n * @returns {number} 面积\r\n */\r\n static calcArea(points) {\r\n if (!points || points.length < 3) return 0;\r\n\r\n const positions = points.map(p => Cesium.Cartesian3.fromDegrees(p[0], p[1], p[2] || 0));\r\n const polygon = new Cesium.PolygonGeometry({\r\n polygonHierarchy: new Cesium.PolygonHierarchy(positions)\r\n });\r\n const geometry = Cesium.PolygonGeometry.createGeometry(polygon);\r\n\r\n if (!geometry || !geometry.attributes || !geometry.attributes.position) {\r\n return 0;\r\n }\r\n\r\n const values = geometry.attributes.position.values;\r\n const vertexPositions = [];\r\n for (let i = 0; i < values.length; i += 3) {\r\n vertexPositions.push(new Cesium.Cartesian3(values[i], values[i + 1], values[i + 2]));\r\n }\r\n\r\n // 球面多边形面积(基于单位球上的多边形面积公式)\r\n const area = GeoCalcUtil.#sphericalPolygonArea(vertexPositions);\r\n return Math.abs(area);\r\n }\r\n\r\n /**\r\n * 单位球面上多边形的有向面积(平方米)\r\n * 采用局部切平面投影法:以多边形重心为原点建立切平面,投影后计算二维多边形面积。\r\n * 对于常规 GIS 多边形精度足够;极大规模多边形可后续替换为更严格的球面 excess 算法。\r\n * @param {Cesium.Cartesian3[]} positions 世界坐标顶点\r\n * @returns {number} 面积(平方米)\r\n */\r\n static #sphericalPolygonArea(positions) {\r\n const ellipsoid = Cesium.Ellipsoid.WGS84;\r\n const n = positions.length;\r\n if (n < 3) return 0;\r\n\r\n // 计算近似重心(归一化到椭球面)\r\n let center = new Cesium.Cartesian3(0, 0, 0);\r\n for (const p of positions) {\r\n center = Cesium.Cartesian3.add(center, p, center);\r\n }\r\n center = Cesium.Cartesian3.normalize(center, new Cesium.Cartesian3());\r\n center = ellipsoid.scaleToGeodeticSurface(center, new Cesium.Cartesian3()) || center;\r\n\r\n // 在重心处建立东北天(ENU)局部坐标系\r\n const tangentPlane = new Cesium.EllipsoidTangentPlane(center, ellipsoid);\r\n\r\n // 投影到切平面\r\n const projected = positions.map(p => tangentPlane.projectPointOntoPlane(p, new Cesium.Cartesian2()));\r\n\r\n // 计算二维多边形面积(Shoelace 公式)\r\n let area2 = 0;\r\n for (let i = 0; i < n; i++) {\r\n const p1 = projected[i];\r\n const p2 = projected[(i + 1) % n];\r\n area2 += p1.x * p2.y - p2.x * p1.y;\r\n }\r\n\r\n return Math.abs(area2) * 0.5;\r\n }\r\n\r\n /**\r\n * 获取指定地理坐标的高程\r\n * @param {Cesium.Viewer} viewer Cesium 实例\r\n * @param {Array<number>} coord [lng, lat]\r\n * @returns {Promise<number>} 高程值\r\n */\r\n static async getHeight(viewer, coord) {\r\n const cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1]);\r\n const results = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic]);\r\n return results[0]?.height ?? 0;\r\n }\r\n}","// src/index.js\r\nimport { Config } from './core/Config.js';\r\nimport { ModuleManager } from './core/ModuleManager.js';\r\nimport { SceneModule, LayerType } from './modules/SceneModule.js';\r\nimport { GraphicModule } from './modules/GraphicModule.js';\r\nimport { EventModule } from './modules/EventModule.js';\r\nimport { EditorModule, DrawType, EditMode, SelectType, DeleteMode, ToolName } from './modules/EditorModule.js';\r\nimport { PlotGraphicType } from './modules/PlotGraphicType.js';\r\nimport { CoordinateUtil } from './utils/CoordinateUtil.js';\r\nimport { GeoCalcUtil } from './utils/GeoCalcUtil.js';\r\n\r\n// 核心 SDK 实例(直接导出,无嵌套)\r\nconst xs3d = {\r\n // 初始化 SDK\r\n init: (container, config = {}) => {\r\n // 设置 Cesium Token(提前处理,避免内部模块重复设置)\r\n if (config.cesiumToken) {\r\n window.Cesium.Ion.defaultAccessToken = config.cesiumToken;\r\n }\r\n // 设置全局配置\r\n Config.getInstance().setConfig(config);\r\n // 初始化模块管理器\r\n const moduleManager = ModuleManager.getInstance();\r\n moduleManager.initViewer(container);\r\n return moduleManager;\r\n },\r\n // 获取模块\r\n getModule: (moduleName) => {\r\n return ModuleManager.getInstance().getModule(moduleName);\r\n },\r\n // 销毁 SDK\r\n destroy: () => {\r\n ModuleManager.reset();\r\n Config.getInstance().setConfig({});\r\n if (window.Cesium?.Ion) {\r\n window.Cesium.Ion.defaultAccessToken = '';\r\n }\r\n },\r\n // 暴露核心类(方便高级使用)\r\n Config,\r\n ModuleManager,\r\n SceneModule,\r\n GraphicModule,\r\n EventModule,\r\n EditorModule,\r\n CoordinateUtil,\r\n GeoCalcUtil,\r\n // 导出工具枚举\r\n DrawType,\r\n EditMode,\r\n SelectType,\r\n DeleteMode,\r\n ToolName,\r\n LayerType,\r\n PlotGraphicType\r\n};\r\n\r\n// 仅默认导出(Rollup 会自动处理 UMD 全局变量)\r\nexport default xs3d;","/**\r\n * 坐标转换工具(对齐平台 屏幕/世界/地理坐标转换)\r\n */\r\nexport class CoordinateUtil {\r\n /**\r\n * 坐标转换核心方法\r\n * @param {Cesium.Viewer} viewer Cesium 实例\r\n * @param {Cesium.Cartesian3|Array<number>} coord 源坐标\r\n * @param {string} from 源类型(screen/world/scene)\r\n * @param {string} to 目标类型(screen/world/scene)\r\n * @returns {Cesium.Cartesian3|Cesium.Cartographic} 转换后坐标\r\n */\r\n static transform(viewer, coord, from, to) {\r\n // 统一坐标格式\r\n let sourceCoord = coord;\r\n if (Array.isArray(coord)) {\r\n if (from === 'scene') {\r\n // 地理坐标转世界坐标\r\n sourceCoord = Cesium.Cartesian3.fromDegrees(...coord);\r\n } else if (from === 'world') {\r\n sourceCoord = new Cesium.Cartesian3(coord[0], coord[1], coord[2]);\r\n } else if (from === 'screen') {\r\n // 屏幕坐标数组需先转为 Cartesian2\r\n sourceCoord = new Cesium.Cartesian2(coord[0], coord[1]);\r\n }\r\n }\r\n\r\n // 转换逻辑\r\n switch (`${from}_${to}`) {\r\n // 屏幕坐标 -> 世界坐标\r\n case 'screen_world':\r\n return viewer.camera.pickEllipsoid(sourceCoord);\r\n // 屏幕坐标 -> 地理坐标\r\n case 'screen_scene':\r\n const worldCoord = viewer.camera.pickEllipsoid(sourceCoord);\r\n const cartographic = Cesium.Cartographic.fromCartesian(worldCoord);\r\n return [\r\n Cesium.Math.toDegrees(cartographic.longitude),\r\n Cesium.Math.toDegrees(cartographic.latitude),\r\n cartographic.height\r\n ];\r\n // 世界坐标 -> 屏幕坐标\r\n case 'world_screen':\r\n return Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, sourceCoord);\r\n // 世界坐标 -> 地理坐标\r\n case 'world_scene':\r\n const carto = Cesium.Cartographic.fromCartesian(sourceCoord);\r\n return [\r\n Cesium.Math.toDegrees(carto.longitude),\r\n Cesium.Math.toDegrees(carto.latitude),\r\n carto.height\r\n ];\r\n // 地理坐标 -> 世界坐标(已在入参处理)\r\n case 'scene_world':\r\n return sourceCoord;\r\n // 地理坐标 -> 屏幕坐标\r\n case 'scene_screen':\r\n return Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, sourceCoord);\r\n default:\r\n return sourceCoord;\r\n }\r\n }\r\n}"],"names":["Config","static","getInstance","this","instance","constructor","config","cesiumToken","scene","animation","timeline","baseLayerPicker","fullscreenButton","geocoder","homeButton","infoBox","sceneModePicker","selectionIndicator","navigationHelpButton","navigationInstructionsInitiallyVisible","depthTestAgainstTerrain","getGraphicDefaults","Cesium","withAlpha","color","alpha","point","pixelSize","Color","RED","line","width","material","BLUE","polygon","GREEN","plot","outlineColor","outlineWidth","setConfig","options","k","Array","isArray","defaultsShallow","defaultsDeep","console","log","Ion","defaultAccessToken","getConfig","graphicDefaults","userGraphic","graphic","target","src","sv","tv","Object","prototype","hasOwnProperty","call","Promise","name","LayerType","freeze","XYZ","WMTS","WMS","TMS","SINGLE_IMAGE","TERRAIN","ImageryLayerWrapper","sceneModule","layer","layerId","_layer","_sceneModule","_layerId","_pickable","_eventEnabled","setVisible","visible","show","setAlpha","setBrightness","brightness","setContrast","contrast","setHue","hue","setSaturation","saturation","setGamma","gamma","enableEdit","enabled","enableEvent","imageryProvider","enablePickFeatures","getExtent","provider","rectangle","rect","west","Math","toDegrees","south","east","north","getRange","minLevel","minimumLevel","maxLevel","maximumLevel","getLayer","remove","removeLayer","TerrainLayerWrapper","_provider","_visible","getProvider","TilesetLayerWrapper","tileset","_tileset","setStyle","style","boundingSphere","bs","cartographic","Cartographic","fromCartesian","center","longitude","latitude","locateTo","viewer","zoomTo","getTileset","SceneModule","layerMap","Map","lonLatToWorld","lon","lat","height","Cartesian3","fromDegrees","worldToLonLat","cartesian","screenToWorld","x","y","screenPosition","Cartesian2","pickPositionSupported","precisePosition","pickPosition","ray","camera","getPickRay","globePosition","globe","pick","pickEllipsoid","Ellipsoid","WGS84","worldToScreen","cartesianToCanvasCoordinates","screenToLonLat","worldCoord","lonLatToScreen","lonLatToCartographic","toRadians","cartographicToLonLat","createLayer","url","type","u","toLowerCase","test","includes","autoDetectType","Date","now","has","warn","get","opts","UrlTemplateImageryProvider","WebMapTileServiceImageryProvider","format","tileMatrixSetID","WebMapServiceImageryProvider","layers","parameters","transparent","SingleTileImageryProvider","extent","Rectangle","undefined","credit","CesiumTerrainProvider","fromUrl","requestWaterMask","requestVertexNormals","Cesium3DTileset","maximumScreenSpaceError","maximumMemoryUsage","Error","values","join","createProviderByType","layerOrEntity","async","providerType","terrainProvider","primitives","add","imageryLayers","addImageryProvider","addProviderToViewer","wrapper","wrapLayer","autoLocate","removeListener","initialTilesLoaded","addEventListener","set","EllipsoidTerrainProvider","delete","flyToLonLat","params","heading","pitch","roll","duration","defined","flyTo","destination","orientation","resolve","setView","PlotGeometryUtil","mathDistance","p1","p2","sqrt","wholeDistance","points","distance","length","i","getBaseLength","mid","getAzimuth","startPoint","endPoint","angle","asin","abs","PI","getAngleOfThreePoints","pntA","pntB","pntC","isClockWise","pnt1","pnt2","pnt3","getThirdPoint","startPnt","endPnt","clockWise","azimuth","dx","cos","dy","sin","getArcPoints","radius","startAngle","endAngle","segments","angleDiff","push","_calcSphericalDistance","radPerDeg","lon1","lat1","lon2","lat2","dLat","dLon","a","atan2","_getBearing","from","to","standardBearing","_getPointAtBearingAndDistance","distanceMeters","angularDistance","bearing","_getGeoArcPointsBetween","radiusMeters","toLonLat","toPositions","map","p","_closePolygonPoints","result","prev","curr","first","last","toCartesian3Array","flat","fromDegreesArrayHeights","getPointOnLine","t","getCubicValue","cPnt1","cPnt2","tp","max","min","t2","t3","tp2","tp3","getBisectorNormals","normal","getNormal","dist","uX","uY","d1","d2","bisectorNormalRight","bisectorNormalLeft","ZERO_TOLERANCE","dt","dX1","dY1","dX2","dY2","getLeftMostControlPoint","controlPoints","normalRight","controlX","controlY","pX","pY","n","nX","nY","a11","a12","a22","dX","dY","getRightMostControlPoint","count","normalLeft","getCurvePoints","slice","normals","normalPoints","rightControl","j","FITTING_COUNT","pnt","getBezierPoints","bezierPoints","index","factor","getBinomialFactor","b","getFactorial","getQBSplinePoints","bSplinePoints","m","getQuadricBSplineFactor","createFineArrow","tailWidthFactor","neckWidthFactor","headWidthFactor","headAngle","neckAngle","len","tailWidth","neckWidth","headWidth","tailLeft","tailRight","headLeft","headRight","outlinePoints","createAssaultDirection","neckLeft","neckRight","createStraightArrow","arrowLengthScale","maxArrowLength","leftPnt","rightPnt","createTriangle","createSector","arcPoints","createEllipse","majorEnd","minorEnd","majorVec","minorVec","ellipsePoints","_getAttackArrowHeadPoints","headHeightFactor","neckHeightFactor","headTailFactor","headHeight","headPnt","len2","neckHeight","headEndPnt","neckEndPnt","_getAttackArrowBodyPoints","allLen","widthDif","tempLen","leftBodyPnts","rightBodyPnts","w","left","right","concat","_getSquadTailPoints","swallowTailFactor","createAttackArrow","lnglatPoints","bonePnts","headPnts","bodyPnts","leftPnts","rightPnts","reverse","createSwallowtailAttackArrow","swallowTailPnt","createSquadCombat","tailPnts","createSwallowtailSquadCombat","createDoubleArrow","tempPoint4","connPoint","_getDoubleArrowTempPoint4","leftArrowPnts","rightArrowPnts","_getDoubleArrowPoints","llBodyPnts","lArrowPnts","lrBodyPnts","rlBodyPnts","rArrowPnts","rrBodyPnts","linePnt1","linePnt2","midPnt","distance1","distance2","symPnt","midPnt1","midPnt2","arrowPnts","_getDoubleArrowHeadPoints","neckLeftPoint","neckRightPoint","lPoints","rPoints","createCurvedArrow","curvePoints","createCurve","PlotGraphicType","TRIANGLE","SECTOR","ELLIPSE","FINE_ARROW","ASSAULT_DIRECTION","ATTACK_ARROW","SWALLOWTAIL_ATTACK_ARROW","SQUAD_COMBAT","SWALLOWTAIL_SQUAD_COMBAT","DOUBLE_ARROW","STRAIGHT_ARROW","CURVED_ARROW","CURVE","PointWrapper","graphicModule","entity","_entity","_graphicModule","setPosition","coords","position","setColor","setPixelSize","size","setHeightReference","ref","heightReference","setDisableDepthTestDistance","disableDepthTestDistance","setOutlineColor","setOutlineWidth","setName","id","setNameVisible","label","LabelGraphics","setText","text","Number","POSITIVE_INFINITY","verticalOrigin","VerticalOrigin","BOTTOM","eyeOffset","HeightReference","RELATIVE_TO_GROUND","setFont","font","setTextColor","fillColor","setTextOutlineColor","setTextOutlineWidth","setAlignType","alignType","horizontalOrigins","HorizontalOrigin","CENTER","LEFT","RIGHT","verticalOrigins","TOP","horizontalOrigin","setTextPixelOffset","offset","pixelOffset","setTextScale","scale","removeGraphic","LineWrapper","setPositions","polyline","positions","flatMap","coord","setWidth","setMaterial","setClampToGround","clamp","clampToGround","setLabel","WHITE","BLACK","self","CallbackProperty","anchor","_computeLabelAnchor","_isPlotGraphic","_controlPoints","cps","z","forEach","cp","getValue","JulianDate","c","setPlotType","plotType","_plotType","JSON","parse","stringify","factoryName","_capitalizePlotType","setControlPoints","replace","g","toUpperCase","s","PolygonWrapper","hierarchy","PolygonHierarchy","ModelWrapper","setUrl","model","uri","setScale","setMinimumPixelSize","minimumPixelSize","TextWrapper","setPixelOffset","GraphicModule","graphicMap","wrapperMap","createPoint","graphicId","defaultStyle","entityOptions","entities","CreatePoint","createLine","CreateLine","createPolygon","CreatePolygon","createModel","CreateModel","createText","LabelStyle","FILL_AND_OUTLINE","CreateText","createPlotGraphic","isLine","isLinePlotType","_getPlotOptions","startAngleRad","endAngleRad","getGraphic","EventModule","observers","handlers","registerObserver","eventType","callback","observerId","random","toString","baseType","subType","split","createEventHandler","unregisterObserver","typeObservers","destroyEventHandler","unregisterAllObservers","keys","eventKey","handler","destroy","document","removeEventListener","clear","ScreenSpaceEventHandler","canvas","mouseEventType","getCesiumMouseEventType","setInputAction","movement","screenPos","endPosition","lngLat","e","pickedEntity","listener","postRender","changed","zoomLevel","getZoomLevel","ScreenSpaceEventType","LEFT_CLICK","RIGHT_CLICK","MOUSE_MOVE","LEFT_DOWN","LEFT_UP","positionCartographic","positionCartesian","fromRadians","floor","log2","BaseTool","editorModule","_editor","_viewer","_eventModule","eventModule","_options","_isActive","_handlers","activate","onActivate","deactivate","onDeactivate","clearHandlers","ellipsoid","getTerrainHeight","lonLat","sampleTerrainMostDetailed","createTempEntity","removeTempEntity","generateId","prefix","substr","DrawType","POINT","LINE","POLYGON","RECTANGLE","CIRCLE","PLOT_DRAW_CONFIG","category","minPoints","finishOnCount","finishOnDoubleClick","DrawTool","super","_drawType","drawType","_tempEntities","_tempPositions","_isDrawing","_startPos","_mouseMoveHandler","_clickCount","_previewLine","_previewPolygon","_previewRect","_previewCircle","_previewPlot","_currentMousePos","setDrawType","getDrawType","_onClick","bind","_onMove","_onRightClick","_onKeyDown","clearTempEntities","plotConfig","_handlePlotClick","_drawPoint","_handleLineClick","_handlePolygonClick","_handleRectangleClick","_handleCircleClick","data","_updatePlotPreview","_updateTempLine","_updateTempPolygon","_updateRectOrCirclePreview","key","cancelDrawing","_finishPlotDrawing","finishDrawing","pop","lastTemp","_updateTempPositions","_lngLat","_movement","_emitGraphicCreated","tempPoint","YELLOW","_emitDrawProgress","_finishRectangle","startMarker","_finishCircle","mousePos","previewPositions","flatCoords","cartesians","outline","currentLonLat","_updateRectPreview","_updateCirclePreview","corner1","corner2","c1","c2","pos","_isPreview","_calcDistance","r","_generateCirclePositions","NONE","edgeLonLat","positionsCount","_isCircle","_circleCenter","_circleRadius","metersPerLonDeg","coord1","coord2","d","_normalizeEllipseControlPoints","rawMinor","major","majorLen","hypot","perpUx","perpUy","mouseVec","projectedLen","isEllipse","normalizeForEllipse","pts","geometryPositions","dynamicPositions","cart","finalPositions","_emitDrawCancel","onGraphicCreated","onDrawProgress","onDrawCancel","EditMode","VERTEX","EditTool","_editMode","editMode","_selectedEntity","_selectedEntityId","_editHandles","_positionOutline","_polygonPreview","_isDragging","_dragHandle","_originalPositions","_handleVertexIndices","_rectangleOriginalPositions","_originalEnableInputs","_lastMoveTime","_originalCircleCenter","_originalCircleRadius","_originalEntityCenter","_radiusLine","setEditMode","mode","getEditMode","selectEntity","entityId","_selectEntity","_onMouseDown","_onMouseUp","_deselectEntity","picked","startsWith","clickedHandle","find","handle","_getEntityPositions","screenSpaceCameraController","enableRotate","enableTranslate","_data","_setCursorStyle","_emitEditComplete","cursor","MOVE_THROTTLE_MS","isOverHandle","_updateEntityPosition","_translatePlotControlPoints","newAnchorCartesian","oldAnchorCartesian","deltaX","deltaY","deltaZ","cpCart","newCpCart","newCpCarto","_getPlotControlPointsCenter","ConstantPositionProperty","_clampPositionToGround","match","cpIndex","parseInt","_createEditHandles","_highlightEntity","_emitSelect","_clearEditHandles","_createPlotControlHandles","_getEditablePositions","_createVertexHandles","_createCenterHandleForVertexMode","isSector","clampedPos","CLAMP_TO_GROUND","_createPlotPositionOutline","_createEllipseAxisLines","_createPlotCenterHandle","centerPoint","CYAN","skipOutlineTypes","Set","handles","value","closed","degrees","axisLine","_isRectangle","vertexIdx","handleIdx","circleInfo","_getCircleInfo","centerCartesian","radiusPoint","_getPointOnCircle","radiusCartesian","centerHandle","radiusHandle","_createCircleOutline","_createPositionOutline","_getEntityCenter","clampedCenter","_updateCenterHandlePosition","h","newCenter","isPolyline","CLOSE_POINT_TOLERANCE","_translateEntity","hasEntity","originalCenter","clampedNewCenter","actualNewCenter","newPositions","newPos","oldCenter","oldCenterCartesian","newCenterCartesian","newCenterCartographic","newCenterLon","newCenterLat","clone","relativeTolerance","xy","v0","v1","v2","v3","pow","d01","d12","d23","d30","d02","d13","oppositeSidesEqual","diagonalsEqual","angleRadians","_rotatePerpendicular","newAxis","oldAxis","newLen","oldLen","ux","uy","sign","radiusPos","_computeRectangleNewPositions","originalPositions","draggedIndex","oppositeIndex","newP","oppositePos","neighbor2","newLonLat","handleIndex","indexOf","newCartesian","handleId","handleMatch","oldCenterCart","newRadius","otherIndex","otherCp","otherBearing","newOtherPoint","newMajor","oldMinor","newMinor","draggedVertexIndex","clampedPositions","newCenterLonLat","filter","highlight","getSelectedEntityId","getOriginalPositions","undo","positionsCopy","onSelect","onEditComplete","SelectType","SelectTool","_selectType","selectType","_isSelecting","_selectedIds","_selectionRect","_originalStyles","setSelectType","getSelectType","_cancelSelection","_clearSelectionRect","_createSelectionStartMarker","_finishSelection","_isSelected","_deselect","_select","_clearAllSelections","_updateSelectionRectPreview","insideIds","_getEntitiesInRectangle","_highlightEntitiesInSelection","_getEntitiesInCircle","marker","currentPos","_getRectPositions","endPos","selectedIds","_emitSelectionComplete","emitEvent","_emitSelectionChange","styleKey","original","entityIds","_getOriginalColor","minLon","maxLon","minLat","maxLat","allIds","_getAllGraphicIds","_filterEntitiesInBounds","edge","entityPos","_getEntityPosition","ids","allInBounds","getSelectedIds","onSelectionChange","onSelectionComplete","DeleteMode","SINGLE","SELECTED","DeleteTool","_deleteMode","deleteMode","_hoveredEntity","_hoverEntity","setDeleteMode","getDeleteMode","_clearHoverHighlight","_deleteSingle","hoveredId","_highlightAsDeletable","_emitBeforeDelete","_emitDelete","deleteMultiple","deleted","failed","_emitDeleteMultiple","deleteAll","container","onBeforeDelete","onDelete","onDeleteMultiple","ToolName","DRAW","EDIT","SELECT","DELETE","EditorModule","toolMap","currentTool","currentToolName","setDependencies","deps","init","registerTool","tool","getTool","getCurrentTool","getCurrentToolName","activateTool","deactivateTool","activateDrawTool","drawTool","activateSelectTool","selectTool","activateEditTool","editTool","activateDeleteTool","deleteTool","getDrawTool","getSelectTool","getEditTool","getDeleteTool","onDrawComplete","onEditSelect","deleteSelected","isActive","ModuleManager","modules","cesiumViewer","initViewer","Viewer","creditContainer","cesiumWidget","display","registerModule","getModule","moduleName","moduleInstance","reset","GeoCalcUtil","calcDistance","point1","point2","calcArea","PolygonGeometry","polygonHierarchy","geometry","createGeometry","attributes","vertexPositions","area","sphericalPolygonArea","normalize","scaleToGeodeticSurface","tangentPlane","EllipsoidTangentPlane","projected","projectPointOntoPlane","area2","getHeight","results","window","moduleManager","CoordinateUtil","transform","sourceCoord","SceneTransforms","wgs84ToWindowCoordinates","carto"],"mappings":"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"}
|