huweili-cesium 1.3.1 → 1.3.3
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/js/drawFenceNew.js +165 -31
- package/package.json +1 -1
package/js/drawFenceNew.js
CHANGED
|
@@ -1002,10 +1002,20 @@ export function drawFenceNew() {
|
|
|
1002
1002
|
let centerPointEntity = null
|
|
1003
1003
|
// activePointEntity:活动点实体(跟随鼠标的边界点)
|
|
1004
1004
|
let activePointEntity = null
|
|
1005
|
-
//
|
|
1006
|
-
let
|
|
1005
|
+
// circleWallEntity / circleOutlineEntity / radiusLineEntity:绘制过程预览(与最终围栏一致的贴地圆边)
|
|
1006
|
+
let circleWallEntity = null
|
|
1007
|
+
let circleOutlineEntity = null
|
|
1008
|
+
let radiusLineEntity = null
|
|
1009
|
+
// 预览几何缓存,仅在鼠标移动时更新,避免每帧重复计算
|
|
1010
|
+
let previewCirclePositions = []
|
|
1011
|
+
let previewWallMaxHeights = []
|
|
1012
|
+
let previewWallMinHeights = []
|
|
1013
|
+
let previewRadiusLinePositions = []
|
|
1014
|
+
let previewRenderFrameId = null
|
|
1007
1015
|
// tipEntity:提示文字实体(显示"点击确定圆心"等提示)
|
|
1008
1016
|
let tipEntity = null
|
|
1017
|
+
// radiusLabelEntity:绘制过程中显示当前半径的标签
|
|
1018
|
+
let radiusLabelEntity = null
|
|
1009
1019
|
// nameLabelEntity:围栏名称标签实体
|
|
1010
1020
|
let nameLabelEntity = null
|
|
1011
1021
|
// handler:屏幕事件处理器(监听鼠标点击、移动等)
|
|
@@ -1016,10 +1026,13 @@ export function drawFenceNew() {
|
|
|
1016
1026
|
// ==================== 临时实体ID配置 ====================
|
|
1017
1027
|
// 这些是绘制过程中临时显示的实体,绘制完成后会清理
|
|
1018
1028
|
const tempIds = {
|
|
1019
|
-
|
|
1029
|
+
circleWall: `${options.id}_draw_circle_wall`,
|
|
1030
|
+
circleOutline: `${options.id}_draw_circle_outline`,
|
|
1031
|
+
radiusLine: `${options.id}_draw_radius_line`,
|
|
1020
1032
|
center: `${options.id}_draw_center_point`, // 临时圆心点
|
|
1021
1033
|
active: `${options.id}_draw_active_point`, // 临时边界点
|
|
1022
|
-
tip: `${options.id}_draw_tip
|
|
1034
|
+
tip: `${options.id}_draw_tip`, // 临时提示文字
|
|
1035
|
+
radiusLabel: `${options.id}_draw_radius_label`, // 临时半径标签
|
|
1023
1036
|
}
|
|
1024
1037
|
|
|
1025
1038
|
// ==================== 辅助函数部分 ====================
|
|
@@ -1078,6 +1091,23 @@ export function drawFenceNew() {
|
|
|
1078
1091
|
return geodesic.surfaceDistance
|
|
1079
1092
|
}
|
|
1080
1093
|
|
|
1094
|
+
const formatRadius = (radius) => {
|
|
1095
|
+
if (!Number.isFinite(radius)) return '0 m'
|
|
1096
|
+
if (radius >= 1000) return `${(radius / 1000).toFixed(2)} km`
|
|
1097
|
+
return `${radius.toFixed(2)} m`
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
const getRadiusLabelPosition = () => {
|
|
1101
|
+
if (!centerPosition || !edgePosition) return null
|
|
1102
|
+
const centerCartographic = Cesium.Cartographic.fromCartesian(centerPosition)
|
|
1103
|
+
const edgeCartographic = Cesium.Cartographic.fromCartesian(edgePosition)
|
|
1104
|
+
return Cesium.Cartesian3.fromRadians(
|
|
1105
|
+
(centerCartographic.longitude + edgeCartographic.longitude) / 2,
|
|
1106
|
+
(centerCartographic.latitude + edgeCartographic.latitude) / 2,
|
|
1107
|
+
0,
|
|
1108
|
+
)
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1081
1111
|
/**
|
|
1082
1112
|
* 获取提示文字的位置(鼠标位置优先)
|
|
1083
1113
|
*
|
|
@@ -1099,7 +1129,7 @@ export function drawFenceNew() {
|
|
|
1099
1129
|
}
|
|
1100
1130
|
|
|
1101
1131
|
// 已经有圆心 → 提示用户"移动调整半径,点击或右键完成"
|
|
1102
|
-
return
|
|
1132
|
+
return `移动鼠标调整半径,当前半径:${formatRadius(getRadius())},点击或右键完成绘制`
|
|
1103
1133
|
}
|
|
1104
1134
|
|
|
1105
1135
|
/**
|
|
@@ -1119,6 +1149,42 @@ export function drawFenceNew() {
|
|
|
1119
1149
|
})
|
|
1120
1150
|
}
|
|
1121
1151
|
|
|
1152
|
+
const updatePreviewGeometry = () => {
|
|
1153
|
+
if (!centerPosition || !edgePosition) {
|
|
1154
|
+
previewCirclePositions = []
|
|
1155
|
+
previewWallMaxHeights = []
|
|
1156
|
+
previewWallMinHeights = []
|
|
1157
|
+
previewRadiusLinePositions = []
|
|
1158
|
+
return
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
const radius = getRadius()
|
|
1162
|
+
previewRadiusLinePositions = [centerPosition, edgePosition]
|
|
1163
|
+
|
|
1164
|
+
if (radius <= 0) {
|
|
1165
|
+
previewCirclePositions = []
|
|
1166
|
+
previewWallMaxHeights = []
|
|
1167
|
+
previewWallMinHeights = []
|
|
1168
|
+
return
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
const centerData = cartesianToLngLatHeight(centerPosition)
|
|
1172
|
+
const circleLngLats = generateCircleLngLatPositions(centerData.lng, centerData.lat, radius)
|
|
1173
|
+
const footprint = circleLngLats.map(cartesianFootprintFromLngLat)
|
|
1174
|
+
previewCirclePositions = [...footprint, footprint[0]]
|
|
1175
|
+
previewWallMaxHeights = previewCirclePositions.map(() => height)
|
|
1176
|
+
previewWallMinHeights = previewCirclePositions.map(() => 0)
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
const schedulePreviewUpdate = () => {
|
|
1180
|
+
if (previewRenderFrameId !== null) return
|
|
1181
|
+
previewRenderFrameId = requestAnimationFrame(() => {
|
|
1182
|
+
previewRenderFrameId = null
|
|
1183
|
+
updatePreviewGeometry()
|
|
1184
|
+
map.scene.requestRender()
|
|
1185
|
+
})
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1122
1188
|
// ==================== 核心业务函数 ====================
|
|
1123
1189
|
|
|
1124
1190
|
/**
|
|
@@ -1142,25 +1208,45 @@ export function drawFenceNew() {
|
|
|
1142
1208
|
})
|
|
1143
1209
|
}
|
|
1144
1210
|
|
|
1145
|
-
// 2.
|
|
1146
|
-
if (!
|
|
1147
|
-
|
|
1148
|
-
id: tempIds.
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1211
|
+
// 2. 创建贴地圆边预览(确定圆心后显示,与最终围栏 polyline / wall 一致)
|
|
1212
|
+
if (centerPosition && !circleWallEntity) {
|
|
1213
|
+
circleWallEntity = map.entities.add({
|
|
1214
|
+
id: tempIds.circleWall,
|
|
1215
|
+
wall: {
|
|
1216
|
+
positions: new Cesium.CallbackProperty(() => previewCirclePositions, false),
|
|
1217
|
+
maximumHeights: new Cesium.CallbackProperty(() => previewWallMaxHeights, false),
|
|
1218
|
+
minimumHeights: new Cesium.CallbackProperty(() => previewWallMinHeights, false),
|
|
1219
|
+
material: color.withAlpha(0.18),
|
|
1220
|
+
outline: true,
|
|
1221
|
+
outlineColor: color,
|
|
1222
|
+
outlineWidth,
|
|
1223
|
+
},
|
|
1224
|
+
})
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
if (centerPosition && !circleOutlineEntity) {
|
|
1228
|
+
circleOutlineEntity = map.entities.add({
|
|
1229
|
+
id: tempIds.circleOutline,
|
|
1230
|
+
polyline: {
|
|
1231
|
+
positions: new Cesium.CallbackProperty(() => previewCirclePositions, false),
|
|
1232
|
+
width: outlineWidth,
|
|
1233
|
+
material: color,
|
|
1234
|
+
clampToGround: true,
|
|
1235
|
+
arcType: Cesium.ArcType.GEODESIC,
|
|
1236
|
+
},
|
|
1237
|
+
})
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
if (centerPosition && !radiusLineEntity) {
|
|
1241
|
+
radiusLineEntity = map.entities.add({
|
|
1242
|
+
id: tempIds.radiusLine,
|
|
1243
|
+
polyline: {
|
|
1244
|
+
positions: new Cesium.CallbackProperty(() => previewRadiusLinePositions, false),
|
|
1245
|
+
width: Math.max(1, outlineWidth - 1),
|
|
1246
|
+
material: color.withAlpha(0.85),
|
|
1247
|
+
clampToGround: true,
|
|
1248
|
+
arcType: Cesium.ArcType.GEODESIC,
|
|
1249
|
+
},
|
|
1164
1250
|
})
|
|
1165
1251
|
}
|
|
1166
1252
|
|
|
@@ -1180,7 +1266,32 @@ export function drawFenceNew() {
|
|
|
1180
1266
|
})
|
|
1181
1267
|
}
|
|
1182
1268
|
|
|
1183
|
-
// 4.
|
|
1269
|
+
// 4. 创建半径标签(确定圆心后显示)
|
|
1270
|
+
if (!radiusLabelEntity && centerPosition) {
|
|
1271
|
+
radiusLabelEntity = map.entities.add({
|
|
1272
|
+
id: tempIds.radiusLabel,
|
|
1273
|
+
position: new Cesium.CallbackProperty(() => getRadiusLabelPosition(), false),
|
|
1274
|
+
label: {
|
|
1275
|
+
text: new Cesium.CallbackProperty(() => formatRadius(getRadius()), false),
|
|
1276
|
+
font: 'bold 10px Microsoft YaHei',
|
|
1277
|
+
fillColor: Cesium.Color.WHITE,
|
|
1278
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
1279
|
+
outlineColor: Cesium.Color.BLACK,
|
|
1280
|
+
outlineWidth: 2,
|
|
1281
|
+
showBackground: true,
|
|
1282
|
+
backgroundColor: Cesium.Color.fromCssColorString('rgba(0, 0, 0, 0.75)'),
|
|
1283
|
+
backgroundPadding: new Cesium.Cartesian2(4, 4),
|
|
1284
|
+
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
1285
|
+
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
|
1286
|
+
pixelOffset: new Cesium.Cartesian2(0, -16),
|
|
1287
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
1288
|
+
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000),
|
|
1289
|
+
scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.6),
|
|
1290
|
+
},
|
|
1291
|
+
})
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
// 5. 创建提示文字实体(如果还没有)
|
|
1184
1295
|
if (!tipEntity) {
|
|
1185
1296
|
tipEntity = createMouseTipEntity(map, {
|
|
1186
1297
|
id: tempIds.tip,
|
|
@@ -1196,16 +1307,28 @@ export function drawFenceNew() {
|
|
|
1196
1307
|
*/
|
|
1197
1308
|
const cleanupTempEntities = () => {
|
|
1198
1309
|
// 遍历所有临时实体,如果存在就从地图上移除
|
|
1199
|
-
;[
|
|
1310
|
+
;[circleWallEntity, circleOutlineEntity, radiusLineEntity, centerPointEntity, activePointEntity, radiusLabelEntity, tipEntity, nameLabelEntity].forEach((entity) => {
|
|
1200
1311
|
if (entity) {
|
|
1201
1312
|
map.entities.remove(entity)
|
|
1202
1313
|
}
|
|
1203
1314
|
})
|
|
1204
1315
|
// 将变量清空,防止内存泄露
|
|
1205
|
-
|
|
1316
|
+
circleWallEntity = null
|
|
1317
|
+
circleOutlineEntity = null
|
|
1318
|
+
radiusLineEntity = null
|
|
1206
1319
|
centerPointEntity = null
|
|
1207
1320
|
activePointEntity = null
|
|
1321
|
+
radiusLabelEntity = null
|
|
1322
|
+
tipEntity = null
|
|
1208
1323
|
nameLabelEntity = null
|
|
1324
|
+
previewCirclePositions = []
|
|
1325
|
+
previewWallMaxHeights = []
|
|
1326
|
+
previewWallMinHeights = []
|
|
1327
|
+
previewRadiusLinePositions = []
|
|
1328
|
+
if (previewRenderFrameId !== null) {
|
|
1329
|
+
cancelAnimationFrame(previewRenderFrameId)
|
|
1330
|
+
previewRenderFrameId = null
|
|
1331
|
+
}
|
|
1209
1332
|
}
|
|
1210
1333
|
|
|
1211
1334
|
/**
|
|
@@ -1245,9 +1368,17 @@ export function drawFenceNew() {
|
|
|
1245
1368
|
const footprint = circleLngLats.map(cartesianFootprintFromLngLat)
|
|
1246
1369
|
const wallPositions = [...footprint, footprint[0]]
|
|
1247
1370
|
|
|
1248
|
-
if (
|
|
1249
|
-
map.entities.remove(
|
|
1250
|
-
|
|
1371
|
+
if (circleWallEntity) {
|
|
1372
|
+
map.entities.remove(circleWallEntity)
|
|
1373
|
+
circleWallEntity = null
|
|
1374
|
+
}
|
|
1375
|
+
if (circleOutlineEntity) {
|
|
1376
|
+
map.entities.remove(circleOutlineEntity)
|
|
1377
|
+
circleOutlineEntity = null
|
|
1378
|
+
}
|
|
1379
|
+
if (radiusLineEntity) {
|
|
1380
|
+
map.entities.remove(radiusLineEntity)
|
|
1381
|
+
radiusLineEntity = null
|
|
1251
1382
|
}
|
|
1252
1383
|
|
|
1253
1384
|
const fenceEntity = map.entities.add({
|
|
@@ -1273,13 +1404,14 @@ export function drawFenceNew() {
|
|
|
1273
1404
|
|
|
1274
1405
|
await applyTerrainWallToEntity(map, fenceEntity, circleLngLats, height)
|
|
1275
1406
|
|
|
1276
|
-
;[centerPointEntity, activePointEntity, tipEntity].forEach((entity) => {
|
|
1407
|
+
;[centerPointEntity, activePointEntity, radiusLabelEntity, tipEntity].forEach((entity) => {
|
|
1277
1408
|
if (entity) {
|
|
1278
1409
|
map.entities.remove(entity)
|
|
1279
1410
|
}
|
|
1280
1411
|
})
|
|
1281
1412
|
centerPointEntity = null
|
|
1282
1413
|
activePointEntity = null
|
|
1414
|
+
radiusLabelEntity = null
|
|
1283
1415
|
tipEntity = null
|
|
1284
1416
|
|
|
1285
1417
|
const centerHeights = await sampleTerrainHeights(map, [centerData])
|
|
@@ -1404,6 +1536,7 @@ export function drawFenceNew() {
|
|
|
1404
1536
|
centerPosition = Cesium.Cartesian3.clone(cartesian)
|
|
1405
1537
|
edgePosition = Cesium.Cartesian3.clone(cartesian) // 边界点初始化为圆心
|
|
1406
1538
|
ensurePreviewEntities() // 确保预览实体都创建好
|
|
1539
|
+
schedulePreviewUpdate()
|
|
1407
1540
|
emitChange() // 触发变化回调
|
|
1408
1541
|
return
|
|
1409
1542
|
}
|
|
@@ -1426,6 +1559,7 @@ export function drawFenceNew() {
|
|
|
1426
1559
|
// 如果已经确定了圆心 → 实时更新边界点,让预览跟随鼠标
|
|
1427
1560
|
if (!centerPosition) return
|
|
1428
1561
|
edgePosition = Cesium.Cartesian3.clone(cartesian)
|
|
1562
|
+
schedulePreviewUpdate()
|
|
1429
1563
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
1430
1564
|
|
|
1431
1565
|
// ==================== 事件3:鼠标右键点击 ====================
|