使用d3和Leaflet实现动态缩放

21
使用d3在Leaflet地图上绘制SVG图形是结合了d3的强大功能和可靠的地图控制器的简单方法。有很多例子和指南可以实现这一点,主要有两种方法:
1. 在Leaflet的“覆盖层面板”上附加一个新的SVG元素,如Bostock在这里演示的那样: http://bost.ocks.org/mike/leaflet/
2. 实现一个自定义矢量切片图层,它可以钩入到Leaflet原生瓦片图层生态系统中,如Nelson Minar在这里演示的那样: http://bl.ocks.org/NelsonMinar/5624141
第一种方法通过附加一个leaflet-class来避免Leaflet基于比例尺的缩放,以便任何d3元素在缩放时都被隐藏。当缩放动画结束时,重新计算元素坐标并重绘,然后移除hide-class以再次显示元素。这种方法有效,但与Leaflet的本地GeoJSON图层相比,缩放效果不够清晰,因为后者支持动画缩放。
第二种方法不包含任何特定于实现的代码来解决缩放行为,但仍然可以工作!在动画缩放期间,d3元素被缩放,然后用下一个缩放级别的矢量替换。

我想要实现的是两者的结合。我想基于Geo/TopoJSON绘制非切片矢量,在缩放时进行动画处理。我尝试使用不同的leaflet css类、不同的事件钩子以及多种方式附加和/或重用SVG元素,但还没有达到与使用Leaflet本机GeoJSON矢量图层时类似的效果。我不想使用本机图层的原因是我想利用许多其他d3功能,这些功能并不是Leaflet实现的一部分。

问题:是否有人已经通过结合Leaflet和d3使用非切片矢量实现了动画缩放?如果有 - 如何实现?


你可能想看一下这个d3地图缩放的示例。请注意,它比其他一些d3缩放示例要慢,因为它在缩放时重新计算地图投影,而不是仅使用图形变换来缩放图像。我没有使用Leaflet的经验,但如果您可以通过Javascript调用设置比例/投影,则可以在重新计算d3地图投影的同时从d3缩放函数中执行该操作。但再次强调,在每个步骤中进行大量重新计算,因此缩放可能不会非常平滑。 - AmeliaBR
谢谢您的提示,但我相信解决方案必须基于纯图形方法来实现实际缩放,而不是在过渡期间计算地理坐标的方法。 - averas
1个回答

19

示例

我认为这个是结合Leaflet和d3的最佳解决方案之一,作者是ZJONSSON

d3 + Leaflet集成

在此示例中,使用SVG初始化Leaflet地图,如下所示:map._initPathRoot(),然后使用d3选择该SVG,如下所示:var svg = d3.select("#map").select("svg"), g = svg.append("g");,接下来可以使用d3进行各种操作。

在此示例中,使用Leaflet地图事件map.on("viewreset", update);来调用update并在viewreset上转换d3图层。之后,d3过渡选项将决定d3图层对Leaflet地图平移/缩放事件的反应。

通过这种方式,您可以完全利用d3 + Leaflet库,而不必计算地图边界等烦恼,因为这些已经被Leaflet很好地处理了。

动画矢量缩放

关于动画,最新的Leaflet发布版包括一个平移和缩放动画选项。虽然这不像d3那样可自定义,但您总可以编辑Leaflet源代码来更改过渡持续时间!Leaflet GeoJSON矢量图层(L.geoJson)不需要在Leaflet地图事件中更新(在update中),因为它们已经以SVG形式添加到地图中,并由Leaflet处理。

请注意,如果实现L.geoJson,这也意味着您不需要map._initPathRoot(),因为Leaflet将该图层添加到地图中,并作为SVG处理,所以您只需d3.select即可。

在Leaflet的L.geoJson图层选项中,也可以添加一个className变量,以便您可以通过CSS或d3.select样式来唯一标识每个要素。


我正在将一个geojson图层添加到leaflet中,但没有创建svg图层? - ratata
Leaflet默认创建SVG,但也有一个可以设置的静态属性http://leafletjs.com/reference.html#path-svg。 - fitzpaddy
1
这个解决方案的一个问题是,当前地图中不可见的d3元素在你移动地图时也不会变得可见。有一个处理此问题的示例,使用一个更大的SVG框架与leaflet一起平移,网址为http://bost.ocks.org/mike/leaflet/ -- 但我尝试过无法在不切换到geoJson的情况下使其正常工作。 - Meekohi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接