基于此示例,我一直在尝试使用缩放到边界框功能制作地图:https://bl.ocks.org/mbostock/9656675。
但是对于有岛屿的城市,缩放到选定的陆地的边界框而不是市政的边界框。
我发现在我的数据中,由水分隔的多个区域的市政区由多个具有相同名称标签的多边形组成,而不是像上面Mike Bostocks示例中的单个多边形。
我设法解决了填充区域的问题,所以如果点击其中一个小岛,错误会变得更加明显,但我无法弄清楚如何正确缩放到市政区的边界框而不是土地面积。
我尝试寻找基于areanames过滤或子集featurecollection的不同方法,但我的解决方案最终都给我一个错误的数据类型,或者从-infinity到infinity的边界框。
总而言之,预期的行为是缩放转到突出显示区域的边界框而不是选定的大陆。
到目前为止,这是我的地图: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");
}
提前致谢!
答案 0 :(得分:1)
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。
请注意,对于您的示例,我已将click函数移动到d3.json的回调函数中,以便json
变量的范围涵盖click函数。