我一直在尝试根据以下示例制作具有缩放到边界框功能的 map :https://bl.ocks.org/mbostock/9656675 .
但对于有岛屿的城市,缩放会转到所选陆地的边界框,而不是城市的边界框。
我发现在我的数据中,具有多个被水隔开的区域的城市由具有相同名称标签的多个多边形组成,而不是像上面 Mike Bostocks 示例中的单个多边形。
我设法解决了填充区域的问题,因此如果您单击其中一个小岛,错误会变得更加明显,但我无法弄清楚如何正确缩放到市政当局的边界框而不是土地面积。
我尝试寻找不同的方法来根据区域名称过滤或子集特征集合,但我的解决方案最终都给我一个错误的数据类型,或者一个从 -infinity 到 infinity 的边界框。
总而言之,预期的行为是缩放到突出显示区域的边界框而不是所选陆地。
这是我到目前为止的 map :http://plnkr.co/edit/iywWsM9RLs7UzI40q66M?p=preview
我放慢了缩放速度,这样更容易发现错误,希望不会太烦人。
这是我怀疑出现问题的代码段。
function clicked(d) {
if (d.properties.KOMNAVN == kommune) return reset();
d3.selectAll("path")
.attr("fill", "teal");
kommune = d.properties.KOMNAVN;
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = Math.max(1, Math.min(zoomExtent, 0.95 / Math.max(dx / w, dy / h))),
translate = [w / 2 - scale * x, h / 2 - scale * y];
svg.transition()
.duration(4000)
.call(zoom.transform, d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale));
d3.selectAll("path").filter(function(d) {
return d.properties.KOMNAVN == kommune
})
.attr("fill", "darkred");
}
提前致谢!
最佳答案
path.bounds
(或 projection.fitSize
和 projection.fitExtent
)就此而言,需要一个 geojson 对象,它可以是特征集合。为这个函数提供一个数组会导致问题。
特征集合如下所示:
{
"type":"FeatureCollection",
"features": features
}
其中 features 是一组特征类型。
您的数据集有一个特征集合,您可以过滤这些特征:
var filteredFeatures = data.features.filter(function(feature) {
return feature.properties.property == criteria
})
然后您可以使用这些过滤后的特征创建一个新的特征集合。在您的情况下,这可能看起来像:
var filteredFeatures = json.features.filter(function(feature) {
return feature.properties.KOMNAVN == d.properties.KOMNAVN;
})
var filteredFeatureCollection = {
"type":"FeatureCollection",
"features":filteredFeatures
}
不,您可以将这个新的特征集合发送到 path.bounds。
请注意,对于您的示例,我已将点击函数移动到 d3.json 的回调函数中,以便 json
变量的范围涵盖点击函数。
这是一个 updated plunker.
关于javascript - 如何将特征集合过滤为可与 path.bounds() 一起使用的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48424330/