|
@@ -49,8 +49,8 @@
|
|
|
<div class="down-btn" />
|
|
|
<div class="down-left-btn" />
|
|
|
<div class="down-right-btn" />
|
|
|
- <div class="left-btn" />
|
|
|
- <div class="right-btn" />
|
|
|
+ <div class="left-btn" @click="handleControl('left')" />
|
|
|
+ <div class="right-btn" @click="handleControl('right')" />
|
|
|
<div :class="!!isRefresh ? 'refresh-btn rotate-box' : 'refresh-btn'" @click="handleRefresh" />
|
|
|
</div>
|
|
|
</div>
|
|
@@ -73,9 +73,28 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
+import * as turf from '@turf/turf';
|
|
|
+import Feature from 'ol/Feature';
|
|
|
+import Point from 'ol/geom/Point';
|
|
|
+import Style from 'ol/style/Style';
|
|
|
+import Fill from 'ol/style/Fill';
|
|
|
+import Stroke from 'ol/style/Stroke';
|
|
|
+import Icon from 'ol/style/Icon';
|
|
|
+import Circle from 'ol/geom/Circle';
|
|
|
+import { fromLonLat } from 'ol/proj';
|
|
|
+import videoImg from '@/assets/images/dotIcon/33_forest_defense_video.png';
|
|
|
+import VectorLayer from 'ol/layer/Vector';
|
|
|
+import VectorSource from 'ol/source/Vector';
|
|
|
+import Polygon from 'ol/geom/Polygon';
|
|
|
+
|
|
|
const props = defineProps({
|
|
|
- id: String
|
|
|
+ id: String,
|
|
|
+ activeMap: String
|
|
|
});
|
|
|
+const mapUtils = inject('getMapUtils');
|
|
|
+let map, AMap, marker, circle, sector, vectorLayer;
|
|
|
+const AMapType = ['vectorgraph', 'satellite'];
|
|
|
+const YMapType = ['satellite2', 'satellite3', 'imageMap', 'imageMap2'];
|
|
|
const tabs = ref([
|
|
|
{ label: '', icon: 'icon1' },
|
|
|
{ label: '', icon: 'icon2' },
|
|
@@ -90,13 +109,83 @@ let visibleRange = ref(false);
|
|
|
let detailData = ref({
|
|
|
title: '',
|
|
|
address: '',
|
|
|
- lng: '',
|
|
|
- lat: '',
|
|
|
+ lng: 0,
|
|
|
+ lat: 0,
|
|
|
type: '',
|
|
|
speed: 0,
|
|
|
- video_code: ''
|
|
|
+ video_code: '',
|
|
|
+ radius: 0,
|
|
|
+ startAngle: 0,
|
|
|
+ endAngle: 0
|
|
|
});
|
|
|
|
|
|
+const getData = () => {
|
|
|
+ detailData.value = {
|
|
|
+ title: '高州市根子镇上炕村委会23211312',
|
|
|
+ address: '茂名市高州市坡心东南约400米',
|
|
|
+ lng: 110.819207,
|
|
|
+ lat: 21.711887,
|
|
|
+ type: '云台',
|
|
|
+ speed: 246,
|
|
|
+ video_code: '44092251001320000009',
|
|
|
+ radius: 10000,
|
|
|
+ startAngle: 0,
|
|
|
+ endAngle: 30
|
|
|
+ };
|
|
|
+ initDot();
|
|
|
+};
|
|
|
+// 加载地图标点
|
|
|
+const initDot = () => {
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ // 切换到高德
|
|
|
+ removeMarker();
|
|
|
+ removeVisibleRange();
|
|
|
+ map = mapUtils().getMap();
|
|
|
+ AMap = mapUtils().getAMap();
|
|
|
+ const icon = new AMap.Icon({
|
|
|
+ size: new AMap.Size(37, 40),
|
|
|
+ image: videoImg
|
|
|
+ });
|
|
|
+ // 创建点覆盖物
|
|
|
+ marker = new AMap.Marker({
|
|
|
+ position: new AMap.LngLat(detailData.value.lng, detailData.value.lat),
|
|
|
+ icon: icon,
|
|
|
+ offset: new AMap.Pixel(-18, -20)
|
|
|
+ });
|
|
|
+ map.add(marker);
|
|
|
+ if (visibleRange.value) {
|
|
|
+ addVisibleRange();
|
|
|
+ }
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ // 切换到粤政图
|
|
|
+ map = mapUtils().getMap();
|
|
|
+ vectorLayer = new VectorLayer({
|
|
|
+ source: new VectorSource({
|
|
|
+ features: []
|
|
|
+ })
|
|
|
+ });
|
|
|
+ map.addLayer(vectorLayer);
|
|
|
+ // 创建标注点
|
|
|
+ marker = new Feature({
|
|
|
+ geometry: new Point([detailData.value.lng, detailData.value.lat])
|
|
|
+ });
|
|
|
+ // 定义样式
|
|
|
+ const style = new Style({
|
|
|
+ image: new Icon({
|
|
|
+ // anchor: [0.5, 0.942],
|
|
|
+ anchor: [0.5, 0.5],
|
|
|
+ anchorXUnits: 'fraction',
|
|
|
+ anchorYUnits: 'pixels',
|
|
|
+ scale: 0.146,
|
|
|
+ src: videoImg
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ marker.setStyle(style);
|
|
|
+ vectorLayer.getSource().addFeature(marker);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 调整转速
|
|
|
const handleSpeed = (type) => {
|
|
|
if (type === 'add') {
|
|
@@ -109,12 +198,56 @@ const handleSpeed = (type) => {
|
|
|
// 焦距控制
|
|
|
const handleFocusControl = (type) => {
|
|
|
if (type === 'add') {
|
|
|
-
|
|
|
} else {
|
|
|
-
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 控制视角移动
|
|
|
+const handleControl = (type) => {
|
|
|
+ if (type === 'left') {
|
|
|
+ detailData.value.startAngle -= 1;
|
|
|
+ detailData.value.endAngle -= 1;
|
|
|
+ } else if (type === 'right') {
|
|
|
+ detailData.value.startAngle += 1;
|
|
|
+ detailData.value.endAngle += 1;
|
|
|
+ }
|
|
|
+ if (visibleRange.value) {
|
|
|
+ createSector();
|
|
|
+ }
|
|
|
+};
|
|
|
+// 新增扇形
|
|
|
+const createSector = () => {
|
|
|
+ removeSector();
|
|
|
+ const center = turf.point([detailData.value.lng, detailData.value.lat]);
|
|
|
+ const sectorData = turf.sector(center, detailData.value.radius / 1000, detailData.value.startAngle, detailData.value.endAngle);
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ sector = new AMap.Polyline({
|
|
|
+ path: sectorData.geometry.coordinates,
|
|
|
+ strokeColor: '#ffffff',
|
|
|
+ strokeOpacity: 1,
|
|
|
+ strokeWeight: 1,
|
|
|
+ fillColor: '#ffffff', // 填充色
|
|
|
+ fillOpacity: 0.2 // 填充透明度
|
|
|
+ });
|
|
|
+ map.add(sector);
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ sector = new Feature({
|
|
|
+ geometry: new Polygon(sectorData.geometry.coordinates)
|
|
|
+ });
|
|
|
+ sector.setStyle(
|
|
|
+ new Style({
|
|
|
+ fill: new Fill({
|
|
|
+ color: 'rgba(255, 255, 255, 0)'
|
|
|
+ }),
|
|
|
+ stroke: new Stroke({
|
|
|
+ color: 'rgba(255, 255, 255, 1)',
|
|
|
+ width: 1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ );
|
|
|
+ vectorLayer.getSource().addFeature(sector);
|
|
|
+ }
|
|
|
+};
|
|
|
let isRefresh = ref(false);
|
|
|
// 刷新
|
|
|
const handleRefresh = () => {
|
|
@@ -124,20 +257,122 @@ const handleRefresh = () => {
|
|
|
isRefresh.value = false;
|
|
|
}, 3000);
|
|
|
};
|
|
|
-// 加载地图标点
|
|
|
-const initDot = () => {
|
|
|
|
|
|
-}
|
|
|
-onMounted(() => {
|
|
|
- detailData.value = {
|
|
|
- title: '高州市根子镇上炕村委会23211312',
|
|
|
- address: '茂名市高州市坡心东南约400米',
|
|
|
- lng: '110.819207',
|
|
|
- lat: '21.711887',
|
|
|
- type: '云台',
|
|
|
- speed: 246,
|
|
|
- video_code: '44092251001320000009'
|
|
|
- };
|
|
|
+watch(visibleRange, () => {
|
|
|
+ if (visibleRange.value) {
|
|
|
+ addVisibleRange();
|
|
|
+ } else {
|
|
|
+ removeVisibleRange();
|
|
|
+ }
|
|
|
+});
|
|
|
+// 移除标点
|
|
|
+const removeMarker = () => {
|
|
|
+ if (!marker) return;
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ map.remove(marker);
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ const source = vectorLayer.getSource();
|
|
|
+ source.removeFeature(marker);
|
|
|
+ }
|
|
|
+ marker = null;
|
|
|
+};
|
|
|
+// 添加可视域
|
|
|
+const addVisibleRange = () => {
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ // 圆形范围
|
|
|
+ circle = new AMap.Circle({
|
|
|
+ center: new AMap.LngLat(detailData.value.lng, detailData.value.lat),
|
|
|
+ radius: detailData.value.radius,
|
|
|
+ strokeColor: '#ff0000', // 线颜色
|
|
|
+ strokeOpacity: 0.35, // 线透明度
|
|
|
+ strokeWeight: 1, // 线宽
|
|
|
+ fillColor: '#ff0000', // 填充色
|
|
|
+ fillOpacity: 0.2 // 填充透明度
|
|
|
+ });
|
|
|
+ map.add(circle);
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ const center = turf.point([detailData.value.lng, detailData.value.lat]);
|
|
|
+ const sectorData = turf.sector(center, detailData.value.radius / 1000, 0, 360);
|
|
|
+
|
|
|
+ circle = new Feature({
|
|
|
+ geometry: new Polygon(sectorData.geometry.coordinates)
|
|
|
+ });
|
|
|
+ circle.setStyle(
|
|
|
+ new Style({
|
|
|
+ fill: new Fill({
|
|
|
+ color: 'rgba(255, 0, 0, 0.2)'
|
|
|
+ }),
|
|
|
+ stroke: new Stroke({
|
|
|
+ color: 'rgba(255, 0, 0, 0.35)',
|
|
|
+ width: 1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ );
|
|
|
+
|
|
|
+ // const center = [detailData.value.lng, detailData.value.lat];
|
|
|
+ // circle = new Feature({
|
|
|
+ // geometry: new Circle(center, 100)
|
|
|
+ // // geometry: new Circle(center, detailData.value.radius)
|
|
|
+ // });
|
|
|
+ // circle.setStyle(
|
|
|
+ // new Style({
|
|
|
+ // fill: new Fill({
|
|
|
+ // color: 'rgba(255, 0, 0, 0.2)'
|
|
|
+ // }),
|
|
|
+ // stroke: new Stroke({
|
|
|
+ // color: 'rgba(255, 0, 0, 0.35)',
|
|
|
+ // width: 1
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+ // );
|
|
|
+ vectorLayer.getSource().addFeature(circle);
|
|
|
+ }
|
|
|
+ createSector();
|
|
|
+};
|
|
|
+// 移除可视域
|
|
|
+const removeVisibleRange = () => {
|
|
|
+ if (circle) {
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ map.remove(circle);
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ const source = vectorLayer.getSource();
|
|
|
+ source.removeFeature(circle);
|
|
|
+ }
|
|
|
+ circle = null;
|
|
|
+ }
|
|
|
+ removeSector();
|
|
|
+};
|
|
|
+// 移除扇形
|
|
|
+const removeSector = () => {
|
|
|
+ if (sector) {
|
|
|
+ if (AMapType.includes(props.activeMap)) {
|
|
|
+ map.remove(sector);
|
|
|
+ sector = null;
|
|
|
+ } else if (YMapType.includes(props.activeMap)) {
|
|
|
+ const source = vectorLayer.getSource();
|
|
|
+ source.removeFeature(sector);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+watch(
|
|
|
+ () => props.id,
|
|
|
+ () => {
|
|
|
+ getData();
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => props.activeMap,
|
|
|
+ (newMap, oldMap) => {
|
|
|
+ if ((AMapType.includes(newMap) && AMapType.includes(oldMap)) || (YMapType.includes(newMap) && YMapType.includes(oldMap))) return;
|
|
|
+ initDot();
|
|
|
+ }
|
|
|
+);
|
|
|
+onUnmounted(() => {
|
|
|
+ removeMarker();
|
|
|
+ removeVisibleRange();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
@@ -279,7 +514,7 @@ onMounted(() => {
|
|
|
.gradient-text2 {
|
|
|
font-size: 44px;
|
|
|
font-weight: normal;
|
|
|
- font-font: "PingFang SC", sans-serif;
|
|
|
+ font-font: 'PingFang SC', sans-serif;
|
|
|
}
|
|
|
.gradient-text3 {
|
|
|
font-weight: bold;
|
|
@@ -427,7 +662,7 @@ onMounted(() => {
|
|
|
}
|
|
|
}
|
|
|
.operate-box {
|
|
|
- margin-top:70px;
|
|
|
+ margin-top: 70px;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|