diff --git a/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue b/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue index e0a75aa..0f07fae 100644 --- a/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue +++ b/ruoyi-ui/src/views/cesiumMap/ContextMenu.vue @@ -150,7 +150,7 @@
@@ -309,7 +309,7 @@ export default { ], presetWidths: [1, 2, 3, 4, 5, 6, 8, 10, 12], presetSizes: [6, 8, 10, 12, 14, 16, 18, 20, 24], - presetOpacities: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], + presetOpacities: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], presetFontSizes: [8, 10, 12, 14, 16, 18, 20, 24, 28, 32] } }, diff --git a/ruoyi-ui/src/views/cesiumMap/index.vue b/ruoyi-ui/src/views/cesiumMap/index.vue index fd6a625..69f240e 100644 --- a/ruoyi-ui/src/views/cesiumMap/index.vue +++ b/ruoyi-ui/src/views/cesiumMap/index.vue @@ -153,10 +153,10 @@ export default { defaultStyles: { point: { color: '#FF0000', size: 12 }, line: { color: '#00FF00', width: 3 }, - polygon: { color: '#0000FF', opacity: 0.5, width: 2 }, - rectangle: { color: '#FFA500', opacity: 0.3, width: 2 }, - circle: { color: '#800080', opacity: 0.4, width: 2 }, - sector: { color: '#FF6347', opacity: 0.5, width: 2 }, + polygon: { color: '#0000FF', opacity: 0, width: 3 }, + rectangle: { color: '#FFA500', opacity: 0, width: 3 }, + circle: { color: '#800080', opacity: 0, width: 3 }, + sector: { color: '#FF6347', opacity: 0, width: 3 }, arrow: { color: '#FF0000', width: 6 }, text: { color: '#000000', font: '48px Microsoft YaHei, PingFang SC, sans-serif', backgroundColor: 'rgba(255, 255, 255, 0.8)' }, image: { width: 150, height: 150 } @@ -1256,8 +1256,8 @@ export default { } return new Cesium.PolygonHierarchy(this.drawingPoints); }, false), - // 使用半透明颜色,方便看到地图底图 - material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color).withAlpha(0.5), + // 不填充颜色 + material: Cesium.Color.TRANSPARENT, // 确保贴地 perPositionHeight: false }, @@ -1271,12 +1271,9 @@ export default { } return this.drawingPoints; }, false), - width: this.defaultStyles.line.width, - // 边框使用虚线,表示正在编辑中 - material: new Cesium.PolylineDashMaterialProperty({ - color: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), - dashLength: 16 - }), + width: this.defaultStyles.polygon.width, + // 边框使用实线,表示正在编辑中 + material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), clampToGround: true } }); @@ -1335,6 +1332,7 @@ export default { this.activeCursorPosition = position; // 初始化鼠标位置 // 创建动态预览矩形 this.tempEntity = this.viewer.entities.add({ + // 填充部分 rectangle: { // 关键:使用 CallbackProperty 动态计算矩形范围 coordinates: new Cesium.CallbackProperty(() => { @@ -1344,11 +1342,35 @@ export default { } return Cesium.Rectangle.fromDegrees(0, 0, 0, 0); }, false), - // 样式:半透明填充 + 边框 - material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color).withAlpha(0.5), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), - outlineWidth: 2, + // 设置填充颜色 + 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 []; + }, false), + width: this.defaultStyles.rectangle.width, + material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color), clampToGround: true // 贴地 } }); @@ -1379,14 +1401,36 @@ export default { // 3. 创建最终显示的静态实体 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]; + + // 创建一个复合实体,包含填充和边框 const finalEntity = this.viewer.entities.add({ id: id, + // 填充部分 rectangle: { coordinates: rect, - material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color).withAlpha(this.defaultStyles.polygon.opacity), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), - outlineWidth: this.defaultStyles.polygon.width, + 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), clampToGround: true } }); @@ -1397,9 +1441,10 @@ export default { points: this.drawingPoints.map(p => this.cartesianToLatLng(p)), positions: this.drawingPoints, entity: finalEntity, - color: this.defaultStyles.polygon.color, - opacity: this.defaultStyles.polygon.opacity, - width: this.defaultStyles.polygon.width, + color: this.defaultStyles.rectangle.color, // 填充颜色 + borderColor: this.defaultStyles.rectangle.color, // 边框颜色 + opacity: this.defaultStyles.rectangle.opacity, + width: this.defaultStyles.rectangle.width, label: `矩形 ${this.entityCounter}` }; this.allEntities.push(entityData); @@ -1531,12 +1576,33 @@ export default { return initialRadius; } }, false), - // 样式设置 - material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color).withAlpha(0.5), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.line.color), - outlineWidth: 2, - // height: 0, // 如果需要贴地可开启或使用 heightReference + // 设置填充颜色 + material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color).withAlpha(this.defaultStyles.circle.opacity), + // 移除 outline 属性,改用 polyline 绘制边框 + clampToGround: true + }, + // 边框部分 + polyline: { + // 关键:使用 CallbackProperty 动态计算圆形边框线 + positions: new Cesium.CallbackProperty(() => { + try { + if (this.activeCursorPosition && this.drawingPoints.length > 0 && this.drawingPoints[0]) { + const center = this.drawingPoints[0]; + const edge = this.activeCursorPosition; + if (center && edge && typeof center.x === 'number' && typeof edge.x === 'number') { + const radius = Cesium.Cartesian3.distance(center, edge); + const validRadius = isFinite(radius) && radius > 0 ? radius : initialRadius; + return this.generateCirclePositions(center, validRadius); + } + } + return []; + } catch (e) { + return []; + } + }, false), + width: this.defaultStyles.circle.width, + material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), + clampToGround: true } }); } @@ -1575,16 +1641,28 @@ export default { // 3. 创建最终显示的静态实体 this.entityCounter++; const id = `circle_${this.entityCounter}`; + + // 生成圆形的点,用于绘制边框线 + 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.polygon.color).withAlpha(this.defaultStyles.polygon.opacity), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), - outlineWidth: this.defaultStyles.polygon.width + // 设置填充颜色 + material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color).withAlpha(this.defaultStyles.circle.opacity), + clampToGround: true + }, + // 边框部分 + polyline: { + positions: circlePositions, + width: this.defaultStyles.circle.width, + material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), + clampToGround: true } }); // 4. 记录实体 @@ -1594,9 +1672,10 @@ export default { points: [centerPoint, edgePosition].map(p => this.cartesianToLatLng(p)), positions: [centerPoint, edgePosition], entity: finalEntity, - color: this.defaultStyles.polygon.color, - opacity: this.defaultStyles.polygon.opacity, - width: this.defaultStyles.polygon.width, + color: this.defaultStyles.circle.color, // 填充颜色 + borderColor: this.defaultStyles.circle.color, // 边框颜色 + opacity: this.defaultStyles.circle.opacity, + width: this.defaultStyles.circle.width, radius: radius, label: `圆形 ${this.entityCounter}` }; @@ -1669,6 +1748,7 @@ export default { } // 创建动态预览扇形 this.tempEntity = this.viewer.entities.add({ + // 填充部分 polygon: { hierarchy: new Cesium.CallbackProperty(() => { if (this.drawingPoints.length > 1 && this.activeCursorPosition) { @@ -1684,10 +1764,29 @@ export default { } return new Cesium.PolygonHierarchy([]); }, false), - material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(0.5), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), - outlineWidth: this.defaultStyles.sector.width + // 设置填充颜色 + material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(this.defaultStyles.sector.opacity), + clampToGround: true + }, + // 边框部分 + polyline: { + positions: new Cesium.CallbackProperty(() => { + if (this.drawingPoints.length > 1 && this.activeCursorPosition) { + const centerPoint = this.drawingPoints[0]; + const radiusPoint = this.drawingPoints[1]; + if (!isFinite(fixedRadius) || fixedRadius === 0) { + return []; + } + const startAngle = this.calculatePointAngle(centerPoint, radiusPoint); + const endAngle = this.calculatePointAngle(centerPoint, this.activeCursorPosition); + const positions = this.generateSectorPositions(centerPoint, fixedRadius, startAngle, endAngle); + return positions; + } + return []; + }, false), + width: this.defaultStyles.sector.width, + material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), + clampToGround: true } }); } @@ -1721,13 +1820,19 @@ export default { const finalEntity = this.viewer.entities.add({ id: 'sector-' + new Date().getTime(), name: `扇形 ${this.entityCounter}`, + // 填充部分 polygon: { hierarchy: new Cesium.PolygonHierarchy(positions), - material: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color).withAlpha(0.5), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.sector.color), - outlineWidth: this.defaultStyles.sector.width, - perPositionHeight: false + // 设置填充颜色 + 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), + clampToGround: true } }); // 4. 记录实体 @@ -1741,7 +1846,8 @@ export default { endAngle: endAngle, positions: positions, entity: finalEntity, - color: 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}` @@ -1750,6 +1856,35 @@ export default { // 5. 重置状态,保持绘制状态以继续绘制 this.drawingPoints = []; }, + // 生成圆形的点,用于绘制边框线 + generateCirclePositions(center, radius, numPoints = 64) { + const positions = []; + const ellipsoid = this.viewer.scene.globe.ellipsoid; + + // 计算圆心的经纬度 + const centerCartographic = Cesium.Cartographic.fromCartesian(center); + const centerLatitude = centerCartographic.latitude; + const centerLongitude = centerCartographic.longitude; + + // 生成圆形的点 + for (let i = 0; i <= numPoints; i++) { + const angle = (i / numPoints) * Math.PI * 2; + + // 计算点的经纬度 + // 注意:这里使用简单的方法计算,实际应该考虑地球曲率 + const deltaLatitude = (radius / ellipsoid.maximumRadius) * Math.sin(angle); + const deltaLongitude = (radius / ellipsoid.maximumRadius) * Math.cos(angle) / Math.cos(centerLatitude); + + const latitude = centerLatitude + deltaLatitude; + const longitude = centerLongitude + deltaLongitude; + + // 转换为笛卡尔坐标 + const position = Cesium.Cartesian3.fromRadians(longitude, latitude); + positions.push(position); + } + + return positions; + }, // 计算角度 calculateAngle(center, start, end) { const startLL = Cesium.Cartographic.fromCartesian(start); @@ -2224,16 +2359,23 @@ export default { const id = `polygon_${this.entityCounter}` // 闭合多边形 const polygonPositions = [...positions, positions[0]] + // 创建一个复合实体,包含填充和边框 const entity = this.viewer.entities.add({ id: id, name: `面 ${this.entityCounter}`, + // 填充部分 polygon: { hierarchy: new Cesium.PolygonHierarchy(polygonPositions), - material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color) - .withAlpha(this.defaultStyles.polygon.opacity), - outline: true, - outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), - outlineWidth: this.defaultStyles.polygon.width + // 初始无填充 + material: Cesium.Color.TRANSPARENT, + clampToGround: true + }, + // 边框部分 + polyline: { + positions: polygonPositions, + width: this.defaultStyles.polygon.width, + material: Cesium.Color.fromCssColorString(this.defaultStyles.polygon.color), + clampToGround: true } }) const entityData = { @@ -2243,7 +2385,8 @@ export default { positions: polygonPositions, entity: entity, color: this.defaultStyles.polygon.color, - opacity: this.defaultStyles.polygon.opacity, + borderColor: this.defaultStyles.polygon.color, + opacity: 0, width: this.defaultStyles.polygon.width, label: `面 ${this.entityCounter}` } @@ -2262,8 +2405,8 @@ export default { name: `矩形 ${this.entityCounter}`, rectangle: { coordinates: coordinates, - material: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color) - .withAlpha(this.defaultStyles.rectangle.opacity), + // 移除填充颜色,只显示边框 + material: Cesium.Color.TRANSPARENT, outline: true, outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.rectangle.color), outlineWidth: this.defaultStyles.rectangle.width @@ -2286,8 +2429,8 @@ export default { ellipse: { semiMinorAxis: validRadius, // 半短轴 = 半径 semiMajorAxis: validRadius, // 半长轴 = 半径 - material: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color) - .withAlpha(this.defaultStyles.circle.opacity), + // 移除填充颜色,只显示边框 + material: Cesium.Color.TRANSPARENT, outline: true, outlineColor: Cesium.Color.fromCssColorString(this.defaultStyles.circle.color), outlineWidth: this.defaultStyles.circle.width @@ -2480,29 +2623,37 @@ export default { case 'polygon': if (entity.polygon) { entity.polygon.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) - entity.polygon.outlineColor = Cesium.Color.fromCssColorString(data.color) - entity.polygon.outlineWidth = data.width + } + if (entity.polyline) { + entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) + entity.polyline.width = data.width } break case 'rectangle': if (entity.rectangle) { entity.rectangle.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) - entity.rectangle.outlineColor = Cesium.Color.fromCssColorString(data.color) - entity.rectangle.outlineWidth = data.width + } + if (entity.polyline) { + entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) + entity.polyline.width = data.width } break case 'circle': if (entity.ellipse) { entity.ellipse.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) - entity.ellipse.outlineColor = Cesium.Color.fromCssColorString(data.color) - entity.ellipse.outlineWidth = data.width + } + if (entity.polyline) { + entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) + entity.polyline.width = data.width } break case 'sector': if (entity.polygon) { entity.polygon.material = Cesium.Color.fromCssColorString(data.color).withAlpha(data.opacity) - entity.polygon.outlineColor = Cesium.Color.fromCssColorString(data.color) - entity.polygon.outlineWidth = data.width + } + if (entity.polyline) { + entity.polyline.material = Cesium.Color.fromCssColorString(data.borderColor || data.color) + entity.polyline.width = data.width } break case 'arrow': @@ -2553,6 +2704,10 @@ export default { const entityData = this.contextMenu.entityData // 更新实体数据 entityData[property] = value + // 当修改填充色时,默认设置透明度为 20% + if (property === 'color' && (entityData.type === 'polygon' || entityData.type === 'rectangle' || entityData.type === 'circle' || entityData.type === 'sector')) { + entityData.opacity = 0.2 + } // 更新实体样式 this.updateEntityStyle(entityData) // 隐藏右键菜单 diff --git a/ruoyi-ui/src/views/childRoom/index.vue b/ruoyi-ui/src/views/childRoom/index.vue index 331e55b..a0be8b1 100644 --- a/ruoyi-ui/src/views/childRoom/index.vue +++ b/ruoyi-ui/src/views/childRoom/index.vue @@ -341,13 +341,13 @@ export default { showScaleDialog: false, currentScale: { scaleNumerator: 1, - scaleDenominator: 1000, - unit: 'm' + scaleDenominator: 20, + unit: 'km' }, scaleConfig: { scaleNumerator: 1, - scaleDenominator: 1000, - unit: 'm' + scaleDenominator: 20, + unit: 'km' }, showExternalParamsDialog: false, currentExternalParams: {},