2016-11-03 66 views
6

此问题适用于了解MapBox GL JS内部结构的人。MapBox GL JS性能差异的原因

我正在使用MapBox GL JS渲染多达40,000个多边形的地理地图,每个多边形都根据该多边形的“所有者”进行着色。每个拥有者通常有多个多边形,并且每个多边形的“拥有者”可能随时间而改变。业主人数可以从1人到1000人左右。我遇到性能问题(这取决于我如何处理它),所以我尝试了几种不同的策略。

  1. 将数据驱动样式用于“填充颜色”,其中有单个源和单个图层。我已经尝试了多边形ID和“所有者”ID作为数据驱动样式的类别。
  2. 使用过滤图层,其中每个“所有者”具有单个来源和单独的图层。再次,我已经尝试了多边形ID和“所有者”ID作为筛选条件。
  3. 为每个“所有者”使用单独的来源和图层。

选项三具有最佳的绘图速度。当我缩放和平移时,图层渲染速度非常快。但是每当我更改图层的所有者时,我必须调用setData,并且setData会泄漏内存,所以最终会导致页面崩溃。这个问题2607被关闭为不可操作,所以我不期待解决这个问题。

选项一和二与初始缩放画好,但是当我放大时,他们很慢重新绘制瓷砖。我看着锯齿状的低细节瓦片,直到20-30秒后呈现出来。请注意,如果我使用“所有者”ID而不是“多边形”ID,当“所有者”更改会导致内存泄漏时,我仍然需要调用setData。如果我使用多边形ID,则只需在“所有者”更改时更新图层过滤器或填充颜色类别。但是,如果我使用“多边形”ID,我没有得到明显的性能差异,所以我认为没关系。

所以我的问题是为什么选项三要快得多,当我放大渲染?这是否与分配到绘图的工人数量有关?在选项一和二中,有一个单一来源,所以这意味着图纸只使用一名工人?而在选项三中,每个“所有者”都有一个单独的源,所以我有多个工作人员在进行绘图?

+0

看起来与选项3相关的内存泄漏在v0.29.0中已修复。 – jasonpepper

回答

1

我想你会需要各种技术来解决本质上是细节水平(LOD)问题。我做了类似的工作,涉及绘制一个国家的多个地区来表示一个州内的各个地区,您必须调整数据以适合该视图。

我会推荐的第一件事是为您的区域创建不同级别的细节。第一次扫描可以通过移除区域顶点自动完成,区域顶点与其相邻点在直线的几度之内对齐(地理位置)。可以认为这是因为它们在一条直线上去除了许多不会将细节添加到区域边界的小点。由于这可以是一个自动化(甚至预先存储)的步骤,您可以根据缩放级别创建不同级别的细节。

第二个建议是视图空间剔除。也就是说,如果一个区域不在视口内,请不要渲染它!如果你试图完成这个顶点完美,你最终会遇到和以前一样的CPU问题,所以我建议创建一个Region bounding box(如果你只使用轴对齐的查看,建议提出一个建议,因为它是最简单的解)。

如果您需要非轴对齐的区域,只需创建一个边界圆(基于边界顶点的距离与区域的地理中心距离最大)。

我建议你的各种困难是场景复杂性问题的衍生物。解决这个问题,你将有一个更有效的系统来处理。

祝你好运!

+0

感谢您的建议。但在这种情况下,这似乎不是一个实际的解决方案。我们有一个地图项目的结构,它们的类别和用途非常不同,而不是大量的相似几何体。对于我们的异质情况有何建议? – MrMambo007

+0

谢谢你的回应。我将矢量多边形转换为矢量图块,并看到数据驱动样式和过滤图层的性能有了巨大的提升。从本质上讲,矢量贴图通过创建不同级别的细节和视图空间剔除来完成您的建议。 – jasonpepper

2

我建议使用分类数据驱动样式执行data-join。这使您可以从几何中解耦您的数据属性更新。

查看https://www.mapbox.com/mapbox-gl-js/example/data-join/了解如何将浏览器中的JSON数据加入到矢量图片几何图形的示例。这应该可以扩展到100多万个功能。

+1

这种方法的表现非常好。这就是我决定的方法。 – jasonpepper