Opnelayers:海量图形渲染之聚合

最近由于在工作中涉及到了海量图形渲染的问题,因此我开始研究相关的解决方案。在这个过程中聚合也是一个经常会被人提到的解决方案,我一直对聚合是怀有疑虑的,我认为其无法有效的解决我所面临的问题。

一、基本使用方式

聚合的基本使用方式,可以参考我之前写的这篇文章:Openlayers:实现聚合-CSDN博客

二、尝试使用聚合来优化河流三角网

这篇文章我主要还是想要探讨一下是否能使用聚合来解决我在开发过程中遇到的实际。

我需要渲染一个像这样的河流三角网,由于三角网中的图形数量过多导致无法直接进行渲染。

最简单的方式当然还是用点作为三角网的聚合图形,这种效果实现起来很简单,并且性能上也有保障。

JavaScript 复制代码
  const polygonSource = new VectorSource({
    url: "src/data/河流三角网/BJ.json",
    format: new GeoJSON({
      dataProjection: "EPSG:4547",
      featureProjection: "EPSG:4326",
    }),
  });

  const clusterSource = new Cluster({
    distance: 40,
    source: polygonSource,
    geometryFunction: function (feature) {
      return feature.getGeometry().getPolygon(0).getInteriorPoint();
    }
  });

  const polygonLayer = new VectorLayer({
    properties: {
      name: "多边形图层",
      id: "polygonLayer",
    },
    source: clusterSource,
  });

  window.map.addLayer(polygonLayer);

但是上面的这种效果是没有办法满足我的需求的,我是希望在聚合后渲染的图形依旧可以保持河流的轮廓。

为了实现这样的效果,我筹划了一个方案。就是借助turf.js中的union方法将参与聚合的三角网格进行合并,将合并后的大多边形作为渲染图形。

JavaScript 复制代码
  const polygonSource = new VectorSource({
    url: "src/data/河流三角网/BJ.json",
    format: new GeoJSON({
      dataProjection: "EPSG:4547",
      featureProjection: "EPSG:4326",
    }),
  });

  const clusterSource = new Cluster({
    distance: 40,
    source: polygonSource,
    geometryFunction: function (feature) {
      // 我这里使用的多边形几何类型是MultiPolygon
      return feature.getGeometry().getPolygon(0).getInteriorPoint();
    },
    createCluster: function (point, features) {
      if (features.length > 1) {
        const polygons = turf.featureCollection(
          features.map(f =>
            turf.polygon(f.getGeometry().getPolygon(0).getCoordinates())
          )
        );
        const unionPolygon = turf.union(polygons);
        return new Feature({
          geometry: new Polygon(unionPolygon.geometry.coordinates),
          features: features,
        });
      } else {
        return features[0];
      }
    },
  });

  const polygonLayer = new VectorLayer({
    properties: {
      name: "多边形图层",
      id: "polygonLayer",
    },
    source: clusterSource,
  });

  window.map.addLayer(polygonLayer);

很可惜,最终呈现出来的结果非常的糟糕,主要有以下的几个问题:

  1. 当初始渲染和切换缩放级别时,聚合计算量很大,导致加载速度慢。
  2. 合并后的多边形多是不规则的,其实也不甚美观。

3.合并之后出现了很多空隙,上不知晓是什么原因导致的。

三、总结

最后在我想对聚合方法做一个总结,首先必须承认的是聚合确实一种有效的解决海量图形渲染问题的方案。

但是聚合也是存在着明显的局限性,它主要适用于两种情况:

  1. 在渲染效果上允许使用一个标识来代表一个区域内的图形。
  2. 在计算聚合的过程中没有太过复杂的计算。

因此如果要求较为简单,那么我还是比较建议使用聚合去渲染海量图形的,反之则应该去寻求其它的解决办法。

参考资料

  1. OpenLayers v10.5.0 API - Class: Cluster
  2. Turf.js中文网 | Turf.js中文网
相关推荐
yzzzzzzzzzzzzzzzzz2 分钟前
JavaScript 操作 DOM
开发语言·javascript·ecmascript
奋斗的小羊羊30 分钟前
HTML5关键知识点之多种视频编码工具的使用方法
前端·音视频·html5
前端呆猿37 分钟前
深入解析HTML5中的object-fit属性
前端·css·html5
再学一点就睡37 分钟前
实现大文件上传全流程详解(补偿版本)
前端·javascript·面试
你的人类朋友2 小时前
【Node&Vue】什么是ECMAScript?
前端·javascript·后端
路灯下的光2 小时前
用scss设计一下系统主题有什么方案吗
前端·css·scss
l_tian_tian_3 小时前
SpringClound——网关、服务保护和分布式事务
linux·服务器·前端
一只小风华~3 小时前
CSS @media 媒体查询
前端·css·媒体
shix .3 小时前
最近 | 黄淮教务 | 小工具合集
前端·javascript
John_ToDebug4 小时前
Chrome 内置扩展 vs WebUI:浏览器内核开发中的选择与实践
前端·c++·chrome