|
|
@@ -3,7 +3,11 @@
|
|
|
<div class="mapBox">
|
|
|
<div id="cesiumContainer" style="width: 100%; height: 100vh"></div>
|
|
|
</div>
|
|
|
- <drawPlotView @switchChange="switchChange" />
|
|
|
+ <drawPlotView ref="drawPlotView" :polygonGeoJSON="polygonGeoJSON" :lineGeoJSON="lineGeoJSON"
|
|
|
+ :pointGeoJSON="pointGeoJSON" @useGeoJson="useGeoJson" @switchChange="switchChange"
|
|
|
+ @saveChange="saveChange" @deleteNewDraw="deleteNewDraw" @editDrawConfirm="editDrawConfirm"
|
|
|
+ @showEntrty="showEntrty" @warnDraw="warnDraw"
|
|
|
+ />
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
@@ -14,6 +18,7 @@ import "../../Cesium/Widgets/widgets.css";
|
|
|
|
|
|
import basicGeoJson from "../../assets/geoJson/basic.json";
|
|
|
import bw from "@/assets/windimgs/fanSvg/bw.svg";
|
|
|
+import benchmark from "@/assets/cesiumImg/benchmark.png";
|
|
|
|
|
|
import fjMYLonLatJson from "../fjLonLatJson/fj_MY.json"; //迈越风电场
|
|
|
import fjWHZLonLatJson from "../fjLonLatJson/fj_WHZ.json"; //京能旺海庄
|
|
|
@@ -21,6 +26,10 @@ import fjYPLLonLatJson from "../fjLonLatJson/fj_YPL.json"; //京能营盘梁
|
|
|
import fjSMSLonLatJson from "../fjLonLatJson/fj_SMS.json"; //京能苏木山
|
|
|
|
|
|
import drawPlotView from "./drawPlotView.vue";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import { ElNotification } from 'element-plus'
|
|
|
+// import booleanPointInPolygon from '@turf/boolean-point-in-polygon'
|
|
|
+// import { point, polygon } from '@turf/helpers'
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
|
@@ -29,7 +38,9 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
bw,
|
|
|
+ benchmark,
|
|
|
selectMethod: "",
|
|
|
+ dataSource: [],
|
|
|
restLatLon: [
|
|
|
{
|
|
|
longitude: 114.48789,
|
|
|
@@ -52,6 +63,10 @@ export default {
|
|
|
name: "JNSMS",
|
|
|
},
|
|
|
],
|
|
|
+ handlerAction: null,
|
|
|
+ polygonGeoJSON: [],
|
|
|
+ lineGeoJSON: [],
|
|
|
+ pointGeoJSON: []
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -59,8 +74,9 @@ export default {
|
|
|
},
|
|
|
methods: {
|
|
|
async initCesium() {
|
|
|
- const box = document.getElementById("cesiumContainer");
|
|
|
- const viewer = new Cesium.Viewer(box, {
|
|
|
+ Cesium.Ion.defaultAccessToken =
|
|
|
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwYTQwNDk3MC05YTZkLTQ2ZTEtODc0MS1lZTFkYjFlOTFmNmQiLCJpZCI6MTcyNDQ1LCJpYXQiOjE3NTQ4ODA4MzF9.KnhENYiHxNwTkhTWRA-lHqG59coLVT2FsIyOru2TV3E";
|
|
|
+ const cesiumOptions = {
|
|
|
geocoder: false, // 地址搜索控件
|
|
|
homeButton: false, // 返回地图初始位置控件
|
|
|
infoBox: false, // 地图默认的信息控件
|
|
|
@@ -74,7 +90,9 @@ export default {
|
|
|
vrButton: false,
|
|
|
selectionIndicator: false,
|
|
|
shouldAnimate: true,
|
|
|
- });
|
|
|
+ };
|
|
|
+
|
|
|
+ const viewer = new Cesium.Viewer("cesiumContainer", cesiumOptions);
|
|
|
|
|
|
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
|
|
|
maximumLevel: 18,
|
|
|
@@ -260,11 +278,116 @@ export default {
|
|
|
duration: 3.0,
|
|
|
});
|
|
|
},
|
|
|
-
|
|
|
+ saveChange() {
|
|
|
+ // 移除鼠标事件处理器
|
|
|
+ if (this.handlerAction) {
|
|
|
+ this.handlerAction.destroy();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ warnDraw(polygon, point) {
|
|
|
+ // 判断是否在围栏内
|
|
|
+ this.addPersonPosition(this.viewer, point)
|
|
|
+ const inside = this.$turf.booleanPointInPolygon(point, polygon);
|
|
|
+ if (!inside) {
|
|
|
+ ElNotification({
|
|
|
+ title: '警告',
|
|
|
+ message: '有人员越界,已记录',
|
|
|
+ type: 'error',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //创建区域与人员位置
|
|
|
+ addPersonPosition(viewer, point) {
|
|
|
+ // 创建闪烁点实体
|
|
|
+ const position = Cesium.Cartesian3.fromDegrees(point.coordinates[0], point.coordinates[1]);
|
|
|
+ const blinkingPoint = viewer.entities.add({
|
|
|
+ position: position,
|
|
|
+ point: {
|
|
|
+ pixelSize: 10,
|
|
|
+ color: Cesium.Color.RED,
|
|
|
+ outlineColor: Cesium.Color.WHITE,
|
|
|
+ outlineWidth: 2,
|
|
|
+ // 使用 CallbackProperty 实现闪烁
|
|
|
+ show: new Cesium.CallbackProperty(function(time) {
|
|
|
+ // 获取当前时间的秒数(可自定义频率)
|
|
|
+ const seconds = Cesium.JulianDate.secondsDifference(time, Cesium.JulianDate.fromIso8601('2000-01-01T00:00:00Z'));
|
|
|
+ // 每 1 秒闪烁一次(可调整)
|
|
|
+ return Math.floor(seconds * 2) % 2 === 0; // 2 表示每秒闪烁 2 次(频率)
|
|
|
+ }, false)
|
|
|
+ },
|
|
|
+ });
|
|
|
+ setTimeout(function () {
|
|
|
+ viewer.entities.remove(blinkingPoint);
|
|
|
+ }, 3000);
|
|
|
+ },
|
|
|
+ deleteNewDraw(entity) {
|
|
|
+ this.viewer.entities.remove(entity);
|
|
|
+ },
|
|
|
switchChange(val) {
|
|
|
+ this.polygonGeoJSON = []
|
|
|
+ this.lineGeoJSON = []
|
|
|
+ this.pointGeoJSON = []
|
|
|
this.selectMethod = val.name
|
|
|
- this.drawShapeFn(this.viewer, this.selectMethod)
|
|
|
+ // 移除鼠标事件处理器
|
|
|
+ if (this.handlerAction) {
|
|
|
+ this.handlerAction.destroy();
|
|
|
+ }
|
|
|
+ if (val.name !== 'point') {
|
|
|
+ this.drawShapeFn(this.viewer, this.selectMethod)
|
|
|
+ } else {
|
|
|
+ this.drawPointFn(this.viewer, this.selectMethod)
|
|
|
+ }
|
|
|
},
|
|
|
+ // 使用保存的电子区域
|
|
|
+ async useGeoJson(geoJson) {
|
|
|
+ await new Cesium.GeoJsonDataSource.load(geoJson, {
|
|
|
+ stroke: Cesium.Color.WHITE, // 边框颜色
|
|
|
+ fill: Cesium.Color.WHITE.withAlpha(0.4), // 填充颜色(带透明度)
|
|
|
+ strokeWidth: 3,
|
|
|
+ // clampToGround: true // 贴地(需要地形或开启 globe.depthTestAgainstTerrain)
|
|
|
+ }).then(dataSource =>{
|
|
|
+ this.dataSource.push(dataSource);
|
|
|
+ this.viewer.dataSources.add(dataSource);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ showEntrty(data) {
|
|
|
+ if (data.newdraw) {
|
|
|
+ // flashEntity(data.entity)
|
|
|
+ data.entity.show = false; // 看是否消失
|
|
|
+ setTimeout(() => data.entity.show = true, 100);
|
|
|
+ }
|
|
|
+ function flashEntity(entity, viewer) {
|
|
|
+ if (!entity || !entity.show) return;
|
|
|
+
|
|
|
+ let count = 0;
|
|
|
+ const totalFlashes = 2; // 闪两下(一次闪 = 隐藏+显示)
|
|
|
+ const interval = 80; // 每次状态切换间隔(毫秒)
|
|
|
+
|
|
|
+ const originalShow = entity.show
|
|
|
+
|
|
|
+ const flash = () => {
|
|
|
+ if (count < totalFlashes * 2) {
|
|
|
+ entity.show = !entity.show
|
|
|
+ count++;
|
|
|
+ setTimeout(flash, interval);
|
|
|
+ } else {
|
|
|
+ // 闪烁结束后恢复原始状态(可选)
|
|
|
+ entity.show = originalShow;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ flash();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ removeGeoJsonLayer() {
|
|
|
+ if (this.dataSource && this.dataSource.length > 0) {
|
|
|
+ this.dataSource.forEach(it => {
|
|
|
+ this.viewer.dataSources.remove(it)
|
|
|
+ })
|
|
|
+ this.dataSource = []; // 清空引用
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 绘制电子围栏与路线
|
|
|
drawShapeFn(viewer, value) {
|
|
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
|
|
|
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
|
|
|
@@ -274,7 +397,7 @@ export default {
|
|
|
position: worldPosition,
|
|
|
point: {
|
|
|
color: Cesium.Color.WHITE,
|
|
|
- pixelSize: 5,
|
|
|
+ pixelSize: 1,
|
|
|
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
|
},
|
|
|
});
|
|
|
@@ -282,7 +405,7 @@ export default {
|
|
|
}
|
|
|
let drawingMode = value
|
|
|
let that = this
|
|
|
- function drawShape(positionData) {
|
|
|
+ function drawShape(positionData, type) {
|
|
|
let shape;
|
|
|
if (drawingMode === "line") {
|
|
|
shape = viewer.entities.add({
|
|
|
@@ -292,7 +415,7 @@ export default {
|
|
|
width: 3,
|
|
|
},
|
|
|
});
|
|
|
- that.getDrawlineValue(shape)
|
|
|
+ that.getDrawlineValue(shape, type)
|
|
|
|
|
|
} else if (drawingMode === "polygon") {
|
|
|
shape = viewer.entities.add({
|
|
|
@@ -303,10 +426,11 @@ export default {
|
|
|
),
|
|
|
},
|
|
|
});
|
|
|
- that.getDrawPolygonValue(shape)
|
|
|
+ that.getDrawPolygonValue(shape, type)
|
|
|
}
|
|
|
return shape;
|
|
|
}
|
|
|
+
|
|
|
let activeShapePoints = [];
|
|
|
let activeShape;
|
|
|
let floatingPoint;
|
|
|
@@ -327,7 +451,7 @@ export default {
|
|
|
}
|
|
|
return activeShapePoints;
|
|
|
}, false);
|
|
|
- activeShape = drawShape(dynamicPositions);
|
|
|
+ activeShape = drawShape(dynamicPositions, "norecord");
|
|
|
}
|
|
|
activeShapePoints.push(earthPosition);
|
|
|
createPoint(earthPosition);
|
|
|
@@ -358,8 +482,10 @@ export default {
|
|
|
handler.setInputAction(function (event) {
|
|
|
terminateShape();
|
|
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
|
+
|
|
|
+ this.handlerAction = handler
|
|
|
},
|
|
|
- getDrawlineValue(shape) {
|
|
|
+ getDrawlineValue(shape, type) {
|
|
|
// 获取到线的数据
|
|
|
// 获取 Cartesian3 数组
|
|
|
const cartesianPositions = shape.polyline.positions.getValue(Cesium.JulianDate.now());
|
|
|
@@ -382,10 +508,22 @@ export default {
|
|
|
},
|
|
|
properties: { name: "巡检路线" }
|
|
|
};
|
|
|
- console.log("lineGeoJSON=====>>>>", lineGeoJSON);
|
|
|
+ console.log("lineGeoJSON=====>>>>", JSON.stringify(lineGeoJSON));
|
|
|
+ console.log("shape=====>>>>", shape);
|
|
|
|
|
|
+ if (!type) {
|
|
|
+ this.lineGeoJSON.push(JSON.stringify(lineGeoJSON))
|
|
|
+ let obj = {
|
|
|
+ newdraw: true,
|
|
|
+ type: "line",
|
|
|
+ name: `巡检路线-${dayjs().format('YYYYMMDDHHmmss')}`,
|
|
|
+ data: JSON.stringify(lineGeoJSON),
|
|
|
+ entity: shape
|
|
|
+ }
|
|
|
+ this.$refs.drawPlotView.drawTableData.push(obj)
|
|
|
+ }
|
|
|
},
|
|
|
- getDrawPolygonValue(shape) {
|
|
|
+ getDrawPolygonValue(shape, type) {
|
|
|
// 获取到面的数据
|
|
|
// 获取 hierarchy 对象
|
|
|
const hierarchy = shape.polygon.hierarchy.getValue(Cesium.JulianDate.now());
|
|
|
@@ -412,8 +550,8 @@ export default {
|
|
|
};
|
|
|
})
|
|
|
);
|
|
|
- console.log('Outer ring:', outerLonLat);
|
|
|
- console.log('Holes:', holeArrays);
|
|
|
+ console.log('Outer ring:', JSON.stringify(outerLonLat));
|
|
|
+ console.log('Holes:', JSON.stringify(holeArrays));
|
|
|
|
|
|
// 将面的数据转换为geoJson数据
|
|
|
const coords = [outerLonLat.map(p => [p.lon, p.lat])]; // 外环
|
|
|
@@ -429,8 +567,93 @@ export default {
|
|
|
},
|
|
|
properties: { name: "电子围栏与区域" }
|
|
|
};
|
|
|
- console.log('polygonGeoJSON:', polygonGeoJSON);
|
|
|
- }
|
|
|
+ console.log('polygonGeoJSON:', JSON.stringify(polygonGeoJSON));
|
|
|
+ if (!type) {
|
|
|
+ this.polygonGeoJSON.push(JSON.stringify(polygonGeoJSON))
|
|
|
+ let obj = {
|
|
|
+ newdraw: true,
|
|
|
+ type: "polygon",
|
|
|
+ name: `电子围栏与区域-${dayjs().format('YYYYMMDDHHmmss')}`,
|
|
|
+ data: JSON.stringify(polygonGeoJSON),
|
|
|
+ entity: shape
|
|
|
+ }
|
|
|
+ this.$refs.drawPlotView.drawTableData.push(obj)
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ drawPointFn(viewer, value) {
|
|
|
+ let that = this;
|
|
|
+ // 获取 scene 和 ellipsoid
|
|
|
+ var scene = viewer.scene;
|
|
|
+ var labels = viewer.scene.primitives.add(new Cesium.LabelCollection());
|
|
|
+
|
|
|
+ // 创建 ScreenSpaceEventHandler
|
|
|
+ var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
|
|
|
+
|
|
|
+ // 监听左键点击事件
|
|
|
+ handler.setInputAction(async (click) => {
|
|
|
+ // 获取点击位置的笛卡尔坐标
|
|
|
+ var position = click.position;
|
|
|
+ if (!position) return;
|
|
|
+
|
|
|
+ // 使用 globe.pick 获取包含地形高度的坐标
|
|
|
+ var ray = viewer.camera.getPickRay(position);
|
|
|
+ var cartesian = viewer.scene.globe.pick(ray, viewer.scene);
|
|
|
+
|
|
|
+ if (cartesian) {
|
|
|
+ // 转换为地理坐标
|
|
|
+ var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
|
+ var longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
|
|
+ var latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
|
|
+ var height = cartographic.height;
|
|
|
+
|
|
|
+ const position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
|
|
|
+ const blinkingPoint = viewer.entities.add({
|
|
|
+ position: position,
|
|
|
+ billboard: {
|
|
|
+ image: this.benchmark, // 也可以是 SVG 路径,如 'icon.svg'
|
|
|
+ scale: 0.8,
|
|
|
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
|
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
|
|
+ // 模型贴地
|
|
|
+ heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ let pointObj = {
|
|
|
+ longitude, latitude
|
|
|
+ }
|
|
|
+ this.pointGeoJSON.push(pointObj)
|
|
|
+
|
|
|
+ let obj = {
|
|
|
+ newdraw: true,
|
|
|
+ type: "point",
|
|
|
+ name: `事件标记与协同-${dayjs().format('YYYYMMDDHHmmss')}`,
|
|
|
+ data: JSON.stringify(pointObj),
|
|
|
+ message: "",
|
|
|
+ entity: blinkingPoint
|
|
|
+ }
|
|
|
+ console.log("pointGeoJSON===>>>", pointObj)
|
|
|
+ this.$refs.drawPlotView.drawTableData.push(obj)
|
|
|
+ }
|
|
|
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
|
+
|
|
|
+ this.handlerAction = handler
|
|
|
+ },
|
|
|
+ editDrawConfirm(message, drawObj) {
|
|
|
+ let msg = message.replace(/(.{7})/g, '$1\n');
|
|
|
+ drawObj.entity.label = new Cesium.LabelGraphics({
|
|
|
+ text: msg,
|
|
|
+ font: '14px sans-serif',
|
|
|
+ fillColor: Cesium.Color.WHITE,
|
|
|
+ outlineColor: Cesium.Color.BLACK,
|
|
|
+ outlineWidth: 2,
|
|
|
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
|
+ pixelOffset: new Cesium.Cartesian2(70, 0), // 偏移,避免遮挡
|
|
|
+ // verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
|
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER
|
|
|
+ });
|
|
|
+ },
|
|
|
}
|
|
|
}
|
|
|
</script>
|