【发布时间】:2021-02-07 23:37:11
【问题描述】:
我想从选择的多个 geoJson 路径中获取总质心。 我知道我可以使用path.centroid 获得路径的质心,但我不清楚当我有一组路径时如何获得质心
【问题讨论】:
我想从选择的多个 geoJson 路径中获取总质心。 我知道我可以使用path.centroid 获得路径的质心,但我不清楚当我有一组路径时如何获得质心
【问题讨论】:
如果您使用this answer从路径计算边界框,您只需附加路径的d属性并一起计算它们的边界框。
下面我有一张加拿大萨斯喀彻温省的地图,我不断地将部分添加到选择中并重新计算质心。随着标签变长,您可以看到这一点。
//Width and height
var w = 800;
var h = 800;
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
function getCentroid(element) {
var bbox = element.getBBox();
return [bbox.x + bbox.width / 2, bbox.y + bbox.height / 2];
}
//Load in GeoJSON data
d3.json("https://api.jsonbin.io/b/5f955d1bbd69750f00c34c5e").then(function(json) {
// Rewind the features because they are the wrong way around
json.features = json.features.map(function(feature) {
return turf.rewind(feature, {
reverse: true
});
}).sort(function(a, b) {
return b.properties.name < a.properties.name;
});
var projection = d3.geoMercator().fitSize([w, h], json);
//Define path generator
var path = d3.geoPath()
.projection(projection);
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "steelblue")
.attr("stroke", "white");
var centroids = [];
var p = "";
var description = "";
var tmp = svg.append("path");
json.features.forEach(function(f, i) {
p += path(f);
description += (description ? ", " : "") + f.properties.name;
tmp.attr("d", p);
var centroid = getCentroid(tmp.node());
centroids.push({
x: centroid[0],
y: centroid[1],
description: description
});
});
tmp.remove();
var centroids = svg.selectAll("g")
.data(centroids)
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")"
});
centroids.append("circle")
.attr("r", 5);
centroids.append("text")
.attr("x", 10)
.text(function(d) {
return d.description;
});
});
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
<script src='https://unpkg.com/@turf/turf/turf.min.js'></script>
【讨论】: