cesium-xs-sdk 1.0.19 → 1.0.20
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/dist/cesium-xs-sdk.cjs.js +322 -248
- package/dist/cesium-xs-sdk.cjs.js.map +1 -1
- package/dist/cesium-xs-sdk.esm.js +322 -248
- package/dist/cesium-xs-sdk.esm.js.map +1 -1
- package/dist/cesium-xs-sdk.umd.js +1 -1
- package/dist/cesium-xs-sdk.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/core/LabelDepthConfig.js +15 -0
- package/src/index.d.ts +12 -0
- package/src/index.js +2 -0
- package/src/modules/GraphicModule.js +4 -3
- package/src/modules/tools/BaseTool.js +34 -6
- package/src/modules/tools/DeleteTool.js +8 -7
- package/src/modules/tools/DrawTool.js +129 -174
- package/src/modules/tools/EditTool.js +90 -34
- package/src/modules/tools/MeasureTool.js +46 -21
- package/src/modules/tools/SelectTool.js +4 -3
- package/dist/assets/point-marker.png +0 -0
|
@@ -2050,6 +2050,22 @@ function isLinePlotType(plotType) {
|
|
|
2050
2050
|
].includes(plotType);
|
|
2051
2051
|
}
|
|
2052
2052
|
|
|
2053
|
+
/**
|
|
2054
|
+
* 控制 SDK 内 LabelGraphics / BillboardGraphics / PointPrimitive 的
|
|
2055
|
+
* disableDepthTestDistance 默认值。
|
|
2056
|
+
*
|
|
2057
|
+
* 语义:相机距离图元小于等于 distance(米)时不进行深度测试,
|
|
2058
|
+
* 即近处观察时图元始终绘制在前景,避免被地形/建筑局部遮挡;
|
|
2059
|
+
* 大于 distance 时恢复正常深度测试,避免地球背面透视。
|
|
2060
|
+
*
|
|
2061
|
+
* 默认 8000 米;可在运行时改写:
|
|
2062
|
+
* import { LabelDepthConfig } from 'cesium-xs-sdk'
|
|
2063
|
+
* LabelDepthConfig.distance = 4000
|
|
2064
|
+
*/
|
|
2065
|
+
const LabelDepthConfig = {
|
|
2066
|
+
distance: 8000,
|
|
2067
|
+
};
|
|
2068
|
+
|
|
2053
2069
|
const Cesium$f = getCesium();
|
|
2054
2070
|
|
|
2055
2071
|
/**
|
|
@@ -2087,7 +2103,7 @@ class PointWrapper {
|
|
|
2087
2103
|
}
|
|
2088
2104
|
|
|
2089
2105
|
setDisableDepthTestDistance(distance) {
|
|
2090
|
-
this._entity.point.disableDepthTestDistance = distance;
|
|
2106
|
+
this._entity.point.disableDepthTestDistance = LabelDepthConfig.distance;
|
|
2091
2107
|
return this;
|
|
2092
2108
|
}
|
|
2093
2109
|
|
|
@@ -2123,7 +2139,7 @@ class PointWrapper {
|
|
|
2123
2139
|
this._entity.label.text = text;
|
|
2124
2140
|
|
|
2125
2141
|
// 应用配置选项
|
|
2126
|
-
this._entity.label.disableDepthTestDistance = options.disableDepthTestDistance ??
|
|
2142
|
+
this._entity.label.disableDepthTestDistance = options.disableDepthTestDistance ?? LabelDepthConfig.distance;
|
|
2127
2143
|
this._entity.label.verticalOrigin = options.verticalOrigin ?? Cesium$f.VerticalOrigin.BOTTOM;
|
|
2128
2144
|
this._entity.label.eyeOffset = options.eyeOffset ?? new Cesium$f.Cartesian3(0, 0, -10);
|
|
2129
2145
|
this._entity.label.heightReference = options.heightReference ?? Cesium$f.HeightReference.RELATIVE_TO_GROUND;
|
|
@@ -2712,7 +2728,7 @@ class BillboardWrapper {
|
|
|
2712
2728
|
}
|
|
2713
2729
|
|
|
2714
2730
|
setDisableDepthTestDistance(distance) {
|
|
2715
|
-
this._entity.billboard.disableDepthTestDistance = distance;
|
|
2731
|
+
this._entity.billboard.disableDepthTestDistance = LabelDepthConfig.distance;
|
|
2716
2732
|
return this;
|
|
2717
2733
|
}
|
|
2718
2734
|
|
|
@@ -3653,6 +3669,9 @@ class BaseTool {
|
|
|
3653
3669
|
this._handlers = []; // 注册的事件处理器 ID
|
|
3654
3670
|
// 自维护双击判定器(DOM dblclick 在移动端经常不合成,见 DoubleClickDetector 注释)
|
|
3655
3671
|
this._doubleClickDetector = new DoubleClickDetector();
|
|
3672
|
+
// mousemove rAF 节流状态:多次 move 之间只保留最新一次,与 render 帧同步
|
|
3673
|
+
this._moveRafId = null;
|
|
3674
|
+
this._movePendingCb = null;
|
|
3656
3675
|
}
|
|
3657
3676
|
|
|
3658
3677
|
/**
|
|
@@ -3673,6 +3692,12 @@ class BaseTool {
|
|
|
3673
3692
|
if (!this._isActive) return;
|
|
3674
3693
|
this._isActive = false;
|
|
3675
3694
|
this._doubleClickDetector.reset();
|
|
3695
|
+
// 取消 pending 的 mousemove rAF,避免停用后仍执行预览逻辑
|
|
3696
|
+
if (this._moveRafId != null) {
|
|
3697
|
+
cancelAnimationFrame(this._moveRafId);
|
|
3698
|
+
this._moveRafId = null;
|
|
3699
|
+
this._movePendingCb = null;
|
|
3700
|
+
}
|
|
3676
3701
|
this.onDeactivate();
|
|
3677
3702
|
this.clearHandlers();
|
|
3678
3703
|
}
|
|
@@ -3708,17 +3733,36 @@ class BaseTool {
|
|
|
3708
3733
|
*/
|
|
3709
3734
|
registerObserver(eventType, callback) {
|
|
3710
3735
|
const observerId = this._eventModule.registerObserver(eventType, (lngLat, entity, movement) => {
|
|
3711
|
-
// mouse:move
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
} else {
|
|
3715
|
-
callback(lngLat, entity, movement);
|
|
3716
|
-
}
|
|
3736
|
+
// 统一转发:mouse:move 也带上 EventModule 已计算的 lngLat / pickedEntity,
|
|
3737
|
+
// 避免工具层再调 scene.pickPosition / scene.pick 造成 2× 调用。
|
|
3738
|
+
callback(lngLat, entity, movement);
|
|
3717
3739
|
});
|
|
3718
3740
|
this._handlers.push({ eventType, observerId });
|
|
3719
3741
|
return observerId;
|
|
3720
3742
|
}
|
|
3721
3743
|
|
|
3744
|
+
/**
|
|
3745
|
+
* 将高频 mousemove 处理合并到下一帧:多次调用之间只保留最新一次的回调,
|
|
3746
|
+
* 与 Cesium render 帧对齐(~60Hz),避免全球视角下 pickPosition / CallbackProperty
|
|
3747
|
+
* 在 100+ Hz 浏览器原生频率下成为热点。
|
|
3748
|
+
*
|
|
3749
|
+
* 使用方式(仅对"非交互关键 + 计算密集"的预览路径):
|
|
3750
|
+
* this._scheduleMoveWork(() => this._updatePreview(this._mousePos));
|
|
3751
|
+
*
|
|
3752
|
+
* 注意:callback 应在闭包里读取 this 上的最新字段(_currentMousePos 等),
|
|
3753
|
+
* 不要传参;参数会被合并掉的多次调用的中间值覆盖。
|
|
3754
|
+
*/
|
|
3755
|
+
_scheduleMoveWork(callback) {
|
|
3756
|
+
this._movePendingCb = callback;
|
|
3757
|
+
if (this._moveRafId != null) return;
|
|
3758
|
+
this._moveRafId = requestAnimationFrame(() => {
|
|
3759
|
+
const cb = this._movePendingCb;
|
|
3760
|
+
this._moveRafId = null;
|
|
3761
|
+
this._movePendingCb = null;
|
|
3762
|
+
if (cb) cb();
|
|
3763
|
+
});
|
|
3764
|
+
}
|
|
3765
|
+
|
|
3722
3766
|
/**
|
|
3723
3767
|
* 清除所有已注册的事件处理器
|
|
3724
3768
|
*/
|
|
@@ -4077,39 +4121,66 @@ class DrawTool extends BaseTool {
|
|
|
4077
4121
|
}
|
|
4078
4122
|
}
|
|
4079
4123
|
|
|
4080
|
-
_onMove(
|
|
4081
|
-
|
|
4082
|
-
const screenPos = data.position || data.endPosition;
|
|
4124
|
+
_onMove(lngLat, entity, movement) {
|
|
4125
|
+
const screenPos = movement.position || movement.endPosition;
|
|
4083
4126
|
if (!screenPos) return;
|
|
4084
|
-
|
|
4127
|
+
// 优先使用 EventModule 已计算的 lngLat(避免重复 scene.pickPosition);
|
|
4128
|
+
// 拾取失败(如鼠标移到地球外)时回退到 screenToLonLat。
|
|
4129
|
+
const lonLat = lngLat || this.screenToLonLat({ x: screenPos.x, y: screenPos.y });
|
|
4085
4130
|
if (!lonLat) return;
|
|
4086
4131
|
|
|
4087
4132
|
this._currentMousePos = lonLat;
|
|
4088
4133
|
|
|
4089
4134
|
if (this._drawType === DrawType.POINT) return;
|
|
4090
4135
|
|
|
4136
|
+
// 预览几何更新是计算密集路径(CallbackProperty / 经纬度→ECEF / 标绘算法),
|
|
4137
|
+
// 在全球视角下每帧都跑成本高,合并到下一帧(~60Hz),丢弃中间 move 事件。
|
|
4138
|
+
this._scheduleMoveWork(() => this._applyPreviewUpdate());
|
|
4139
|
+
|
|
4140
|
+
// 鼠标光标类反馈保持同步(每次 mousemove 都要响应,不走 rAF 合并)
|
|
4141
|
+
if (
|
|
4142
|
+
(this._drawType === DrawType.LINE || this._drawType === DrawType.POLYGON) &&
|
|
4143
|
+
this._isDrawing
|
|
4144
|
+
) {
|
|
4145
|
+
this._updatePreviewCursor();
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
|
|
4149
|
+
/**
|
|
4150
|
+
* 真正执行预览更新:由 _scheduleMoveWork 在下一帧调用一次,读取
|
|
4151
|
+
* this._currentMousePos / _startPos / _tempPositions 等最新字段。
|
|
4152
|
+
*/
|
|
4153
|
+
_applyPreviewUpdate() {
|
|
4154
|
+
const lonLat = this._currentMousePos;
|
|
4155
|
+
if (!lonLat) return;
|
|
4156
|
+
|
|
4091
4157
|
// 标绘类型预览
|
|
4092
4158
|
const plotConfig = PLOT_DRAW_CONFIG[this._drawType];
|
|
4093
4159
|
if (plotConfig) {
|
|
4094
4160
|
if (this._isDrawing && this._tempPositions.length >= plotConfig.minPoints - 1) {
|
|
4095
|
-
this._updatePlotPreview(plotConfig
|
|
4161
|
+
this._updatePlotPreview(plotConfig);
|
|
4096
4162
|
}
|
|
4097
4163
|
return;
|
|
4098
4164
|
}
|
|
4099
4165
|
|
|
4100
4166
|
if (this._isDrawing) {
|
|
4101
4167
|
if (this._drawType === DrawType.LINE) {
|
|
4102
|
-
this._updateTempLine(
|
|
4168
|
+
this._updateTempLine();
|
|
4103
4169
|
} else if (this._drawType === DrawType.POLYGON) {
|
|
4104
|
-
this._updateTempPolygon(
|
|
4170
|
+
this._updateTempPolygon();
|
|
4105
4171
|
}
|
|
4106
4172
|
}
|
|
4107
4173
|
|
|
4108
4174
|
if (this._startPos) {
|
|
4109
|
-
this._updateRectOrCirclePreview(
|
|
4175
|
+
this._updateRectOrCirclePreview();
|
|
4110
4176
|
}
|
|
4111
4177
|
}
|
|
4112
4178
|
|
|
4179
|
+
_updatePreviewCursor() {
|
|
4180
|
+
// 简化占位:原 _onMove 中没有显式 cursor 处理,保留 hook 以备后用。
|
|
4181
|
+
// 真正的鼠标光标样式由 _onMove 主流程维护,这里无副作用。
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4113
4184
|
_onKeyDown(data) {
|
|
4114
4185
|
// ESC 取消绘制
|
|
4115
4186
|
if (data.key === 'Escape') {
|
|
@@ -4256,7 +4327,7 @@ class DrawTool extends BaseTool {
|
|
|
4256
4327
|
.setScale(0.5)
|
|
4257
4328
|
.setVerticalOrigin(Cesium$c.VerticalOrigin.BOTTOM)
|
|
4258
4329
|
.setHeightReference(Cesium$c.HeightReference.CLAMP_TO_GROUND)
|
|
4259
|
-
.setDisableDepthTestDistance(
|
|
4330
|
+
.setDisableDepthTestDistance(LabelDepthConfig.distance);
|
|
4260
4331
|
|
|
4261
4332
|
// 选择图片来源:自定义 URL 优先,否则使用 SDK 内置 base64 图标
|
|
4262
4333
|
const imageSource = (typeof imgUrl === 'string' && imgUrl.trim() !== '')
|
|
@@ -4365,25 +4436,23 @@ class DrawTool extends BaseTool {
|
|
|
4365
4436
|
}
|
|
4366
4437
|
}
|
|
4367
4438
|
|
|
4368
|
-
_updateTempLine(
|
|
4369
|
-
//
|
|
4370
|
-
|
|
4371
|
-
if (mousePos) {
|
|
4372
|
-
previewPositions.push(mousePos);
|
|
4373
|
-
}
|
|
4374
|
-
|
|
4375
|
-
// 计算 Cartesian3 数组
|
|
4376
|
-
const flatCoords = [];
|
|
4377
|
-
for (const c of previewPositions) {
|
|
4378
|
-
flatCoords.push(c[0], c[1], c[2] || 0);
|
|
4379
|
-
}
|
|
4380
|
-
const cartesians = Cesium$c.Cartesian3.fromDegreesArrayHeights(flatCoords);
|
|
4381
|
-
|
|
4439
|
+
_updateTempLine() {
|
|
4440
|
+
// 第一次创建时建立稳定的 CallbackProperty,回调内部读 this._tempPositions +
|
|
4441
|
+
// this._currentMousePos(与 _updateTempPolygon 同模式),避免每次 move 都重建。
|
|
4382
4442
|
if (!this._previewLine) {
|
|
4383
4443
|
// 首次创建预览线(黑白相间的斑马纹路)
|
|
4384
4444
|
this._previewLine = this.createTempEntity(this.generateId('temp_line'), {
|
|
4385
4445
|
polyline: {
|
|
4386
|
-
positions:
|
|
4446
|
+
positions: new Cesium$c.CallbackProperty(() => {
|
|
4447
|
+
const previewPositions = [...this._tempPositions];
|
|
4448
|
+
if (this._currentMousePos) previewPositions.push(this._currentMousePos);
|
|
4449
|
+
if (previewPositions.length < 2) return [];
|
|
4450
|
+
const flatCoords = [];
|
|
4451
|
+
for (const c of previewPositions) {
|
|
4452
|
+
flatCoords.push(c[0], c[1], c[2] || 0);
|
|
4453
|
+
}
|
|
4454
|
+
return Cesium$c.Cartesian3.fromDegreesArrayHeights(flatCoords);
|
|
4455
|
+
}, false),
|
|
4387
4456
|
material: new Cesium$c.PolylineDashMaterialProperty({
|
|
4388
4457
|
color: Cesium$c.Color.WHITE,
|
|
4389
4458
|
gapColor: Cesium$c.Color.BLACK,
|
|
@@ -4394,12 +4463,6 @@ class DrawTool extends BaseTool {
|
|
|
4394
4463
|
}
|
|
4395
4464
|
});
|
|
4396
4465
|
this._tempEntities.push(this._previewLine);
|
|
4397
|
-
} else {
|
|
4398
|
-
// 直接更新位置属性,避免重建实体
|
|
4399
|
-
// this._previewLine.polyline.positions = cartesians;
|
|
4400
|
-
this._previewLine.polyline.positions = new Cesium$c.CallbackProperty(() => {
|
|
4401
|
-
return cartesians;
|
|
4402
|
-
}, false);
|
|
4403
4466
|
}
|
|
4404
4467
|
}
|
|
4405
4468
|
|
|
@@ -4447,116 +4510,87 @@ class DrawTool extends BaseTool {
|
|
|
4447
4510
|
}
|
|
4448
4511
|
}
|
|
4449
4512
|
|
|
4450
|
-
_updateRectOrCirclePreview(
|
|
4513
|
+
_updateRectOrCirclePreview() {
|
|
4451
4514
|
if (!this._startPos) return;
|
|
4452
4515
|
|
|
4453
4516
|
if (this._drawType === DrawType.RECTANGLE) {
|
|
4454
|
-
this._updateRectPreview(
|
|
4517
|
+
this._updateRectPreview();
|
|
4455
4518
|
} else if (this._drawType === DrawType.CIRCLE) {
|
|
4456
|
-
this._updateCirclePreview(
|
|
4519
|
+
this._updateCirclePreview();
|
|
4457
4520
|
}
|
|
4458
4521
|
}
|
|
4459
4522
|
|
|
4460
|
-
_updateRectPreview(
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
// 计算矩形四个角
|
|
4465
|
-
const positions = [
|
|
4466
|
-
[corner1[0], corner1[1]],
|
|
4467
|
-
[corner2[0], corner1[1]],
|
|
4468
|
-
[corner2[0], corner2[1]],
|
|
4469
|
-
[corner1[0], corner2[1]],
|
|
4470
|
-
[corner1[0], corner1[1]]
|
|
4471
|
-
];
|
|
4472
|
-
|
|
4473
|
-
const flatCoords = [];
|
|
4474
|
-
for (const c of positions) {
|
|
4475
|
-
flatCoords.push(c[0], c[1], 0);
|
|
4476
|
-
}
|
|
4477
|
-
const cartesians = Cesium$c.Cartesian3.fromDegreesArrayHeights(flatCoords);
|
|
4478
|
-
|
|
4523
|
+
_updateRectPreview() {
|
|
4524
|
+
// 第一次创建时建立稳定的 CallbackProperty,回调内部读 this._startPos / _currentMousePos,
|
|
4525
|
+
// 避免每个 mousemove 都 new CallbackProperty + 重绑几何(参见 polygon preview 同模式)。
|
|
4479
4526
|
if (!this._previewRect) {
|
|
4527
|
+
const polylinePositions = new Cesium$c.CallbackProperty(() => this._computeRectCornersFlat(2), false);
|
|
4528
|
+
const polygonHierarchy = new Cesium$c.CallbackProperty(() => {
|
|
4529
|
+
const cartesians = this._computeRectCornersFlat(2);
|
|
4530
|
+
return new Cesium$c.PolygonHierarchy(cartesians);
|
|
4531
|
+
}, false);
|
|
4480
4532
|
this._previewRect = this.createTempEntity(this.generateId('temp_rect'), {
|
|
4481
4533
|
polyline: {
|
|
4482
|
-
positions:
|
|
4534
|
+
positions: polylinePositions,
|
|
4483
4535
|
material: Cesium$c.Color.YELLOW.withAlpha(0.7),
|
|
4484
4536
|
width: 2
|
|
4485
4537
|
},
|
|
4486
4538
|
polygon: {
|
|
4487
|
-
hierarchy:
|
|
4539
|
+
hierarchy: polygonHierarchy,
|
|
4488
4540
|
material: Cesium$c.Color.YELLOW.withAlpha(0.2),
|
|
4489
4541
|
outline: false
|
|
4490
4542
|
}
|
|
4491
4543
|
});
|
|
4492
4544
|
this._previewRect._isPreview = true;
|
|
4493
4545
|
this._tempEntities.push(this._previewRect);
|
|
4494
|
-
} else {
|
|
4495
|
-
// 直接更新位置属性
|
|
4496
|
-
this._previewRect.polyline.positions = new Cesium$c.CallbackProperty(() => {
|
|
4497
|
-
const c1 = this._startPos;
|
|
4498
|
-
const c2 = this._currentMousePos;
|
|
4499
|
-
if (!c1 || !c2) return cartesians;
|
|
4500
|
-
const pos = [
|
|
4501
|
-
[c1[0], c1[1]],
|
|
4502
|
-
[c2[0], c1[1]],
|
|
4503
|
-
[c2[0], c2[1]],
|
|
4504
|
-
[c1[0], c2[1]],
|
|
4505
|
-
[c1[0], c1[1]]
|
|
4506
|
-
];
|
|
4507
|
-
const flat = [];
|
|
4508
|
-
for (const p of pos) {
|
|
4509
|
-
flat.push(p[0], p[1], 0);
|
|
4510
|
-
}
|
|
4511
|
-
return Cesium$c.Cartesian3.fromDegreesArrayHeights(flat);
|
|
4512
|
-
}, false);
|
|
4513
|
-
this._previewRect.polygon.hierarchy = new Cesium$c.CallbackProperty(() => {
|
|
4514
|
-
const c1 = this._startPos;
|
|
4515
|
-
const c2 = this._currentMousePos;
|
|
4516
|
-
if (!c1 || !c2) return new Cesium$c.PolygonHierarchy(cartesians);
|
|
4517
|
-
const pos = [
|
|
4518
|
-
[c1[0], c1[1]],
|
|
4519
|
-
[c2[0], c1[1]],
|
|
4520
|
-
[c2[0], c2[1]],
|
|
4521
|
-
[c1[0], c2[1]],
|
|
4522
|
-
[c1[0], c1[1]]
|
|
4523
|
-
];
|
|
4524
|
-
const flat = [];
|
|
4525
|
-
for (const p of pos) {
|
|
4526
|
-
flat.push(p[0], p[1], 0);
|
|
4527
|
-
}
|
|
4528
|
-
return new Cesium$c.PolygonHierarchy(Cesium$c.Cartesian3.fromDegreesArrayHeights(flat));
|
|
4529
|
-
}, false);
|
|
4530
4546
|
}
|
|
4531
4547
|
}
|
|
4532
4548
|
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4549
|
+
/**
|
|
4550
|
+
* 计算矩形四个角点的 Cartesian3[](含起末闭合点):
|
|
4551
|
+
* [start, (currLon, startLat), curr, (startLon, currLat), start]
|
|
4552
|
+
* 返回数组便于 polyline 与 polygon 共用;调用方负责包装 PolygonHierarchy。
|
|
4553
|
+
*/
|
|
4554
|
+
_computeRectCornersFlat() {
|
|
4555
|
+
const c1 = this._startPos;
|
|
4556
|
+
const c2 = this._currentMousePos;
|
|
4557
|
+
if (!c1 || !c2) {
|
|
4558
|
+
return [Cesium$c.Cartesian3.fromDegrees(0, 0, 0)];
|
|
4559
|
+
}
|
|
4560
|
+
const flat = [
|
|
4561
|
+
c1[0], c1[1], 0,
|
|
4562
|
+
c2[0], c1[1], 0,
|
|
4563
|
+
c2[0], c2[1], 0,
|
|
4564
|
+
c1[0], c2[1], 0,
|
|
4565
|
+
c1[0], c1[1], 0
|
|
4566
|
+
];
|
|
4567
|
+
return Cesium$c.Cartesian3.fromDegreesArrayHeights(flat);
|
|
4568
|
+
}
|
|
4537
4569
|
|
|
4570
|
+
_updateCirclePreview() {
|
|
4571
|
+
// 第一次创建时建立稳定的 CallbackProperty,回调内部读 this._startPos / _currentMousePos,
|
|
4572
|
+
// 避免每个 mousemove 都 new CallbackProperty 并重建几何。
|
|
4573
|
+
const segments = 64;
|
|
4538
4574
|
if (!this._previewCircle) {
|
|
4575
|
+
const hierarchy = new Cesium$c.CallbackProperty(() => {
|
|
4576
|
+
const center = this._startPos;
|
|
4577
|
+
const r = this._calcDistance(center, this._currentMousePos);
|
|
4578
|
+
if (!center || !this._currentMousePos) {
|
|
4579
|
+
return new Cesium$c.PolygonHierarchy([]);
|
|
4580
|
+
}
|
|
4581
|
+
const pos = this._generateCirclePositions(center, r, segments);
|
|
4582
|
+
const flat = pos.flatMap(c => [c[0], c[1], 0]);
|
|
4583
|
+
return new Cesium$c.PolygonHierarchy(Cesium$c.Cartesian3.fromDegreesArrayHeights(flat));
|
|
4584
|
+
}, false);
|
|
4539
4585
|
this._previewCircle = this.createTempEntity(this.generateId('temp_circle'), {
|
|
4540
4586
|
polygon: {
|
|
4541
|
-
hierarchy
|
|
4542
|
-
const positions = this._generateCirclePositions(center, radius, segments);
|
|
4543
|
-
const flat = positions.flatMap(c => [c[0], c[1], 0]);
|
|
4544
|
-
return new Cesium$c.PolygonHierarchy(Cesium$c.Cartesian3.fromDegreesArrayHeights(flat));
|
|
4545
|
-
}, false),
|
|
4587
|
+
hierarchy,
|
|
4546
4588
|
material: Cesium$c.Color.YELLOW.withAlpha(0.2),
|
|
4547
4589
|
outline: false // 地形贴合时不支持 outline,设为 false 避免警告
|
|
4548
4590
|
}
|
|
4549
4591
|
});
|
|
4550
4592
|
this._previewCircle._isPreview = true;
|
|
4551
4593
|
this._tempEntities.push(this._previewCircle);
|
|
4552
|
-
} else {
|
|
4553
|
-
// 直接更新
|
|
4554
|
-
this._previewCircle.polygon.hierarchy = new Cesium$c.CallbackProperty(() => {
|
|
4555
|
-
const r = this._calcDistance(this._startPos, this._currentMousePos);
|
|
4556
|
-
const pos = this._generateCirclePositions(this._startPos, r, 64);
|
|
4557
|
-
const flat = pos.flatMap(c => [c[0], c[1], 0]);
|
|
4558
|
-
return new Cesium$c.PolygonHierarchy(Cesium$c.Cartesian3.fromDegreesArrayHeights(flat));
|
|
4559
|
-
}, false);
|
|
4560
4594
|
}
|
|
4561
4595
|
}
|
|
4562
4596
|
|
|
@@ -4724,37 +4758,39 @@ class DrawTool extends BaseTool {
|
|
|
4724
4758
|
* @param {object} config 标绘配置
|
|
4725
4759
|
* @param {Array} mousePos 当前鼠标位置 [lon, lat, height]
|
|
4726
4760
|
*/
|
|
4727
|
-
_updatePlotPreview(config
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
if (mousePos) {
|
|
4733
|
-
previewPositions.push(mousePos);
|
|
4734
|
-
}
|
|
4735
|
-
|
|
4736
|
-
if (previewPositions.length < config.minPoints) return;
|
|
4737
|
-
|
|
4761
|
+
_updatePlotPreview(config) {
|
|
4762
|
+
// 标绘预览整体思路:
|
|
4763
|
+
// 第一次调用时建立稳定的 CallbackProperty,回调内部读取 this._tempPositions +
|
|
4764
|
+
// this._currentMousePos 重新生成几何。这样 mouve 之间的预览更新只是一帧一次的
|
|
4765
|
+
// 几何重算,没有 CallbackProperty 重建开销。
|
|
4738
4766
|
const factoryName = `create${this._capitalizePlotType(config.plotType)}`;
|
|
4739
4767
|
if (!PlotGeometryUtil[factoryName]) {
|
|
4740
4768
|
console.warn(`未知标绘类型: ${config.plotType}`);
|
|
4741
4769
|
return;
|
|
4742
4770
|
}
|
|
4743
|
-
|
|
4744
|
-
const
|
|
4745
|
-
const positions = PlotGeometryUtil[factoryName](geometryPositions);
|
|
4771
|
+
const isEllipse = config.plotType === PlotGraphicType.ELLIPSE;
|
|
4772
|
+
const normalizeForEllipse = (pts) => isEllipse ? this._normalizeEllipseControlPoints(pts) : pts;
|
|
4746
4773
|
const isLine = config.category === 'line';
|
|
4747
|
-
const
|
|
4748
|
-
for (const c of positions) {
|
|
4749
|
-
flatCoords.push(c[0], c[1], c[2] || 0);
|
|
4750
|
-
}
|
|
4751
|
-
const cartesians = Cesium$c.Cartesian3.fromDegreesArrayHeights(flatCoords);
|
|
4774
|
+
const minPoints = config.minPoints;
|
|
4752
4775
|
|
|
4753
4776
|
if (!this._previewPlot) {
|
|
4777
|
+
// 标绘预览几何工厂:把"读 this._tempPositions + this._currentMousePos 并生成
|
|
4778
|
+
// 标绘几何"的逻辑抽到一个内部方法,由稳定的 CallbackProperty 在每帧调用。
|
|
4779
|
+
// 避免每次 mousemove 都重建 CallbackProperty + 重新计算整个几何。
|
|
4780
|
+
const computePlotGeometry = () => {
|
|
4781
|
+
const dynamicPositions = [...this._tempPositions];
|
|
4782
|
+
if (this._currentMousePos) dynamicPositions.push(this._currentMousePos);
|
|
4783
|
+
if (dynamicPositions.length < minPoints) return null;
|
|
4784
|
+
const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));
|
|
4785
|
+
const flat = [];
|
|
4786
|
+
for (const c of pos) flat.push(c[0], c[1], c[2] || 0);
|
|
4787
|
+
return Cesium$c.Cartesian3.fromDegreesArrayHeights(flat);
|
|
4788
|
+
};
|
|
4789
|
+
|
|
4754
4790
|
if (isLine) {
|
|
4755
4791
|
this._previewPlot = this.createTempEntity(this.generateId('temp_plot'), {
|
|
4756
4792
|
polyline: {
|
|
4757
|
-
positions: new Cesium$c.CallbackProperty(() =>
|
|
4793
|
+
positions: new Cesium$c.CallbackProperty(() => computePlotGeometry() || [], false),
|
|
4758
4794
|
material: Cesium$c.Color.YELLOW,
|
|
4759
4795
|
width: 2,
|
|
4760
4796
|
clampToGround: true
|
|
@@ -4763,12 +4799,19 @@ class DrawTool extends BaseTool {
|
|
|
4763
4799
|
} else {
|
|
4764
4800
|
this._previewPlot = this.createTempEntity(this.generateId('temp_plot'), {
|
|
4765
4801
|
polygon: {
|
|
4766
|
-
hierarchy: new Cesium$c.CallbackProperty(() =>
|
|
4802
|
+
hierarchy: new Cesium$c.CallbackProperty(() => {
|
|
4803
|
+
const c = computePlotGeometry();
|
|
4804
|
+
return new Cesium$c.PolygonHierarchy(c || []);
|
|
4805
|
+
}, false),
|
|
4767
4806
|
material: Cesium$c.Color.YELLOW.withAlpha(0.3),
|
|
4768
4807
|
outline: false
|
|
4769
4808
|
},
|
|
4770
4809
|
polyline: {
|
|
4771
|
-
positions: new Cesium$c.CallbackProperty(() =>
|
|
4810
|
+
positions: new Cesium$c.CallbackProperty(() => {
|
|
4811
|
+
const c = computePlotGeometry();
|
|
4812
|
+
if (!c || c.length === 0) return [];
|
|
4813
|
+
return [...c, c[0]];
|
|
4814
|
+
}, false),
|
|
4772
4815
|
material: Cesium$c.Color.YELLOW,
|
|
4773
4816
|
width: 1
|
|
4774
4817
|
}
|
|
@@ -4776,51 +4819,6 @@ class DrawTool extends BaseTool {
|
|
|
4776
4819
|
}
|
|
4777
4820
|
this._previewPlot._isPreview = true;
|
|
4778
4821
|
this._tempEntities.push(this._previewPlot);
|
|
4779
|
-
} else {
|
|
4780
|
-
const self = this;
|
|
4781
|
-
if (isLine) {
|
|
4782
|
-
this._previewPlot.polyline.positions = new Cesium$c.CallbackProperty(() => {
|
|
4783
|
-
const dynamicPositions = [...self._tempPositions];
|
|
4784
|
-
if (self._currentMousePos) {
|
|
4785
|
-
dynamicPositions.push(self._currentMousePos);
|
|
4786
|
-
}
|
|
4787
|
-
if (dynamicPositions.length < config.minPoints) return [];
|
|
4788
|
-
const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));
|
|
4789
|
-
const flat = [];
|
|
4790
|
-
for (const c of pos) {
|
|
4791
|
-
flat.push(c[0], c[1], c[2] || 0);
|
|
4792
|
-
}
|
|
4793
|
-
return Cesium$c.Cartesian3.fromDegreesArrayHeights(flat);
|
|
4794
|
-
}, false);
|
|
4795
|
-
} else {
|
|
4796
|
-
this._previewPlot.polygon.hierarchy = new Cesium$c.CallbackProperty(() => {
|
|
4797
|
-
const dynamicPositions = [...self._tempPositions];
|
|
4798
|
-
if (self._currentMousePos) {
|
|
4799
|
-
dynamicPositions.push(self._currentMousePos);
|
|
4800
|
-
}
|
|
4801
|
-
if (dynamicPositions.length < config.minPoints) return new Cesium$c.PolygonHierarchy([]);
|
|
4802
|
-
const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));
|
|
4803
|
-
const flat = [];
|
|
4804
|
-
for (const c of pos) {
|
|
4805
|
-
flat.push(c[0], c[1], c[2] || 0);
|
|
4806
|
-
}
|
|
4807
|
-
return new Cesium$c.PolygonHierarchy(Cesium$c.Cartesian3.fromDegreesArrayHeights(flat));
|
|
4808
|
-
}, false);
|
|
4809
|
-
this._previewPlot.polyline.positions = new Cesium$c.CallbackProperty(() => {
|
|
4810
|
-
const dynamicPositions = [...self._tempPositions];
|
|
4811
|
-
if (self._currentMousePos) {
|
|
4812
|
-
dynamicPositions.push(self._currentMousePos);
|
|
4813
|
-
}
|
|
4814
|
-
if (dynamicPositions.length < config.minPoints) return [];
|
|
4815
|
-
const pos = PlotGeometryUtil[factoryName](normalizeForEllipse(dynamicPositions));
|
|
4816
|
-
const flat = [];
|
|
4817
|
-
for (const c of pos) {
|
|
4818
|
-
flat.push(c[0], c[1], c[2] || 0);
|
|
4819
|
-
}
|
|
4820
|
-
const cart = Cesium$c.Cartesian3.fromDegreesArrayHeights(flat);
|
|
4821
|
-
return [...cart, cart[0]];
|
|
4822
|
-
}, false);
|
|
4823
|
-
}
|
|
4824
4822
|
}
|
|
4825
4823
|
}
|
|
4826
4824
|
|
|
@@ -5243,9 +5241,9 @@ class EditTool extends BaseTool {
|
|
|
5243
5241
|
}
|
|
5244
5242
|
}
|
|
5245
5243
|
|
|
5246
|
-
_onMove(
|
|
5247
|
-
//
|
|
5248
|
-
const screenPos =
|
|
5244
|
+
_onMove(_lngLat, _entity, movement) {
|
|
5245
|
+
// BaseTool.registerObserver 现在统一转发 (lngLat, entity, movement)
|
|
5246
|
+
const screenPos = movement.position || movement.endPosition;
|
|
5249
5247
|
if (!screenPos) return;
|
|
5250
5248
|
|
|
5251
5249
|
// 非拖拽时做节流,避免 hover 检测过于频繁
|
|
@@ -5453,7 +5451,7 @@ class EditTool extends BaseTool {
|
|
|
5453
5451
|
pixelSize: 12,
|
|
5454
5452
|
outlineColor: Cesium$b.Color.BLACK,
|
|
5455
5453
|
outlineWidth: 2,
|
|
5456
|
-
disableDepthTestDistance:
|
|
5454
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5457
5455
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND
|
|
5458
5456
|
}
|
|
5459
5457
|
});
|
|
@@ -5501,7 +5499,7 @@ class EditTool extends BaseTool {
|
|
|
5501
5499
|
pixelSize: 14,
|
|
5502
5500
|
outlineColor: Cesium$b.Color.BLUE,
|
|
5503
5501
|
outlineWidth: 2,
|
|
5504
|
-
disableDepthTestDistance:
|
|
5502
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5505
5503
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND
|
|
5506
5504
|
}
|
|
5507
5505
|
});
|
|
@@ -5668,7 +5666,7 @@ class EditTool extends BaseTool {
|
|
|
5668
5666
|
pixelSize: 12,
|
|
5669
5667
|
outlineColor: Cesium$b.Color.BLACK,
|
|
5670
5668
|
outlineWidth: 2,
|
|
5671
|
-
disableDepthTestDistance:
|
|
5669
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5672
5670
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND,
|
|
5673
5671
|
}
|
|
5674
5672
|
});
|
|
@@ -5694,7 +5692,7 @@ class EditTool extends BaseTool {
|
|
|
5694
5692
|
pixelSize: 14,
|
|
5695
5693
|
outlineColor: Cesium$b.Color.BLUE,
|
|
5696
5694
|
outlineWidth: 2,
|
|
5697
|
-
disableDepthTestDistance:
|
|
5695
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5698
5696
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND
|
|
5699
5697
|
}
|
|
5700
5698
|
});
|
|
@@ -5708,7 +5706,7 @@ class EditTool extends BaseTool {
|
|
|
5708
5706
|
pixelSize: 12,
|
|
5709
5707
|
outlineColor: Cesium$b.Color.YELLOW,
|
|
5710
5708
|
outlineWidth: 2,
|
|
5711
|
-
disableDepthTestDistance:
|
|
5709
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5712
5710
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND
|
|
5713
5711
|
}
|
|
5714
5712
|
});
|
|
@@ -5733,7 +5731,7 @@ class EditTool extends BaseTool {
|
|
|
5733
5731
|
pixelSize: 12,
|
|
5734
5732
|
outlineColor: Cesium$b.Color.BLACK,
|
|
5735
5733
|
outlineWidth: 2,
|
|
5736
|
-
disableDepthTestDistance:
|
|
5734
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5737
5735
|
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
5738
5736
|
}
|
|
5739
5737
|
});
|
|
@@ -5765,7 +5763,7 @@ class EditTool extends BaseTool {
|
|
|
5765
5763
|
pixelSize: 10,
|
|
5766
5764
|
outlineColor: Cesium$b.Color.RED,
|
|
5767
5765
|
outlineWidth: 2,
|
|
5768
|
-
disableDepthTestDistance:
|
|
5766
|
+
disableDepthTestDistance: LabelDepthConfig.distance
|
|
5769
5767
|
}
|
|
5770
5768
|
}
|
|
5771
5769
|
);
|
|
@@ -5833,7 +5831,7 @@ class EditTool extends BaseTool {
|
|
|
5833
5831
|
pixelSize: 14,
|
|
5834
5832
|
outlineColor: Cesium$b.Color.BLUE,
|
|
5835
5833
|
outlineWidth: 2,
|
|
5836
|
-
disableDepthTestDistance:
|
|
5834
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
5837
5835
|
heightReference: Cesium$b.HeightReference.CLAMP_TO_GROUND
|
|
5838
5836
|
}
|
|
5839
5837
|
});
|
|
@@ -6036,24 +6034,43 @@ class EditTool extends BaseTool {
|
|
|
6036
6034
|
return this._clampPositionToGround(newPos);
|
|
6037
6035
|
});
|
|
6038
6036
|
this._selectedEntity.polyline.positions = newPositions;
|
|
6039
|
-
|
|
6040
|
-
//
|
|
6037
|
+
|
|
6038
|
+
// 修复:更新所有顶点和中点控制点位置
|
|
6041
6039
|
this._editHandles.forEach((handle) => {
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6040
|
+
if (!handle.id || handle.id.includes('center')) return;
|
|
6041
|
+
// 顶点 handle:__edit_handle_<index>
|
|
6042
|
+
const vertexMatch = handle.id.match(/__edit_handle_(\d+)$/);
|
|
6043
|
+
if (vertexMatch) {
|
|
6044
|
+
const index = parseInt(vertexMatch[1], 10);
|
|
6045
|
+
if (newPositions[index]) {
|
|
6046
|
+
const posProp = handle.position;
|
|
6047
|
+
if (posProp && typeof posProp.setValue === 'function') {
|
|
6048
|
+
posProp.setValue(newPositions[index]);
|
|
6049
|
+
} else {
|
|
6050
|
+
handle.position = new Cesium$b.ConstantPositionProperty(newPositions[index]);
|
|
6051
|
+
}
|
|
6052
|
+
}
|
|
6045
6053
|
return;
|
|
6046
6054
|
}
|
|
6047
|
-
//
|
|
6048
|
-
const
|
|
6049
|
-
if (
|
|
6050
|
-
const
|
|
6051
|
-
|
|
6052
|
-
|
|
6055
|
+
// 中点 handle:__edit_handle_mid_<li>_<ri>
|
|
6056
|
+
const midMatch = handle.id.match(/__edit_handle_mid_(\d+)_(\d+)/);
|
|
6057
|
+
if (midMatch) {
|
|
6058
|
+
const li = parseInt(midMatch[1], 10);
|
|
6059
|
+
const ri = parseInt(midMatch[2], 10);
|
|
6060
|
+
const left = newPositions[li];
|
|
6061
|
+
const right = newPositions[ri];
|
|
6062
|
+
if (!left || !right) return;
|
|
6063
|
+
const midCart = Cesium$b.Cartesian3.midpoint(left, right, new Cesium$b.Cartesian3());
|
|
6064
|
+
const clamped = this._clampPositionToGround(midCart);
|
|
6065
|
+
const posProp = handle.position;
|
|
6066
|
+
if (posProp && typeof posProp.setValue === 'function') {
|
|
6067
|
+
posProp.setValue(clamped);
|
|
6068
|
+
} else {
|
|
6069
|
+
handle.position = new Cesium$b.ConstantPositionProperty(clamped);
|
|
6053
6070
|
}
|
|
6054
6071
|
}
|
|
6055
6072
|
});
|
|
6056
|
-
|
|
6073
|
+
|
|
6057
6074
|
// 更新原始位置缓存
|
|
6058
6075
|
this._originalPositions = newPositions;
|
|
6059
6076
|
} else if (Cesium$b.defined(this._selectedEntity.polygon)) {
|
|
@@ -6104,18 +6121,40 @@ class EditTool extends BaseTool {
|
|
|
6104
6121
|
return this._clampPositionToGround(newPos);
|
|
6105
6122
|
});
|
|
6106
6123
|
|
|
6107
|
-
//
|
|
6124
|
+
// 修复:更新顶点和中点控制点位置。
|
|
6125
|
+
// 注意:正则 `/__edit_handle_(\d+)$/` 只匹配顶点 handle;
|
|
6126
|
+
// 中点 handle 的 ID 是 `__edit_handle_mid_<li>_<ri>`,需要单独处理。
|
|
6108
6127
|
this._editHandles.forEach((handle) => {
|
|
6109
|
-
|
|
6110
|
-
|
|
6128
|
+
if (!handle.id || handle.id.includes('center')) return;
|
|
6129
|
+
// 顶点 handle:__edit_handle_<index>
|
|
6130
|
+
const vertexMatch = handle.id.match(/__edit_handle_(\d+)$/);
|
|
6131
|
+
if (vertexMatch) {
|
|
6132
|
+
const index = parseInt(vertexMatch[1], 10);
|
|
6133
|
+
if (newPositions[index]) {
|
|
6134
|
+
const posProp = handle.position;
|
|
6135
|
+
if (posProp && typeof posProp.setValue === 'function') {
|
|
6136
|
+
posProp.setValue(newPositions[index]);
|
|
6137
|
+
} else {
|
|
6138
|
+
handle.position = new Cesium$b.ConstantPositionProperty(newPositions[index]);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6111
6141
|
return;
|
|
6112
6142
|
}
|
|
6113
|
-
//
|
|
6114
|
-
const
|
|
6115
|
-
if (
|
|
6116
|
-
const
|
|
6117
|
-
|
|
6118
|
-
|
|
6143
|
+
// 中点 handle:__edit_handle_mid_<li>_<ri>
|
|
6144
|
+
const midMatch = handle.id.match(/__edit_handle_mid_(\d+)_(\d+)/);
|
|
6145
|
+
if (midMatch) {
|
|
6146
|
+
const li = parseInt(midMatch[1], 10);
|
|
6147
|
+
const ri = parseInt(midMatch[2], 10);
|
|
6148
|
+
const left = newPositions[li];
|
|
6149
|
+
const right = newPositions[ri];
|
|
6150
|
+
if (!left || !right) return;
|
|
6151
|
+
const midCart = Cesium$b.Cartesian3.midpoint(left, right, new Cesium$b.Cartesian3());
|
|
6152
|
+
const clamped = this._clampPositionToGround(midCart);
|
|
6153
|
+
const posProp = handle.position;
|
|
6154
|
+
if (posProp && typeof posProp.setValue === 'function') {
|
|
6155
|
+
posProp.setValue(clamped);
|
|
6156
|
+
} else {
|
|
6157
|
+
handle.position = new Cesium$b.ConstantPositionProperty(clamped);
|
|
6119
6158
|
}
|
|
6120
6159
|
}
|
|
6121
6160
|
});
|
|
@@ -6676,7 +6715,14 @@ class EditTool extends BaseTool {
|
|
|
6676
6715
|
// 多边形顶点拖动:通过 CallbackProperty 让 Cesium 直接从 handle 位置读,
|
|
6677
6716
|
// 这里只需要更新 handle.position 即可,几何会跟着弯折,
|
|
6678
6717
|
// 远比每帧 newPositions + new PolygonHierarchy 顺滑。
|
|
6679
|
-
|
|
6718
|
+
// 复用现有 Property 实例并 setValue:避免替换 Property 引用导致
|
|
6719
|
+
// Cesium 某些情况下不重新渲染。
|
|
6720
|
+
const dragPosProp = this._dragHandle.position;
|
|
6721
|
+
if (dragPosProp && typeof dragPosProp.setValue === 'function') {
|
|
6722
|
+
dragPosProp.setValue(newCartesian);
|
|
6723
|
+
} else {
|
|
6724
|
+
this._dragHandle.position = new Cesium$b.ConstantPositionProperty(newCartesian);
|
|
6725
|
+
}
|
|
6680
6726
|
|
|
6681
6727
|
// 修复:多边形编辑后重新计算并更新中心控制点位置
|
|
6682
6728
|
this._updateCenterHandlePosition();
|
|
@@ -6719,7 +6765,14 @@ class EditTool extends BaseTool {
|
|
|
6719
6765
|
if (!left || !right) return;
|
|
6720
6766
|
const midCart = Cesium$b.Cartesian3.midpoint(left, right, new Cesium$b.Cartesian3());
|
|
6721
6767
|
const clamped = this._clampPositionToGround(midCart);
|
|
6722
|
-
|
|
6768
|
+
// 复用现有 Property 实例并 setValue:避免替换 Property 引用导致
|
|
6769
|
+
// Cesium 某些情况下不重新渲染。
|
|
6770
|
+
const posProp = handle.position;
|
|
6771
|
+
if (posProp && typeof posProp.setValue === 'function') {
|
|
6772
|
+
posProp.setValue(clamped);
|
|
6773
|
+
} else {
|
|
6774
|
+
handle.position = new Cesium$b.ConstantPositionProperty(clamped);
|
|
6775
|
+
}
|
|
6723
6776
|
});
|
|
6724
6777
|
}
|
|
6725
6778
|
|
|
@@ -6942,14 +6995,15 @@ class SelectTool extends BaseTool {
|
|
|
6942
6995
|
}
|
|
6943
6996
|
}
|
|
6944
6997
|
|
|
6945
|
-
_onMove(
|
|
6998
|
+
_onMove(lngLat, _entity, movement) {
|
|
6946
6999
|
// mouse:move passes movement object from BaseTool
|
|
6947
|
-
const screenPos =
|
|
7000
|
+
const screenPos = movement.position || movement.endPosition;
|
|
6948
7001
|
if (!screenPos) return;
|
|
6949
7002
|
|
|
6950
7003
|
if (!this._isSelecting || !this._startPos) return;
|
|
6951
7004
|
|
|
6952
|
-
|
|
7005
|
+
// 优先使用 EventModule 已计算的 lngLat(避免重复 scene.pickPosition)。
|
|
7006
|
+
const lonLat = lngLat || this.screenToLonLat({ x: screenPos.x, y: screenPos.y });
|
|
6953
7007
|
if (!lonLat) return;
|
|
6954
7008
|
|
|
6955
7009
|
this._updateSelectionRectPreview(lonLat);
|
|
@@ -7441,17 +7495,18 @@ class DeleteTool extends BaseTool {
|
|
|
7441
7495
|
}
|
|
7442
7496
|
}
|
|
7443
7497
|
|
|
7444
|
-
_onMove(
|
|
7445
|
-
const screenPos =
|
|
7498
|
+
_onMove(_lngLat, pickedEntity, movement) {
|
|
7499
|
+
const screenPos = movement.position || movement.endPosition;
|
|
7446
7500
|
if (!screenPos) return;
|
|
7447
7501
|
|
|
7448
|
-
|
|
7449
|
-
|
|
7502
|
+
// 优先使用 EventModule 已计算的 pickedEntity(避免重复 scene.pick)。
|
|
7503
|
+
// EventModule 已经做过 pickedEntity.id(Pick 对象 → Entity 实例)取一次,
|
|
7504
|
+
// 这里直接取 Entity.id(字符串)即可。
|
|
7450
7505
|
let hoveredId = null;
|
|
7451
7506
|
|
|
7452
|
-
if (Cesium$9.defined(
|
|
7453
|
-
const entityId =
|
|
7454
|
-
if (!entityId.startsWith('__temp_') && !entityId.startsWith('__edit_handle_')) {
|
|
7507
|
+
if (Cesium$9.defined(pickedEntity) && Cesium$9.defined(pickedEntity.id)) {
|
|
7508
|
+
const entityId = pickedEntity.id;
|
|
7509
|
+
if (typeof entityId === 'string' && !entityId.startsWith('__temp_') && !entityId.startsWith('__edit_handle_')) {
|
|
7455
7510
|
hoveredId = entityId;
|
|
7456
7511
|
}
|
|
7457
7512
|
}
|
|
@@ -7734,6 +7789,24 @@ const LABEL_BORDER_COLOR = '#FB120E';
|
|
|
7734
7789
|
const LABEL_BACKGROUND_COLOR = '#ffffff';
|
|
7735
7790
|
const LABEL_TEXT_COLOR = '#000000';
|
|
7736
7791
|
|
|
7792
|
+
// 模块级 measure canvas 单例:测量标签每次重绘文字宽度时复用,避免
|
|
7793
|
+
// 每次都 document.createElement + getContext(之前在 _createLabelImage 中是热路径)。
|
|
7794
|
+
// 延迟到首次调用时再创建:jsdom 等环境顶层 document.createElement('canvas').getContext 不可用。
|
|
7795
|
+
let _measureCanvas = null;
|
|
7796
|
+
let _measureCtx = null;
|
|
7797
|
+
function _measureTextWidth(text, font) {
|
|
7798
|
+
if (!_measureCanvas) {
|
|
7799
|
+
try {
|
|
7800
|
+
_measureCanvas = document.createElement('canvas');
|
|
7801
|
+
_measureCtx = _measureCanvas.getContext('2d');
|
|
7802
|
+
} catch (e) {
|
|
7803
|
+
return Math.max(1, text.length * 8);
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
_measureCtx.font = font;
|
|
7807
|
+
return Math.max(1, Math.ceil(_measureCtx.measureText(text).width));
|
|
7808
|
+
}
|
|
7809
|
+
|
|
7737
7810
|
/**
|
|
7738
7811
|
* 测量类型枚举
|
|
7739
7812
|
*/
|
|
@@ -7921,8 +7994,8 @@ class MeasureTool extends BaseTool {
|
|
|
7921
7994
|
this._updateMeasurement();
|
|
7922
7995
|
}
|
|
7923
7996
|
|
|
7924
|
-
_onMove(
|
|
7925
|
-
const screenPos =
|
|
7997
|
+
_onMove(lngLat, entity, movement) {
|
|
7998
|
+
const screenPos = movement.position || movement.endPosition;
|
|
7926
7999
|
if (!screenPos) return;
|
|
7927
8000
|
|
|
7928
8001
|
// 拖拽顶点中:节流更新该顶点位置与对应几何/标注
|
|
@@ -7931,7 +8004,8 @@ class MeasureTool extends BaseTool {
|
|
|
7931
8004
|
if (now - this._lastDragMoveTime < this._dragThrottleMs) return;
|
|
7932
8005
|
this._lastDragMoveTime = now;
|
|
7933
8006
|
|
|
7934
|
-
|
|
8007
|
+
// 拖动路径优先用 EventModule 已计算的 lngLat;否则 fallback。
|
|
8008
|
+
const lonLat = lngLat || this.screenToLonLat({ x: screenPos.x, y: screenPos.y });
|
|
7935
8009
|
if (lonLat) {
|
|
7936
8010
|
this._updateVertexDuringDrag(this._dragVertexIndex, lonLat, this._dragResult);
|
|
7937
8011
|
|
|
@@ -7945,25 +8019,27 @@ class MeasureTool extends BaseTool {
|
|
|
7945
8019
|
return;
|
|
7946
8020
|
}
|
|
7947
8021
|
|
|
7948
|
-
// 非拖拽:检测悬停,更新光标(与 EditTool
|
|
8022
|
+
// 非拖拽:检测悬停,更新光标(与 EditTool 风格一致)。优先用 EventModule 给的 entity。
|
|
7949
8023
|
let isOverFinishedVertex = false;
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
8024
|
+
if (Cesium$7.defined(entity)) {
|
|
8025
|
+
try {
|
|
8026
|
+
// EventModule 传过来的是 Cesium Entity 实例(不是 Pick 对象),直接用于命中判定
|
|
8027
|
+
isOverFinishedVertex = !!this._findFinishedPointHit(entity);
|
|
8028
|
+
} catch (e) {
|
|
8029
|
+
// ignore
|
|
7955
8030
|
}
|
|
7956
|
-
} catch (e) {
|
|
7957
|
-
// ignore
|
|
7958
8031
|
}
|
|
7959
8032
|
// 悬停在角点上:CSS `grab`(开放的手)暗示"可拖动";无浏览器支持时回退 `default`
|
|
7960
8033
|
this._setCanvasCursor(isOverFinishedVertex ? 'grab' : 'default');
|
|
7961
8034
|
|
|
7962
|
-
const lonLat = this.screenToLonLat({ x: screenPos.x, y: screenPos.y });
|
|
8035
|
+
const lonLat = lngLat || this.screenToLonLat({ x: screenPos.x, y: screenPos.y });
|
|
7963
8036
|
if (!lonLat) return;
|
|
7964
8037
|
this._mousePos = lonLat;
|
|
8038
|
+
|
|
8039
|
+
// 非拖拽预览路径:用 rAF 合并 mousemove,与 render 帧同步,避免全球视角下
|
|
8040
|
+
// 多次 mousemove 之间重复重建几何/canvas。
|
|
7965
8041
|
if (this._isMeasuring) {
|
|
7966
|
-
this._updateMeasurement();
|
|
8042
|
+
this._scheduleMoveWork(() => this._updateMeasurement());
|
|
7967
8043
|
}
|
|
7968
8044
|
}
|
|
7969
8045
|
|
|
@@ -8743,7 +8819,7 @@ class MeasureTool extends BaseTool {
|
|
|
8743
8819
|
verticalOrigin: Cesium$7.VerticalOrigin.BOTTOM,
|
|
8744
8820
|
horizontalOrigin: Cesium$7.HorizontalOrigin.CENTER,
|
|
8745
8821
|
pixelOffset: new Cesium$7.Cartesian2(0, -6),
|
|
8746
|
-
disableDepthTestDistance:
|
|
8822
|
+
disableDepthTestDistance: LabelDepthConfig.distance
|
|
8747
8823
|
}
|
|
8748
8824
|
});
|
|
8749
8825
|
entity._lastText = text;
|
|
@@ -8769,11 +8845,8 @@ class MeasureTool extends BaseTool {
|
|
|
8769
8845
|
const triangleHeight = 8;
|
|
8770
8846
|
const rectHeight = 20;
|
|
8771
8847
|
|
|
8772
|
-
//
|
|
8773
|
-
const
|
|
8774
|
-
const measureCtx = measureCanvas.getContext('2d');
|
|
8775
|
-
measureCtx.font = font;
|
|
8776
|
-
const textWidth = Math.max(1, Math.ceil(measureCtx.measureText(text).width));
|
|
8848
|
+
// 复用模块级 measure canvas 单例,避免每次 mousemove 都 document.createElement('canvas')
|
|
8849
|
+
const textWidth = _measureTextWidth(text, font);
|
|
8777
8850
|
const rectWidth = textWidth + paddingX * 2;
|
|
8778
8851
|
const width = rectWidth + borderWidth * 2;
|
|
8779
8852
|
const height = rectHeight + triangleHeight + borderWidth * 2;
|
|
@@ -8895,7 +8968,7 @@ class MeasureTool extends BaseTool {
|
|
|
8895
8968
|
style: Cesium$7.LabelStyle.FILL_AND_OUTLINE,
|
|
8896
8969
|
verticalOrigin: Cesium$7.VerticalOrigin.BOTTOM,
|
|
8897
8970
|
horizontalOrigin: Cesium$7.HorizontalOrigin.CENTER,
|
|
8898
|
-
disableDepthTestDistance:
|
|
8971
|
+
disableDepthTestDistance: LabelDepthConfig.distance,
|
|
8899
8972
|
pixelOffset: new Cesium$7.Cartesian2(0, -10)
|
|
8900
8973
|
}
|
|
8901
8974
|
});
|
|
@@ -8910,7 +8983,7 @@ class MeasureTool extends BaseTool {
|
|
|
8910
8983
|
pixelSize: 8,
|
|
8911
8984
|
outlineColor: Cesium$7.Color.fromCssColorString(MEASURE_POINT_OUTLINE_COLOR),
|
|
8912
8985
|
outlineWidth: 1,
|
|
8913
|
-
disableDepthTestDistance:
|
|
8986
|
+
disableDepthTestDistance: LabelDepthConfig.distance
|
|
8914
8987
|
}
|
|
8915
8988
|
});
|
|
8916
8989
|
this._pointEntities.push(point);
|
|
@@ -11979,6 +12052,7 @@ const xs3d = {
|
|
|
11979
12052
|
Zoom,
|
|
11980
12053
|
Compass,
|
|
11981
12054
|
DistanceLegend,
|
|
12055
|
+
LabelDepthConfig,
|
|
11982
12056
|
// 导出工具枚举
|
|
11983
12057
|
DrawType,
|
|
11984
12058
|
EditMode,
|