给定 geoJSON 对象,将 d3 中的地图居中 [英] Center a map in d3 given a geoJSON object
问题描述
目前在 d3 中,如果您有一个要绘制的 geoJSON 对象,则必须对其进行缩放和平移,以使其达到所需的大小,然后将其平移以使其居中.这是一项非常繁琐的反复试验任务,我想知道是否有人知道获得这些值的更好方法?
Currently in d3 if you have a geoJSON object that you are going to draw you have to scale it and translate it in order to get it to the size that one wants and translate it in order to center it. This is a very tedious task of trial and error, and I was wondering if anyone knew a better way to obtain these values?
例如,如果我有这个代码
So for instance if I have this code
var path, vis, xy;
xy = d3.geo.mercator().scale(8500).translate([0, -1200]);
path = d3.geo.path().projection(xy);
vis = d3.select("#vis").append("svg:svg").attr("width", 960).attr("height", 600);
d3.json("../../data/ireland2.geojson", function(json) {
return vis.append("svg:g")
.attr("class", "tracts")
.selectAll("path")
.data(json.features).enter()
.append("svg:path")
.attr("d", path)
.attr("fill", "#85C3C0")
.attr("stroke", "#222");
});
我到底是如何获得 .scale(8500) 和 .translate([0, -1200]) 而不一点一点的?
How the hell do I obtain .scale(8500) and .translate([0, -1200]) without going little by little?
推荐答案
以下内容似乎大致符合您的要求.缩放似乎没问题.将它应用到我的地图时,有一个小的偏移量.这个小偏移可能是因为我使用 translate 命令将地图居中,而我可能应该使用 center 命令.
The following seems to do approximately what you want. The scaling seems to be ok. When applying it to my map there is a small offset. This small offset is probably caused because I use the translate command to center the map, while I should probably use the center command.
- 创建一个投影和 d3.geo.path
- 计算当前投影的边界
- 使用这些边界来计算比例和平移
- 重新创建投影
在代码中:
var width = 300;
var height = 400;
var vis = d3.select("#vis").append("svg")
.attr("width", width).attr("height", height)
d3.json("nld.json", function(json) {
// create a first guess for the projection
var center = d3.geo.centroid(json)
var scale = 150;
var offset = [width/2, height/2];
var projection = d3.geo.mercator().scale(scale).center(center)
.translate(offset);
// create the path
var path = d3.geo.path().projection(projection);
// using the path determine the bounds of the current map and use
// these to determine better values for the scale and translation
var bounds = path.bounds(json);
var hscale = scale*width / (bounds[1][0] - bounds[0][0]);
var vscale = scale*height / (bounds[1][1] - bounds[0][1]);
var scale = (hscale < vscale) ? hscale : vscale;
var offset = [width - (bounds[0][0] + bounds[1][0])/2,
height - (bounds[0][1] + bounds[1][1])/2];
// new projection
projection = d3.geo.mercator().center(center)
.scale(scale).translate(offset);
path = path.projection(projection);
// add a rectangle to see the bound of the svg
vis.append("rect").attr('width', width).attr('height', height)
.style('stroke', 'black').style('fill', 'none');
vis.selectAll("path").data(json.features).enter().append("path")
.attr("d", path)
.style("fill", "red")
.style("stroke-width", "1")
.style("stroke", "black")
});
这篇关于给定 geoJSON 对象,将 d3 中的地图居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!