diff --git a/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue b/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue index 7e45967..95fa751 100644 --- a/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue +++ b/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue @@ -172,6 +172,25 @@ + + + + + + + +
+ 移动鼠标调整位置,左键确认,右键取消 +
+ 0) numPoints = Math.max(8, Math.min(numPoints, maxPoints)); const angleStep = angleDiff / (numPoints - 1); // 生成扇形的顶点(顺时针方向) for (let i = 0; i < numPoints; i++) { @@ -5491,8 +5524,10 @@ export default { return null; } }, - // 添加箭头实体 + // 添加箭头实体(箭头仅保留首尾两点,避免 PolylineArrowMaterial 在中间段显示额外箭头) addArrowEntity(positions) { + if (!positions || positions.length < 2) return null + const arrowPositions = positions.length === 2 ? positions : [positions[0], positions[positions.length - 1]] this.entityCounter++ const id = `arrow_${this.entityCounter}` // 创建箭头实体,使用固定宽度以确保等比例放大 @@ -5500,7 +5535,7 @@ export default { id: id, name: `箭头 ${this.entityCounter}`, polyline: { - positions: positions, + positions: arrowPositions, width: 12, // 增加宽度以获得更大的箭头头部 material: new Cesium.PolylineArrowMaterialProperty( Cesium.Color.fromCssColorString(this.defaultStyles.arrow.color) @@ -5513,8 +5548,8 @@ export default { const entityData = { id, type: 'arrow', - points: positions.map(p => this.cartesianToLatLng(p)), - positions: positions, + points: arrowPositions.map(p => this.cartesianToLatLng(p)), + positions: arrowPositions, entity: entity, color: this.defaultStyles.arrow.color, width: this.defaultStyles.arrow.width, @@ -6417,6 +6452,403 @@ export default { } this.addWaypointContext = null; }, + + /** 为空域图形(多边形/矩形/圆形/扇形)添加或更新中心名称标签,微软雅黑、不加粗,清晰可读 */ + updateAirspaceEntityLabel(entityData) { + if (!entityData || !entityData.entity || !['polygon', 'rectangle', 'circle', 'sector'].includes(entityData.type)) return + const entity = entityData.entity + const name = entityData.name + const font = '16px Microsoft YaHei' + const labelStyle = { + text: name || '', + font, + fillColor: Cesium.Color.fromCssColorString('#1a1a1a'), + style: Cesium.LabelStyle.FILL, + verticalOrigin: Cesium.VerticalOrigin.CENTER, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + backgroundColor: Cesium.Color.fromCssColorString('rgba(255, 255, 255, 0.95)'), + backgroundPadding: new Cesium.Cartesian2(10, 6), + disableDepthTestDistance: Number.POSITIVE_INFINITY + } + if (!name) { + entity.label = undefined + return + } + const that = this + const getCenter = () => { + const c = that.getAirspaceCenter(entityData) + return c || Cesium.Cartesian3.ZERO + } + entity.label = { + ...labelStyle, + position: new Cesium.CallbackProperty(getCenter, false) + } + }, + + /** 开始空域位置调整模式:右键菜单点击「调整位置」后进入,移动鼠标预览,左键确认、右键取消 */ + startAirspacePositionEdit() { + const ed = this.contextMenu.entityData; + if (!ed || !['polygon', 'rectangle', 'circle', 'sector', 'arrow'].includes(ed.type)) { + this.contextMenu.visible = false; + return; + } + const entityData = this.allEntities.find(e => (e.entity === ed.entity || e === ed) && e.type === ed.type) || ed; + if (!entityData.entity) { + this.contextMenu.visible = false; + return; + } + this.contextMenu.visible = false; + entityData.entity.show = false; + const center = this.getAirspaceCenter(entityData); + this.airspacePositionEditContext = { entityData, mouseCartesian: center || null }; + this.createAirspacePositionPreviewEntity(); + this.$message && this.$message.info('移动鼠标调整位置,左键确认,右键取消'); + }, + + /** 创建空域位置调整的预览实体(使用 CallbackProperty,每帧渲染时读取 mouseCartesian,与测距绘制一致) */ + createAirspacePositionPreviewEntity() { + const ctx = this.airspacePositionEditContext; + if (!ctx || !ctx.entityData || this.airspacePositionEditPreviewEntity) return; + const entityData = ctx.entityData; + const color = entityData.color || this.defaultStyles.polygon.color; + const borderColor = entityData.borderColor || color; + const opacity = entityData.opacity != null ? entityData.opacity : 0; + const width = entityData.width != null ? entityData.width : 2; + const that = this; + + switch (entityData.type) { + case 'polygon': { + if (!entityData.positions || entityData.positions.length < 3) return; + this.airspacePositionEditPreviewEntity = this.viewer.entities.add({ + polygon: { + hierarchy: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const oldCenter = that.getAirspaceCenter(entityData); + if (!mc || !oldCenter) return new Cesium.PolygonHierarchy(entityData.positions); + const delta = Cesium.Cartesian3.subtract(mc, oldCenter, new Cesium.Cartesian3()); + const newPositions = entityData.positions.map(p => Cesium.Cartesian3.add(p, delta, new Cesium.Cartesian3())); + return new Cesium.PolygonHierarchy(newPositions); + }, false), + material: Cesium.Color.TRANSPARENT + }, + polyline: { + positions: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const oldCenter = that.getAirspaceCenter(entityData); + if (!mc || !oldCenter) return entityData.positions; + const delta = Cesium.Cartesian3.subtract(mc, oldCenter, new Cesium.Cartesian3()); + const newPositions = entityData.positions.map(p => Cesium.Cartesian3.add(p, delta, new Cesium.Cartesian3())); + return [...newPositions, newPositions[0]]; + }, false), + width, + material: Cesium.Color.fromCssColorString(borderColor), + arcType: Cesium.ArcType.NONE + } + }); + break; + } + case 'rectangle': { + this.airspacePositionEditPreviewEntity = this.viewer.entities.add({ + rectangle: { + coordinates: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const rect = entityData.entity.rectangle.coordinates.getValue(Cesium.JulianDate.now()); + if (!mc || !rect) return rect || Cesium.Rectangle.fromDegrees(0, 0, 0, 0); + const oldCenter = that.getAirspaceCenter(entityData); + if (!oldCenter) return rect; + const oldCarto = Cesium.Cartographic.fromCartesian(oldCenter); + const newCarto = Cesium.Cartographic.fromCartesian(mc); + const dLon = newCarto.longitude - oldCarto.longitude; + const dLat = newCarto.latitude - oldCarto.latitude; + return new Cesium.Rectangle( + Cesium.Math.negativePiToPi(rect.west + dLon), + Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.south + dLat)), + Cesium.Math.negativePiToPi(rect.east + dLon), + Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.north + dLat)) + ); + }, false), + material: Cesium.Color.fromCssColorString(color).withAlpha(opacity) + }, + polyline: { + positions: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const rect = entityData.entity.rectangle.coordinates.getValue(Cesium.JulianDate.now()); + if (!rect) return []; + const oldCenter = that.getAirspaceCenter(entityData); + if (!oldCenter) { + const sw = Cesium.Cartesian3.fromRadians(rect.west, rect.south); + const se = Cesium.Cartesian3.fromRadians(rect.east, rect.south); + const ne = Cesium.Cartesian3.fromRadians(rect.east, rect.north); + const nw = Cesium.Cartesian3.fromRadians(rect.west, rect.north); + return [sw, se, ne, nw, sw]; + } + const center = mc || oldCenter; + const oldCarto = Cesium.Cartographic.fromCartesian(oldCenter); + const newCarto = Cesium.Cartographic.fromCartesian(center); + const dLon = newCarto.longitude - oldCarto.longitude; + const dLat = newCarto.latitude - oldCarto.latitude; + const newWest = Cesium.Math.negativePiToPi(rect.west + dLon); + const newEast = Cesium.Math.negativePiToPi(rect.east + dLon); + const newSouth = Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.south + dLat)); + const newNorth = Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.north + dLat)); + const sw = Cesium.Cartesian3.fromRadians(newWest, newSouth); + const se = Cesium.Cartesian3.fromRadians(newEast, newSouth); + const ne = Cesium.Cartesian3.fromRadians(newEast, newNorth); + const nw = Cesium.Cartesian3.fromRadians(newWest, newNorth); + return [sw, se, ne, nw, sw]; + }, false), + width, + material: Cesium.Color.fromCssColorString(borderColor), + arcType: Cesium.ArcType.NONE + } + }); + break; + } + case 'circle': { + const radius = entityData.radius || 1000; + this.airspacePositionEditPreviewEntity = this.viewer.entities.add({ + position: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + return mc || that.getAirspaceCenter(entityData) || Cesium.Cartesian3.ZERO; + }, false), + ellipse: { + semiMajorAxis: radius, + semiMinorAxis: radius, + material: Cesium.Color.fromCssColorString(color).withAlpha(opacity), + arcType: Cesium.ArcType.NONE + }, + polyline: { + positions: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const center = mc || that.getAirspaceCenter(entityData); + if (!center) return []; + return that.generateCirclePositions(center, radius, 64); + }, false), + width, + material: Cesium.Color.fromCssColorString(borderColor), + arcType: Cesium.ArcType.NONE + } + }); + break; + } + case 'sector': { + const radius = entityData.radius || 1000; + const startAngle = entityData.startAngle != null ? entityData.startAngle : 0; + const endAngle = entityData.endAngle != null ? entityData.endAngle : Math.PI * 0.5; + this.airspacePositionEditPreviewEntity = this.viewer.entities.add({ + polygon: { + hierarchy: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const center = mc || that.getAirspaceCenter(entityData); + if (!center) return new Cesium.PolygonHierarchy([]); + const positions = that.generateSectorPositions(center, radius, startAngle, endAngle, 64); + return new Cesium.PolygonHierarchy(positions); + }, false), + material: Cesium.Color.fromCssColorString(color).withAlpha(opacity) + }, + polyline: { + positions: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const center = mc || that.getAirspaceCenter(entityData); + if (!center) return []; + return that.generateSectorPositions(center, radius, startAngle, endAngle, 64); + }, false), + width, + material: Cesium.Color.fromCssColorString(borderColor), + arcType: Cesium.ArcType.NONE + } + }); + break; + } + case 'arrow': { + const arrowColor = entityData.color || this.defaultStyles.arrow.color; + this.airspacePositionEditPreviewEntity = this.viewer.entities.add({ + polyline: { + positions: new Cesium.CallbackProperty(() => { + const mc = that.airspacePositionEditContext?.mouseCartesian; + const oldCenter = that.getAirspaceCenter(entityData); + if (!mc || !oldCenter || !entityData.positions || entityData.positions.length < 2) return entityData.positions || []; + const delta = Cesium.Cartesian3.subtract(mc, oldCenter, new Cesium.Cartesian3()); + const first = entityData.positions[0]; + const last = entityData.positions[entityData.positions.length - 1]; + return [ + Cesium.Cartesian3.add(first, delta, new Cesium.Cartesian3()), + Cesium.Cartesian3.add(last, delta, new Cesium.Cartesian3()) + ]; + }, false), + width: 12, + material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.fromCssColorString(arrowColor)), + arcType: Cesium.ArcType.NONE, + widthInMeters: false + } + }); + break; + } + } + }, + + /** 获取空域图形的中心点(笛卡尔坐标) */ + getAirspaceCenter(entityData) { + if (!entityData) return null; + switch (entityData.type) { + case 'polygon': + if (entityData.positions && entityData.positions.length > 0) { + const sum = entityData.positions.reduce((acc, p) => Cesium.Cartesian3.add(acc, p, new Cesium.Cartesian3()), new Cesium.Cartesian3()); + return Cesium.Cartesian3.divideByScalar(sum, entityData.positions.length, new Cesium.Cartesian3()); + } + break; + case 'rectangle': + if (entityData.entity && entityData.entity.rectangle && entityData.entity.rectangle.coordinates) { + const rect = entityData.entity.rectangle.coordinates.getValue(Cesium.JulianDate.now()); + if (rect) { + const west = rect.west, south = rect.south, east = rect.east, north = rect.north; + return Cesium.Cartesian3.fromRadians((west + east) / 2, (south + north) / 2); + } + } + if (entityData.points && entityData.points.length >= 2) { + const lngs = entityData.points.map(p => p.lng), lats = entityData.points.map(p => p.lat); + return Cesium.Cartesian3.fromDegrees((Math.min(...lngs) + Math.max(...lngs)) / 2, (Math.min(...lats) + Math.max(...lats)) / 2); + } + break; + case 'circle': + if (entityData.entity && entityData.entity.position) { + return entityData.entity.position.getValue(Cesium.JulianDate.now()); + } + if (entityData.points && entityData.points[0]) { + return Cesium.Cartesian3.fromDegrees(entityData.points[0].lng, entityData.points[0].lat); + } + break; + case 'sector': + if (entityData.center) { + return Cesium.Cartesian3.fromDegrees(entityData.center.lng, entityData.center.lat); + } + if (entityData.positions && entityData.positions.length > 0) { + const sum = entityData.positions.reduce((acc, p) => Cesium.Cartesian3.add(acc, p, new Cesium.Cartesian3()), new Cesium.Cartesian3()); + return Cesium.Cartesian3.divideByScalar(sum, entityData.positions.length, new Cesium.Cartesian3()); + } + break; + case 'arrow': + if (entityData.positions && entityData.positions.length >= 2) { + const sum = entityData.positions.reduce((acc, p) => Cesium.Cartesian3.add(acc, p, new Cesium.Cartesian3()), new Cesium.Cartesian3()); + return Cesium.Cartesian3.divideByScalar(sum, entityData.positions.length, new Cesium.Cartesian3()); + } + break; + } + return null; + }, + + /** 应用空域位置调整并退出模式 */ + applyAirspacePositionEdit(newCenter) { + const ctx = this.airspacePositionEditContext; + if (!ctx || !ctx.entityData) return; + const entityData = ctx.entityData; + // 先移除预览实体,避免与真实实体同时显示导致“两个箭头”现象(尤其当箭头穿过矩形/圆形空域时) + if (this.airspacePositionEditPreviewEntity) { + this.viewer.entities.remove(this.airspacePositionEditPreviewEntity); + this.airspacePositionEditPreviewEntity = null; + } + const oldCenter = this.getAirspaceCenter(entityData); + if (!oldCenter) return; + const delta = Cesium.Cartesian3.subtract(newCenter, oldCenter, new Cesium.Cartesian3()); + const oldCarto = Cesium.Cartographic.fromCartesian(oldCenter); + const newCarto = Cesium.Cartographic.fromCartesian(newCenter); + const dLon = newCarto.longitude - oldCarto.longitude; + const dLat = newCarto.latitude - oldCarto.latitude; + + switch (entityData.type) { + case 'polygon': + if (entityData.positions && entityData.positions.length > 0) { + entityData.positions = entityData.positions.map(p => Cesium.Cartesian3.add(p, delta, new Cesium.Cartesian3())); + entityData.points = entityData.positions.map(p => this.cartesianToLatLng(p)); + const closed = [...entityData.positions, entityData.positions[0]]; + entityData.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(entityData.positions); + entityData.entity.polyline.positions = closed; + } + break; + case 'rectangle': { + const rect = entityData.entity.rectangle.coordinates.getValue(Cesium.JulianDate.now()); + if (rect) { + const newWest = Cesium.Math.negativePiToPi(rect.west + dLon); + const newEast = Cesium.Math.negativePiToPi(rect.east + dLon); + const newSouth = Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.south + dLat)); + const newNorth = Math.max(-Cesium.Math.PI_OVER_TWO, Math.min(Cesium.Math.PI_OVER_TWO, rect.north + dLat)); + const newRect = new Cesium.Rectangle(newWest, newSouth, newEast, newNorth); + entityData.entity.rectangle.coordinates = newRect; + const sw = Cesium.Cartesian3.fromRadians(newRect.west, newRect.south); + const se = Cesium.Cartesian3.fromRadians(newRect.east, newRect.south); + const ne = Cesium.Cartesian3.fromRadians(newRect.east, newRect.north); + const nw = Cesium.Cartesian3.fromRadians(newRect.west, newRect.north); + entityData.entity.polyline.positions = [sw, se, ne, nw, sw]; + entityData.points = [this.cartesianToLatLng(sw), this.cartesianToLatLng(se), this.cartesianToLatLng(ne), this.cartesianToLatLng(nw)]; + } + break; + } + case 'circle': + entityData.entity.position = newCenter; + const radius = entityData.radius || 1000; + entityData.entity.polyline.positions = this.generateCirclePositions(newCenter, radius); + entityData.points = [this.cartesianToLatLng(newCenter), entityData.points && entityData.points[1] ? entityData.points[1] : this.cartesianToLatLng(newCenter)]; + break; + case 'sector': { + const newCenterLL = this.cartesianToLatLng(newCenter); + entityData.center = newCenterLL; + const r = entityData.radius || 1000; + const sa = entityData.startAngle != null ? entityData.startAngle : 0; + const ea = entityData.endAngle != null ? entityData.endAngle : Math.PI * 0.5; + const positions = this.generateSectorPositions(newCenter, r, sa, ea); + entityData.positions = positions; + entityData.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(positions); + entityData.entity.polyline.positions = positions; + break; + } + case 'arrow': + if (entityData.positions && entityData.positions.length >= 2) { + const first = entityData.positions[0]; + const last = entityData.positions[entityData.positions.length - 1]; + const newFirst = Cesium.Cartesian3.add(first, delta, new Cesium.Cartesian3()); + const newLast = Cesium.Cartesian3.add(last, delta, new Cesium.Cartesian3()); + const arrowPositions = [newFirst, newLast]; + const arrowColor = entityData.color || this.defaultStyles.arrow.color; + const oldEntity = entityData.entity; + this.viewer.entities.remove(oldEntity); + const newEntity = this.viewer.entities.add({ + id: oldEntity.id, + name: oldEntity.name, + polyline: { + positions: arrowPositions, + width: 12, + material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.fromCssColorString(arrowColor)), + arcType: Cesium.ArcType.NONE, + widthInMeters: false + } + }); + entityData.entity = newEntity; + entityData.positions = arrowPositions; + entityData.points = [this.cartesianToLatLng(newFirst), this.cartesianToLatLng(newLast)]; + newEntity.clickHandler = (e) => { + this.selectEntity(entityData); + e.stopPropagation(); + }; + } + break; + } + entityData.entity.show = true; + this.notifyDrawingEntitiesChanged(); + }, + + /** 清除空域位置调整模式 */ + clearAirspacePositionEdit() { + if (this.airspacePositionEditPreviewEntity) { + this.viewer.entities.remove(this.airspacePositionEditPreviewEntity); + this.airspacePositionEditPreviewEntity = null; + } + if (this.airspacePositionEditContext && this.airspacePositionEditContext.entityData) { + this.airspacePositionEditContext.entityData.entity.show = true; + } + this.airspacePositionEditContext = null; + if (this.viewer.scene.requestRender) this.viewer.scene.requestRender(); + }, + toggleRouteLock() { const ed = this.contextMenu.entityData; if (!ed || ed.type !== 'route' || ed.routeId == null) { @@ -7424,6 +7856,10 @@ export default { if (property === 'color' && (entityData.type === 'polygon' || entityData.type === 'rectangle' || entityData.type === 'circle' || entityData.type === 'sector' || entityData.type === 'powerZone')) { entityData.opacity = 0.2 } + // 命名:为多边形/矩形/圆形/扇形添加或更新中心标签 + if (property === 'name' && ['polygon', 'rectangle', 'circle', 'sector'].includes(entityData.type)) { + this.updateAirspaceEntityLabel(entityData) + } // 更新实体样式 this.updateEntityStyle(entityData) // 若修改的是空域/威力区图形的样式,触发自动保存到房间,避免刷新后样式丢失 @@ -7723,8 +8159,9 @@ export default { data = { points: entity.points || [], opacity: entity.opacity != null ? entity.opacity : 0, - width: entity.width != null ? entity.width : 4, - borderColor: entity.borderColor || entity.color + width: entity.width != null ? entity.width : 2, + borderColor: entity.borderColor || entity.color, + name: entity.name || '' }; break case 'rectangle': if (entity.points && entity.points.length >= 2) { @@ -7734,16 +8171,18 @@ export default { coordinates: { west: Math.min(...lngs), south: Math.min(...lats), east: Math.max(...lngs), north: Math.max(...lats) }, points: entity.points, opacity: entity.opacity != null ? entity.opacity : 0, - width: entity.width != null ? entity.width : 4, - borderColor: entity.borderColor || entity.color + width: entity.width != null ? entity.width : 2, + borderColor: entity.borderColor || entity.color, + name: entity.name || '' } } else { data = { coordinates: entity.coordinates || {}, points: entity.points || [], opacity: entity.opacity != null ? entity.opacity : 0, - width: entity.width != null ? entity.width : 4, - borderColor: entity.borderColor || entity.color + width: entity.width != null ? entity.width : 2, + borderColor: entity.borderColor || entity.color, + name: entity.name || '' } } break @@ -7753,8 +8192,9 @@ export default { center: entity.points && entity.points[0] ? entity.points[0] : (entity.positions && entity.positions[0] ? this.cartesianToLatLng(entity.positions[0]) : (entity.center && typeof entity.center.lat === 'number' ? entity.center : null)), radius: entity.radius, opacity: entity.opacity != null ? entity.opacity : 0, - width: entity.width != null ? entity.width : 4, - borderColor: entity.borderColor || entity.color + width: entity.width != null ? entity.width : 2, + borderColor: entity.borderColor || entity.color, + name: entity.name || '' }; break case 'ellipse': case 'hold_ellipse': @@ -7771,8 +8211,9 @@ export default { startAngle: entity.startAngle, endAngle: entity.endAngle, opacity: entity.opacity != null ? entity.opacity : 0, - width: entity.width != null ? entity.width : 3, - borderColor: entity.borderColor || entity.color + width: entity.width != null ? entity.width : 2, + borderColor: entity.borderColor || entity.color, + name: entity.name || '' }; break case 'arrow': data = { points: entity.points || [] }; break @@ -8024,7 +8465,7 @@ export default { case 'polygon': { const polygonPositions = entityData.data.points.map(p => Cesium.Cartesian3.fromDegrees(p.lng, p.lat)) const polyOpacity = entityData.data.opacity != null ? entityData.data.opacity : 0 - const polyWidth = entityData.data.width != null ? entityData.data.width : 4 + const polyWidth = entityData.data.width != null ? entityData.data.width : 2 const polyBorderColor = entityData.data.borderColor || color entity = this.viewer.entities.add({ polygon: { @@ -8038,7 +8479,23 @@ export default { arcType: Cesium.ArcType.NONE } }) - break + const polyEntityData = { + id: entity.id, + type: 'polygon', + points: entityData.data.points, + positions: polygonPositions, + entity, + color, + borderColor: polyBorderColor, + opacity: polyOpacity, + width: polyWidth, + label: entityData.label || '面', + name: entityData.data.name || '' + } + this.allEntities.push(polyEntityData) + if (polyEntityData.name) this.updateAirspaceEntityLabel(polyEntityData) + this.notifyDrawingEntitiesChanged() + return } case 'rectangle': { let rectCoords = entityData.data.coordinates @@ -8049,7 +8506,7 @@ export default { } if (!rectCoords) break const rectOpacity = entityData.data.opacity != null ? entityData.data.opacity : 0 - const rectWidth = entityData.data.width != null ? entityData.data.width : 4 + const rectWidth = entityData.data.width != null ? entityData.data.width : 2 const rectBorderColor = entityData.data.borderColor || color const rectColor = Cesium.Color.fromCssColorString(color).withAlpha(rectOpacity) const southwest = Cesium.Cartesian3.fromDegrees(rectCoords.west, rectCoords.south) @@ -8069,7 +8526,7 @@ export default { arcType: Cesium.ArcType.NONE } }) - this.allEntities.push({ + const rectEntityData = { id: entity.id, type: 'rectangle', points: entityData.data.points || [], @@ -8079,8 +8536,11 @@ export default { borderColor: rectBorderColor, opacity: rectOpacity, width: rectWidth, - label: entityData.label || '矩形' - }) + label: entityData.label || '矩形', + name: entityData.data.name || '' + } + this.allEntities.push(rectEntityData) + if (rectEntityData.name) this.updateAirspaceEntityLabel(rectEntityData) return } case 'circle': { @@ -8092,7 +8552,7 @@ export default { const circleCenter = Cesium.Cartesian3.fromDegrees(entityData.data.center.lng, entityData.data.center.lat) const circlePositions = this.generateCirclePositions(circleCenter, radius) const circleOpacity = entityData.data.opacity != null ? entityData.data.opacity : 0 - const circleWidth = entityData.data.width != null ? entityData.data.width : 4 + const circleWidth = entityData.data.width != null ? entityData.data.width : 2 const circleBorderColor = entityData.data.borderColor || color entity = this.viewer.entities.add({ position: circleCenter, @@ -8109,7 +8569,24 @@ export default { arcType: Cesium.ArcType.NONE } }) - break + const circleEntityData = { + id: entity.id, + type: 'circle', + points: [entityData.data.center], + positions: [circleCenter], + entity, + radius, + color, + borderColor: circleBorderColor, + opacity: circleOpacity, + width: circleWidth, + label: entityData.label || '圆形', + name: entityData.data.name || '' + } + this.allEntities.push(circleEntityData) + if (circleEntityData.name) this.updateAirspaceEntityLabel(circleEntityData) + this.notifyDrawingEntitiesChanged() + return } case 'hold_circle': { const hcRadius = entityData.data.radius || 1000 @@ -8182,7 +8659,7 @@ export default { const startAngle = d.startAngle != null ? d.startAngle : 0 const endAngle = d.endAngle != null ? d.endAngle : Math.PI * 0.5 const sectorOpacity = d.opacity != null ? d.opacity : 0 - const sectorWidth = d.width != null ? d.width : 3 + const sectorWidth = d.width != null ? d.width : 2 const sectorBorderColor = d.borderColor || color const positions = this.generateSectorPositions(center, d.radius, startAngle, endAngle) entity = this.viewer.entities.add({ @@ -8197,7 +8674,7 @@ export default { arcType: Cesium.ArcType.NONE } }) - this.allEntities.push({ + const sectorEntityData = { id: entity.id, type: 'sector', center: d.center, @@ -8210,15 +8687,19 @@ export default { borderColor: sectorBorderColor, opacity: sectorOpacity, width: sectorWidth, - label: entityData.label || '扇形' - }) + label: entityData.label || '扇形', + name: entityData.data.name || '' + } + this.allEntities.push(sectorEntityData) + if (sectorEntityData.name) this.updateAirspaceEntityLabel(sectorEntityData) this.notifyDrawingEntitiesChanged() return } case 'arrow': { const pts = entityData.data.points if (!pts || pts.length < 2) break - const arrowPositions = pts.map(p => Cesium.Cartesian3.fromDegrees(p.lng, p.lat)) + const allPositions = pts.map(p => Cesium.Cartesian3.fromDegrees(p.lng, p.lat)) + const arrowPositions = allPositions.length === 2 ? allPositions : [allPositions[0], allPositions[allPositions.length - 1]] entity = this.viewer.entities.add({ polyline: { positions: arrowPositions, @@ -8231,7 +8712,7 @@ export default { this.allEntities.push({ id: entity.id, type: 'arrow', - points: pts, + points: [pts[0], pts[pts.length - 1]], positions: arrowPositions, entity, color, @@ -8353,14 +8834,18 @@ export default { } } if (entity) { - this.allEntities.push({ + const pushed = { id: entity.id, type: entityData.type, label: entityData.label, color: color, entity, ...entityData.data - }) + } + this.allEntities.push(pushed) + if (['polygon', 'circle'].includes(entityData.type) && pushed.name) { + this.updateAirspaceEntityLabel(pushed) + } if (this.getDrawingEntityTypes().includes(entityData.type)) this.notifyDrawingEntitiesChanged() } },