墨卡托预测

墨卡托投影是地图中最容易识别的投影之一。像所有地图投影一样,它具有失真,对于墨卡托,投影这在极地地区最为明显。它是一个圆柱形投影,经线垂直运行,纬度水平延伸。

比例取决于你的 svg 的大小,在这个例子中,所有使用的比例都是 960 像素宽,450 像素高的 svg。

下面的地图显示了天梭的墨卡托投影的 Indicatrix ,每个圆圈实际上都是相同的尺寸,但投影显然有些比其他更大: StackOverflow 文档

这种失真是因为投影试图避免地图的一维拉伸。随着经线开始在北极和南极合并,它们之间的距离开始接近零,但是投影的表面是矩形的(不是地图,虽然它也是矩形)并且不允许改变距离在投影中的经络之间。这将沿着极点附近的 x 轴拉伸特征,扭曲它们的形状。为了解决这个问题,墨卡托伸展 y 轴以及接近极点,这使得指标呈圆形。

上面地图的投影基本上是默认的墨卡托投影向上移动了一点:

var projection = d3.geoMercator()
    .scale(155)
    .center([0,40]) // Pan north 40 degrees
    .translate([width/2,height/2]);

要使投影在具有已知纬度和已知经度的给定点上居中,你可以通过指定中心轻松平移到该点:

var projection = d3.geoMercator()
    .center([longitude,latitude])

这将平移到投影表面上的那个特征(但不是缩放)(看起来像上面的地图)。

比例需要根据感兴趣的区域进行调整,较大的数字等于较大的特征(较大的放大程度),较小的数字则相反。缩小可以是一个很好的方法,让你的方向看你的功能相对于你所关注的点 - 如果你找不到它们。

由于墨卡托投影的性质,赤道附近或低纬度地区的这种投影效果最好,而极地区域可能会高度扭曲。失真甚至沿着任何水平线,因此宽但不高的区域也可能是好的,而在其北极和南极之间具有大的差异的区域具有更多的视觉失真。

例如,对于印度,我们可以使用:

var projection = d3.geoMercator()
    .scale(800)
    .center([77,21])
    .translate([width/2,height/2]);

这给了我们(再次使用天梭的指示器显示失真): StackOverflow 文档

这具有低水平的失真,但是圆圈的大小基本相同(你可以看到顶部两行之间的重叠比底部两行更大,因此可以看到失真)。总的来说,地图显示了印度熟悉的形状。

区域内的变形不是线性的,它极向夸大了两极,因此加拿大北极和南极的距离相当远,并且位置相当接近极点意味着扭曲可能是站不住脚的:

var projection = d3.geoMercator()
    .scale(225)
    .center([-95,69.75])
    .translate([width/2,height/2]);

StackOverflow 文档

这一预测使得格陵兰岛看起来像加拿大一样大,而实际上加拿大的面积几乎是格陵兰岛的五倍。这只是因为格陵兰岛比加拿大的大部分地区更北(对不起安大略省,我似乎已经切断了你的一些南极)。

由于 y 轴在墨卡托的极点附近相当大,因此该投影使用了加拿大地理中心以北的一个点。如果处理高纬度区域,你可能需要定制中心点以考虑此拉伸。

如果你需要极地区域的墨卡托投影,有一种方法可以最大限度地减少失真并仍然使用墨卡托投影。你可以通过旋转地球来实现此目的。如果你在默认墨卡托上旋转 x 轴,你会看到它向左或向右平移(你只需在你投射到的圆柱体中旋转地球仪),如果你改变了默认墨卡托的 y 轴,你可以将地球转向侧面或任何其他角度。这是一个旋转 -90 度的墨卡托:

var projection = d3.geoMercator()
.scale(155)
.rotate([0,-90]);
.translate([width/2,height/2]);

StackOverflow 文档

指标点与上面的第一张地图位于相同的位置。当达到地图的顶部或底部时,失真仍会增加。如果地球围绕[0,0]的北极和[180,0]处的南极旋转,这就是默认墨卡托地图的显示方式,旋转已将我们投射的圆柱体转向 90 度相对于两极。注意两极不再具有难以保持的变形,这提供了另一种方法来投射极点附近的区域而不会有太多的区域变形。

再次以加拿大为例,我们可以将地图旋转到中心坐标,这样可以最大限度地减少区域内的失真。为此,我们可以再次旋转到中心点,但这需要一个额外的步骤。通过居中我们平移到一个特征,通过旋转,我们将地球移动到我们之下,所以我们需要我们的居中坐标的负数:

var projection = d3.geoMercator()
    .scale(500)
    .rotate([96,-64.15])
    .translate([width/2,height/2]);    

StackOverflow 文档

请注意,天梭的指示器现在在区域中显示出低失真。比例因子也比以前大得多,因为加拿大现在位于投影的原点,并且沿着地图中间的特征小于顶部或底部(参见上面的第一个指标)。我们不需要居中,因为这个投影的中心点或原点位于 [-96,64.15],居中会让我们离开这一点。