leaflet天地图GeoJSON边界添加自定义背景

需求:地图根据用户权限设置操作权限,不可操作区域叠加灰色斜杠

效果

 

 

L.geoJSON添加的边界按顺序叠加,但是都是叠加在svg内,无法通过调整区域层级叠加imgLayer的方式添加效果。

 通过调试和查看文档,发现svg可以添加背景图片
需要创建svg图片元素,并获取需要禁用的区域添加自定义图片。

 

原逻辑:不添加灰色禁用背景
1. 绘制所有底图
2. 给底图默认添加禁用区域填充颜色
3. 绘制有权限区域底图
4. 绘制有权限区域的底图
5. 分别绘制无权限和有权限区域的预警填充.


现逻辑将第二步使用颜色填充默认区域改成用背景填充
代码如下

 

// townList为所有区域数据,包含geoJson需要的经纬度坐标
townsList.forEach(el => {
      const bound = L.geoJSON([el] as any, {
        style: {
          weight: 1,
          fillOpacity: 1,
          color: '#666',
          fillColor: 'url(#disableImg)', // 这里设置为下面创建的斜杠图片svg元素id
          className: 'disable-layer'
        },
        onEachFeature: this.mouseClick
      });
      bound.addTo(this.map);
    });
        this.setDisableLayer();

/**
   * @description: 设置底图为禁用状态
   */
  setDisableLayer() {
    const svgEl = document.querySelector<HTMLElement>('.leaflet-zoom-animated');
    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
    const pattern = document.createElementNS(
      'http://www.w3.org/2000/svg',
      'pattern'
    );
    pattern.setAttributeNS(null, 'id', 'disableImg');
    pattern.setAttributeNS(null, 'patternUnits', 'userSpaceOnUse');
    this.setSvgSize(pattern, 10);
    const svgimg = document.createElementNS(
      'http://www.w3.org/2000/svg',
      'image'
    );
    svgimg.setAttributeNS(
      'http://www.w3.org/1999/xlink',
      'xlink:href',
      require('@/assets/imgs/warningPublish/map disable.jpg')
    );
    this.setSvgSize(svgimg, 10);
    svgimg.setAttributeNS(null, 'preserveAspectRatio', 'none');
    pattern.appendChild(svgimg);
    defs.appendChild(pattern);
    svgEl && svgEl.appendChild(defs);
    this.disableBg.pattern = pattern;
    this.disableBg.svgimg = svgimg;
  }

/**
   * @description: 设置禁用的区域斜杠条纹大小
   * @param  el svg图片的Pattern和Image元素
   * @param  size 宽高
   */
  setSvgSize(el: SVGImageElement | SVGPatternElement, size: number) {
    el.setAttributeNS(null, 'width', size + '');
    el.setAttributeNS(null, 'height', size + '');
    el.setAttributeNS(null, 'x', '0');
    el.setAttributeNS(null, 'y', '0');
  }


监听地图缩放,根据缩放等级调整斜杠大小
this.map.on('zoomend', (e: L.LeafletMouseEvent) => {
      if (this.disableBg.svgimg && this.disableBg.pattern) {
        //获取当前放大或者缩小的等级
        let scale = e.target.getZoom();
        const baseSize = scale < 10 ? 0.625 : 1;
        const size = baseSize * scale;
        this.setSvgSize(this.disableBg.svgimg, size);
        this.setSvgSize(this.disableBg.pattern, size);
      }
    });

创建SVG的元素需要用setAttributeNS,并指定namespace如:
const svgimg = document.createElementNS(
'http://www.w3.org/2000/svg',
'image'
);

 


posted @ 2022-02-11 16:34  陈年风褛1874  阅读(1728)  评论(0编辑  收藏  举报