使用d3和Leaflet实现动画缩放

时间:2014-01-19 11:50:07

标签: d3.js leaflet

使用d3在Leaflet地图上绘制SVG人工制品是一种简单的方法,可以将实体地图控制器与d3的强度结合起来。有许多示例和指南,如何实现这一点,两种主要方法似乎是:

  1. 在Leaflet"覆盖窗格中添加新的SVG元素"正如博斯托克所说:http://bost.ocks.org/mike/leaflet/

  2. 实现一个自定义矢量切片图层,该图层挂钩到Leaflets本机切片层生态系统,如Nelson Minar所示:http://bl.ocks.org/NelsonMinar/5624141

  3. 第一种方法通过附加传单类来避免Leaflets基于缩放的缩放,以便在缩放发生时隐藏任何d3元素。当缩放动画结束时,重新计算元素坐标并重新绘制,然后移除隐藏类以再次暴露元素。这有效,但与Leaflet的原生GeoJSON图层相比,放大/缩小的体验不太干净,因为后者支持动画缩放。

    第二种方法不包含任何特定于实现的代码来解决缩放行为,但无论如何都以某种方式工作! d3元素在动画缩放期间缩放,然后用下一个缩放级别向量整齐地替换。

    我想要实现的是两者的结合。我想绘制基于Geo / TopoJSON的非基于图块的矢量,这些矢量在放大/缩小期间被动画化。我已经摆弄了使用不同的传单css类,不同的事件挂钩,以及以多种方式附加和/或重用SVG元素,但尚未实现类似于使用Leaflet时所经历的行为的行为&# 39; s原生GeoJSON矢量图层。我不想使用原生图层的原因是我想要使用大量其他d3功能,而不是Leaflet实现的一部分。

    问题:使用非基于图块的向量组合Leaflet和d3时,是否有人实现了动画缩放?如果是这样 - 怎么样?

1 个答案:

答案 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 }}