当前位置: 首页 > article >正文

leaflet矢量瓦片vetorgrid显示聚合和图标裁剪显示不全的问题

1、问题现象

使用leaflet显示矢量瓦片会出现图片挤压的问题和图片裁剪显示不全的问题

2、解决办法和思路

1)数据抽稀

方法一:在createTile方法通过控制feature在单张瓦片里面显示的数量,在小层级的时候进行筛选过滤,对点数据类型,代码如下:

//判断当期瓦片里面的features,然后对数据进行抽稀,显示的数量不超过5个
            //小于14层的瓦片,抽稀,显示的数量不超过5个,大于14级全部显示
            if (
              (coords.z <= 14 && layer.features.length > 5 && feat.id % Math.ceil(layer.features.length / 5) == 0) ||
              layer.features.length <= 5 ||
              coords.z > 14 ||
              feat.type != 1
            ) {
              var featureLayer = this._createLayer(feat, pxPerExtent)

              for (var j = 0; j < styleOptions.length; j++) {
                var style = L.extend({}, L.Path.prototype.options, styleOptions[j])
                featureLayer.render(renderer, style)
                renderer._addPath(featureLayer)
              }

              if (this.options.interactive) {
                featureLayer.makeInteractive()
              }

              if (storeFeatures) {
                renderer._features[id] = {
                  layerName: layerName,
                  feature: featureLayer
                }
              }
            }

方法二:通过设置矢量瓦片vectorTileLayerStyles的样式,可以获取到当前的层级和数据信息,设置一个空的占位图标解决抽稀问题:

vectorTileLayerStyles[layerStyle.layername] = function (properties: any, zoom: number) {
      if (options && options.length > 0) {
        let style = {} //返回的数据格式
        options.forEach((item: any) => {
          //如何当前的层级落在option的zoom数组范围内
          if (zoom >= item.zoom[0] && zoom <= item.zoom[1]) {
            let icon = L.icon({
              iconUrl: `/static/images/Iconpoint/${item.iconName}.svg`,
              iconSize: item.iconSize
            })
            //点的数据抽稀设置
            if (item.sliceCount && item.fieldname) {
              let data = properties[item.fieldname]
              //测试用
              // data = data.split('.')[1]
              //取余数
              if (data && Number(data) % Number(item.sliceCount) == 0) {
                style = {
                  icon: icon
                }
              } else {
                style = {
                  icon: defaultIcon
                }
              }
            }
          }
        })
        return style

 

 options配置如下:

         options: [
            {
              zoom: [1, 10], //不同层级下的显示最小值和最大值
              sliceCount: 70, //抽稀的数量
              iconSize: [23, 30],
              iconName: 'monitorvideo',
              fieldname: 'gbindexcode'//抽稀属性字段
            },
            {
              zoom: [11, 12], //不同层级下的显示
              sliceCount: 20, //抽稀的数量
              iconSize: [23, 30],
              iconName: 'monitorvideo',
              fieldname: 'gbindexcode'
            },
            {
              zoom: [13, 15], //不同层级下的显示
              sliceCount: 10, //抽稀的数量
              iconSize: [23, 30],
              iconName: 'monitorvideo',
              fieldname: 'gbindexcode'
            },
            {
              zoom: [16, 20], //不同层级下的显示
              sliceCount: 1, //抽稀的数量
              iconSize: [23, 30],
              iconName: 'monitorvideo',
              fieldname: 'gbindexcode'
            }
          ]

2)图片边缘裁切的问题处理

在gridlayer绘制的时候判断当前的数据是否会超出绘制边界,超出绘制边界后不予显示(可能会存在数据丢失的问题),也可以移动绘制的位置让其显示完全

_updateIcon: function (layer) {
    if (!this._drawing) {
      return
    }

    var icon = layer.options.icon,
      options = icon.options,
      size = L.point(options.iconSize),
      anchor = options.iconAnchor || (size && size.divideBy(2, true)),
      p = layer._point.subtract(anchor),
      ctx = this._ctx,
      img = layer._getImage()
    if (img.complete) {
      if (p.x + size.x > 256 || p.x < 0 || p.y + size.y > 256 || p.y < 0) {
        console.log('图像超出画板边界!')
      } else {
        ctx.drawImage(img, p.x, p.y, size.x, size.y)
      }
    } else {
      L.DomEvent.on(img, 'load', function () {
        if (p.x + size.x > 256 || p.x < 0 || p.y + size.y > 256 || p.y < 0) {
          console.log('图像超出画板边界!')
        } else {
          ctx.drawImage(img, p.x, p.y, size.x, size.y)
        }
      })
    }

    this._drawnLayers[layer._leaflet_id] = layer
  }
})

3、解决结果

4、参考资料

Leaflet.VectorGrid API reference

https://gis.stackexchange.com/questions/448812/leaflet-vectorgrid-circle-markers-cut-off-at-border-in-custom-implementation

Rendering errors (symbol clipping) at vector tile edges · Issue #149 · Leaflet/Leaflet.VectorGrid · GitHub

canvas 绘制图片 - ctx.drawImage()-CSDN博客

leaflet瓦片图层缩放级别外不隐藏_leafeft marker按照zomm显示隐藏-CSDN博客


http://www.kler.cn/a/380879.html

相关文章:

  • 十六届蓝桥杯嵌入式资料 看这个就够了(附CSDN开源程序)
  • el-date-picker日期选择器动态设置日期
  • 基于vue框架的的冷链食品物流信息管理系统v81wb(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 「Mac畅玩鸿蒙与硬件27」UI互动应用篇4 - 猫与灯的互动应用
  • 1565412310
  • Axure大屏可视化模板:赋能各行各业的数据展示与管理
  • Swift 开发教程系列 - 第2章:Swift 基础语法
  • 地理信息科学专业想搞GIS开发:学前端还是后端?
  • 多核架构的基本概念
  • 分布式追踪与告警系统:保障分布式系统稳定运行的利器
  • Jest进阶知识:测试快照 - 确保组件渲染输出正确
  • 学习记录:js算法(八十六):全排列 II
  • 棋牌游戏防ddos攻击,高防IP好用吗?
  • IO流篇(一、File)
  • 承建网站提高访问者留存率
  • 对于IIC的理解
  • Python小白学习教程从入门到入坑------第二十六课 单例模式(语法进阶)
  • 探索Java与C++中的类成员访问修饰符:从默认设置到封装实践
  • 【系统架构设计师】预测试卷一:论文(包括4篇论文主题对应的写作要点分析)
  • AUTOSAR COM 与 LargeDataCOM 模块解析及 C++ 实现示例
  • Docker:容器编排 Docker Compose
  • WPF中的CommandParameter如何使用
  • 11.04学习
  • 《Python游戏编程入门》注-第4章7
  • 如何封装一个axios,封装axios有哪些好处
  • PHP露营地管理平台小程序系统源码