|
@@ -1,10 +1,22 @@
|
|
|
<template>
|
|
|
<div class="video-resource">
|
|
|
+ <div class="buttons">
|
|
|
+ <el-button @click="addFeatures">随机新增</el-button>
|
|
|
+ <el-input v-model="sss"></el-input>
|
|
|
+ <el-button @click="delFeatures">删除一个</el-button>
|
|
|
+ <el-button @click="clearFeatures">清空</el-button>
|
|
|
+ </div>
|
|
|
<EasyMapComponent
|
|
|
class="map"
|
|
|
:showBaseSwitch="false"
|
|
|
@easyMapLoad="mapLoad"
|
|
|
/>
|
|
|
+ <div ref="ref_pointHoverOverlay" class="hover-info">
|
|
|
+ {{ pointHoverInfo.id }}
|
|
|
+ </div>
|
|
|
+ <div ref="ref_pointClickOverlay" class="click-info">
|
|
|
+ {{ pointClickInfo.id }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -25,6 +37,11 @@ import {useStore} from 'vuex'
|
|
|
import axios from "axios";
|
|
|
import {ElMessage, ElMessageBox} from "element-plus";
|
|
|
import MapStyle from "@/views/screen/video-resource/map-style";
|
|
|
+import * as source from "ol/source";
|
|
|
+import * as layer from "ol/layer";
|
|
|
+import * as format from "ol/format";
|
|
|
+import {randomNum} from "@/utils/util";
|
|
|
+import * as ol from "ol";
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: 'App',
|
|
@@ -35,39 +52,129 @@ export default defineComponent({
|
|
|
const state = reactive({
|
|
|
map: <any>null,
|
|
|
mapFunc: null,
|
|
|
- videoLayer: null
|
|
|
+ pointLayer: <any>null,
|
|
|
+ pointSource: <any>null,
|
|
|
+ pointHoverOverlay: <any>null,
|
|
|
+ pointClickOverlay: <any>null,
|
|
|
+ pointHoverInfo: <any>{},
|
|
|
+ pointClickInfo: <any>{},
|
|
|
+ sss: ''
|
|
|
});
|
|
|
+ const ref_pointHoverOverlay = ref()
|
|
|
+ const ref_pointClickOverlay = ref()
|
|
|
const mapLoad = (map: null, func: null) => {
|
|
|
state.map = map
|
|
|
state.mapFunc = func
|
|
|
- that.$easyMap.initShape({
|
|
|
- map: state.map,
|
|
|
- layerName: "track-point-line",
|
|
|
- layerZIndex: 7,
|
|
|
- list: [
|
|
|
- {
|
|
|
- easyMapParams: {
|
|
|
- id: `1`,
|
|
|
- position: 'POINT(109.19 19.45)',
|
|
|
- normalStyle: MapStyle.videoPointStyle()
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- easyMapParams: {
|
|
|
- id: `2`,
|
|
|
- position: 'POLYGON((108.26 19.07, 110.19 18.45, 111.19 20.45,109.19 19.45))',
|
|
|
- normalStyle: MapStyle.normalStyleArea()
|
|
|
- }
|
|
|
- },
|
|
|
- ]
|
|
|
- });
|
|
|
- const addFeatures = (arr: any) => {}
|
|
|
- const delFeatures = (arr: any) => {}
|
|
|
+ // 初始化source
|
|
|
+ state.pointSource = new source.Vector({
|
|
|
+ features: [],
|
|
|
+ wrapX: false
|
|
|
+ })
|
|
|
+ // 初始化layer
|
|
|
+ state.pointLayer = new layer.VectorImage({
|
|
|
+ source: state.pointSource,
|
|
|
+ zIndex: 10,
|
|
|
+ style: (feat: any) => {
|
|
|
+ feat.setStyle(MapStyle.videoPointStyle())
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.map.addLayer(state.pointLayer)
|
|
|
+ // 初始化悬浮
|
|
|
+ state.pointHoverOverlay = new ol.Overlay({
|
|
|
+ id: 'pointHoverOverlay',
|
|
|
+ element: ref_pointHoverOverlay.value,
|
|
|
+ autoPan: false,
|
|
|
+ offset: [0, -40],
|
|
|
+ positioning: 'top-center',
|
|
|
+ stopEvent: true,
|
|
|
+ autoPanAnimation: {
|
|
|
+ duration: 250
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.map.addOverlay(state.pointHoverOverlay)
|
|
|
+ state.map.on('pointermove', (e: {
|
|
|
+ coordinate(coordinate: any): unknown; pixel: any;
|
|
|
+ }) => {
|
|
|
+ state.pointHoverOverlay.setPosition(undefined)
|
|
|
+ state.pointHoverInfo = {}
|
|
|
+ state.map.forEachFeatureAtPixel(e.pixel, (f: any) => {
|
|
|
+ if (f.get('layerType') === 'video') {
|
|
|
+ state.pointHoverInfo = f.get('val')
|
|
|
+ state.pointHoverOverlay.setPosition(e.coordinate)
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ })
|
|
|
+ // 初始化点击
|
|
|
+ state.pointClickOverlay = new ol.Overlay({
|
|
|
+ id: 'pointClickOverlay',
|
|
|
+ element: ref_pointClickOverlay.value,
|
|
|
+ autoPan: false,
|
|
|
+ offset: [0, 0],
|
|
|
+ positioning: 'top-left',
|
|
|
+ stopEvent: true,
|
|
|
+ autoPanAnimation: {
|
|
|
+ duration: 250
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.map.addOverlay(state.pointClickOverlay)
|
|
|
+ state.map.on('singleclick', (e: {
|
|
|
+ coordinate(coordinate: any): unknown; pixel: any;
|
|
|
+ }) => {
|
|
|
+ state.pointClickOverlay.setPosition(undefined)
|
|
|
+ state.pointHoverInfo = {}
|
|
|
+ state.map.forEachFeatureAtPixel(e.pixel, (f: any) => {
|
|
|
+ if (f.get('layerType') === 'video') {
|
|
|
+ state.pointClickInfo = f.get('val')
|
|
|
+ state.pointClickOverlay.setPosition(e.coordinate)
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const mockWKT = () => {
|
|
|
+ const lon = that.$util.randomNum(108, 111, 6)
|
|
|
+ const lat = that.$util.randomNum(18, 20, 6)
|
|
|
+ return `POINT(${lon} ${lat})`
|
|
|
+ }
|
|
|
+ const addFeatures = (arr: any) => {
|
|
|
+ arr = []
|
|
|
+ for (let i = 0; i < 8; i++) {
|
|
|
+ arr.push({
|
|
|
+ wkt: mockWKT(),
|
|
|
+ id: `点位_${new Date().getTime()}_${i}`,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ arr.forEach((v: any, i: number) => {
|
|
|
+ const feat = new format.WKT().readFeature(v.wkt)
|
|
|
+ feat.setId(v.id)
|
|
|
+ feat.set('val', v)
|
|
|
+ feat.set('layerType', 'video')
|
|
|
+ state.pointSource.addFeature(feat)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const delFeatures = (arr: any) => {
|
|
|
+ state.sss.split(',').forEach(v => {
|
|
|
+ console.log(state.pointSource.getFeatureById(v))
|
|
|
+ if (state.pointClickInfo.id === v) {
|
|
|
+ state.pointClickOverlay.setPosition(undefined)
|
|
|
+ }
|
|
|
+ state.pointSource.removeFeature(state.pointSource.getFeatureById(v))
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const clearFeatures = () => {
|
|
|
+ state.pointSource.clear()
|
|
|
}
|
|
|
-
|
|
|
return {
|
|
|
...toRefs(state),
|
|
|
mapLoad,
|
|
|
+ addFeatures,
|
|
|
+ delFeatures,
|
|
|
+ clearFeatures,
|
|
|
+ ref_pointHoverOverlay,
|
|
|
+ ref_pointClickOverlay,
|
|
|
}
|
|
|
}
|
|
|
})
|
|
@@ -82,5 +189,10 @@ export default defineComponent({
|
|
|
width: 100%;
|
|
|
height: 100vh;
|
|
|
}
|
|
|
+ .click-info {
|
|
|
+ width: 300px;
|
|
|
+ height: 100px;
|
|
|
+ background-color: red;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|