最近由于在工作中涉及到了海量图形渲染的问题,因此我开始研究相关的解决方案。在这个过程中聚合也是一个经常会被人提到的解决方案,我一直对聚合是怀有疑虑的,我认为其无法有效的解决我所面临的问题。
一、基本使用方式
聚合的基本使用方式,可以参考我之前写的这篇文章:Openlayers:实现聚合-CSDN博客
二、尝试使用聚合来优化河流三角网
这篇文章我主要还是想要探讨一下是否能使用聚合来解决我在开发过程中遇到的实际。
我需要渲染一个像这样的河流三角网,由于三角网中的图形数量过多导致无法直接进行渲染。
最简单的方式当然还是用点作为三角网的聚合图形,这种效果实现起来很简单,并且性能上也有保障。
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
方法将参与聚合的三角网格进行合并,将合并后的大多边形作为渲染图形。
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);
很可惜,最终呈现出来的结果非常的糟糕,主要有以下的几个问题:
- 当初始渲染和切换缩放级别时,聚合计算量很大,导致加载速度慢。
- 合并后的多边形多是不规则的,其实也不甚美观。
3.合并之后出现了很多空隙,上不知晓是什么原因导致的。
三、总结
最后在我想对聚合方法做一个总结,首先必须承认的是聚合确实一种有效的解决海量图形渲染问题的方案。
但是聚合也是存在着明显的局限性,它主要适用于两种情况:
- 在渲染效果上允许使用一个标识来代表一个区域内的图形。
- 在计算聚合的过程中没有太过复杂的计算。
因此如果要求较为简单,那么我还是比较建议使用聚合去渲染海量图形的,反之则应该去寻求其它的解决办法。