【问题标题】:D3: zoom to bounding box with d3-tilesD3:使用 d3-tiles 缩放到边界框
【发布时间】:2018-06-08 16:13:33
【问题描述】:

我已经成功地将 D3(矢量)地图分层到 d3-tile(光栅)地图之上,该地图从 Mapbox 中提取瓦片。手动缩放效果完美,矢量和光栅同步。

我现在正在尝试实现 Mike Bostock 'zoom-to-bounding-box' 功能,通过该功能,应用程序会在用户单击时放大到所需的国家/地区。我想我快到了,但现在似乎不匹配,地图缩小到外太空,可以这么说。

我已经在jsfiddle 中重现了这个问题。

我需要在“缩放”功能中进行哪些修改,以使地图按预期正确缩放?我认为这就是问题所在:

  vector.selectAll("path")
    .attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
    .style("stroke-width", 1 / transform.k);

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    编辑:看起来主要问题只是投影的更新

    使用常量投影

    这里的主要问题是您正在根据缩放和计算边界框来更改投影。

    放大后,你有这条线:

    projection.scale...
    

    您似乎正在尝试根据缩放来更新投影,但平移和缩放已由 svg 元素的 transform 属性处理。

    投影改为用于将球面地理坐标转换为二维空间。它用于计算一个国家的边界​​,如果它发生变化,边界就会移动,这可能是无意的。删除此投影更新可以让您大部分时间到达那里。

    另一个大问题是您将点击处理程序中的比例限制为比您需要的值低很多的值(例如,您将比例限制为最大 8,但初始比例为 4096)。

    移除限制和投影更新应该可以让您点击放大国家/地区。但我们还没有完成!

    另一个问题是您的reset 函数不会重置为原始视图,这会使其缩小到远处。使用初始缩放设置而不是 d3.zoomIdentity 可以解决问题。

    这些编辑的结果在这里:https://jsfiddle.net/m7cn0p47/99/

    可选:合并转换

    更改许多 DOM 节点通常效率低下。在这种情况下,您将更改 zoomed 中的每个路径向量。将转换应用到一个 g 元素(在本例中为 ID 为 vectorg 元素)通常更有效。

    代替:

    vector.selectAll("path")
      .attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
      .style("stroke-width", 1 / transform.k);
    

    你可以简单的改成:

    vector
      .attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
      .style("stroke-width", 1 / transform.k);
    

    您还必须从 CSS 中的路径中删除 stroke-width,因为它正在覆盖它。

    以下是这些更改和更正的更新小提琴:https://jsfiddle.net/m7cn0p47/96/

    【讨论】:

    • 史蒂夫,这是一个非常彻底和全面的答案。我非常感谢花时间分享这个。谢谢。
    • 感谢您的客气话——很高兴它成功了!
    • 你好 Alex - 只是一个简单的问题。我一直在使用以下图块集修改您的代码:.tiles.mapbox.com/v3/mapbox.natural-earth-2/。我如何将您的缩放调整为边界框脚本,以便视口不会在更高的缩放级别显示“不可用”图块?这个想法是缩放应该设置在可以存在并因此显示图块的最大 k 处...?
    • Lex,我针对上述问题提出了一个新问题。您可以在这里找到它 - 您的见解将不胜感激! stackoverflow.com/questions/50834044/…
    • 嗨,我不确定你是否打算为 Lex 做这个,但他的回答是另一个。我确实回答了您更新的问题,但我不会在 Stack Overflow 上几周。
    【解决方案2】:

    在您的示例中,您将转换直接应用于父 SVG。在 bl.ocks 示例中,他们在 svg 内创建了一个组 g 以应用转换。

    在您的缩放功能中,您正在使用 css 转换,就像 bl.ocks 单击缩放示例一样。更新到clickHandler中的css转换函数和示例中相同的缩放计算,点击缩放正常工作。

    https://jsfiddle.net/bamboo/m7cn0p47/3/

    缩放在状态或更多原子部分上效果更好。美国、法国、西班牙等地都有偏远的岛屿或阿拉斯加。当它实际上只包括周围区域时,它可以产生放大缩小的效果。

    【讨论】:

    • 您好 Lex,感谢您提供看起来很有希望的答案。你确定你引用了正确的小提琴吗?您提到的美国在非洲上空分层,似乎没有按预期扩展。如果我遗漏了什么,请告诉我,再次感谢。
    • Lex,这又是非常有前途的,我正在通过你的脚本来了解你做了什么。但是,存在一个问题,当您放大到国家/地区时,您不会在放大时刷新图块。您的脚本只是“冻结”栅格图层,可以这么说,并且不会将更详细的图块显示为当您缩小时,您会变得更近,反之亦然。这是一个小问题吗?我不知道。请检查以下内容以了解我对刷新图块的含义:plnkr.co/edit/8muX27u0kSnuPwtmmZlU?p=preview
    • 有什么想法吗?一直在修改您的代码,但无法使其正常工作... :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 2017-01-31
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    相关资源
    最近更新 更多