cesium-xs-sdk 1.0.12 → 1.0.14
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 +302 -45
- package/dist/cesium-xs-sdk.cjs.js.map +1 -1
- package/dist/cesium-xs-sdk.esm.js +302 -45
- 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/index.d.ts +4 -1
- package/src/modules/MilitarySymbolModule.js +273 -37
- package/src/modules/militarySymbolAssets.js +37 -10
|
@@ -9198,17 +9198,38 @@ class ControlModule {
|
|
|
9198
9198
|
}
|
|
9199
9199
|
}
|
|
9200
9200
|
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
'small-radio': toDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="80" height="80"><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><circle cx="36.93" cy="48.5" r="22" style="fill:none;stroke:red;stroke-miterlimit:10;stroke-width:4.535433070866142px"/><polyline points="42.56 25.87 53.06 9.51 54.06 27.5 65.07 10.37" style="fill:none;stroke:red;stroke-linejoin:bevel;stroke-width:4.535433070866142px"/><rect width="80" height="80" style="fill:red;opacity:0"/></g></g></svg>`),
|
|
9209
|
-
'large-radio': toDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="80" height="80"><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><polygon points="39.96 28.87 51.18 48.3 62.4 67.73 39.96 67.73 17.53 67.73 28.75 48.3 39.96 28.87" style="fill:none;stroke:red;stroke-miterlimit:10;stroke-width:4.535433070866142px"/><polyline points="39.96 28.64 50.46 12.27 51.46 30.27 62.47 13.14" style="fill:none;stroke:red;stroke-linejoin:bevel;stroke-width:4.535433070866142px"/><rect width="80" height="80" style="fill:red;opacity:0"/></g></g></svg>`),
|
|
9201
|
+
/**
|
|
9202
|
+
* 军标内置默认图标。
|
|
9203
|
+
* SDK 内置常见军标类型的默认图标,业务层可通过 imgUrl / useDefaultIcon 参数覆盖或追加。
|
|
9204
|
+
*/
|
|
9205
|
+
const DEFAULT_SYMBOL_SVGS = {
|
|
9206
|
+
'small-radio': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="80" height="80"><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><circle cx="36.93" cy="48.5" r="22" style="fill:none;stroke:red;stroke-miterlimit:10;stroke-width:4.535433070866142px"/><polyline points="42.56 25.87 53.06 9.51 54.06 27.5 65.07 10.37" style="fill:none;stroke:red;stroke-linejoin:bevel;stroke-width:4.535433070866142px"/><rect width="80" height="80" style="fill:red;opacity:0"/></g></g></svg>`,
|
|
9207
|
+
'large-radio': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="80" height="80"><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><polygon points="39.96 28.87 51.18 48.3 62.4 67.73 39.96 67.73 17.53 67.73 28.75 48.3 39.96 28.87" style="fill:none;stroke:red;stroke-miterlimit:10;stroke-width:4.535433070866142px"/><polyline points="39.96 28.64 50.46 12.27 51.46 30.27 62.47 13.14" style="fill:none;stroke:red;stroke-linejoin:bevel;stroke-width:4.535433070866142px"/><rect width="80" height="80" style="fill:red;opacity:0"/></g></g></svg>`,
|
|
9210
9208
|
};
|
|
9211
9209
|
|
|
9210
|
+
/** Blob URL 缓存,避免重复创建 */
|
|
9211
|
+
const blobUrlCache = new Map();
|
|
9212
|
+
|
|
9213
|
+
/**
|
|
9214
|
+
* 获取内置军标图标的 Blob URL(比 data URI 更利于 Cesium 材质加载)
|
|
9215
|
+
* @param {string} type 军标类型
|
|
9216
|
+
* @returns {string | null}
|
|
9217
|
+
*/
|
|
9218
|
+
function getDefaultSymbolImage(type) {
|
|
9219
|
+
const svg = DEFAULT_SYMBOL_SVGS[type];
|
|
9220
|
+
if (!svg) return null;
|
|
9221
|
+
if (blobUrlCache.has(type)) return blobUrlCache.get(type);
|
|
9222
|
+
try {
|
|
9223
|
+
const blob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
|
|
9224
|
+
const url = URL.createObjectURL(blob);
|
|
9225
|
+
blobUrlCache.set(type, url);
|
|
9226
|
+
return url;
|
|
9227
|
+
} catch (e) {
|
|
9228
|
+
console.warn('生成军标图标 Blob URL 失败', e);
|
|
9229
|
+
return null;
|
|
9230
|
+
}
|
|
9231
|
+
}
|
|
9232
|
+
|
|
9212
9233
|
const Cesium$2 = getCesium();
|
|
9213
9234
|
|
|
9214
9235
|
/**
|
|
@@ -9227,10 +9248,21 @@ class MilitarySymbolModule {
|
|
|
9227
9248
|
this.eventModule = null;
|
|
9228
9249
|
|
|
9229
9250
|
this._editMode = false;
|
|
9251
|
+
this._editSymbolId = null;
|
|
9252
|
+
/** @type {Map<string, {move: Cesium.Entity, scale: Cesium.Entity, rotate: Cesium.Entity}>} */
|
|
9253
|
+
this._editHandles = new Map();
|
|
9230
9254
|
this._draggingId = null;
|
|
9255
|
+
this._draggingHandle = null;
|
|
9256
|
+
this._dragStartScreen = null;
|
|
9257
|
+
this._dragStartScale = 1;
|
|
9258
|
+
this._dragStartRotation = 0;
|
|
9259
|
+
this._dragStartDist = 0;
|
|
9260
|
+
this._dragStartAngle = 0;
|
|
9231
9261
|
this._dragObserverIds = [];
|
|
9232
9262
|
/** @type {Set<Function>} */
|
|
9233
9263
|
this._positionChangedCallbacks = new Set();
|
|
9264
|
+
/** @type {Set<Function>} */
|
|
9265
|
+
this._transformChangedCallbacks = new Set();
|
|
9234
9266
|
}
|
|
9235
9267
|
|
|
9236
9268
|
/**
|
|
@@ -9287,7 +9319,7 @@ class MilitarySymbolModule {
|
|
|
9287
9319
|
_resolveImage(id, options) {
|
|
9288
9320
|
const globalMode = this._defaultIconMode || this.config.militarySymbol?.defaultIconMode;
|
|
9289
9321
|
const mode = options.iconMode || globalMode || 'default';
|
|
9290
|
-
const defaultImage =
|
|
9322
|
+
const defaultImage = getDefaultSymbolImage(options.type);
|
|
9291
9323
|
const registeredImage = this.defaultImageMap.get(options.type);
|
|
9292
9324
|
const imgUrl = options.imgUrl || registeredImage || null;
|
|
9293
9325
|
|
|
@@ -9330,7 +9362,10 @@ class MilitarySymbolModule {
|
|
|
9330
9362
|
_loadImage(url) {
|
|
9331
9363
|
return new Promise((resolve, reject) => {
|
|
9332
9364
|
const img = new Image();
|
|
9333
|
-
|
|
9365
|
+
// data URI / blob URL 等同源资源不需要 crossOrigin;跨域 http 资源需要
|
|
9366
|
+
if (url && /^https?:\/\//.test(url)) {
|
|
9367
|
+
img.crossOrigin = 'anonymous';
|
|
9368
|
+
}
|
|
9334
9369
|
img.onload = () => resolve(img);
|
|
9335
9370
|
img.onerror = (e) => reject(e);
|
|
9336
9371
|
img.src = url;
|
|
@@ -9384,6 +9419,131 @@ class MilitarySymbolModule {
|
|
|
9384
9419
|
return this.symbolMap.has(id) ? id : null;
|
|
9385
9420
|
}
|
|
9386
9421
|
|
|
9422
|
+
/**
|
|
9423
|
+
* 根据鼠标拾取结果判断是否为编辑控制点
|
|
9424
|
+
* @private
|
|
9425
|
+
*/
|
|
9426
|
+
_getHandleType(pickedEntity) {
|
|
9427
|
+
if (!pickedEntity) return null;
|
|
9428
|
+
const id = typeof pickedEntity.id === 'string' ? pickedEntity.id : pickedEntity.id?.id;
|
|
9429
|
+
if (!id) return null;
|
|
9430
|
+
if (id.endsWith('_move')) return 'move';
|
|
9431
|
+
if (id.endsWith('_scale')) return 'scale';
|
|
9432
|
+
if (id.endsWith('_rotate')) return 'rotate';
|
|
9433
|
+
return null;
|
|
9434
|
+
}
|
|
9435
|
+
|
|
9436
|
+
/**
|
|
9437
|
+
* 计算编辑控制点的三维坐标
|
|
9438
|
+
* @private
|
|
9439
|
+
*/
|
|
9440
|
+
_getHandlePositions(position) {
|
|
9441
|
+
const center = Cesium$2.Cartesian3.fromDegrees(position[0], position[1], position[2] || 0);
|
|
9442
|
+
const matrix = Cesium$2.Transforms.eastNorthUpToFixedFrame(center);
|
|
9443
|
+
const offsetMeters = 120;
|
|
9444
|
+
const scaleOffset = Cesium$2.Matrix4.multiplyByPoint(
|
|
9445
|
+
matrix,
|
|
9446
|
+
new Cesium$2.Cartesian3(offsetMeters, 0, 0),
|
|
9447
|
+
new Cesium$2.Cartesian3()
|
|
9448
|
+
);
|
|
9449
|
+
const rotateOffset = Cesium$2.Matrix4.multiplyByPoint(
|
|
9450
|
+
matrix,
|
|
9451
|
+
new Cesium$2.Cartesian3(0, offsetMeters, 0),
|
|
9452
|
+
new Cesium$2.Cartesian3()
|
|
9453
|
+
);
|
|
9454
|
+
return { center, scale: scaleOffset, rotate: rotateOffset };
|
|
9455
|
+
}
|
|
9456
|
+
|
|
9457
|
+
/**
|
|
9458
|
+
* 为指定军标创建编辑控制点
|
|
9459
|
+
* @private
|
|
9460
|
+
*/
|
|
9461
|
+
_createEditHandles(symbolId) {
|
|
9462
|
+
this._removeEditHandles(symbolId);
|
|
9463
|
+
const symbol = this.symbolMap.get(symbolId);
|
|
9464
|
+
if (!symbol) return;
|
|
9465
|
+
|
|
9466
|
+
const positions = this._getHandlePositions(symbol.metadata.position);
|
|
9467
|
+
const commonPoint = {
|
|
9468
|
+
pixelSize: 14,
|
|
9469
|
+
outlineColor: Cesium$2.Color.WHITE,
|
|
9470
|
+
outlineWidth: 2,
|
|
9471
|
+
heightReference: Cesium$2.HeightReference.CLAMP_TO_GROUND,
|
|
9472
|
+
};
|
|
9473
|
+
const commonLabel = {
|
|
9474
|
+
font: '12px Microsoft YaHei',
|
|
9475
|
+
fillColor: Cesium$2.Color.WHITE,
|
|
9476
|
+
outlineColor: Cesium$2.Color.BLACK,
|
|
9477
|
+
outlineWidth: 2,
|
|
9478
|
+
style: Cesium$2.LabelStyle.FILL_AND_OUTLINE,
|
|
9479
|
+
verticalOrigin: Cesium$2.VerticalOrigin.BOTTOM,
|
|
9480
|
+
horizontalOrigin: Cesium$2.HorizontalOrigin.CENTER,
|
|
9481
|
+
pixelOffset: new Cesium$2.Cartesian2(0, -10),
|
|
9482
|
+
heightReference: Cesium$2.HeightReference.CLAMP_TO_GROUND,
|
|
9483
|
+
};
|
|
9484
|
+
|
|
9485
|
+
const handles = {};
|
|
9486
|
+
handles.move = this.viewer.entities.add({
|
|
9487
|
+
id: `${symbolId}_move`,
|
|
9488
|
+
position: positions.center,
|
|
9489
|
+
point: { ...commonPoint, color: Cesium$2.Color.LIME },
|
|
9490
|
+
label: { ...commonLabel, text: '移动' },
|
|
9491
|
+
});
|
|
9492
|
+
handles.scale = this.viewer.entities.add({
|
|
9493
|
+
id: `${symbolId}_scale`,
|
|
9494
|
+
position: positions.scale,
|
|
9495
|
+
point: { ...commonPoint, color: Cesium$2.Color.DEEPSKYBLUE },
|
|
9496
|
+
label: { ...commonLabel, text: '缩放' },
|
|
9497
|
+
});
|
|
9498
|
+
handles.rotate = this.viewer.entities.add({
|
|
9499
|
+
id: `${symbolId}_rotate`,
|
|
9500
|
+
position: positions.rotate,
|
|
9501
|
+
point: { ...commonPoint, color: Cesium$2.Color.RED },
|
|
9502
|
+
label: { ...commonLabel, text: '旋转' },
|
|
9503
|
+
});
|
|
9504
|
+
|
|
9505
|
+
this._editHandles.set(symbolId, handles);
|
|
9506
|
+
}
|
|
9507
|
+
|
|
9508
|
+
/**
|
|
9509
|
+
* 移除指定军标的编辑控制点
|
|
9510
|
+
* @private
|
|
9511
|
+
*/
|
|
9512
|
+
_removeEditHandles(symbolId) {
|
|
9513
|
+
const handles = this._editHandles.get(symbolId);
|
|
9514
|
+
if (!handles) return;
|
|
9515
|
+
Object.values(handles).forEach((entity) => {
|
|
9516
|
+
if (entity) this.viewer.entities.remove(entity);
|
|
9517
|
+
});
|
|
9518
|
+
this._editHandles.delete(symbolId);
|
|
9519
|
+
}
|
|
9520
|
+
|
|
9521
|
+
/**
|
|
9522
|
+
* 更新控制点位置以跟随军标
|
|
9523
|
+
* @private
|
|
9524
|
+
*/
|
|
9525
|
+
_updateHandlePositions(symbolId) {
|
|
9526
|
+
const symbol = this.symbolMap.get(symbolId);
|
|
9527
|
+
const handles = this._editHandles.get(symbolId);
|
|
9528
|
+
if (!symbol || !handles) return;
|
|
9529
|
+
const positions = this._getHandlePositions(symbol.metadata.position);
|
|
9530
|
+
handles.move.position = positions.center;
|
|
9531
|
+
handles.scale.position = positions.scale;
|
|
9532
|
+
handles.rotate.position = positions.rotate;
|
|
9533
|
+
}
|
|
9534
|
+
|
|
9535
|
+
/**
|
|
9536
|
+
* 将 WGS84 坐标转换为屏幕坐标
|
|
9537
|
+
* @private
|
|
9538
|
+
*/
|
|
9539
|
+
_cartesianToScreen(cartesian) {
|
|
9540
|
+
if (!cartesian) return null;
|
|
9541
|
+
try {
|
|
9542
|
+
return Cesium$2.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, cartesian);
|
|
9543
|
+
} catch (e) {
|
|
9544
|
+
return null;
|
|
9545
|
+
}
|
|
9546
|
+
}
|
|
9387
9547
|
/**
|
|
9388
9548
|
* 创建军标图元
|
|
9389
9549
|
* @param {string} id 军标唯一ID
|
|
@@ -9394,6 +9554,7 @@ class MilitarySymbolModule {
|
|
|
9394
9554
|
* @param {string} [options.imgUrl] 自定义图标 URL
|
|
9395
9555
|
* @param {'default'|'custom'|'overlay'} [options.iconMode] 图标模式,默认 'default'
|
|
9396
9556
|
* @param {number} [options.scale] billboard 缩放,默认 0.6
|
|
9557
|
+
* @param {number} [options.rotation] billboard 旋转角度(度),默认 0
|
|
9397
9558
|
* @param {boolean} [options.visible] 是否可见,默认 true
|
|
9398
9559
|
* @returns {{id: string, entity: Cesium.Entity, metadata: object}}
|
|
9399
9560
|
*/
|
|
@@ -9406,6 +9567,7 @@ class MilitarySymbolModule {
|
|
|
9406
9567
|
const position = options.position || [0, 0, 0];
|
|
9407
9568
|
const image = this._resolveImage(id, options);
|
|
9408
9569
|
const scale = options.scale ?? 0.6;
|
|
9570
|
+
const rotation = options.rotation ?? 0;
|
|
9409
9571
|
const visible = options.visible !== false;
|
|
9410
9572
|
const name = options.name ?? id;
|
|
9411
9573
|
const iconMode = options.iconMode || 'default';
|
|
@@ -9416,10 +9578,10 @@ class MilitarySymbolModule {
|
|
|
9416
9578
|
billboard: {
|
|
9417
9579
|
image,
|
|
9418
9580
|
scale,
|
|
9581
|
+
rotation: Cesium$2.Math.toRadians(rotation),
|
|
9419
9582
|
verticalOrigin: Cesium$2.VerticalOrigin.BOTTOM,
|
|
9420
9583
|
horizontalOrigin: Cesium$2.HorizontalOrigin.CENTER,
|
|
9421
9584
|
heightReference: Cesium$2.HeightReference.CLAMP_TO_GROUND,
|
|
9422
|
-
disableDepthTestDistance: 100000,
|
|
9423
9585
|
},
|
|
9424
9586
|
label: {
|
|
9425
9587
|
text: name,
|
|
@@ -9432,7 +9594,6 @@ class MilitarySymbolModule {
|
|
|
9432
9594
|
horizontalOrigin: Cesium$2.HorizontalOrigin.CENTER,
|
|
9433
9595
|
pixelOffset: new Cesium$2.Cartesian2(0, 4),
|
|
9434
9596
|
heightReference: Cesium$2.HeightReference.CLAMP_TO_GROUND,
|
|
9435
|
-
disableDepthTestDistance: 100000,
|
|
9436
9597
|
show: true,
|
|
9437
9598
|
},
|
|
9438
9599
|
show: visible,
|
|
@@ -9444,6 +9605,7 @@ class MilitarySymbolModule {
|
|
|
9444
9605
|
name,
|
|
9445
9606
|
position: [position[0], position[1], position[2] || 0],
|
|
9446
9607
|
scale,
|
|
9608
|
+
rotation,
|
|
9447
9609
|
visible,
|
|
9448
9610
|
iconMode,
|
|
9449
9611
|
imgUrl: options.imgUrl || null,
|
|
@@ -9465,6 +9627,10 @@ class MilitarySymbolModule {
|
|
|
9465
9627
|
return false;
|
|
9466
9628
|
}
|
|
9467
9629
|
this.viewer.entities.remove(symbol.entity);
|
|
9630
|
+
this._removeEditHandles(id);
|
|
9631
|
+
if (this._editSymbolId === id) {
|
|
9632
|
+
this.disableEditMode();
|
|
9633
|
+
}
|
|
9468
9634
|
this.symbolMap.delete(id);
|
|
9469
9635
|
if (this._draggingId === id) {
|
|
9470
9636
|
this._draggingId = null;
|
|
@@ -9477,6 +9643,11 @@ class MilitarySymbolModule {
|
|
|
9477
9643
|
* 删除所有军标
|
|
9478
9644
|
*/
|
|
9479
9645
|
removeAll() {
|
|
9646
|
+
this._editHandles.forEach((_, id) => this._removeEditHandles(id));
|
|
9647
|
+
this._editHandles.clear();
|
|
9648
|
+
if (this._editMode) {
|
|
9649
|
+
this.disableEditMode();
|
|
9650
|
+
}
|
|
9480
9651
|
this.symbolMap.forEach((symbol) => {
|
|
9481
9652
|
this.viewer.entities.remove(symbol.entity);
|
|
9482
9653
|
});
|
|
@@ -9488,7 +9659,7 @@ class MilitarySymbolModule {
|
|
|
9488
9659
|
/**
|
|
9489
9660
|
* 更新军标属性
|
|
9490
9661
|
* @param {string} id 军标ID
|
|
9491
|
-
* @param {Object} fields 支持 position / name / scale / imgUrl / visible
|
|
9662
|
+
* @param {Object} fields 支持 position / name / scale / rotation / imgUrl / visible
|
|
9492
9663
|
* @returns {boolean} 是否更新成功
|
|
9493
9664
|
*/
|
|
9494
9665
|
update(id, fields = {}) {
|
|
@@ -9516,6 +9687,11 @@ class MilitarySymbolModule {
|
|
|
9516
9687
|
metadata.scale = fields.scale;
|
|
9517
9688
|
}
|
|
9518
9689
|
|
|
9690
|
+
if (fields.rotation !== undefined) {
|
|
9691
|
+
entity.billboard.rotation = Cesium$2.Math.toRadians(fields.rotation);
|
|
9692
|
+
metadata.rotation = fields.rotation;
|
|
9693
|
+
}
|
|
9694
|
+
|
|
9519
9695
|
if (fields.imgUrl !== undefined || fields.iconMode !== undefined) {
|
|
9520
9696
|
const newIconMode = fields.iconMode || metadata.iconMode;
|
|
9521
9697
|
const newImgUrl = fields.imgUrl !== undefined ? fields.imgUrl : metadata.imgUrl;
|
|
@@ -9595,13 +9771,14 @@ class MilitarySymbolModule {
|
|
|
9595
9771
|
const pitch = options.pitch ?? -Cesium$2.Math.PI_OVER_TWO;
|
|
9596
9772
|
const range = options.range ?? 5000;
|
|
9597
9773
|
|
|
9598
|
-
return
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9774
|
+
return new Promise((resolve) => {
|
|
9775
|
+
this.viewer.camera.flyTo({
|
|
9776
|
+
destination: Cesium$2.Cartesian3.fromDegrees(position[0], position[1], (position[2] || 0) + range),
|
|
9777
|
+
orientation: { heading: 0, pitch, roll: 0 },
|
|
9778
|
+
duration,
|
|
9779
|
+
complete: () => resolve(true),
|
|
9780
|
+
cancel: () => resolve(false),
|
|
9781
|
+
});
|
|
9605
9782
|
});
|
|
9606
9783
|
}
|
|
9607
9784
|
|
|
@@ -9627,49 +9804,115 @@ class MilitarySymbolModule {
|
|
|
9627
9804
|
}
|
|
9628
9805
|
|
|
9629
9806
|
/**
|
|
9630
|
-
*
|
|
9631
|
-
*
|
|
9807
|
+
* 启用军标编辑模式(生成移动/缩放/旋转控制点)
|
|
9808
|
+
* @param {string} id 要编辑的军标ID
|
|
9632
9809
|
*/
|
|
9633
|
-
enableEditMode() {
|
|
9634
|
-
if (this._editMode)
|
|
9810
|
+
enableEditMode(id) {
|
|
9811
|
+
if (this._editMode) {
|
|
9812
|
+
if (this._editSymbolId === id) return;
|
|
9813
|
+
this.disableEditMode();
|
|
9814
|
+
}
|
|
9815
|
+
if (!this.symbolMap.has(id)) {
|
|
9816
|
+
console.warn(`军标 ${id} 不存在,无法启用编辑`);
|
|
9817
|
+
return;
|
|
9818
|
+
}
|
|
9635
9819
|
if (!this.eventModule) {
|
|
9636
|
-
console.warn('MilitarySymbolModule 未注入 EventModule
|
|
9820
|
+
console.warn('MilitarySymbolModule 未注入 EventModule,无法启用编辑');
|
|
9637
9821
|
return;
|
|
9638
9822
|
}
|
|
9639
9823
|
|
|
9640
9824
|
this._editMode = true;
|
|
9825
|
+
this._editSymbolId = id;
|
|
9826
|
+
this._createEditHandles(id);
|
|
9827
|
+
|
|
9828
|
+
const downId = this.eventModule.registerObserver('mouse:down', (lngLat, pickedEntity, movement) => {
|
|
9829
|
+
const handleType = this._getHandleType(pickedEntity);
|
|
9830
|
+
let symbolId = null;
|
|
9831
|
+
if (handleType) {
|
|
9832
|
+
symbolId = this._editSymbolId;
|
|
9833
|
+
} else {
|
|
9834
|
+
symbolId = this._getSymbolIdFromPick(pickedEntity);
|
|
9835
|
+
}
|
|
9836
|
+
if (!symbolId || symbolId !== this._editSymbolId) return;
|
|
9837
|
+
|
|
9838
|
+
const symbol = this.symbolMap.get(symbolId);
|
|
9839
|
+
const centerScreen = this._cartesianToScreen(symbol.entity.position.getValue(Cesium$2.JulianDate.now()));
|
|
9840
|
+
const mouseScreen = movement.position;
|
|
9841
|
+
if (centerScreen && mouseScreen) {
|
|
9842
|
+
const dx = mouseScreen.x - centerScreen.x;
|
|
9843
|
+
const dy = mouseScreen.y - centerScreen.y;
|
|
9844
|
+
this._dragStartDist = Math.hypot(dx, dy);
|
|
9845
|
+
this._dragStartAngle = Math.atan2(dx, -dy);
|
|
9846
|
+
} else {
|
|
9847
|
+
this._dragStartDist = 0;
|
|
9848
|
+
this._dragStartAngle = 0;
|
|
9849
|
+
}
|
|
9641
9850
|
|
|
9642
|
-
const downId = this.eventModule.registerObserver('mouse:down', (lngLat, pickedEntity) => {
|
|
9643
|
-
const symbolId = this._getSymbolIdFromPick(pickedEntity);
|
|
9644
|
-
if (!symbolId) return;
|
|
9645
9851
|
this._draggingId = symbolId;
|
|
9852
|
+
this._draggingHandle = handleType || 'move';
|
|
9853
|
+
this._dragStartScale = symbol.metadata.scale;
|
|
9854
|
+
this._dragStartRotation = symbol.metadata.rotation || 0;
|
|
9646
9855
|
this.viewer.scene.screenSpaceCameraController.enableInputs = false;
|
|
9647
9856
|
});
|
|
9648
9857
|
|
|
9649
9858
|
const moveId = this.eventModule.registerObserver('mouse:move', (lngLat, pickedEntity, movement) => {
|
|
9650
9859
|
if (!this._draggingId || !movement?.endPosition) return;
|
|
9651
9860
|
|
|
9652
|
-
const
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
carto.
|
|
9661
|
-
|
|
9662
|
-
|
|
9861
|
+
const symbol = this.symbolMap.get(this._draggingId);
|
|
9862
|
+
if (!symbol) return;
|
|
9863
|
+
|
|
9864
|
+
if (this._draggingHandle === 'move') {
|
|
9865
|
+
const cartesian = this.viewer.scene.pickPosition(movement.endPosition)
|
|
9866
|
+
|| this.viewer.scene.camera.pickEllipsoid(movement.endPosition, this.viewer.scene.globe.ellipsoid);
|
|
9867
|
+
if (!cartesian) return;
|
|
9868
|
+
|
|
9869
|
+
const carto = Cesium$2.Cartographic.fromCartesian(cartesian);
|
|
9870
|
+
const position = [
|
|
9871
|
+
Cesium$2.Math.toDegrees(carto.longitude),
|
|
9872
|
+
Cesium$2.Math.toDegrees(carto.latitude),
|
|
9873
|
+
carto.height,
|
|
9874
|
+
];
|
|
9875
|
+
this.update(this._draggingId, { position });
|
|
9876
|
+
this._updateHandlePositions(this._draggingId);
|
|
9877
|
+
} else if (this._draggingHandle === 'scale') {
|
|
9878
|
+
const centerScreen = this._cartesianToScreen(symbol.entity.position.getValue(Cesium$2.JulianDate.now()));
|
|
9879
|
+
if (!centerScreen) return;
|
|
9880
|
+
const dx = movement.endPosition.x - centerScreen.x;
|
|
9881
|
+
const dy = movement.endPosition.y - centerScreen.y;
|
|
9882
|
+
const dist = Math.hypot(dx, dy);
|
|
9883
|
+
const ratio = this._dragStartDist > 0 ? dist / this._dragStartDist : 1;
|
|
9884
|
+
const newScale = Math.max(0.1, this._dragStartScale * ratio);
|
|
9885
|
+
this.update(this._draggingId, { scale: newScale });
|
|
9886
|
+
} else if (this._draggingHandle === 'rotate') {
|
|
9887
|
+
const centerScreen = this._cartesianToScreen(symbol.entity.position.getValue(Cesium$2.JulianDate.now()));
|
|
9888
|
+
if (!centerScreen) return;
|
|
9889
|
+
const dx = movement.endPosition.x - centerScreen.x;
|
|
9890
|
+
const dy = movement.endPosition.y - centerScreen.y;
|
|
9891
|
+
const angle = Math.atan2(dx, -dy);
|
|
9892
|
+
const deltaDeg = Cesium$2.Math.toDegrees(angle - this._dragStartAngle);
|
|
9893
|
+
let newRotation = this._dragStartRotation + deltaDeg;
|
|
9894
|
+
newRotation = ((newRotation % 360) + 360) % 360;
|
|
9895
|
+
this.update(this._draggingId, { rotation: newRotation });
|
|
9896
|
+
}
|
|
9663
9897
|
});
|
|
9664
9898
|
|
|
9665
9899
|
const upId = this.eventModule.registerObserver('mouse:up', () => {
|
|
9666
9900
|
if (!this._draggingId) return;
|
|
9667
9901
|
const symbol = this.symbolMap.get(this._draggingId);
|
|
9668
|
-
const payload = symbol
|
|
9902
|
+
const payload = symbol
|
|
9903
|
+
? {
|
|
9904
|
+
id: this._draggingId,
|
|
9905
|
+
position: [...symbol.metadata.position],
|
|
9906
|
+
scale: symbol.metadata.scale,
|
|
9907
|
+
rotation: symbol.metadata.rotation,
|
|
9908
|
+
}
|
|
9909
|
+
: null;
|
|
9669
9910
|
this._draggingId = null;
|
|
9911
|
+
this._draggingHandle = null;
|
|
9670
9912
|
this.viewer.scene.screenSpaceCameraController.enableInputs = true;
|
|
9671
9913
|
if (payload) {
|
|
9672
|
-
this._positionChangedCallbacks.forEach((callback) => callback(payload));
|
|
9914
|
+
this._positionChangedCallbacks.forEach((callback) => callback({ id: payload.id, position: payload.position }));
|
|
9915
|
+
this._transformChangedCallbacks.forEach((callback) => callback(payload));
|
|
9673
9916
|
}
|
|
9674
9917
|
});
|
|
9675
9918
|
|
|
@@ -9677,13 +9920,12 @@ class MilitarySymbolModule {
|
|
|
9677
9920
|
}
|
|
9678
9921
|
|
|
9679
9922
|
/**
|
|
9680
|
-
*
|
|
9923
|
+
* 禁用军标编辑模式
|
|
9681
9924
|
*/
|
|
9682
9925
|
disableEditMode() {
|
|
9683
9926
|
if (!this._editMode) return;
|
|
9684
9927
|
if (this.eventModule) {
|
|
9685
9928
|
this._dragObserverIds.forEach((observerId) => {
|
|
9686
|
-
// 每个观察者注册时的事件类型固定,分别注销
|
|
9687
9929
|
['mouse:down', 'mouse:move', 'mouse:up'].forEach((eventType) => {
|
|
9688
9930
|
try {
|
|
9689
9931
|
this.eventModule.unregisterObserver(eventType, observerId);
|
|
@@ -9694,13 +9936,18 @@ class MilitarySymbolModule {
|
|
|
9694
9936
|
});
|
|
9695
9937
|
}
|
|
9696
9938
|
this._dragObserverIds = [];
|
|
9939
|
+
if (this._editSymbolId) {
|
|
9940
|
+
this._removeEditHandles(this._editSymbolId);
|
|
9941
|
+
}
|
|
9942
|
+
this._editSymbolId = null;
|
|
9697
9943
|
this._draggingId = null;
|
|
9944
|
+
this._draggingHandle = null;
|
|
9698
9945
|
this.viewer.scene.screenSpaceCameraController.enableInputs = true;
|
|
9699
9946
|
this._editMode = false;
|
|
9700
9947
|
}
|
|
9701
9948
|
|
|
9702
9949
|
/**
|
|
9703
|
-
*
|
|
9950
|
+
* 注册位置变化回调(仅位置)
|
|
9704
9951
|
* @param {Function} callback 回调参数 { id, position }
|
|
9705
9952
|
* @returns {Function} 注销函数
|
|
9706
9953
|
*/
|
|
@@ -9708,6 +9955,16 @@ class MilitarySymbolModule {
|
|
|
9708
9955
|
this._positionChangedCallbacks.add(callback);
|
|
9709
9956
|
return () => this._positionChangedCallbacks.delete(callback);
|
|
9710
9957
|
}
|
|
9958
|
+
|
|
9959
|
+
/**
|
|
9960
|
+
* 注册变换变化回调(位置、缩放、旋转)
|
|
9961
|
+
* @param {Function} callback 回调参数 { id, position, scale, rotation }
|
|
9962
|
+
* @returns {Function} 注销函数
|
|
9963
|
+
*/
|
|
9964
|
+
onTransformChanged(callback) {
|
|
9965
|
+
this._transformChangedCallbacks.add(callback);
|
|
9966
|
+
return () => this._transformChangedCallbacks.delete(callback);
|
|
9967
|
+
}
|
|
9711
9968
|
}
|
|
9712
9969
|
|
|
9713
9970
|
/**
|