Browse Source

标签避让

CzRger 1 year ago
parent
commit
c466748138
3 changed files with 158 additions and 6 deletions
  1. 4 0
      src/router/index.ts
  2. 0 6
      src/views/element/index-ol.vue
  3. 154 0
      src/views/track-tag/index.vue

+ 4 - 0
src/router/index.ts

@@ -27,6 +27,10 @@ const routes = [
         path: '/ship-playback',
         component: () => import('@/views/ship-playback/has-line.vue'),
     },
+    {
+        path: '/track-tag',
+        component: () => import('@/views/track-tag/index.vue'),
+    },
 ]
 
 const router = createRouter({

+ 0 - 6
src/views/element/index-ol.vue

@@ -232,9 +232,6 @@ export default defineComponent({
         offset: [0, -30],
         positioning: 'bottom-center',
         stopEvent: true,
-        autoPanAnimation: {
-          duration: 250
-        }
       })
       state.map.addOverlay(state.mapHover.overlay)
       state.mapClick.overlay = new ol.Overlay({
@@ -245,9 +242,6 @@ export default defineComponent({
         positioning: 'bottom-center',
         stopEvent: true,
         insertFirst: false,
-        autoPanAnimation: {
-          duration: 250
-        }
       })
       state.map.addOverlay(state.mapClick.overlay)
       state.map.on('pointermove', function (evt) {

+ 154 - 0
src/views/track-tag/index.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="main">
+    <EasyMapComponent
+      class="map"
+      layout="info"
+      @easyMapLoad="mapLoad"
+    />
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import {ElMessage, ElMessageBox} from "element-plus";
+import * as layer from "ol/layer";
+import * as format from "ol/format";
+import * as source from "ol/source";
+import * as ol from "ol"
+import * as geom from "ol/geom";
+import * as turf from '@turf/turf'
+import * as style from "ol/style";
+
+export default defineComponent({
+  name: '',
+  components: {
+  },
+  props: {},
+  setup(props, {emit}) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      map: <any>null,
+      mapFunc: <any>null,
+    })
+    const mapLoad = (map, func) => {
+      state.map = map
+      state.mapFunc = func
+      initMap()
+    }
+    const initMap = () => {
+      const feats = new format.GeoJSON().readFeatures(turf.randomPoint(1000, {bbox: state.mapFunc.getBBOX()}))
+      const l = new layer.Vector({
+        zIndex: 2,
+        source: new source.Vector({
+          features: feats
+        }),
+        style: new style.Style({
+          image: new style.Circle({
+            radius: 10,
+            fill: new style.Fill({
+              color: 'red',
+            }),
+          })
+        }),
+        // declutter: true
+      })
+      state.map.addLayer(l)
+      const tagL = new layer.Vector({
+        zIndex: 3,
+        source: new source.Vector({
+          features: feats
+        }),
+        style: capturePointStyle('这是标签'),
+        declutter: true
+      })
+      state.map.addLayer(tagL)
+    }
+    const capturePointStyle = (name = null) => {
+      const _style = []
+      const displacementY = 10
+      if (name) {
+        const canvas = document.createElement("canvas");
+        const context = canvas.getContext("2d");
+        const length = String(name).length;
+        canvas.width = length * 20;
+        canvas.height = 40;
+        const x = 0   //  起点x
+        const y = 0   //  起点y
+        let r = 4   //  圆角
+        const arrowW = 10   //  提示框箭头宽度
+        const arrowY = 6   //  提示框箭头高度
+        const w = canvas.width
+        const h = canvas.height - arrowY
+        if (w < 2 * r) r = w / 2;
+        if (h < 2 * r) r = h / 2;
+        context.beginPath();
+        context.moveTo(x + r, y);
+        context.arcTo(x + w, y, x + w, y + h, r);
+        context.arcTo(x + w, y + h, x, y + h, r);
+        context.lineTo(x + w, y + h);
+        context.lineTo(x + w / 2 + arrowW / 2, y + h);
+        context.lineTo(x + w / 2, y + h + arrowY);
+        context.lineTo(x + w / 2 - arrowW / 2, y + h );
+        context.arcTo(x, y + h, x, y, r);
+        context.arcTo(x, y, x + w, y, r);
+        context.closePath();
+        context.fillStyle = "rgba(0,0,0,0.7)";
+        context.fill();
+        _style.push(new style.Style({
+          image: new style.Icon({
+            img: canvas,
+            imgSize: [w, canvas.height],
+            displacement: [0, displacementY + 34]
+          }),
+          text: new style.Text({
+            // 位置
+            textAlign: "center",
+            // 基准线
+            // 文字样式
+            font: "12px 微软雅黑",
+            // 文本内容
+            text: `${name}`,
+            // 文字颜色
+            fill: new style.Fill({ color: "#FFFFFF" }),
+            offsetY: -(displacementY + 36),
+            offsetX: 0
+          }),
+        }))
+      }
+      return _style
+    }
+    onMounted(() => {
+    })
+    return {
+      ...toRefs(state),
+      mapLoad,
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.main {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  position: relative;
+  justify-content: center;
+}
+</style>