【问题标题】:Achieving animated zoom with d3 and Leaflet使用 d3 和 Leaflet 实现动画缩放
【发布时间】:2014-02-08 13:56:18
【问题描述】:

使用 d3 在 Leaflet 地图上绘制 SVG 人工制品是获得结合 d3 优势的实体地图控制器的简单方法。有许多示例和指南来说明如何实现这一点,两种主要方法似乎是:

  1. 在 Leaflet 的“覆盖窗格”上附加一个新的 SVG 元素,如 Bostock 所示:http://bost.ocks.org/mike/leaflet/

  2. 实施一个自定义矢量切片层,该层与 Leaflets 原生切片层生态系统挂钩,正如 Nelson Minar 所展示的那样:http://bl.ocks.org/NelsonMinar/5624141

第一种方法通过附加一个传单类来避免传单基于比例的缩放,以便在缩放发生时隐藏任何 d3 元素。当缩放动画结束时,元素坐标被重新计算并重新绘制,之后隐藏类被移除以再次暴露元素。这可行,但提供的放大/缩小体验不如 Leaflet 的原生 GeoJSON 层,因为后者支持动画缩放。

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

我想要实现的是两者的结合。我想绘制基于 Geo/TopoJSON 的非基于瓦片的矢量,这些矢量在放大/缩小期间动画。我一直在摆弄使用不同的传单 css 类、不同的事件挂钩以及以多种方式附加和/或重用 SVG 元素,但尚未实现与使用 Leaflet 的本机 GeoJSON 向量时所经历的行为类似的行为层。我不想使用本机层的原因是我想利用大量其他 d3 功能,这些功能根本不是 Leaflet 实现的一部分。

问题:有没有人在使用非平铺矢量结合 Leaflet 和 d3 时实现动画缩放?如果是这样 - 如何?

【问题讨论】:

  • 您可能想查看 (this example) d3 地图上的动画缩放。请注意,它比其他一些 d3 缩放示例要慢,因为它在缩放时重新计算地图投影,而不是仅使用图形变换来缩放图像。我对 Leaflet 没有任何经验,但是如果您可以使用 Javascript 调用设置比例/投影,那么您可以在重新计算 d3 地图投影的同时从 d3 缩放功能中执行此操作。但同样,每一步都需要大量重新计算,因此缩放可能不会非常流畅。
  • 感谢您的提示,但是是的,我认为解决方案必须基于纯图形方法进行实际缩放,而不是在过渡期间计算地理坐标。

标签: d3.js leaflet


【解决方案1】:

示例

我认为this 是我找到的结合 Leaflet 和 d3 的最佳解决方案之一,ZJONSSON

d3 + Leaflet 集成

在本例中,Leaflet 地图在此处map._initPathRoot() 初始化为 SVG,然后使用 d3 var svg = d3.select("#map").select("svg"), g = svg.append("g"); 选择 SVG,之后就可以享受 d3 的所有乐趣了。

在本例中,Leaflet 地图事件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 它即可。

还可以在L.geoJson 图层选项中添加className 变量,这样您就可以通过CSS 或d3.select 通过在Leaflet onEachFeature 期间分配的唯一类ID 来设置功能。

【讨论】:

  • 我正在向传单添加一个 geojson 层,但没有创建 svg 层?
  • Leaflet 默认创建 SVG 但也有一个静态属性可以设置leafletjs.com/reference.html#path-svg
  • 此解决方案的一个问题是,在您平移时,当前地图中不可见的 d3 元素将不可见。有一个使用更大的 SVG 框架处理此问题的示例,该框架在 bost.ocks.org/mike/leaflet 处使用传单平移 - 但如果不切换到 geoJson,我将无法使其工作。
猜你喜欢
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多