使用d3在Leaflet地图上绘制SVG人工制品是一种简单的方法,可以将实体地图控制器与d3的强度结合起来。有许多示例和指南,如何实现这一点,两种主要方法似乎是:
在Leaflet"覆盖窗格中添加新的SVG元素"正如博斯托克所说:http://bost.ocks.org/mike/leaflet/
实现一个自定义矢量切片图层,该图层挂钩到Leaflets本机切片层生态系统,如Nelson Minar所示:http://bl.ocks.org/NelsonMinar/5624141
第一种方法通过附加传单类来避免Leaflets基于缩放的缩放,以便在缩放发生时隐藏任何d3元素。当缩放动画结束时,重新计算元素坐标并重新绘制,然后移除隐藏类以再次暴露元素。这有效,但与Leaflet的原生GeoJSON图层相比,放大/缩小的体验不太干净,因为后者支持动画缩放。
第二种方法不包含任何特定于实现的代码来解决缩放行为,但无论如何都以某种方式工作! d3元素在动画缩放期间缩放,然后用下一个缩放级别向量整齐地替换。
我想要实现的是两者的结合。我想绘制基于Geo / TopoJSON的非基于图块的矢量,这些矢量在放大/缩小期间被动画化。我已经摆弄了使用不同的传单css类,不同的事件挂钩,以及以多种方式附加和/或重用SVG元素,但尚未实现类似于使用Leaflet时所经历的行为的行为&# 39; s原生GeoJSON矢量图层。我不想使用原生图层的原因是我想要使用大量其他d3功能,而不是Leaflet实现的一部分。
问题:使用非基于图块的向量组合Leaflet和d3时,是否有人实现了动画缩放?如果是这样 - 怎么样?
答案 0 :(得分:19)
示例强>
我认为this是我通过ZJONSSON组合Leaflet和d3找到的最佳解决方案之一。
d3 +传单整合
在这个例子中,Leaflet地图在这里map._initPathRoot()
作为SVG启动,然后使用d3 var svg = d3.select("#map").select("svg"),
g = svg.append("g");
选择SVG,之后可以获得所有d3乐趣。
在此示例中,宣传单地图事件map.on("viewreset", update);
用于调用update
并在地图viewreset
上转换d3图层。在此之后,d3过渡选项将确定d3层如何对Leaflet地图平移/缩放事件做出反应。
通过这种方式,您可以获得d3 + Leaflet库的全部范围,而无需计算地图边界等麻烦,因为Leaflet可以很好地处理它。
动画矢量缩放
对于动画,最新的Leaflet版本包含Pan and Zoom animation选项。虽然这不像d3那样可自定义,但您可以随时编辑Leaflet src代码以更改转换持续时间! Leaflet GeoJSON矢量图层(L.geoJson
)不需要在Leaflet地图事件(update
)中更新,因为它们已经作为SVG添加到地图中并由Leaflet处理。
请注意,如果实施L.geoJson
,这也意味着您不需要map._initPathRoot()
,因为Leaflet会将图层添加到地图中作为SVG,因此您只需d3.select
它。
还可以在className
图层选项中添加L.geoJson
变量,以便您可以通过CSS或d3.select
通过在Leaflet {{1期间分配的唯一类ID }}