D3:缩放到带有d3-tiles的边界框 [英] D3: zoom to bounding box with d3-tiles

查看:107
本文介绍了D3:缩放到带有d3-tiles的边界框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地将D3(矢量)地图分层到了从Mapbox提取图块的d3瓦片(栅格)地图上.手动缩放效果完美,矢量和栅格都同步.

I have successfully layered a D3 (vector) map on top of a d3-tile (raster) map that pulls tiles from Mapbox. The manual zoom works perfectly, and both vector and raster are in sync.

我现在正在尝试实施Mike Bostock'缩放到边界框"功能,使应用程序在用户单击时放大所需的国家/地区.我想我快到了,但是现在似乎不匹配了,可以这么说,地图缩小到了外太空.

I am now trying to implement the Mike Bostock 'zoom-to-bounding-box' feature, whereby the application zooms on a desired country upon user click. I think I am nearly there, but right now there seems to be a mismatch and the map zooms out into outer space, so to speak.

我已在此 jsfiddle 中重现了该问题.

I have reproduced the issue in this jsfiddle.

我需要在缩放"功能中进行哪些修改,以使地图正确缩放并达到预期效果?我认为这是问题所在:

What do I need to amend in the 'zoomed' function so that the map zooms correctly and as expected? I think this is where the issue lies:

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

推荐答案

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

Edit: It looks like the main issue is just the update of projection

这里的主要问题是您正在基于缩放更改投影并从中计算出边界框.

The main issue here is that you're changing the projection based on zooming and calculating the bounding box from them.

在缩放中,您具有以下行:

In zoomed, you have this line:

projection.scale...

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

It seems like you're trying to update the projection based on your zooming, but translating and scaling are already handled by the transform attribute of the svg elements.

改为使用投影将球形地理坐标转换为2d空间.它用于计算国家/地区的范围,如果它发生变化,范围会四处移动,这可能是意料之外的.删除此投影更新会带您大部分去那里.

The projection is instead used to translate spherical geographic coordinates into 2d space. It's used to calculate the bounds of a country and if it changes, the bounds move around, which is probably unintended. Removing this projection update gets you most of the way there.

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

The other big issue is that you clamp the scale in your click handler to values that are a lot lower than what you need (for instance you clamp the scale to a max of 8, but have an initial scale of 4096).

卸下固定夹和更新投影,应使您单击放大的国家/地区.但是我们还没有完成!

Removing the clamp and the projection update should get you click-to-zoom on countries. But we're not done yet!

另一个问题是您的reset函数不会重置为原始视图,因此会缩小到远处.使用初始缩放设置代替d3.zoomIdentity解决了该问题.

Another issue is that your reset function does not reset to the original view, which makes it zoom off into the distance. Using the initial zoom settings instead of d3.zoomIdentity addresses the problem.

这些修改的结果在这里: https://jsfiddle.net/m7cn​​0p47/99/

The results of these edits are here: https://jsfiddle.net/m7cn0p47/99/

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

It's generally inefficient to alter many DOM nodes. In this case you're altering each of your path vectors in zoomed. Applying the transform to one g element (in this case the g element with id vector) instead is usually more efficient.

代替:

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,因为它会覆盖它.

You'll also have to remove stroke-width from path in the CSS because it is overwriting it.

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

Here's an updated fiddle with those changes and corrections: https://jsfiddle.net/m7cn0p47/96/

这篇关于D3:缩放到带有d3-tiles的边界框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