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中文网
相关推荐
克里斯蒂亚诺更新11 小时前
微信小程序app.js中每30秒调用一次wx.getLocation
javascript·微信小程序·小程序
IT_陈寒11 小时前
Vue 3.4 实战:这7个Composition API技巧让我的开发效率飙升50%
前端·人工智能·后端
鄃鳕11 小时前
C++坑系列,C++ std::atomic 拷贝构造函数问题分析与解决方案
java·javascript·c++
少年阿闯~~12 小时前
HTML——1px问题
前端·html
Never_Satisfied12 小时前
在JavaScript / HTML中,实现`<iframe>` 自适应高度
开发语言·javascript·html
Mike_jia12 小时前
SafeLine:自托管WAF颠覆者!一键部署守护Web安全的雷池防线
前端
brzhang12 小时前
把网页的“好句子”都装进侧边栏:我做了个叫 Markbox 的收藏器,开源!
前端·后端·架构
VincentFHR14 小时前
Canvas 高性能K线图,支持无限左右滑动
前端·数据可视化·canvas
sophie旭14 小时前
一道面试题,开始性能优化之旅(3)-- DNS查询+TCP(二)
前端·面试·性能优化
面向星辰14 小时前
css选择器(继承补充)
前端·css