我是d3的新手-会尝试解释我的理解,但不确定我是否正确。
秘密是知道某些方法将在制图空间(纬度,经度)上运行,而另一些方法将在笛卡尔空间(屏幕上的x,y)上运行。制图空间(我们的星球)(几乎)是球形的,而笛卡尔空间(屏幕)是平坦的-为了将一个地图空间映射到另一个地图空间,您需要一种算法,称为投影。这个空间太短,无法深入到迷人的投影主题以及它们如何扭曲地理特征以将球面变为平面方面。有些设计用于节省角度,有些设计用于节省距离,依此类推-总是存在一个折衷方案(Mike Bostock 收集了大量示例)。
在d3中,投影对象具有中心属性/设置器,以地图单位给出:
projection.center([位置])
如果指定了center,则将投影的中心设置到指定的位置(经度和纬度以度为单位的两元素数组),然后返回投影。如果未指定center,则返回当前中心,默认为⟨0°,0°⟩。
还有一个以像素为单位的平移-投影中心相对于画布的位置:
projection.translate([point])
如果指定了point,则将投影的平移偏移量设置为指定的两元素数组[x,y]并返回投影。如果未指定point,则返回当前平移偏移量,默认为[480,250]。平移偏移量确定投影中心的像素坐标。默认平移偏移将⟨0°,0°⟩放置在960×500区域的中心。
当我想在画布上居中放置特征时,我想将投影中心设置为特征边界框的中心-这在使用墨卡托时对我有用对我的国家(巴西)(WGS 84,在谷歌地图中使用)时,这对我有用,从未使用其他投影和半球进行过测试。您可能需要针对其他情况进行调整,但是如果您遵循了这些基本原则,就可以了。
例如,给定一个投影和路径:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
bounds
从中的方法以像素为单位path
返回边界框。使用它来找到正确的比例,将以像素为单位的尺寸与以地图单位为单位的尺寸进行比较(0.95使您在最适合宽度或高度的基础上留出5%的边距)。这里的基本几何形状,计算在对角相对的角处给出的矩形的宽度/高度:
var b = path.bounds(feature),
s = 0.9 / Math.max(
(b[1][0] - b[0][0]) / width,
(b[1][1] - b[0][1]) / height
);
projection.scale(s);
使用该d3.geo.bounds
方法以地图单位查找边界框:
b = d3.geo.bounds(feature);
将投影的中心设置为边界框的中心:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
使用translate
方法将地图的中心移动到画布的中心:
projection.translate([width/2, height/2]);
现在,您应该将地图中心的地图项以5%的边距缩放。