leftMap海图封装全局公用绘制方法,多图层同时绘制

业务需求:同一个页面能够打开多个弹框,分别绘制对应的点位或图形,关闭某个弹框清除对应的图层,不影响其他图层的正常使用。

1.初始化onMounted的时候执行获取数据的操作,请求list数据获取需要撒点的所有图标以及经纬度信息

2.执行list接口,采用回调函数的方式,获取到数据后,在vue里进行预处理图标样式

3.stores封装全局地图图层公用方法(可复制,Util方法可复制也可自行定义)

Util.d.ts文件中的公用工具

export default class Util {
    /**
     * 阻止事件冒泡
     * @param e
     */
    static stopEventPop(e: any): void;
    /**
     * 重复绑定函数,只执行最后一次
     * @param func
     * @param wait
     * @param options
     */
    static debounce(func: any, wait?: number, options?: {
        leading?: boolean | undefined;
        /**
         * @see maxWait
         */
        maxWait?: number | undefined;
        /**
         * @see trailing
         */
        trailing?: boolean | undefined;
    }): any;
    /**
     *移除数组中predicate(断言)返回为真值的所有元素,并返回移除元素组成的数组
     * @param array
     * @param func
     * @returns {Array}
     */
    static remove(array: any[], func: any): any;
    /**
     * 判断数据中是否存在某一元素
     * @param array
     * @param item
     * @returns {boolean}
     */
    static includes(array: any[], item: any): any;
    /**
     * 通过fn函数返回值进行分组
     * @param data
     * @param fn
     */
    static groupBy(data: any[], fn: any): any;
    /**
     * 数组元素去重
     * @param array
     * @returns {Array}
     */
    static uniq(array: any): any;
    /**
     * 比较source中的对象在target中是否有修改
     * @param source
     * @param target
     */
    static compileObj(source: any, target: any): boolean;
    /**
     * 数组对象中的特定属性的去重数组
     * @param data
     * @param field
     */
    static unionByField(data?: never[], field?: string): any;
    /**
     * 转换表单为多行数据对象,rowKey为行记录主键(如:人员编号)
     * @param data
     * @param splitStr
     * @param suffixStr
     */
    static convertFormValueToMultiObj(data?: any, splitStr?: string, suffixStr?: string): any;
    /**
     * 创建虚拟key,从1开始避免有判断key是否存在时布尔值异常
     * @param data
     * @param key
     * @param keyNum
     */
    static virtualKey(data?: never[], key?: string, keyNum?: number): any[];
    /**
     * 返回固定数量的0字符串
     * @param num
     */
    static fillZeroStr(num: number): any;
    /**
     * 返回固定数量的字符串,用join连接
     * @param num
     * @param char
     * @param join
     */
    static fillStr(num: number, char?: string, join?: string): any;
    /**
     * join 值添加单引号包裹
     * @param arr
     * @param sep
     */
    static joinSingleQuote(arr?: never[], sep?: string): string;
    /**
     * 将文本转换为数组,使用','切分, 去重
     * @param str
     */
    static textToArr(str?: string): string[];
    /**
     * 将字符串文本转换为数组,使用','切分,不去重
     * @param str
     */
    static stringToArr(str?: string): string[];
    /**
     * 数组中存在移除,不存在添加
     * @param data
     * @param key
     */
    static exitRemoveOrNoExitAdd(data: any[], key: any): any[];
    /**
     * 合并数组通过属性
     * @param objects
     * @param others
     * @param key
     */
    static mergeBy(objects: any[], others: any[], key: any): any[];
    static stringToMultiCheckBox(field: any, data: any): any;
    /**
     * 树型组件转换数据
     * @param data
     * @param callback
     */
    static convertTreeData({ data, callback }: {
        data: any[];
        callback: any;
    }): any[];
    /**
     * 为表格数据中添加key虚字段(用于表格编辑行标识)
     * @param data
     * @param rowKey
     */
    static tableRowKeyFormat(data: any[], rowKey: any): any[] | undefined;
    /**
     * 是否url地址
     * @param path
     * @returns {boolean}
     */
    static isUrl(path: any): boolean;
    /**
     * 路径转换
     * 示例:/userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
     * @param url
     * @returns {*}
     */
    static urlToList(url: string): string[];
    /**
     * 是否日期类型
     * @param value
     * @returns {boolean}
     */
    static isDate(value: any): boolean;
    /**
     * 是否日期时间类型
     * @param value
     * @returns {boolean}
     */
    static isDatetime(value: any): boolean;
    /**
     * 是否时间类型
     * @param value
     * @returns {boolean}
     */
    static isTime(value: any): boolean;
    /**
     * 获取日期匹配的正则
     * @param value
     */
    static getDateMatch(value: any): RegExpMatchArray | null;
    /**
     * 是否可以匹配日期格式
     * @param value
     */
    static isDateMatch(value: any): boolean;
    /**
     * 转换为一个 dayjs 日期类型
     * @param value
     * @returns {*}
     */
    static convertDate(value: any): any;
    /**
     * 校验是否为日期对象
     * @param val
     * @returns {*}
     */
    static validDate(val: any): any;
    /**
     * 转换值为对应类型
     * @param val
     * @returns {*}
     */
    static convertBaseValue(val: any): any;
    /**
     * 转换表单数据
     * @param data
     */
    static convertValueTemplate(data: any, convertValueCallback: Function, field: string[]): any;
    /**
     * 转换表单数据
     * @param data
     */
    static convertValue(data: any): any;
    /**
     * 转换值为对应类型
     * @param val
     * @returns {*}
     */
    static convertBaseValueDate(val: any): any;
    /**
     * 转换表单数据
     * @param data
     */
    static convertValueDate(data: any): any;
    static formatDayjs(value: any, format?: string): any;
    /**
     * 将日期转换成对应的格式,不传默认为YYYY-MM-DD
     * @param value
     * @param format
     */
    static format(value: any, format?: string): any;
    static formatDate(d: any): string;
    static formatToMonDay(d: any): string;
    /**
     * 将日期格式化成YYYY-MM-DD HH:mm
     * @param value
     */
    static formatToDateMin(value: any): any;
    /**
     * 将日期格式化成YYYY-MM-DD
     * @param value
     */
    static formatToDate(value: any): any;
    /**
     * 将日期格式化成HH:mm:ss
     * @param value
     */
    static formatToTime(value: any): any;
    /**
     * 将日期格式化成YYYY-MM-DD HH:mm:ss
     * @param value
     */
    static formatToDateTime(value: any): any;
    /**
     * 判断传入参数是否为数据
     * isArray([1, 2, 3]) => true
     * isArray(document.body.children); => false
     * isArray('abc'); => false
     * @param value
     */
    static isArray(value: any): any;
    /**
     * 判断传入参数是否为boolean
     * isBoolean(false); => true
     * isBoolean(null); => false
     * @param value
     */
    static isBoolean(value: any): any;
    /**
     * 判断传入参数是否为null, '', undefined,{}
     * 数字和boolean行返回都是true
     * isEmpty(); => true
     * isEmpty({}); => true
     * isEmpty([]); => true
     * isEmpty(true); => true
     * isEmpty(false); => true
     * isEmpty(undefined); => true
     * isEmpty(null); => true
     * isEmpty(1); => true
     * isEmpty(''); => true
     * @param value
     */
    static isEmpty(value: any): any;
    /**
     * 判断传入参数不为空,说明见isEmpty
     * @param value
     * @returns {boolean}
     */
    static isNotEmpty(value: any): boolean;
    /**
     * 判断传入参数是否为方法
     */
    static isFunction(value: any): any;
    /**
     * 判断传入参数是否NaN
     * isNaN(NaN); => true
     * isNaN(new Number(NaN)); => true
     * isNaN(undefined); => false
     * @param value
     */
    static isNaN(value: any): any;
    /**
     * 判断传入参数是否为null
     * isNull(null); => true
     * isNull(''); => false
     * @param value
     */
    static isNull(value: any): any;
    /**
     * 判断传入参数是否为数字
     * isNumber(3); => true
     * isNumber('3'); => false
     * isNumber(Infinity); => true
     * isNumber(Number.MIN_VALUE); => true
     * @param value
     */
    static isNumber(value: any): any;
    /**
     * 判断传入参数是否纯对象
     * isPlainObject(new Foo) => false
     * isPlainObject([1, 2, 3]); => false
     * isPlainObject({}); => true
     * isPlainObject({ 'x': 0, 'y': 0 }); => true
     * isPlainObject(Object.create(null)); => true
     * @param value
     */
    static isPlainObject(value: any): any;
    /**
     * 判断传入参数是否为纯字符串
     * isString('abc'); => true
     * isString(1); => false
     * isString({}); => false
     * @param value
     */
    static isString(value: any): any;
    /**
     * 判断是否已target参数结尾,如果position有值,则从position位置开始
     * endsWith('abc', 'c');  => true
     * endsWith('abc', 'b'); => false
     * endsWith('abc', 'b', 2); => true
     * @param value 目标string字符串
     * @param target 需要判断的字符串
     * @param position 末尾起始位置判断 默认值string.length
     */
    static endsWith(value: any, target: any, position?: any): any;
    /**
     *  判断是否已target参数开始,如果position有值,则从position位置开始
     *  startsWith('abc', 'a'); => true
     *  startsWith('abc', 'b'); => false
     *  startsWith('abc', 'b', 1); => true
     * @param value
     * @param target
     * @param position
     */
    static startsWith(value: any, target: any, position: any): any;
    /**
     * value后补全chars字符串,直至整体长度达到length
     * padEnd('abc', 6); => 'abc   '
     * padEnd('abc', 6, '_-'); => 'abc_-_'
     * padEnd('abc', 3); => 'abc'
     * @param value
     * @param length
     * @param chars 默认为' '
     */
    static padEnd(value: any, length: any, chars: any): any;
    /**
     * value前补全chars字符串,直至整体长度达到length
     * padStart('abc', 6); => '   abc'
     * padStart('abc', 6, '_-'); => '_-_abc'
     * padStart('abc', 3);  => 'abc'
     * @param value
     * @param length
     * @param chars
     * @returns {*|string}
     */
    static padStart(value: any, length: any, chars: any): any;
    /**
     * 将value值前后的chars移除,chars默认值为whitespace
     * trim('  abc  '); => 'abc'
     * @param value
     * @param chars
     */
    static trim(value: any, chars: any): any;
    /**
     * 将value值末尾的chars移除,chars默认值为whitespace
     * trimEnd('  abc  '); => '  abc'
     * @param value
     * @param chars
     */
    static trimEnd(value: any, chars: any): any;
    /**
     * 将value值开始的chars移除,chars默认值为whitespace
     * trimStart('  abc  '); => 'abc  '
     * @param value
     * @param chars
     * @returns {*|string}
     */
    static trimStart(value: any, chars: any): any;
    /**
     * 是否手机号
     * 以1开头后跟10位数字
     * @param str
     * @return {boolean}
     */
    static isMobile(str: string): boolean;
    static isFixedLine(str: string): boolean;
    static pureString(str: string): boolean;
    static isFax(str: string): boolean;
    /**
     * 是否Email 地址
     * @param str
     * @return {boolean}
     */
    static isEmail(str: string): boolean;
    /**
     * 是否 邮编
     * @param str
     * @return {boolean}
     */
    static isZipCode(str: string): boolean;
    /**
     * 判断是否为身份证号码
     * @param str
     * @returns {boolean}
     */
    static isIdCard(str: string): boolean;
    /**
     * 删除字符串结尾的字符串,不传默认为','
     * @param value
     * @param char
     * @returns {*}
     */
    static deleteEndChar(value: any, char?: string): any;
    /**
     * 删除字符串开头的字符, 不传默认为','
     * deleteStartChar('test', 't'); => 'est'
     * deleteStartChar('test', 'te'); => 'st'
     * deleteStartChar('test'); => 'test'
     * deleteStartChar(',test'); => 'test'
     * @param value
     * @param char
     * @returns {string}
     */
    static deleteStartChar(value: any, char?: string): any;
    /**
     * 是否对象
     * @param value
     */
    static isObject(value: any): any;
    /**
     * 删除字符串结尾出现的指定字符串
     * @param str
     * @param deleteChar
     * @returns {*}
     */
    static deleteAllEndChar(str: any, deleteChar: any): any;
    /**
     * 可比较字符串,数字,数组,对象,布尔是否相等
     * 比较数组时,内部已经忽略数组顺序,将传入数组参数进行排序.sort()
     * @param value
     * @param other
     */
    static isEqual(value: any, other: any): any;
    static cloneDeep(value: any): any;
    /**
     * 数组转对象,按field取值作为key
     * @param array
     * @param field
     */
    static keyBy(array: any, field: any): any;
    /**
     * 是否不相同
     * @param value
     * @param other
     */
    static isNotEqual(value: any, other: any): boolean;
    /**
     * 转换成驼峰
     * @param str
     */
    static toCamel(str: string): any;
    /**
     * 日期时间比较 val1 是否早于 val2   dayjs('2010-10-20').isBefore('2010-10-21') // true
     * @param val1
     * @param val2
     * @returns {boolean}
     */
    static isBefore(val1: any, val2: any): boolean;
    /**
     * 日期时间判断
     * 时间val1和时间val2  是否相等   dayjs('2010-10-20').isSame('2010-10-20') // true
     * @param val1
     * @param val2
     * @returns {boolean}
     */
    static isSame(val1: any, val2: any): boolean;
    /**
     * 日期时间判断
     * 时间val1是否晚于时间val2    dayjs('2010-10-20').isAfter('2010-10-19') // true
     * @param val1
     * @param val2
     * @returns {boolean}
     */
    static isAfter(val1: any, val2: any): boolean;
    /**
     * 时间 val1 是否在时间val2和val3范围内,在时间范围内返回true  dayjs('2010-10-20').isBetween('2010-10-19', '2010-10-25') // true
     * @param val1
     * @param val2
     * @param val3
     * @returns {boolean}
     */
    static isBetween(val1: any, val2: any, val3: any): boolean;
    /**
     * 返回数组重复项
     * [1,2,3,4,4,2]   => [2,4]
     * @param data
     */
    static selfRepeat(data: any[]): any[];
    /**
     * 数组去重
     * @param data
     * @returns {Array}
     */
    static union(data: any[]): any[];
    /**
     *  获取字符串中特殊字符的长度
     */
    static speLen(text: any, len: any): any;
    /**
     *  获取字符串中数字字符的长度
     */
    static numLen(text: any, len: any): any;
    /**
     *  获取需要显示字符串长度
     */
    static columnLen(text: any, len: any): any;
    /**
     * 清空对象中的‘’和null
     * @param params
     * @returns Object
     */
    static omitBy(params: any): any;
    /**
     * 根据某个属性查找重复数据
     * @param data  [{}]
     * @param field 数组中对象的某个属性
     * @returns {Array} 重复数据
     */
    static getRepeatBy(data: any[], field: any): any[];
    /**
     * 首字母大写
     * @param str
     */
    static _capitalize(str: string): string | undefined;
    /**
     * 拼接年月字符串,isDay 是否需要天数
     */
    static getYearMonth(year: any, month: any, isDay: any): any;
    /**
     * 将hex颜色转成rgba
     * @param hex
     * @param opacity
     */
    static hexToRgba(hex: any, opacity?: number): {
        rgba: string | null;
    };
    /**
     * 将rgb颜色转成hex
     * @param color
     */
    static colorRGB2Hex(color: any): {
        hex: string | null;
        a: number;
    };
    /**
     * 将时间戳转为 xx天xx小时xx分格式
     * @param mss
     */
    static formatDuring(mss: number): string;
    /**
     * 将时间戳转为小时数
     * @param mss
     */
    static formatHour(mss: number): number;
    /**
     * 混淆记住密码
     * @param password
     * @returns {string}
     */
    static confusePass(password: any): string;
    /**
     * 解析混淆的密码
     * @param confusePass
     * @returns {string}
     */
    static reConfusePass(confusePass: any): any;
    /**
     * 转换HTML
     * @param oldStr
     * @returns {*}
     */
    static transferEntityName2Char(oldStr: any): any;
    /**
     * 默认值
     * @param val
     * @returns
     */
    static dvb(val: any): boolean;
    /**
     * 当前值为空返回默认值
     * @param val
     * @param d
     * @returns
     */
    static defaultVal(val: any, d: any): any;
}

