Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3避免投影超出帧的数据_Javascript_D3.js_Map Projections - Fatal编程技术网

Javascript D3避免投影超出帧的数据

Javascript D3避免投影超出帧的数据,javascript,d3.js,map-projections,Javascript,D3.js,Map Projections,我正在做一个D3项目,涉及一个大的可缩放地图。一切看起来都很好,工作也很好,只是当我缩放和平移时,视图可能会有点滞后 我想知道D3是否有办法避免投影超出帧的地图数据。如果可能的话,我希望在不牺牲细节的情况下提高性能。任何提示或提示都将不胜感激 这里有几个选项。我将把这个问题概括为使用d3优化显示大量地理数据的方法 投影。clipExtent(范围) 此方法采用一个阵列,标记特征绘制范围的左上角和右下角(在投影/像素坐标空间中)。将要素剪裁到指定的范围。每个点仍然贯穿投影,但您不必绘制它们,也不必

我正在做一个D3项目,涉及一个大的可缩放地图。一切看起来都很好,工作也很好,只是当我缩放和平移时,视图可能会有点滞后


我想知道D3是否有办法避免投影超出帧的地图数据。如果可能的话,我希望在不牺牲细节的情况下提高性能。任何提示或提示都将不胜感激

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

投影。clipExtent(范围)

此方法采用一个阵列,标记特征绘制范围的左上角和右下角(在投影/像素坐标空间中)。将要素剪裁到指定的范围。每个点仍然贯穿投影,但您不必绘制它们,也不必沿边进行大圆采样。严格地说,这接近于问题的要求

投影。clipAngle(角度)

上述方法适用于投影空间,而此方法适用于未投影空间。此方法采用表示角度(以度为单位)的值,并基于此角度和投影的旋转中心剪裁特征。根据您的投影,旋转可能是平移和居中地图的合适方法。您必须计算给定缩放级别和居中的最大剪辑角度,这将在投影到剪辑角度指定的小圆之前剪辑贴图。通过避免在剪裁之前投影点,这在上述方面有所改进,但由于小圆圈很少与视口一致,因此会绘制一些超出所需范围的特征(尽管要小得多)。上述内容可与此方法相结合

可以制作自定义预剥离函数以获得更好的结果。为了在投影之前将特征剪裁到指定的框中,柱面投影比其他投影更容易,这将提高效率

其他选项

  • 矢量图块
矢量图块可以从许多来源获得——尽管我并不特别关心d3图块(我一直在研究另一种选择,但太忙了,没有时间真正关注它)。您仍然需要在每次缩放时加载平铺,在每次平移时加载一些平铺,但此选项为您提供了最大范围的细节和适当的数据分辨率

  • 边界框
上述方法的一种替代方法是在每个多边形上存储边界框信息(不要在运行时执行)。绘制地图时,过滤与视口有任何重叠的多边形将只启用相关特征的选择性渲染。根据投影和缩放机制,这可以在投影或未投影的坐标空间中完成

这可以通过以两个或更多比例加载特征来实现:缩小所有特征的绘制与可见性无关,但在缩小时以适当的分辨率进行。放大某个深度时,使用更详细的特征,但基于边界框进行过滤

  • 帆布
我之所以在这里包括这一点,是因为SVG有时会成为关键点,具体取决于绘制的特征的数量和类型。切换到画布可能是一种改进

  • 投影类型
投影类型不影响速度,等矩形投影速度快,某些方位投影速度慢。虽然我只测试了any中的
projection.invert()
,但投影类型是一个因素

预投影几何体是所有几何体中最快的,它完全绕过了投影:特征坐标空间以像素为单位。有关该主题的更多信息,请参阅

结合边界框方法和/或基于当前范围剪裁的函数,这可能是一种非常快速的方法

  • 缩放事件
我根据你问题的内容添加了这一点:投影特征是否需要放大的相同时间。图形可能是可变的,但投影的运行方式是相同的。这表明您可能正在使用
.on(“缩放”
事件)。这不是很有效:平移事件的每一次勾选都需要重新绘制,换句话说,单个平移可能会触发许多缩放事件。这意味着您需要在平移期间几乎不间断地投影特征

一个简单的解决方案是使用
.on(“end”
事件作为重绘地图的事件。这样,我们每次缩放只重绘一次地图


但是,您可能会变得更复杂。如果您想让地图在整个平移事件中跟随鼠标,您可以使用变换来平移地图,避免投影任何内容,然后在缩放结束时,重新投影地图并删除变换。这几乎肯定需要重新考虑缩放功能。我采取了在确定是否发生平移以避免在缩放比例不变时重画簇时使用类似的方法().

我想您应该使用进入/退出模式。是吗?@MichaelRovinsky是的,这是正确的。下面是一个使用坐标过滤器渲染50K对象的示例:查看第108-123行。如果您需要更多信息,请告诉我help@MichaelRovinsky好的,我想我明白了它的要点。把这个例子从简单的圆圈改成简单的圆圈需要一些时间国家多边形数据,但我可以。基本上只计算元素是否在框架内。如果不在框架内,则将其从画布上移除。哇,太好了,非常感谢!添加
projection.clipExtent(extent)
projection.clipAngle(angle)
立即提高了性能!我还将尝试边界框的想法。我还发现你关于剪切投影的其他帖子非常有用!