d3.js D3避免投影超出框架的数据

gpnt7bae  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(126)

我正在做一个D3项目,涉及到一个大的可缩放Map。一切看起来都很好,工作正常,除了当我缩放和平移视图可以得到一点滞后。
我想知道D3是否有办法让我避免投影超出框架的Map数据。如果可能的话,我希望在不牺牲细节的情况下提高性能。任何提示或技巧都将非常感谢!

yx2lnoni

yx2lnoni1#

这里有几个选项,我将把这个问题概括为用d3优化显示大量地理数据的方法。

投影.clipExtent(范围)

这个方法使用一个数组来标记特征的绘制范围的左上角和右下角(在投影/像素坐标空间中)。特征被裁剪到指定的范围。每个点仍然穿过投影,但是你不必绘制它们或者沿着边缘做大圆采样。严格地说,这接近于问题所要求的。

投影.clipAngle(Angular )

上述方法适用于投影空间,而此方法适用于非投影空间。(以度为单位),并根据此Angular 和投影的旋转中心裁剪要素。根据投影的不同,旋转可能是平移Map和居中Map的合适方法。您必须计算给定缩放级别和居中的最大裁剪Angular ,这将在投影到由裁剪Angular 指定的小圆之前裁剪Map。2这通过避免在裁剪之前投影点的需要而改进了上述方法,但是由于小圆很少与视口一致,因此将有一些要素绘制在所需范围之外(尽管少得多)。3上述方法可以与此方法结合使用。
可以使用自定义的预剪切功能来获得更好的结果。这对于圆柱投影比其他投影更容易,以便在投影之前将要素剪切到指定的框中,这将提高效率。

其他选项

  • 矢量图块

矢量图块可以从很多来源获得--尽管我并不特别喜欢d3图块(我一直在研究一个替代方案,但一直忙碌,没有真正关注它)。您仍然需要在每次缩放时加载图块,并在每次平移时加载一些图块,但此选项可以为您提供最大范围的细节和适当的数据分辨率。

  • 边界框

另一种方法是在每个多边形上存储边界框信息(不要在运行中执行)。绘制Map时,过滤与视口有重叠的多边形将只对相关要素进行选择性渲染。根据投影和缩放机制,这可以在投影坐标空间或非投影坐标空间中完成。
这可以通过在两个或更多尺度上加载特征来补充:缩小时,绘制所有要素,而不考虑可见性,但在缩小时以适当的分辨率绘制。当放大超过一定深度时,使用更详细的要素,但根据边界框进行过滤。

  • 画布

我在这里包括这个只是因为SVG有时可能是一个瓶颈,这取决于要绘制的要素的数量和类型。

  • 投影类型

投影类型确实会影响速度,等矩形投影速度快,一些方位角投影速度慢。虽然我只在任何detail中测试了projection.invert(),但投影类型是一个因素。
但是,预投影几何体是最快的,它完全绕过了投影:要素坐标空间以像素为单位。有关该主题的更多信息,请参阅here
结合边界框方法和/或基于当前范围进行裁剪的函数,这可能是一种非常快速的方法。

  • 缩放事件

我根据您的问题添加以下内容:投影放大或不放大的要素所需的时间应该相同。绘图可能是可变的,但投影运行的方式是相同的。这表明您可能使用了.on("zoom"事件。这不是很有效率:平移的每一个动作都需要一次重绘,换句话说,一次平移可能会触发很多次缩放。2这意味着你需要在平移过程中不断地投影特征。
一个简单的解决方案是使用.on("end"事件作为重绘Map的事件,这样我们每次缩放只重绘一次Map。
然而,你可能会变得更复杂。如果你想让Map在整个平移事件中跟随鼠标,你可以使用变换来平移Map,避免需要投影任何东西,然后在缩放结束时,重新投影Map并删除变换。这几乎肯定需要重新考虑你的缩放功能。我'我以前采用了一种类似的方法来确定是否发生了平移,以避免在缩放比例不变(example)时重绘聚类。

相关问题