|
|
|
@ -32,12 +32,14 @@ |
|
|
|
:visible="contextMenu.visible" |
|
|
|
:position="contextMenu.position" |
|
|
|
:entity-data="contextMenu.entityData" |
|
|
|
:route-locked="routeLocked" |
|
|
|
@delete="deleteEntityFromContextMenu" |
|
|
|
@update-property="updateEntityProperty" |
|
|
|
@edit-platform-position="openPlatformIconPositionDialog" |
|
|
|
@edit-platform-heading="openPlatformIconHeadingDialog" |
|
|
|
@show-transform-box="showPlatformIconTransformBox" |
|
|
|
@toggle-route-label="toggleRouteLabelVisibility" |
|
|
|
@toggle-route-lock="toggleRouteLock" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- 定位弹窗 --> |
|
|
|
@ -171,6 +173,8 @@ export default { |
|
|
|
}, |
|
|
|
// 航线飞机标牌显示状态:routeId -> true 显示 / false 隐藏,不设则默认显示 |
|
|
|
routeLabelVisible: {}, |
|
|
|
// 航线上锁状态:routeId -> true 上锁(不可编辑)/ false 或未设 可编辑 |
|
|
|
routeLocked: {}, |
|
|
|
// 默认样式 |
|
|
|
defaultStyles: { |
|
|
|
point: { color: '#FF0000', size: 12 }, |
|
|
|
@ -491,8 +495,8 @@ export default { |
|
|
|
return positions; |
|
|
|
}, false), |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString('#800080'), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial('#800080'), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -699,8 +703,8 @@ export default { |
|
|
|
polyline: { |
|
|
|
positions: linePositions, |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString('#008aff'), |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
material: this.getPolylineSolidMaterial('#008aff'), |
|
|
|
clampToGround: true, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -935,19 +939,10 @@ export default { |
|
|
|
const wpColor = wpStyle.color || '#ffffff'; |
|
|
|
const wpOutline = wpStyle.outlineColor || '#0078FF'; |
|
|
|
const wpOutlineW = wpStyle.outlineWidth != null ? wpStyle.outlineWidth : 2; |
|
|
|
// 航线默认紫色、线宽 3;与主航线一致的线型用于主线和转弯半径弧 |
|
|
|
// 航线默认紫色、线宽 3;与测距线一致使用轮廓材质,平滑无锯齿 |
|
|
|
const lineWidth = lineStyle.width != null ? lineStyle.width : 3; |
|
|
|
const lineColor = lineStyle.color || '#800080'; |
|
|
|
const gapColor = lineStyle.gapColor != null ? lineStyle.gapColor : '#000000'; |
|
|
|
const dashLen = lineStyle.dashLength != null ? lineStyle.dashLength : 20; |
|
|
|
const useDash = (lineStyle.style || 'solid') === 'dash'; |
|
|
|
const lineMaterial = useDash |
|
|
|
? new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString(lineColor), |
|
|
|
gapColor: Cesium.Color.fromCssColorString(gapColor), |
|
|
|
dashLength: dashLen |
|
|
|
}) |
|
|
|
: Cesium.Color.fromCssColorString(lineColor); |
|
|
|
const lineMaterial = this.getPolylineSolidMaterial(lineColor); |
|
|
|
// 先收集所有航点的世界坐标 |
|
|
|
const originalPositions = []; |
|
|
|
waypoints.forEach((wp) => { |
|
|
|
@ -1110,7 +1105,7 @@ export default { |
|
|
|
finalPathPositions.push(exit); |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `hold-line-${routeId}-${i}`, |
|
|
|
polyline: { positions: [entry, ...arcPoints.slice(1), exit], width: 8, material: Cesium.Color.ORANGE, arcType: Cesium.ArcType.NONE, zIndex: 20 }, |
|
|
|
polyline: { positions: [entry, ...arcPoints.slice(1), exit], width: 8, material: this.getPolylineSolidMaterial('#FFA500'), clampToGround: true, zIndex: 20 }, |
|
|
|
properties: { routeId: routeId } |
|
|
|
}); |
|
|
|
lastPos = exit; |
|
|
|
@ -1127,7 +1122,7 @@ export default { |
|
|
|
const arcPoints = this.computeArcPositions(lastPos, currPos, nextLogical, radius); |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `arc-line-${routeId}-${i}`, |
|
|
|
polyline: { positions: arcPoints, width: lineWidth, material: lineMaterial, arcType: Cesium.ArcType.NONE, zIndex: 20 }, |
|
|
|
polyline: { positions: arcPoints, width: lineWidth, material: lineMaterial, clampToGround: true, zIndex: 20 }, |
|
|
|
properties: { routeId: routeId } |
|
|
|
}); |
|
|
|
// 转弯半径两侧航点与航线整体航点风格一致,点击均打开原航点编辑(dbId 为当前 wp.id) |
|
|
|
@ -1178,13 +1173,13 @@ export default { |
|
|
|
positions: finalPathPositions, |
|
|
|
width: lineWidth, |
|
|
|
material: lineMaterial, |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
clampToGround: true, |
|
|
|
zIndex: 1 |
|
|
|
}, |
|
|
|
properties: {isMissionRouteLine: true, routeId: routeId} |
|
|
|
}); |
|
|
|
if (this.allEntities) { |
|
|
|
this.allEntities.push({id: lineId, entity: routeEntity, type: 'route'}); |
|
|
|
this.allEntities.push({ id: lineId, entity: routeEntity, type: 'route', routeId }); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
@ -1688,18 +1683,27 @@ export default { |
|
|
|
imageryProvider: false, |
|
|
|
terrainProvider: new Cesium.EllipsoidTerrainProvider(), |
|
|
|
baseLayer: false, |
|
|
|
// 按需渲染:仅在场景变化时渲染,降低空闲时 CPU/GPU 占用(若某处界面不刷新可主动调用 viewer.scene.requestRender()) |
|
|
|
requestRenderMode: true, |
|
|
|
maximumRenderTimeChange: Infinity, |
|
|
|
// 允许截图时读取 canvas 内容(若截图仅用 readPixels 可改为 false 以提升性能) |
|
|
|
contextOptions: { |
|
|
|
preserveDrawingBuffer: true, |
|
|
|
webgl: { |
|
|
|
antialias: true, |
|
|
|
msaa: true, |
|
|
|
msaaSamples: 8 |
|
|
|
} |
|
|
|
} |
|
|
|
antialias: true // 开启 WebGL 全局抗锯齿 |
|
|
|
}, |
|
|
|
// 多重采样抗锯齿(WebGL2 下生效,8 在浏览器缩放时线条更平滑) |
|
|
|
msaaSamples: 8 |
|
|
|
}) |
|
|
|
this.viewer.cesiumWidget.creditContainer.style.display = "none" |
|
|
|
// 启用 FXAA 后处理,进一步减轻线条锯齿感 |
|
|
|
try { |
|
|
|
if (this.viewer.scene.postProcessStages && this.viewer.scene.postProcessStages.fxaa) { |
|
|
|
this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
} catch (e) { /* 部分 Cesium 版本可能无此 API */ } |
|
|
|
// 根据浏览器缩放比例提高渲染分辨率,减轻 80% 等缩放下线条锯齿 |
|
|
|
this.applyResolutionScale() |
|
|
|
this._resolutionScaleCleanup = this.setupResolutionScaleListener() |
|
|
|
// 按需渲染时:实体增删改后主动请求一帧,避免界面不刷新 |
|
|
|
if (this.viewer.scene.requestRenderMode) { |
|
|
|
this.viewer.entities.collectionChanged.addEventListener(() => { |
|
|
|
@ -1735,7 +1739,6 @@ export default { |
|
|
|
console.log('Cesium离线二维地图已加载') |
|
|
|
|
|
|
|
// 1. 定义全局拾取处理器(含防抖,避免双击误触导致相机高度剧烈变化) |
|
|
|
this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas); |
|
|
|
this.handler.setInputAction((click) => { |
|
|
|
// 隐藏右键菜单 |
|
|
|
@ -1779,6 +1782,11 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
this.entityClickDebounceTimer = setTimeout(() => { |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
// 上锁的航线不打开编辑 |
|
|
|
if (this.routeLocked[routeId]) { |
|
|
|
this.$message && this.$message.info('该航线已上锁,请右键选择“解锁”后再编辑'); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (isWaypoint) { |
|
|
|
console.log(`>>> [地图触发] 点击了点 ${dbId}, 属于航线 ${routeId}`); |
|
|
|
this.$emit('open-waypoint-dialog', dbId, routeId); |
|
|
|
@ -1869,8 +1877,26 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 特殊处理:右键点击航点或航线时,从实体属性解析出 routeId,用于显示航线“上锁/解锁”菜单 |
|
|
|
if (!entityData && pickedEntity.properties) { |
|
|
|
const now = Cesium.JulianDate.now(); |
|
|
|
const props = pickedEntity.properties.getValue ? pickedEntity.properties.getValue(now) : null; |
|
|
|
if (props) { |
|
|
|
const isWp = props.isMissionWaypoint && props.isMissionWaypoint.getValue ? props.isMissionWaypoint.getValue() : props.isMissionWaypoint; |
|
|
|
const isLine = props.isMissionRouteLine && props.isMissionRouteLine.getValue ? props.isMissionRouteLine.getValue() : props.isMissionRouteLine; |
|
|
|
if (isWp || isLine) { |
|
|
|
let rId = props.routeId; |
|
|
|
if (rId && rId.getValue) rId = rId.getValue(); |
|
|
|
if (rId) entityData = { type: 'route', routeId: rId }; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 航线实体在 allEntities 中可能没有 routeId,从 id 解析 |
|
|
|
if (entityData && entityData.type === 'route' && entityData.id && !entityData.routeId) { |
|
|
|
entityData = { ...entityData, routeId: entityData.id.replace('route-line-', '') }; |
|
|
|
} |
|
|
|
if (entityData && entityData.type !== 'route') { |
|
|
|
if (entityData) { |
|
|
|
this.contextMenu = { |
|
|
|
visible: true, |
|
|
|
position: { |
|
|
|
@ -2503,28 +2529,25 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
this.tempEntity = this.viewer.entities.add({ |
|
|
|
polyline: { |
|
|
|
positions: this.drawingPoints, |
|
|
|
positions: this.getPolylinePositionsStraightIn2D([...this.drawingPoints], false), |
|
|
|
width: this.defaultStyles.line.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.line.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
// 创建新的预览虚线(使用 CallbackProperty 实现实时更新) |
|
|
|
// 创建新的预览线(与测距线一致:轮廓材质,2D 下直线) |
|
|
|
this.tempPreviewEntity = this.viewer.entities.add({ |
|
|
|
polyline: { |
|
|
|
positions: new Cesium.CallbackProperty(() => { |
|
|
|
if (this.activeCursorPosition) { |
|
|
|
return [this.drawingPoints[this.drawingPoints.length - 1], this.activeCursorPosition]; |
|
|
|
if (this.activeCursorPosition && this.drawingPoints.length > 0) { |
|
|
|
return this.getPolylinePositionsStraightIn2D([this.drawingPoints[this.drawingPoints.length - 1], this.activeCursorPosition], false); |
|
|
|
} |
|
|
|
return [this.drawingPoints[this.drawingPoints.length - 1]]; |
|
|
|
return this.drawingPoints.length > 0 ? [this.drawingPoints[this.drawingPoints.length - 1]] : []; |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.line.width, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.line.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -2630,16 +2653,15 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
polyline: { |
|
|
|
// positions 使用 CallbackProperty 实现动态闭合线 |
|
|
|
positions: new Cesium.CallbackProperty(() => { |
|
|
|
if (this.activeCursorPosition) { |
|
|
|
// 闭合回路:[所有点, 鼠标位置, 回到起点] |
|
|
|
return [...this.drawingPoints, this.activeCursorPosition, this.drawingPoints[0]]; |
|
|
|
if (this.activeCursorPosition && this.drawingPoints.length >= 2) { |
|
|
|
return this.getPolylinePositionsStraightIn2D([...this.drawingPoints, this.activeCursorPosition], true); |
|
|
|
} |
|
|
|
return this.drawingPoints; |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.polygon.width, |
|
|
|
// 边框使用实线,表示正在编辑中 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
// 边框与测距线一致:轮廓材质,2D 下直线 |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.polygon.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -2659,12 +2681,6 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
finishPolygonDrawing() { |
|
|
|
const positions = [...this.drawingPoints] |
|
|
|
const entity = this.addPolygonEntity(positions) |
|
|
|
// 计算面积 |
|
|
|
const area = this.calculatePolygonArea(positions) |
|
|
|
this.measurementResult = { |
|
|
|
area: area, |
|
|
|
type: 'polygon' |
|
|
|
} |
|
|
|
// 重置绘制点数组,保持绘制状态以继续绘制 |
|
|
|
this.drawingPoints = [] |
|
|
|
if (this.tempEntity) { |
|
|
|
@ -2707,34 +2723,23 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
return Cesium.Rectangle.fromDegrees(0, 0, 0, 0); |
|
|
|
}, false), |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color).withAlpha(this.defaultStyles.rectangle.opacity) |
|
|
|
// 设置填充颜色 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color).withAlpha(this.defaultStyles.rectangle.opacity), |
|
|
|
clampToGround: true // 贴地 |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
// 关键:使用 CallbackProperty 动态计算矩形边框线 |
|
|
|
positions: new Cesium.CallbackProperty(() => { |
|
|
|
if (this.drawingPoints.length > 0 && this.activeCursorPosition) { |
|
|
|
// 计算矩形的四个角点 |
|
|
|
const rect = Cesium.Rectangle.fromCartesianArray([this.drawingPoints[0], this.activeCursorPosition]); |
|
|
|
const west = rect.west; |
|
|
|
const south = rect.south; |
|
|
|
const east = rect.east; |
|
|
|
const north = rect.north; |
|
|
|
|
|
|
|
// 创建四个角点的笛卡尔坐标 |
|
|
|
const southwest = Cesium.Cartesian3.fromRadians(west, south); |
|
|
|
const southeast = Cesium.Cartesian3.fromRadians(east, south); |
|
|
|
const northeast = Cesium.Cartesian3.fromRadians(east, north); |
|
|
|
const northwest = Cesium.Cartesian3.fromRadians(west, north); |
|
|
|
|
|
|
|
// 返回闭合的边框线位置数组 |
|
|
|
return [southwest, southeast, northeast, northwest, southwest]; |
|
|
|
return this.getRectangleBorderPositions(rect); |
|
|
|
} |
|
|
|
return []; |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.rectangle.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.rectangle.color), |
|
|
|
clampToGround: true // 贴地 |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -2765,20 +2770,8 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
this.entityCounter++; |
|
|
|
const id = `rectangle_${this.entityCounter}`; |
|
|
|
|
|
|
|
// 计算矩形的四个角点 |
|
|
|
const west = rect.west; |
|
|
|
const south = rect.south; |
|
|
|
const east = rect.east; |
|
|
|
const north = rect.north; |
|
|
|
|
|
|
|
// 创建四个角点的笛卡尔坐标 |
|
|
|
const southwest = Cesium.Cartesian3.fromRadians(west, south); |
|
|
|
const southeast = Cesium.Cartesian3.fromRadians(east, south); |
|
|
|
const northeast = Cesium.Cartesian3.fromRadians(east, north); |
|
|
|
const northwest = Cesium.Cartesian3.fromRadians(west, north); |
|
|
|
|
|
|
|
// 创建边框线的位置数组(闭合) |
|
|
|
const borderPositions = [southwest, southeast, northeast, northwest, southwest]; |
|
|
|
// 创建边框线位置(按等经度/等纬度采样,2D 缩小时仍为直线) |
|
|
|
const borderPositions = this.getRectangleBorderPositions(rect); |
|
|
|
|
|
|
|
// 创建一个复合实体,包含填充和边框 |
|
|
|
const finalEntity = this.viewer.entities.add({ |
|
|
|
@ -2786,14 +2779,15 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
// 填充部分 |
|
|
|
rectangle: { |
|
|
|
coordinates: rect, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color).withAlpha(this.defaultStyles.rectangle.opacity) |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color).withAlpha(this.defaultStyles.rectangle.opacity), |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
positions: borderPositions, |
|
|
|
width: this.defaultStyles.rectangle.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.rectangle.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
// 4. 记录到实体列表 |
|
|
|
@ -2807,16 +2801,10 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
borderColor: this.defaultStyles.rectangle.color, // 边框颜色 |
|
|
|
opacity: this.defaultStyles.rectangle.opacity, |
|
|
|
width: this.defaultStyles.rectangle.width, |
|
|
|
label: `矩形 ${this.entityCounter}` |
|
|
|
label: `矩形空域 ${this.entityCounter}` |
|
|
|
}; |
|
|
|
this.allEntities.push(entityData); |
|
|
|
// 5. 计算并显示面积 |
|
|
|
const area = this.calculateRectangleArea(rect); |
|
|
|
this.measurementResult = { |
|
|
|
area: area, |
|
|
|
type: 'rectangle' |
|
|
|
}; |
|
|
|
// 6. 重置状态,保持绘制状态以继续绘制 |
|
|
|
// 5. 重置状态,保持绘制状态以继续绘制 |
|
|
|
this.drawingPoints = []; |
|
|
|
}, |
|
|
|
// 计算矩形面积(辅助方法) |
|
|
|
@ -2940,9 +2928,10 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
}, false), |
|
|
|
// 设置填充颜色 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color).withAlpha(this.defaultStyles.circle.opacity), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
// 移除 outline 属性,改用 polyline 绘制边框 |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 - 使用 polyline |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
// 关键:使用 CallbackProperty 动态计算圆形边框线 |
|
|
|
positions: new Cesium.CallbackProperty(() => { |
|
|
|
@ -2962,8 +2951,8 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.circle.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.circle.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -3006,21 +2995,24 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
// 生成圆形的点,用于绘制边框线 |
|
|
|
const circlePositions = this.generateCirclePositions(centerPoint, radius); |
|
|
|
|
|
|
|
// 创建一个复合实体,包含填充和边框 |
|
|
|
const finalEntity = this.viewer.entities.add({ |
|
|
|
id: id, |
|
|
|
position: centerPoint, |
|
|
|
// 填充部分 |
|
|
|
ellipse: { |
|
|
|
semiMajorAxis: radius, |
|
|
|
semiMinorAxis: radius, |
|
|
|
// 设置填充颜色 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color).withAlpha(this.defaultStyles.circle.opacity), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
positions: circlePositions, |
|
|
|
width: this.defaultStyles.circle.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.circle.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
// 4. 记录实体 |
|
|
|
@ -3035,18 +3027,10 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
opacity: this.defaultStyles.circle.opacity, |
|
|
|
width: this.defaultStyles.circle.width, |
|
|
|
radius: radius, |
|
|
|
label: `圆形 ${this.entityCounter}` |
|
|
|
label: `圆形空域 ${this.entityCounter}` |
|
|
|
}; |
|
|
|
this.allEntities.push(entityData); |
|
|
|
// 5. 计算面积 (π * r²) 并显示 |
|
|
|
// 半径单位是米,面积单位是平方米 |
|
|
|
const area = Math.PI * Math.pow(radius, 2); |
|
|
|
this.measurementResult = { |
|
|
|
radius: radius, // 也可以额外显示半径 |
|
|
|
area: area, |
|
|
|
type: 'circle' |
|
|
|
}; |
|
|
|
// 6. 重置状态,保持绘制状态以继续绘制 |
|
|
|
// 5. 重置状态,保持绘制状态以继续绘制 |
|
|
|
this.drawingPoints = []; |
|
|
|
this.activeCursorPosition = null; |
|
|
|
}, |
|
|
|
@ -3073,7 +3057,8 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
}, |
|
|
|
// 绘制扇形 |
|
|
|
startSectorDrawing() { |
|
|
|
this.drawingPoints = []; |
|
|
|
// 重置绘制状态 |
|
|
|
this.drawingPoints = []; // 存储圆心、半径端点、角度端点 |
|
|
|
// 1. 清理旧实体 |
|
|
|
if (this.tempEntity) this.viewer.entities.remove(this.tempEntity); |
|
|
|
if (this.tempPreviewEntity) this.viewer.entities.remove(this.tempPreviewEntity); |
|
|
|
@ -3104,18 +3089,15 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
return []; |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.sector.width, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.sector.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
// --- 情况B:第二次点击(确定半径) --- |
|
|
|
else if (this.drawingPoints.length === 1) { |
|
|
|
this.drawingPoints.push(position); |
|
|
|
this.activeCursorPosition = position; |
|
|
|
this.activeCursorPosition = position; // 更新 activeCursorPosition 为实际点击位置 |
|
|
|
const centerPoint = this.drawingPoints[0]; |
|
|
|
const radiusPoint = this.drawingPoints[1]; |
|
|
|
const fixedRadius = Cesium.Cartesian3.distance(centerPoint, radiusPoint); |
|
|
|
@ -3142,7 +3124,9 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
return new Cesium.PolygonHierarchy([]); |
|
|
|
}, false), |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(this.defaultStyles.sector.opacity) |
|
|
|
// 设置填充颜色 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(this.defaultStyles.sector.opacity), |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
@ -3161,15 +3145,15 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
return []; |
|
|
|
}, false), |
|
|
|
width: this.defaultStyles.sector.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.sector.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
// --- 情况C:第三次点击(确定角度) --- |
|
|
|
else if (this.drawingPoints.length === 2) { |
|
|
|
this.drawingPoints.push(position); |
|
|
|
this.activeCursorPosition = null; |
|
|
|
this.activeCursorPosition = null; // 停止动态更新 |
|
|
|
// 传递角度点位置去结束绘制 |
|
|
|
this.finishSectorDrawing(this.drawingPoints[0], this.drawingPoints[1], this.drawingPoints[2]); |
|
|
|
} |
|
|
|
@ -3195,18 +3179,20 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
// 3. 创建最终显示的静态实体 |
|
|
|
const finalEntity = this.viewer.entities.add({ |
|
|
|
id: 'sector-' + new Date().getTime(), |
|
|
|
name: `扇形 ${this.entityCounter}`, |
|
|
|
name: `扇形空域 ${this.entityCounter}`, |
|
|
|
// 填充部分 |
|
|
|
polygon: { |
|
|
|
hierarchy: new Cesium.PolygonHierarchy(positions), |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(this.defaultStyles.sector.opacity) |
|
|
|
// 设置填充颜色 |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(this.defaultStyles.sector.opacity), |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
positions: positions, |
|
|
|
width: this.defaultStyles.sector.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.sector.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
// 4. 记录实体 |
|
|
|
@ -3220,18 +3206,18 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
endAngle: endAngle, |
|
|
|
positions: positions, |
|
|
|
entity: finalEntity, |
|
|
|
color: this.defaultStyles.sector.color, |
|
|
|
borderColor: this.defaultStyles.sector.color, |
|
|
|
color: this.defaultStyles.sector.color, // 填充颜色 |
|
|
|
borderColor: this.defaultStyles.sector.color, // 边框颜色 |
|
|
|
opacity: 0.5, |
|
|
|
width: this.defaultStyles.sector.width, |
|
|
|
label: `扇形 ${this.entityCounter}` |
|
|
|
label: `扇形空域 ${this.entityCounter}` |
|
|
|
}; |
|
|
|
this.allEntities.push(entityData); |
|
|
|
// 5. 重置状态,保持绘制状态以继续绘制 |
|
|
|
this.drawingPoints = []; |
|
|
|
}, |
|
|
|
// 生成圆形的点,用于绘制边框线 |
|
|
|
generateCirclePositions(center, radius, numPoints = 1024) { |
|
|
|
// 生成圆形的点,用于绘制边框线(提高分段数以减轻锯齿) |
|
|
|
generateCirclePositions(center, radius, numPoints = 256) { |
|
|
|
const positions = []; |
|
|
|
const ellipsoid = this.viewer.scene.globe.ellipsoid; |
|
|
|
|
|
|
|
@ -3307,8 +3293,8 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
// 确保角度差不为零 |
|
|
|
angleDiff = Math.max(0.01, angleDiff); |
|
|
|
// 计算扇形的顶点数(根据角度差确定,确保平滑) |
|
|
|
const numPoints = Math.max(200, Math.ceil(angleDiff * 180 / Math.PI)); |
|
|
|
// 计算扇形的顶点数(根据角度差确定,确保平滑;提高分段数以减轻锯齿) |
|
|
|
const numPoints = Math.max(64, Math.ceil(angleDiff * 180 / Math.PI / 2)); |
|
|
|
const angleStep = angleDiff / (numPoints - 1); |
|
|
|
// 生成扇形的顶点(顺时针方向) |
|
|
|
for (let i = 0; i < numPoints; i++) { |
|
|
|
@ -3323,14 +3309,6 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
positions.push(center); |
|
|
|
return positions; |
|
|
|
}, |
|
|
|
// 生成扇形边缘点 |
|
|
|
generateSectorEdgePoint(center, radius, angle) { |
|
|
|
const centerLL = Cesium.Cartographic.fromCartesian(center); |
|
|
|
const distance = radius / 6378137; |
|
|
|
const lat = centerLL.latitude + Math.sin(angle) * distance; |
|
|
|
const lng = centerLL.longitude + Math.cos(angle) * distance / Math.cos(centerLL.latitude); |
|
|
|
return Cesium.Cartesian3.fromRadians(lng, lat); |
|
|
|
}, |
|
|
|
// 计算两点之间的距离(米) |
|
|
|
calculateDistance(point1, point2) { |
|
|
|
return Cesium.Cartesian3.distance(point1, point2); |
|
|
|
@ -3372,12 +3350,12 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
} |
|
|
|
return []; |
|
|
|
}, false), |
|
|
|
width: 12, // 增加宽度以获得更大的箭头头部 |
|
|
|
// 使用箭头材质 |
|
|
|
width: 8, // 增加宽度以获得更大的箭头头部 |
|
|
|
// 使用箭头材质以显示箭头方向 |
|
|
|
material: new Cesium.PolylineArrowMaterialProperty( |
|
|
|
Cesium.Color.fromCssColorString(this.defaultStyles.arrow.color) |
|
|
|
), |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
clampToGround: true, // 贴地 |
|
|
|
widthInMeters: false // 使用像素宽度模式 |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -3425,11 +3403,11 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
name: `箭头 ${this.entityCounter}`, |
|
|
|
polyline: { |
|
|
|
positions: positions, |
|
|
|
width: 12, // 增加宽度以获得更大的箭头头部 |
|
|
|
width: 8, // 增加宽度以获得更大的箭头头部 |
|
|
|
material: new Cesium.PolylineArrowMaterialProperty( |
|
|
|
Cesium.Color.fromCssColorString(this.defaultStyles.arrow.color) |
|
|
|
), |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
clampToGround: true, |
|
|
|
// 使用像素宽度模式,确保箭头在缩放时保持比例 |
|
|
|
widthInMeters: false |
|
|
|
} |
|
|
|
@ -3707,14 +3685,15 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
addLineEntity(positions, pointEntities = []) { |
|
|
|
this.entityCounter++ |
|
|
|
const id = `line_${this.entityCounter}` |
|
|
|
const straightPositions = this.getPolylinePositionsStraightIn2D(positions, false) |
|
|
|
const entity = this.viewer.entities.add({ |
|
|
|
id: id, |
|
|
|
name: `线 ${this.entityCounter}`, |
|
|
|
polyline: { |
|
|
|
positions: positions, |
|
|
|
positions: straightPositions, |
|
|
|
width: this.defaultStyles.line.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.line.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}) |
|
|
|
const entityData = { |
|
|
|
@ -3739,23 +3718,21 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
addPolygonEntity(positions) { |
|
|
|
this.entityCounter++ |
|
|
|
const id = `polygon_${this.entityCounter}` |
|
|
|
// 闭合多边形 |
|
|
|
const polygonPositions = [...positions, positions[0]] |
|
|
|
// 创建一个复合实体,包含填充和边框 |
|
|
|
const straightBorder = this.getPolylinePositionsStraightIn2D(polygonPositions, false) |
|
|
|
const entity = this.viewer.entities.add({ |
|
|
|
id: id, |
|
|
|
name: `面 ${this.entityCounter}`, |
|
|
|
// 填充部分 |
|
|
|
polygon: { |
|
|
|
hierarchy: new Cesium.PolygonHierarchy(polygonPositions), |
|
|
|
material: Cesium.Color.TRANSPARENT |
|
|
|
material: Cesium.Color.TRANSPARENT, |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
// 边框部分 |
|
|
|
polyline: { |
|
|
|
positions: polygonPositions, |
|
|
|
positions: straightBorder, |
|
|
|
width: this.defaultStyles.polygon.width, |
|
|
|
material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(this.defaultStyles.polygon.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}) |
|
|
|
const entityData = { |
|
|
|
@ -3768,7 +3745,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
borderColor: this.defaultStyles.polygon.color, |
|
|
|
opacity: 0, |
|
|
|
width: this.defaultStyles.polygon.width, |
|
|
|
label: `面 ${this.entityCounter}` |
|
|
|
label: `多边形空域 ${this.entityCounter}` |
|
|
|
} |
|
|
|
this.allEntities.push(entityData) |
|
|
|
entity.clickHandler = (e) => { |
|
|
|
@ -3782,7 +3759,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
const id = `rectangle_${this.entityCounter}` |
|
|
|
const entity = this.viewer.entities.add({ |
|
|
|
id: id, |
|
|
|
name: `矩形 ${this.entityCounter}`, |
|
|
|
name: `矩形空域 ${this.entityCounter}`, |
|
|
|
rectangle: { |
|
|
|
coordinates: coordinates, |
|
|
|
// 移除填充颜色,只显示边框 |
|
|
|
@ -3803,17 +3780,17 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
const id = `circle_${this.entityCounter}` |
|
|
|
const entity = this.viewer.entities.add({ |
|
|
|
id: id, |
|
|
|
name: `圆形 ${this.entityCounter}`, |
|
|
|
name: `圆形空域 ${this.entityCounter}`, |
|
|
|
position: center, // 圆心位置 |
|
|
|
// 【优化】使用 ellipse (椭圆) 绘制圆形 |
|
|
|
ellipse: { |
|
|
|
semiMinorAxis: validRadius, |
|
|
|
semiMajorAxis: validRadius, |
|
|
|
semiMinorAxis: validRadius, // 半短轴 = 半径 |
|
|
|
semiMajorAxis: validRadius, // 半长轴 = 半径 |
|
|
|
// 移除填充颜色,只显示边框 |
|
|
|
material: Cesium.Color.TRANSPARENT, |
|
|
|
outline: true, |
|
|
|
outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), |
|
|
|
outlineWidth: this.defaultStyles.circle.width, |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
outlineWidth: this.defaultStyles.circle.width |
|
|
|
} |
|
|
|
}) |
|
|
|
// 【重要修改】直接把 entity 推入数组 |
|
|
|
@ -3821,6 +3798,113 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
return entity |
|
|
|
}, |
|
|
|
// ================== 工具方法 ================== |
|
|
|
/** 生成普通纯色折线材质(无轮廓/发光) */ |
|
|
|
getPolylineSolidMaterial(cssColor) { |
|
|
|
const color = Cesium.Color.fromCssColorString(cssColor) |
|
|
|
return new Cesium.ColorMaterialProperty(color) |
|
|
|
}, |
|
|
|
/** 根据浏览器缩放比例设置渲染分辨率,减轻 80% 等缩放下线条锯齿 */ |
|
|
|
applyResolutionScale() { |
|
|
|
if (!this.viewer || !this.viewer.cesiumWidget) return |
|
|
|
const vv = window.visualViewport |
|
|
|
const scale = (vv && typeof vv.scale === 'number') ? vv.scale : 1 |
|
|
|
// 始终使用至少 2.2 倍超采样,80% 缩放下再按比例提高(上限 2.5),显著减轻线条锯齿 |
|
|
|
let resolutionScale = 2.2 |
|
|
|
if (scale > 0 && scale < 1) { |
|
|
|
resolutionScale = Math.min(2.5, 1 / scale) |
|
|
|
if (resolutionScale < 2.0) resolutionScale = 2.0 |
|
|
|
} |
|
|
|
this.viewer.resolutionScale = resolutionScale |
|
|
|
try { |
|
|
|
if (typeof this.viewer.cesiumWidget.resize === 'function') { |
|
|
|
this.viewer.cesiumWidget.resize() |
|
|
|
} |
|
|
|
} catch (e) { /* 忽略 resize 异常 */ } |
|
|
|
if (this.viewer.scene.requestRenderMode) this.viewer.scene.requestRender() |
|
|
|
}, |
|
|
|
/** 监听浏览器缩放/窗口变化,更新 resolutionScale;返回取消监听的函数 */ |
|
|
|
setupResolutionScaleListener() { |
|
|
|
const onResize = () => { |
|
|
|
this.applyResolutionScale() |
|
|
|
} |
|
|
|
if (window.visualViewport) { |
|
|
|
window.visualViewport.addEventListener('resize', onResize) |
|
|
|
window.visualViewport.addEventListener('scroll', onResize) |
|
|
|
} |
|
|
|
window.addEventListener('resize', onResize) |
|
|
|
return () => { |
|
|
|
if (window.visualViewport) { |
|
|
|
window.visualViewport.removeEventListener('resize', onResize) |
|
|
|
window.visualViewport.removeEventListener('scroll', onResize) |
|
|
|
} |
|
|
|
window.removeEventListener('resize', onResize) |
|
|
|
} |
|
|
|
}, |
|
|
|
/** 按等经度/等纬度采样矩形边框,使在 2D 地图缩小时仍显示为直线(避免测地线弯弧);分段数提高以减轻锯齿 */ |
|
|
|
getRectangleBorderPositions(rect, segmentsPerEdge = 64) { |
|
|
|
const west = rect.west |
|
|
|
const south = rect.south |
|
|
|
const east = rect.east |
|
|
|
const north = rect.north |
|
|
|
const positions = [] |
|
|
|
const n = Math.max(2, segmentsPerEdge) |
|
|
|
for (let i = 0; i <= n; i++) { |
|
|
|
const lon = west + (east - west) * (i / n) |
|
|
|
positions.push(Cesium.Cartesian3.fromRadians(lon, south)) |
|
|
|
} |
|
|
|
for (let i = 1; i <= n; i++) { |
|
|
|
const lat = south + (north - south) * (i / n) |
|
|
|
positions.push(Cesium.Cartesian3.fromRadians(east, lat)) |
|
|
|
} |
|
|
|
for (let i = 1; i <= n; i++) { |
|
|
|
const lon = east - (east - west) * (i / n) |
|
|
|
positions.push(Cesium.Cartesian3.fromRadians(lon, north)) |
|
|
|
} |
|
|
|
for (let i = 1; i < n; i++) { |
|
|
|
const lat = north - (north - south) * (i / n) |
|
|
|
positions.push(Cesium.Cartesian3.fromRadians(west, lat)) |
|
|
|
} |
|
|
|
return positions |
|
|
|
}, |
|
|
|
/** 在 2D 墨卡托下将一段线采样为“直线”(避免测地线弯弧);返回 Cartesian3 数组含起点到终点;分段数提高以减轻锯齿 */ |
|
|
|
sampleSegmentStraightIn2D(cartesianA, cartesianB, numSegments = 64) { |
|
|
|
const cgA = Cesium.Cartographic.fromCartesian(cartesianA) |
|
|
|
const cgB = Cesium.Cartographic.fromCartesian(cartesianB) |
|
|
|
const lonA = cgA.longitude |
|
|
|
const latA = cgA.latitude |
|
|
|
const lonB = cgB.longitude |
|
|
|
const latB = cgB.latitude |
|
|
|
const yA = Math.log(Math.tan(Math.PI / 4 + latA / 2)) |
|
|
|
const yB = Math.log(Math.tan(Math.PI / 4 + latB / 2)) |
|
|
|
const n = Math.max(1, numSegments) |
|
|
|
const positions = [] |
|
|
|
for (let i = 0; i <= n; i++) { |
|
|
|
const t = i / n |
|
|
|
const x = lonA + t * (lonB - lonA) |
|
|
|
const y = yA + t * (yB - yA) |
|
|
|
const lat = 2 * Math.atan(Math.exp(y)) - Math.PI / 2 |
|
|
|
positions.push(Cesium.Cartesian3.fromRadians(x, lat)) |
|
|
|
} |
|
|
|
return positions |
|
|
|
}, |
|
|
|
/** 将折线/多边形顶点按 2D 墨卡托“直线”采样,使缩放小时仍显示为直;closed 为 true 表示多边形闭合;分段数提高以减轻锯齿 */ |
|
|
|
getPolylinePositionsStraightIn2D(positions, closed = false, segmentsPerEdge = 64) { |
|
|
|
if (!positions || positions.length < 2) return positions |
|
|
|
const n = positions.length |
|
|
|
const result = [] |
|
|
|
const segs = closed ? n : n - 1 |
|
|
|
for (let seg = 0; seg < segs; seg++) { |
|
|
|
const i = seg |
|
|
|
const j = closed ? (seg + 1) % n : seg + 1 |
|
|
|
const sampled = this.sampleSegmentStraightIn2D(positions[i], positions[j], segmentsPerEdge) |
|
|
|
if (seg === 0) { |
|
|
|
result.push(...sampled) |
|
|
|
} else { |
|
|
|
for (let k = 1; k < sampled.length; k++) result.push(sampled[k]) |
|
|
|
} |
|
|
|
} |
|
|
|
return result |
|
|
|
}, |
|
|
|
getClickPosition(pixelPosition) { |
|
|
|
const cartesian = this.viewer.camera.pickEllipsoid(pixelPosition, this.viewer.scene.globe.ellipsoid) |
|
|
|
return cartesian |
|
|
|
@ -4028,7 +4112,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
break |
|
|
|
case 'line': |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4037,7 +4121,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
entity.polygon.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) |
|
|
|
} |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.borderColor || data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4046,7 +4130,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
entity.rectangle.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) |
|
|
|
} |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.borderColor || data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4055,7 +4139,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
entity.ellipse.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) |
|
|
|
} |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.borderColor || data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4079,7 +4163,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
entity.ellipse.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) |
|
|
|
} |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.borderColor || data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4088,7 +4172,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
entity.polygon.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) |
|
|
|
} |
|
|
|
if (entity.polyline) { |
|
|
|
entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) |
|
|
|
entity.polyline.material = this.getPolylineSolidMaterial(data.borderColor || data.color) |
|
|
|
entity.polyline.width = data.width |
|
|
|
} |
|
|
|
break |
|
|
|
@ -4121,6 +4205,21 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
this.selectedEntity = null |
|
|
|
} |
|
|
|
}, |
|
|
|
/** 右键航线:上锁/解锁,上锁后该航线不可编辑 */ |
|
|
|
toggleRouteLock() { |
|
|
|
const ed = this.contextMenu.entityData; |
|
|
|
if (!ed || ed.type !== 'route' || ed.routeId == null) { |
|
|
|
this.contextMenu.visible = false; |
|
|
|
return; |
|
|
|
} |
|
|
|
const routeId = ed.routeId; |
|
|
|
const nextLocked = !this.routeLocked[routeId]; |
|
|
|
this.$set(this.routeLocked, routeId, nextLocked); |
|
|
|
this.contextMenu.visible = false; |
|
|
|
this.$message && this.$message.success(nextLocked ? '航线已上锁,无法修改' : '航线已解锁,可以编辑'); |
|
|
|
this.$emit('route-lock-changed', { routeId, locked: nextLocked }); |
|
|
|
}, |
|
|
|
|
|
|
|
/** 右键飞机:切换该航线飞机标牌的显示/隐藏 */ |
|
|
|
toggleRouteLabelVisibility() { |
|
|
|
const ed = this.contextMenu.entityData |
|
|
|
@ -4365,13 +4464,13 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
const names = { |
|
|
|
point: '点', |
|
|
|
line: '线', |
|
|
|
polygon: '面', |
|
|
|
rectangle: '矩形', |
|
|
|
circle: '圆形', |
|
|
|
polygon: '多边形空域', |
|
|
|
rectangle: '矩形空域', |
|
|
|
circle: '圆形空域', |
|
|
|
ellipse: '椭圆', |
|
|
|
hold_circle: '圆形盘旋', |
|
|
|
hold_ellipse: '椭圆盘旋', |
|
|
|
sector: '扇形', |
|
|
|
sector: '扇形空域', |
|
|
|
arrow: '箭头', |
|
|
|
text: '文本', |
|
|
|
image: '图片' |
|
|
|
@ -4473,12 +4572,13 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
break |
|
|
|
case 'line': |
|
|
|
const linePositions = entityData.data.points.map(p => Cesium.Cartesian3.fromDegrees(p.lng, p.lat)) |
|
|
|
const straightLinePositions = this.getPolylinePositionsStraightIn2D(linePositions, false) |
|
|
|
entity = this.viewer.entities.add({ |
|
|
|
polyline: { |
|
|
|
positions: linePositions, |
|
|
|
positions: straightLinePositions, |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString(color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(color), |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: entityData.label || '线', |
|
|
|
@ -4502,7 +4602,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
outlineWidth: 2 |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: entityData.label || '面', |
|
|
|
text: entityData.label || '多边形空域', |
|
|
|
font: '14px sans-serif', |
|
|
|
fillColor: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
@ -4523,7 +4623,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
outlineWidth: 2 |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: entityData.label || '矩形', |
|
|
|
text: entityData.label || '矩形空域', |
|
|
|
font: '14px sans-serif', |
|
|
|
fillColor: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
@ -4551,7 +4651,7 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
outlineWidth: 2 |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: entityData.label || '圆形', |
|
|
|
text: entityData.label || '圆形空域', |
|
|
|
font: '14px sans-serif', |
|
|
|
fillColor: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
@ -4878,13 +4978,12 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
id: selectedLineEntity.id, |
|
|
|
name: selectedLineEntity.label, |
|
|
|
polyline: { |
|
|
|
positions: newPositions, |
|
|
|
positions: this.getPolylinePositionsStraightIn2D(newPositions, false), |
|
|
|
width: selectedLineEntity.width, |
|
|
|
material: Cesium.Color.fromCssColorString(selectedLineEntity.color), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial(selectedLineEntity.color), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}) |
|
|
|
// 更新线实体的引用和位置数组 |
|
|
|
selectedLineEntity.entity = newEntity |
|
|
|
selectedLineEntity.positions = newPositions |
|
|
|
// 更新点数据 |
|
|
|
@ -4973,6 +5072,10 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
this.scaleBarCleanup() |
|
|
|
this.scaleBarCleanup = null |
|
|
|
} |
|
|
|
if (typeof this._resolutionScaleCleanup === 'function') { |
|
|
|
this._resolutionScaleCleanup() |
|
|
|
this._resolutionScaleCleanup = null |
|
|
|
} |
|
|
|
|
|
|
|
if (this.viewer) { |
|
|
|
this.viewer.destroy() |
|
|
|
@ -5088,13 +5191,13 @@ this.viewer.scene.postProcessStages.fxaa.enabled = true |
|
|
|
semiMinorAxis: radiusInMeters, |
|
|
|
semiMajorAxis: radiusInMeters, |
|
|
|
material: Cesium.Color.RED.withAlpha(0), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
clampToGround: true |
|
|
|
}, |
|
|
|
polyline: { |
|
|
|
positions: circlePositions, |
|
|
|
width: 2, |
|
|
|
material: Cesium.Color.RED, |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
material: this.getPolylineSolidMaterial('#FF0000'), |
|
|
|
clampToGround: true |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
|