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中文网
相关推荐
不会飞的鲨鱼1 分钟前
【QQ音乐】sign签名| data参数 | AES-GCM加密 | webpack(上)
开发语言·javascript·webpack
竹鹿众猿31 分钟前
ElementUI表单验证指南
前端·vue.js·elementui
Jim-zf33 分钟前
Flutter 实现6个验收码输入框
开发语言·javascript·flutter
贩卖纯净水.33 分钟前
webpack的安装及其后序部分
前端·webpack·node.js
初遇你时动了情1 小时前
ts 泛型
javascript·react.js·typescript
EndingCoder3 小时前
React从基础入门到高级实战:React 生态与工具 - React 单元测试
前端·javascript·react.js·typescript·单元测试·前端框架
年纪轻轻只想躺平4 小时前
Vue2部分知识点和注意项
前端·javascript·vue.js
多则惑少则明5 小时前
Vue开发系列——Vue 生命周期钩子 及常见知识点
前端·javascript·vue.js·前端框架
菥菥爱嘻嘻6 小时前
JS手写代码篇---Pomise.race
开发语言·前端·javascript
CodeCipher7 小时前
前端Vue3列表滑动无限加载实现
前端·javascript·vue.js·vue