CzRger 1 年間 前
コミット
e6fa768585

+ 135 - 8
src/components/easyMap/func/base-draw.ts

@@ -71,7 +71,7 @@ export const getBaseDrawConfig = () => {
  * @param arr > polyBorderType:styles为空的时候,Polygon的边框类型索引,默认0,实线,取globalLineDash数组索引
  * @param arr > polyBorderDash:styles为空的时候,Polygon的边框类型,默认null,优先级比polyBorderType高
  */
-export const drawViews = (map, arr) => {
+export const drawViews = (map, arr, isAuto = true) => {
     let _source
     const realLayer = map.getLayers().getArray().filter(v => v.get(layerFlag[0]) === layerFlag[1])
     if (realLayer[0]) {
@@ -86,6 +86,7 @@ export const drawViews = (map, arr) => {
         map.addLayer(_vector);
     }
     _source.clear() //  清空标绘
+    const autoPosition: any = []
     const features = arr.filter(v => {
          try {
              new format.WKT().readFeature(v.wkt)
@@ -97,6 +98,20 @@ export const drawViews = (map, arr) => {
     }).map(v => {
         const feat: any = new format.WKT().readFeature(v.wkt)
         const type = feat.getGeometry().getType()
+        switch (type) {
+            case 'Point': autoPosition.push(feat.getGeometry().getCoordinates())
+                break
+            case 'LineString': autoPosition.push(...feat.getGeometry().getCoordinates())
+                break
+            case 'Polygon': autoPosition.push(...feat.getGeometry().getCoordinates()[0])
+                break
+        }
+        for (const [kVal, vVal] of Object.entries(v)) {
+            // @ts-ignore
+            if (vVal === null || vVal === undefined || (typeof vVal === 'string' && vVal.trim() === '') || (typeof vVal === 'object' && vVal?.length === 0)) {
+                delete v[kVal]
+            }
+        }
         const {
             textOffsetY = (type === 'Point' ? -30 : 0),
             pointIcon, pointScale, pointOffset,
@@ -170,11 +185,14 @@ export const drawViews = (map, arr) => {
         return feat
     })
     _source.addFeatures(features)
+    if (isAuto) {
+        getShapeView(map, autoPosition)
+    }
 }
 
 let baseDrawTooltipElement;
 let baseDrawHelpTooltipElement;
-export const drawEdits = (map, obj, emitWkt) => {
+export const drawEdits = (map, obj, emitWkt, isAuto = true) => {
     return new Promise((resolve => {
         if (!isValue(obj.textOffsetY)) {
             obj.textOffsetY = (obj.featureType === 'Point' ? -30 : 0)
@@ -285,9 +303,6 @@ export const drawEdits = (map, obj, emitWkt) => {
         }
         if (!baseDrawTooltipElement) {
             reset()
-            if (obj.wkt) {
-                drawViews(map, [obj])
-            }
             let _source
             const realLayer = map.getLayers().getArray().filter(v => v.get(layerFlag[0]) === layerFlag[1])
             if (realLayer[0]) {
@@ -302,6 +317,23 @@ export const drawEdits = (map, obj, emitWkt) => {
                 _vector.set(layerFlag[0], layerFlag[1])
                 map.addLayer(_vector);
             }
+            if (obj.wkt) {
+                const feat: any = new format.WKT().readFeature(obj.wkt)
+                _source.addFeature(feat)
+                const autoPosition: any = []
+                const type = feat.getGeometry().getType()
+                switch (type) {
+                    case 'Point': autoPosition.push(feat.getGeometry().getCoordinates())
+                        break
+                    case 'LineString': autoPosition.push(...feat.getGeometry().getCoordinates())
+                        break
+                    case 'Polygon': autoPosition.push(...feat.getGeometry().getCoordinates()[0])
+                        break
+                }
+                if (isAuto) {
+                    getShapeView(map, autoPosition)
+                }
+            }
             const modifyInteraction = new Modify({
                 source: _source,
             });
@@ -401,7 +433,49 @@ export const drawEdits = (map, obj, emitWkt) => {
                 };
                 const addInteraction = () => {
                     const id = 'baseDrawName'
+                    let drawLastPoint = ''
+                    let drawLastPointTimer: any = null
+                    let drawCircleDBClickTimer: any = null
                     const draw = new interaction.Draw({
+                        stopClick: true,
+                        condition: (e) => {
+                            // 圆形单击即触发finishCondition,跳过
+                            if (obj.featureType === 'Circle') {
+                                return true
+                            }
+                            const str = e.coordinate.join(',')
+                            let flag = true
+                            // 进行延时判断,避免只要鼠标不移动,单击后间隔很久也会视为双击,
+                            if (!drawLastPointTimer && str === drawLastPoint) {
+                                flag = false
+                            } else {
+                                if (drawLastPointTimer) {
+                                    clearTimeout(drawLastPointTimer)
+                                }
+                                drawLastPoint = str
+                            }
+                            drawLastPointTimer = setTimeout(() => {
+                                drawLastPointTimer = null
+                            }, 1000)
+                            return flag
+                        },
+                        finishCondition: (e) => {
+                            if (obj.featureType !== 'Circle') {
+                                return true
+                            }
+                            let flag = true
+                            //  圆形进行双击延时监听判断
+                            if (!drawCircleDBClickTimer) {
+                                flag = false
+                            }
+                            if (drawCircleDBClickTimer) {
+                                clearTimeout(drawCircleDBClickTimer)
+                            }
+                            drawCircleDBClickTimer = setTimeout(() => {
+                                drawCircleDBClickTimer = null
+                            }, 1000)
+                            return flag
+                        },
                         source: _source,//测量绘制层数据源
                         type: obj.featureType,  //几何图形类型
                         // geometryFunction: typeSelect === 'rectangle' ? createBox() : null,
@@ -481,9 +555,11 @@ export const drawEdits = (map, obj, emitWkt) => {
                         //     helpMsg = continueMsg; //绘制线时提示相应内容
                         // }
                     }
-                    baseDrawHelpTooltipElement.innerHTML = helpMsg; //将提示信息设置到对话框中显示
-                    helpTooltip.setPosition(evt.coordinate);//设置帮助提示框的位置
-                    baseDrawHelpTooltipElement.classList.remove('hidden');//移除帮助提示框的隐藏样式进行显示
+                    if (baseDrawHelpTooltipElement) {
+                        baseDrawHelpTooltipElement.innerHTML = helpMsg; //将提示信息设置到对话框中显示
+                        helpTooltip.setPosition(evt.coordinate);//设置帮助提示框的位置
+                        baseDrawHelpTooltipElement.classList.remove('hidden');//移除帮助提示框的隐藏样式进行显示
+                    }
                 };
                 map.on('pointermove', pointerMoveHandler); //地图容器绑定鼠标移动事件,动态显示帮助提示框内容
                 //地图绑定鼠标移出事件,鼠标移出时为帮助提示框设置隐藏样式
@@ -506,4 +582,55 @@ export const drawEdits = (map, obj, emitWkt) => {
             // }
         })
     }))
+}
+export const drawExit = (map) => {
+    if (baseDrawTooltipElement) {
+        baseDrawTooltipElement.parentNode?.removeChild?.(baseDrawTooltipElement);
+        baseDrawTooltipElement = null
+    }
+    if (baseDrawHelpTooltipElement) {
+        baseDrawHelpTooltipElement.parentNode?.removeChild?.(baseDrawHelpTooltipElement);
+        baseDrawHelpTooltipElement = null
+    }
+    const oldLayer = map.getLayers().getArray().filter(v => v.get(layerFlag[0]) === layerFlag[1])
+    if (oldLayer) {
+        map.removeLayer(oldLayer[0])
+    }
+    const oldDraw = map.getInteractions().getArray().filter(v => v.get(drawFlag[0]) === drawFlag[1])
+    if (oldDraw) {
+        map.removeInteraction(oldDraw[0])
+    }
+    const oldModify = map.getInteractions().getArray().filter(v => v.get(modifyFlag[0]) === modifyFlag[1])
+    if (oldModify) {
+        map.removeInteraction(oldModify[0])
+    }
+}
+
+const getShapeView = (map, position, L = 600) => {
+    const center = extent.getCenter(extent.boundingExtent(position))
+    let x = 0
+    let y = 0
+    position.forEach(v => {
+        if (Math.abs(v[0] - center[0]) > x) {
+            x = Math.abs(v[0] - center[0])
+        }
+        if (Math.abs(v[1] - center[1]) > y) {
+            y = Math.abs(v[1] - center[1])
+        }
+    })
+    const resolution = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) / (L / document.body.clientWidth * document.body.clientHeight)
+    if (map) {
+        if (position.length > 1) {
+            map.getView().animate({
+                center, resolution
+            })
+        } else {
+            map.getView().animate({
+                center, zoom: 12
+            })
+        }
+    }
+    return {
+        center, resolution
+    }
 }

+ 42 - 0
src/components/easyMap/func/draw.ts

@@ -147,7 +147,49 @@ export default function Draw (map, typeSelect) {
             };
             const addInteraction = () => {
                 const id = 'drawName'
+                let drawLastPoint = ''
+                let drawLastPointTimer: any = null
+                let drawCircleDBClickTimer: any = null
                 const draw = new interaction.Draw({
+                    stopClick: true,
+                    condition: (e) => {
+                        // 圆形单击即触发finishCondition,跳过
+                        if (typeSelect === 'circle') {
+                            return true
+                        }
+                        const str = e.coordinate.join(',')
+                        let flag = true
+                        // 进行延时判断,避免只要鼠标不移动,单击后间隔很久也会视为双击,
+                        if (!drawLastPointTimer && str === drawLastPoint) {
+                            flag = false
+                        } else {
+                            if (drawLastPointTimer) {
+                                clearTimeout(drawLastPointTimer)
+                            }
+                            drawLastPoint = str
+                        }
+                        drawLastPointTimer = setTimeout(() => {
+                            drawLastPointTimer = null
+                        }, 1000)
+                        return flag
+                    },
+                    finishCondition: (e) => {
+                        if (typeSelect !== 'circle') {
+                            return true
+                        }
+                        let flag = true
+                        //  圆形进行双击延时监听判断
+                        if (!drawCircleDBClickTimer) {
+                            flag = false
+                        }
+                        if (drawCircleDBClickTimer) {
+                            clearTimeout(drawCircleDBClickTimer)
+                        }
+                        drawCircleDBClickTimer = setTimeout(() => {
+                            drawCircleDBClickTimer = null
+                        }, 1000)
+                        return flag
+                    },
                     source: _source,//测量绘制层数据源
                     // @ts-ignore
                     type: typeMapper.get(typeSelect),  //几何图形类型

+ 9 - 0
src/components/easyMap/func/location.ts

@@ -7,6 +7,7 @@ import * as proj from 'ol/proj'
 import * as interaction from 'ol/interaction'
 import * as coordinate from 'ol/coordinate'
 import * as format from "ol/format";
+import {fromExtent} from 'ol/geom/Polygon';
 // @ts-ignore
 import LocationImg from '../images/location.png'
 import {ElMessage} from "element-plus";
@@ -16,6 +17,14 @@ export let locationTooltipElement
 export default function Location ({map, position = null, wkt = null, zoom = null, color = '#039ff3'}) {
     try {
         const feat: any = new format.WKT().readFeature(position ? `POINT(${position[0]} ${position[1]})` : wkt)
+        const mapViewExtent = map.getView().get('extent')
+        if (mapViewExtent) {
+            const poly = fromExtent(mapViewExtent)
+            if (!poly.intersectsCoordinate(feat.getGeometry().getCoordinates())) {
+                ElMessage.warning('超出范围,无法定位该位置!')
+                return
+            }
+        }
         let _source
         const realLayer = map.getLayers().getArray().filter(v => v.get(layerFlag[0]) === layerFlag[1])
         if (realLayer[0]) {

+ 1 - 1
src/components/easyMap/func/measure.scss

@@ -40,6 +40,6 @@
   vertical-align: middle;
   margin-left: 10px;
   cursor: pointer;
-  //background: url('@/assets/images/map/lineDel.png') no-repeat;
+  background: url('@/assets/images/map/lineDel.png') no-repeat;
   background-size: 100% 100%;
 }

+ 42 - 0
src/components/easyMap/func/measure.ts

@@ -142,7 +142,49 @@ export default function Measure (map, typeSelect) {
         };
         const addInteraction = () => {
             const id = 'measureName'
+            let drawLastPoint = ''
+            let drawLastPointTimer: any = null
+            let drawCircleDBClickTimer: any = null
             const draw = new interaction.Draw({
+                stopClick: true,
+                condition: (e) => {
+                    // 圆形单击即触发finishCondition,跳过
+                    if (typeSelect === 'circle') {
+                        return true
+                    }
+                    const str = e.coordinate.join(',')
+                    let flag = true
+                    // 进行延时判断,避免只要鼠标不移动,单击后间隔很久也会视为双击,
+                    if (!drawLastPointTimer && str === drawLastPoint) {
+                        flag = false
+                    } else {
+                        if (drawLastPointTimer) {
+                            clearTimeout(drawLastPointTimer)
+                        }
+                        drawLastPoint = str
+                    }
+                    drawLastPointTimer = setTimeout(() => {
+                        drawLastPointTimer = null
+                    }, 1000)
+                    return flag
+                },
+                finishCondition: (e) => {
+                    if (typeSelect !== 'circle') {
+                        return true
+                    }
+                    let flag = true
+                    //  圆形进行双击延时监听判断
+                    if (!drawCircleDBClickTimer) {
+                        flag = false
+                    }
+                    if (drawCircleDBClickTimer) {
+                        clearTimeout(drawCircleDBClickTimer)
+                    }
+                    drawCircleDBClickTimer = setTimeout(() => {
+                        drawCircleDBClickTimer = null
+                    }, 1000)
+                    return flag
+                },
                 source: _source,//测量绘制层数据源
                 // @ts-ignore
                 type: typeMapper.get(typeSelect),  //几何图形类型

BIN
src/components/easyMap/images/bg-ht.png


BIN
src/components/easyMap/images/bg-hys.png


BIN
src/components/easyMap/images/bg-lt.png


BIN
src/components/easyMap/images/bg-wxt.png


BIN
src/components/easyMap/images/fullscreen-btn-bg.png


BIN
src/components/easyMap/images/fullscreen-icon.png


BIN
src/components/easyMap/images/position-btn-bg.png


BIN
src/components/easyMap/images/position-icon.png


+ 10 - 0
src/components/easyMap/index.vue

@@ -294,6 +294,7 @@ export default defineComponent({
         },
         drawViews,
         drawEdits,
+        drawExit,
         zoom: ref_olMap.value.mapBasicInfo.zoom,
         mouse: ref_olMap.value.mapBasicInfo.mouse,
       });
@@ -338,6 +339,11 @@ export default defineComponent({
       BaseDraw.drawViews(easyMap.value, arr)
     }
     const drawEdits = (obj: any, emitFunc) => {
+      for (const [k, v] of Object.entries(obj)) {
+        if (v === null || v === undefined || (typeof v === 'string' && v.trim() === '') || (typeof v === 'object' && v?.length === 0)) {
+          delete obj[k]
+        }
+      }
       state.drawEditsConfig = Object.assign(BaseDraw.getBaseDrawConfig(), obj, {
         emitFunc
       })
@@ -361,6 +367,10 @@ export default defineComponent({
         })
       })
     }
+    const drawExit = () => {
+      state.drawEditsConfig.show = false
+      BaseDraw.drawExit(easyMap.value)
+    }
     const drawEditsSwitchFeatureType = (val) => {
       state.drawEditsConfig.wkt = null
       state.drawEditsConfig.featureType = val

+ 7 - 3
src/components/easyMap/ol-map.vue

@@ -69,7 +69,7 @@
     },
     props: {
       baseMapLayers: { default: () => [] },
-      baseMapView: {},
+      baseMapView: <any>{},
       layout: {}
     },
     setup(props, { emit }) {
@@ -84,7 +84,7 @@
           formatLatitude: <any>null,
         },
         interactionZoom: props.baseMapView.zoom,
-        realBaseLayers: null,
+        realBaseLayers: <any>null,
       });
       const easyMapOl = ref()
       const ref_easyMapOl = ref()
@@ -93,6 +93,10 @@
       const ref_easyMap_scaleLine = ref()
       const initMap = () => {
         state.realBaseLayers = props.baseMapLayers.map(v => InitMapInfoClass.isInternet ? InitMapInfoClass.initInternet(v) : InitMapInfoClass.initBaseLayer(v))
+        const view = new ol.View(props.baseMapView)
+        for (const baseMapViewKey in props.baseMapView) {
+          view.set(baseMapViewKey, props.baseMapView[baseMapViewKey])
+        }
         easyMapOl.value = new ol.Map({
           target: ref_easyMapOl.value,
           layers: [
@@ -102,7 +106,7 @@
               zIndex: 1
             }),
           ],
-          view: new ol.View(props.baseMapView),
+          view: view,
           controls: control.defaults({
             attribution: false,
             rotate: false,

+ 4 - 0
src/router/index.ts

@@ -12,6 +12,10 @@ const routes = [
         path: '/track-status',
         component: () => import('@/views/track-status/index.vue'),
     },
+    {
+        path: '/ais-test',
+        component: () => import('@/views/ais-test/index.vue'),
+    },
 ]
 
 const router = createRouter({

+ 8 - 0
src/store/modules/easy-map.ts

@@ -11,6 +11,8 @@ const state = {
 		value: null,
 		feature: null
 	},
+	isDrawing: false,
+	isTooling: false,
 }
 
 const mutations = {
@@ -21,6 +23,12 @@ const mutations = {
 			state.hoverInfo = data
 		}
 	},
+	SET_IS_TOOLING(state, flag) {
+		state.isTooling = flag
+	},
+	SET_IS_DRAWING(state, flag) {
+		state.isDrawing = flag
+	},
 }
 
 const actions = {

+ 1 - 0
src/views/index.vue

@@ -2,6 +2,7 @@
   <div>
     <el-button @click="$router.push('/mock-track')">模拟轨迹</el-button>
     <el-button @click="$router.push('/track-status')">船舶轨迹状态查询</el-button>
+    <el-button @click="$router.push('/ais-test')">AIS测试</el-button>
   </div>
 </template>
 

+ 2 - 2
src/views/init-speed-track/index.vue

@@ -2,7 +2,7 @@
   <div class="init-speed-track" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.5)">
     <EasyMapComponent
         class="map"
-        :showBaseSwitch="true"
+        layout="info"
         @easyMapLoad="mapLoad"
     />
     <div class="track">
@@ -585,7 +585,7 @@ export default defineComponent({
 <style lang="scss" scoped>
 .init-speed-track {
   width: 100%;
-  height: 100%;
+  height: 100vh;
   position: relative;
   .map {
     width: 100%;

+ 5 - 0
vite.config.ts

@@ -9,6 +9,11 @@ import VitePluginHtmlEnv from 'vite-plugin-html-env'
 
 // https://vitejs.dev/config/
 export default defineConfig({
+  define: {
+    'process.env': process.env,
+    // enable hydration mismatch details in production build
+    __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
+  },
   plugins: [vue(), viteCompression(), VitePluginHtmlEnv(), visualizer(), createSvgIconsPlugin({
     // 指定需要缓存的图标文件夹
     iconDirs: [resolve(process.cwd(), 'src/assets/svg/global'), resolve(process.cwd(), 'src/assets/svg/business')],