huweili-cesium 1.2.12 → 1.2.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/js/index.js +1 -0
- package/js/measureDistance.js +413 -0
- package/package.json +3 -1
package/js/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { getClickHandler, openDroneDetailById, closeDroneDetailById, bindDroneLa
|
|
|
8
8
|
export { createCustomToolbarButtons } from './customToolbarButtons.js'
|
|
9
9
|
export { drawFence } from './drawFence.js'
|
|
10
10
|
export { drawFenceNew } from './drawFenceNew.js'
|
|
11
|
+
export { measureDistance } from './measureDistance.js'
|
|
11
12
|
export { createDroneRippleDom } from './droneRipple.js'
|
|
12
13
|
export { geometryConfig } from './geometry.js'
|
|
13
14
|
export { groundLinkConfig } from './groundLink.js'
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 两点地面直线测距模块
|
|
3
|
+
*
|
|
4
|
+
* 点击地图上第一个点作为起点,再点击第二个点作为终点,测量两点之间的地面直线距离。
|
|
5
|
+
* 无论地图处于 2D 还是 3D,采样点都会被转换为贴地坐标(height = 0),不携带高度。
|
|
6
|
+
*
|
|
7
|
+
* @author huweili
|
|
8
|
+
* @email czxyhuweili@163.com
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
import * as Cesium from 'cesium'
|
|
12
|
+
import { useMapStore } from './stores/mapStore.js'
|
|
13
|
+
|
|
14
|
+
export function measureDistance() {
|
|
15
|
+
const mapStore = useMapStore()
|
|
16
|
+
|
|
17
|
+
const formatDistance = (distance) => {
|
|
18
|
+
if (!Number.isFinite(distance)) return '0 m'
|
|
19
|
+
if (distance >= 1000) return `${(distance / 1000).toFixed(2)} km`
|
|
20
|
+
return `${distance.toFixed(2)} m`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const createMouseTipEntity = (map, options) => {
|
|
24
|
+
return map.entities.add({
|
|
25
|
+
id: options.id,
|
|
26
|
+
position: new Cesium.CallbackProperty(() => options.getPosition(), false),
|
|
27
|
+
label: {
|
|
28
|
+
text: new Cesium.CallbackProperty(() => options.getText(), false),
|
|
29
|
+
font: options.font || '10px Microsoft YaHei',
|
|
30
|
+
fillColor: options.fillColor || Cesium.Color.WHITE,
|
|
31
|
+
showBackground: true,
|
|
32
|
+
backgroundColor: Cesium.Color.fromCssColorString(options.backgroundColor || 'rgba(0, 0, 0, 0.6)'),
|
|
33
|
+
backgroundPadding: options.backgroundPadding || new Cesium.Cartesian2(10, 6),
|
|
34
|
+
verticalOrigin: options.verticalOrigin || Cesium.VerticalOrigin.BOTTOM,
|
|
35
|
+
horizontalOrigin: options.horizontalOrigin || Cesium.HorizontalOrigin.LEFT,
|
|
36
|
+
pixelOffset: options.pixelOffset || new Cesium.Cartesian2(16, -16),
|
|
37
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
38
|
+
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, options.maxDistance || Number.POSITIVE_INFINITY)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 从屏幕坐标拾取地面点,并强制转换为 height = 0 的地面坐标。
|
|
45
|
+
* @param {Cesium.Viewer} map Cesium Viewer 实例
|
|
46
|
+
* @param {Cesium.Cartesian2} screenPosition 屏幕坐标
|
|
47
|
+
* @returns {Cesium.Cartesian3|null}
|
|
48
|
+
*/
|
|
49
|
+
const getGroundCartesianFromScreen = (map, screenPosition) => {
|
|
50
|
+
if (!screenPosition) return null
|
|
51
|
+
|
|
52
|
+
const scene = map.scene
|
|
53
|
+
let cartesian = null
|
|
54
|
+
|
|
55
|
+
if (scene.pickPositionSupported) {
|
|
56
|
+
cartesian = scene.pickPosition(screenPosition)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!Cesium.defined(cartesian)) {
|
|
60
|
+
const ray = map.camera.getPickRay(screenPosition)
|
|
61
|
+
if (!ray) return null
|
|
62
|
+
cartesian = scene.globe.pick(ray, scene)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!Cesium.defined(cartesian)) return null
|
|
66
|
+
|
|
67
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
|
68
|
+
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const cartesianToLngLatHeight = (cartesian) => {
|
|
72
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
|
73
|
+
return {
|
|
74
|
+
lng: Cesium.Math.toDegrees(cartographic.longitude),
|
|
75
|
+
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
|
76
|
+
height: 0
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const createGroundPolylinePositions = (startPosition, endPosition, segmentCount = 32) => {
|
|
81
|
+
if (!startPosition || !endPosition) return []
|
|
82
|
+
|
|
83
|
+
const start = Cesium.Cartographic.fromCartesian(startPosition)
|
|
84
|
+
const end = Cesium.Cartographic.fromCartesian(endPosition)
|
|
85
|
+
const positions = []
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i <= segmentCount; i += 1) {
|
|
88
|
+
const t = i / segmentCount
|
|
89
|
+
positions.push(
|
|
90
|
+
Cesium.Cartesian3.fromRadians(
|
|
91
|
+
Cesium.Math.lerp(start.longitude, end.longitude, t),
|
|
92
|
+
Cesium.Math.lerp(start.latitude, end.latitude, t),
|
|
93
|
+
0
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return positions
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const getGroundDistance = (startPosition, endPosition) => {
|
|
102
|
+
if (!startPosition || !endPosition) return 0
|
|
103
|
+
return Cesium.Cartesian3.distance(startPosition, endPosition)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 开始两点地面直线测距
|
|
108
|
+
* @param {Object} options 配置项
|
|
109
|
+
* @param {string} [options.mapId] 地图实例 ID
|
|
110
|
+
* @param {string} options.id 测距图形唯一标识
|
|
111
|
+
* @param {string} [options.color='#00ffff'] 线和点颜色
|
|
112
|
+
* @param {number} [options.width=3] 线宽
|
|
113
|
+
* @param {(result: Object) => void} [options.onFinish] 测距完成回调
|
|
114
|
+
* @param {(result: Object) => void} [options.onChange] 测距过程回调
|
|
115
|
+
* @param {() => void} [options.onCancel] 取消回调
|
|
116
|
+
* @returns {Object|null} 测距控制器
|
|
117
|
+
*/
|
|
118
|
+
const startMeasure = (options = {}) => {
|
|
119
|
+
const map = mapStore.getMap(options.mapId)
|
|
120
|
+
if (!map) {
|
|
121
|
+
console.error('地图实例不存在')
|
|
122
|
+
return null
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!options.id) {
|
|
126
|
+
console.error('测距时必须提供 id')
|
|
127
|
+
return null
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (mapStore.hasGraphicMap(options.id, options.mapId)) {
|
|
131
|
+
console.warn(`id: ${options.id} 测距结果已存在`)
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const color = Cesium.Color.fromCssColorString(options.color || '#00ffff')
|
|
136
|
+
const width = options.width ?? 3
|
|
137
|
+
const clampToGround = options.clampToGround ?? true
|
|
138
|
+
const lineMaterial =
|
|
139
|
+
options.lineMaterial ||
|
|
140
|
+
new Cesium.PolylineGlowMaterialProperty({
|
|
141
|
+
color: Cesium.Color.fromAlpha(color, options.opacity ?? 0.95),
|
|
142
|
+
glowPower: options.glowPower ?? 0.12,
|
|
143
|
+
taperPower: options.taperPower ?? 0
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
let startPosition = null
|
|
147
|
+
let endPosition = null
|
|
148
|
+
let floatingPosition = null
|
|
149
|
+
let cursorPosition = null
|
|
150
|
+
let startPointEntity = null
|
|
151
|
+
let endPointEntity = null
|
|
152
|
+
let lineEntity = null
|
|
153
|
+
let distanceLabelEntity = null
|
|
154
|
+
let tipEntity = null
|
|
155
|
+
let handler = null
|
|
156
|
+
let isFinished = false
|
|
157
|
+
|
|
158
|
+
const tempIds = {
|
|
159
|
+
startPoint: `${options.id}_measure_start_point`,
|
|
160
|
+
endPoint: `${options.id}_measure_end_point`,
|
|
161
|
+
line: `${options.id}_measure_line`,
|
|
162
|
+
label: `${options.id}_measure_label`,
|
|
163
|
+
tip: `${options.id}_measure_tip`
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const getLinePositions = () => {
|
|
167
|
+
if (!startPosition) return []
|
|
168
|
+
const targetPosition = endPosition || floatingPosition
|
|
169
|
+
if (!targetPosition) return [startPosition]
|
|
170
|
+
return createGroundPolylinePositions(startPosition, targetPosition, options.segmentCount ?? 48)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const getCurrentDistance = () => getGroundDistance(startPosition, endPosition || floatingPosition)
|
|
174
|
+
|
|
175
|
+
const getMidPosition = () => {
|
|
176
|
+
const targetPosition = endPosition || floatingPosition
|
|
177
|
+
if (!startPosition || !targetPosition) return startPosition || targetPosition || cursorPosition || null
|
|
178
|
+
const startCartographic = Cesium.Cartographic.fromCartesian(startPosition)
|
|
179
|
+
const endCartographic = Cesium.Cartographic.fromCartesian(targetPosition)
|
|
180
|
+
return Cesium.Cartesian3.fromRadians(
|
|
181
|
+
(startCartographic.longitude + endCartographic.longitude) / 2,
|
|
182
|
+
(startCartographic.latitude + endCartographic.latitude) / 2,
|
|
183
|
+
0
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const getTipText = () => {
|
|
188
|
+
if (!startPosition) return '点击确定起点'
|
|
189
|
+
if (!endPosition) return `点击确定终点,当前距离:${formatDistance(getCurrentDistance())}`
|
|
190
|
+
return `测距完成:${formatDistance(getCurrentDistance())}`
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const buildResult = () => ({
|
|
194
|
+
id: options.id,
|
|
195
|
+
start: startPosition ? cartesianToLngLatHeight(startPosition) : null,
|
|
196
|
+
end: endPosition ? cartesianToLngLatHeight(endPosition) : null,
|
|
197
|
+
distance: getGroundDistance(startPosition, endPosition),
|
|
198
|
+
distanceText: formatDistance(getGroundDistance(startPosition, endPosition))
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const emitChange = () => {
|
|
202
|
+
if (typeof options.onChange !== 'function' || !startPosition) return
|
|
203
|
+
options.onChange({
|
|
204
|
+
id: options.id,
|
|
205
|
+
start: cartesianToLngLatHeight(startPosition),
|
|
206
|
+
end: (endPosition || floatingPosition) ? cartesianToLngLatHeight(endPosition || floatingPosition) : null,
|
|
207
|
+
distance: getCurrentDistance(),
|
|
208
|
+
distanceText: formatDistance(getCurrentDistance())
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const ensurePreviewEntities = () => {
|
|
213
|
+
if (!startPointEntity) {
|
|
214
|
+
startPointEntity = map.entities.add({
|
|
215
|
+
id: tempIds.startPoint,
|
|
216
|
+
position: startPosition,
|
|
217
|
+
point: {
|
|
218
|
+
pixelSize: 10,
|
|
219
|
+
color,
|
|
220
|
+
outlineColor: Cesium.Color.WHITE,
|
|
221
|
+
outlineWidth: 2,
|
|
222
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
223
|
+
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!lineEntity) {
|
|
229
|
+
lineEntity = map.entities.add({
|
|
230
|
+
id: tempIds.line,
|
|
231
|
+
polyline: {
|
|
232
|
+
positions: new Cesium.CallbackProperty(() => getLinePositions(), false),
|
|
233
|
+
width,
|
|
234
|
+
material: lineMaterial,
|
|
235
|
+
clampToGround,
|
|
236
|
+
arcType: Cesium.ArcType.GEODESIC,
|
|
237
|
+
granularity: options.granularity ?? Cesium.Math.toRadians(0.2),
|
|
238
|
+
depthFailMaterial: options.depthFailMaterial || new Cesium.ColorMaterialProperty(Cesium.Color.fromAlpha(color, 0.7))
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (!distanceLabelEntity) {
|
|
244
|
+
distanceLabelEntity = map.entities.add({
|
|
245
|
+
id: tempIds.label,
|
|
246
|
+
position: new Cesium.CallbackProperty(() => getMidPosition(), false),
|
|
247
|
+
label: {
|
|
248
|
+
text: new Cesium.CallbackProperty(() => formatDistance(getCurrentDistance()), false),
|
|
249
|
+
font: '14px Microsoft YaHei',
|
|
250
|
+
fillColor: Cesium.Color.WHITE,
|
|
251
|
+
showBackground: true,
|
|
252
|
+
backgroundColor: Cesium.Color.fromCssColorString('rgba(0, 0, 0, 0.65)'),
|
|
253
|
+
backgroundPadding: new Cesium.Cartesian2(10, 6),
|
|
254
|
+
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
255
|
+
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
|
256
|
+
pixelOffset: new Cesium.Cartesian2(0, -12),
|
|
257
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
258
|
+
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, Number.POSITIVE_INFINITY)
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const createEndPointEntity = () => {
|
|
265
|
+
if (endPointEntity || !endPosition) return
|
|
266
|
+
endPointEntity = map.entities.add({
|
|
267
|
+
id: tempIds.endPoint,
|
|
268
|
+
position: endPosition,
|
|
269
|
+
point: {
|
|
270
|
+
pixelSize: 10,
|
|
271
|
+
color,
|
|
272
|
+
outlineColor: Cesium.Color.WHITE,
|
|
273
|
+
outlineWidth: 2,
|
|
274
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
275
|
+
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
276
|
+
}
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const removeTemporaryEntities = () => {
|
|
281
|
+
;[startPointEntity, endPointEntity, lineEntity, distanceLabelEntity, tipEntity].forEach((entity) => {
|
|
282
|
+
if (entity) map.entities.remove(entity)
|
|
283
|
+
})
|
|
284
|
+
startPointEntity = null
|
|
285
|
+
endPointEntity = null
|
|
286
|
+
lineEntity = null
|
|
287
|
+
distanceLabelEntity = null
|
|
288
|
+
tipEntity = null
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const destroyHandler = () => {
|
|
292
|
+
if (handler) {
|
|
293
|
+
handler.destroy()
|
|
294
|
+
handler = null
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const cancel = () => {
|
|
299
|
+
if (isFinished) return
|
|
300
|
+
destroyHandler()
|
|
301
|
+
removeTemporaryEntities()
|
|
302
|
+
if (typeof options.onCancel === 'function') options.onCancel()
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const finalize = () => {
|
|
306
|
+
if (isFinished || !startPosition || !endPosition) return null
|
|
307
|
+
isFinished = true
|
|
308
|
+
destroyHandler()
|
|
309
|
+
if (tipEntity) {
|
|
310
|
+
map.entities.remove(tipEntity)
|
|
311
|
+
tipEntity = null
|
|
312
|
+
}
|
|
313
|
+
createEndPointEntity()
|
|
314
|
+
const result = buildResult()
|
|
315
|
+
const graphic = {
|
|
316
|
+
id: options.id,
|
|
317
|
+
startPointEntity,
|
|
318
|
+
endPointEntity,
|
|
319
|
+
lineEntity,
|
|
320
|
+
labelEntity: distanceLabelEntity,
|
|
321
|
+
result,
|
|
322
|
+
type: 'measureDistance'
|
|
323
|
+
}
|
|
324
|
+
mapStore.setGraphicMap(options.id, graphic, options.mapId)
|
|
325
|
+
if (typeof options.onFinish === 'function') options.onFinish(result)
|
|
326
|
+
return result
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
tipEntity = createMouseTipEntity(map, {
|
|
330
|
+
id: tempIds.tip,
|
|
331
|
+
getPosition: () => cursorPosition || endPosition || floatingPosition || startPosition,
|
|
332
|
+
getText: getTipText
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
handler = new Cesium.ScreenSpaceEventHandler(map.scene.canvas)
|
|
336
|
+
|
|
337
|
+
handler.setInputAction((movement) => {
|
|
338
|
+
if (isFinished) return
|
|
339
|
+
cursorPosition = getGroundCartesianFromScreen(map, movement.endPosition)
|
|
340
|
+
if (startPosition && cursorPosition) {
|
|
341
|
+
floatingPosition = cursorPosition
|
|
342
|
+
emitChange()
|
|
343
|
+
}
|
|
344
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
345
|
+
|
|
346
|
+
handler.setInputAction((click) => {
|
|
347
|
+
if (isFinished) return
|
|
348
|
+
const cartesian = getGroundCartesianFromScreen(map, click.position)
|
|
349
|
+
if (!cartesian) return
|
|
350
|
+
|
|
351
|
+
if (!startPosition) {
|
|
352
|
+
startPosition = cartesian
|
|
353
|
+
floatingPosition = cartesian
|
|
354
|
+
cursorPosition = cartesian
|
|
355
|
+
ensurePreviewEntities()
|
|
356
|
+
emitChange()
|
|
357
|
+
return
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
endPosition = cartesian
|
|
361
|
+
floatingPosition = null
|
|
362
|
+
createEndPointEntity()
|
|
363
|
+
finalize()
|
|
364
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
365
|
+
|
|
366
|
+
handler.setInputAction(() => {
|
|
367
|
+
cancel()
|
|
368
|
+
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
id: options.id,
|
|
372
|
+
finish: finalize,
|
|
373
|
+
cancel,
|
|
374
|
+
destroy: cancel,
|
|
375
|
+
getStart: () => (startPosition ? cartesianToLngLatHeight(startPosition) : null),
|
|
376
|
+
getEnd: () => (endPosition ? cartesianToLngLatHeight(endPosition) : null),
|
|
377
|
+
getDistance: () => getGroundDistance(startPosition, endPosition || floatingPosition),
|
|
378
|
+
getDistanceText: () => formatDistance(getGroundDistance(startPosition, endPosition || floatingPosition))
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* 删除测距结果
|
|
384
|
+
* @param {string} id 测距图形 ID
|
|
385
|
+
* @param {string} [mapId] 地图实例 ID
|
|
386
|
+
* @returns {boolean}
|
|
387
|
+
*/
|
|
388
|
+
const destroyMeasure = (id, mapId) => {
|
|
389
|
+
const map = mapStore.getMap(mapId)
|
|
390
|
+
if (!map) {
|
|
391
|
+
console.error('地图实例不存在')
|
|
392
|
+
return false
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const graphic = mapStore.getGraphicMap(id, mapId)
|
|
396
|
+
if (!graphic) {
|
|
397
|
+
console.warn(`id: ${id} 测距结果不存在`)
|
|
398
|
+
return false
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
;[graphic.startPointEntity, graphic.endPointEntity, graphic.lineEntity, graphic.labelEntity].forEach((entity) => {
|
|
402
|
+
if (entity) map.entities.remove(entity)
|
|
403
|
+
})
|
|
404
|
+
mapStore.removeGraphicMap(id, mapId)
|
|
405
|
+
return true
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
startMeasure,
|
|
410
|
+
destroyMeasure,
|
|
411
|
+
formatDistance
|
|
412
|
+
}
|
|
413
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huweili-cesium",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.14",
|
|
4
4
|
"description": "基于 Cesium 的地图工具库(无人机态势、轨迹、围栏、工具栏等)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
"./drawFence.js": "./js/drawFence.js",
|
|
40
40
|
"./drawFenceNew": "./js/drawFenceNew.js",
|
|
41
41
|
"./drawFenceNew.js": "./js/drawFenceNew.js",
|
|
42
|
+
"./measureDistance": "./js/measureDistance.js",
|
|
43
|
+
"./measureDistance.js": "./js/measureDistance.js",
|
|
42
44
|
"./dronePlannedRoute": "./js/dronePlannedRoute.js",
|
|
43
45
|
"./dronePlannedRoute.js": "./js/dronePlannedRoute.js",
|
|
44
46
|
"./droneRipple": "./js/droneRipple.js",
|