全局地图绘制stores方法

import { defineStore } from "pinia";
import "@msa/map-leaflet/dist/index.css";
import { Util } from "@msa/msa-core";
import {
  L,
  LeafletDrawLayerUtil,
  createMapManager,
  drawShapeLayer,
  markerGroupLayer,
  measureLayer,
  shipIconLayer,
  shipTrackLayer,
} from "@msa/map-leaflet";

export interface MapState {
  $loading: Record<string, boolean>;
}

export const useMapStore = defineStore("map", {
  state: (): MapState => ({
    $loading: {},
  }),
  getters: {},
  actions: {
    async initMap() {
      const tileUrl = import.meta.env.VITE_TILE_URL;
      const tileLabelUrl = import.meta.env.VITE_TILE_LABEL_URL;
      const mapManager = createMapManager({
        id: "map-app",
        tiles: [tileUrl, tileLabelUrl],
        center: [20.01, 110.01],
        zoom: 5,
        minZoom: 3,
        maxZoom: 18,
        zoomRulePosition: "bottomright",
        mouseLocPosition: "bottomright",
        zoomControlPosition: "bottomright",
        // // 图层设置为canvas svg
        // preferCanvas: true,
      });

      if (!mapManager) {
        return;
      }

      const onShipClick = (_shipData: any, shipFlag: boolean) => {
        if (shipFlag) {
        }
      };

      const drawLayerGroup = new L.FeatureGroup();
      drawLayerGroup.addTo(mapManager.map);
      LeafletDrawLayerUtil.initLayer(mapManager.map, drawLayerGroup);
      const canvasRender = L.canvas({ padding: 0.5 });
      const shipLayer = shipIconLayer({
        map: mapManager.map,
        shipData: [],
        onShipClick,
        sailFlagSpeed: 1,
        showDynamicIconZoom: 12,
        renderer: canvasRender,
      });
      const trackLayer = shipTrackLayer({
        map: mapManager.map,
        isSnake: true,
        shipData: [],
        shipTrackDataObj: {},
        renderer: canvasRender,
        circleLabelTitle: (item: any) => {
          // 轨迹的title
          return item.utc ? Util.formatToDateTime(item.utc) : "-";
        },
        circleHoverTitle: (item: any) => {
          // 鼠标悬浮的title;
          return `<div>时间:${item.utc ? Util.formatToDateTime(item.utc) : "-"}</div>`;
        },
      });
      const markerLayer = markerGroupLayer({
        map: mapManager.map,
        renderer: canvasRender,
      });
      const drawLayer = drawShapeLayer({
        map: mapManager.map,
      });
      const globalMeasureLayer = measureLayer({
        map: mapManager.map,
      });
      const areaDrawLayer = drawShapeLayer({
        map: mapManager.map,
      });
      window.globalMarkerLayer = markerLayer;
      window.globalShipLayer = shipLayer;
      window.globalTrackLayer = trackLayer;
      window.globalDrawLayer = drawLayer;
      window.globalMeasureLayer = globalMeasureLayer;
      window.globalCanvasRender = canvasRender;
      window.globalAreaDrawLayer = areaDrawLayer;
      window.leafletMap = mapManager.map;
      //业务组件的图层
      window.globalLayerGroup = {};
    },
    /**
     * 新建图层--layerGroup
     */
    newLayerGroup(groupName: string = "") {
      if (Util.isEmpty(window.globalLayerGroup[groupName])) {
        window.globalLayerGroup[groupName] = new L.LayerGroup();
        window.globalLayerGroup[groupName].addTo(window.leafletMap);
      }
    },
    /**
     * 清空指定图层
     */
    removeLayerGroup(groupName: string = "") {
      if (Util.isNotEmpty(window.globalLayerGroup[groupName])) {
        window.globalLayerGroup[groupName].clearLayers &&
          window.globalLayerGroup[groupName].clearLayers();
        //通航要素图层
        window.globalLayerGroup[groupName].clear && window.globalLayerGroup[groupName].clear();
      }
    },
    /**
     * 清空全部海图图层
     */
    removeAllLayerGroup() {
      Object.keys(window.globalLayerGroup).map((key) => {
        if (Util.isNotEmpty(window.globalLayerGroup[key])) {
          window.globalLayerGroup[key].clearLayers && window.globalLayerGroup[key].clearLayers();
          //通航要素图层
          window.globalLayerGroup[key].clear && window.globalLayerGroup[key].clear();
        }
      });
    },
    /**
     * 添加layer
     */
    addLayer(groupName: string = "", layer: any) {
      window.globalLayerGroup[groupName]?.addLayer(layer);
    },
    /**
     * 删除指定layer
     */
    removeLayer(groupName: string = "", layer: any) {
      window.globalLayerGroup[groupName]?.removeLayer(layer);
    },
    /**
     * 判断图层是否存在
     * 返回 true:代表图层存在
     * 返回 false: 代表图层不存在
     */
    groupIsExist(groupName: string = "") {
      return Util.isNotEmpty(window.globalLayerGroup[groupName]);
    },
  },
});

4.引入公共图层的绘制

5.继续执行initDcrNavigationBaseInfoItem方法,进行点位撒点和图层,每次绘制之前调用 mapStore.removeLayerGroup()清除之前的图层,避免vue3的多次执行onMounted问题

6.至此以上步骤,海图的基本点位的绘制、hover提示事件、点击事件都已经完成。下面做修改海图的某一个具体点位的信息功能(一般按钮都在修改页添加一下功能):

(1.)“修改按钮”(清除旧点位,添加新点位);

(2.)“清除按钮”(清除修改的点位位置);

(3.)“取消按钮”(修改点位后取消,恢复原有点位,减少重绘)

7.关闭当前页面,移出当前图层,清除当前所有点位的撒点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值