在d3js中寻找具有特定投影的世界地图

时间:2019-02-17 10:05:52

标签: javascript d3.js geo map-projections

我玩过 d3js(v5)地图, 我正在尝试生成这张地图(屏幕截图是从随机网站上截取的), 对于我的特殊情况,无需出示南极洲

enter image description here

我在这里阅读了文档:https://github.com/d3/d3-geo#projections, 并按照说明进行操作并使用了geoMercator,得到了这张平面地图,出于某些原因,该地图在北部的边界处。

enter image description here

获取第一张地图布局的正确方法是什么? 有什么建议吗?

1 个答案:

答案 0 :(得分:3)

您正在查看的投影是Mercator投影。

对于d3.geoMercator(),比例值是从形成投影面的圆柱体的圆周中得出的。比例值是每个弧度的像素数。默认值预计将圆柱的360度拉伸到960像素以上:960/Math.PI/2

对于垂直角距离,没有这样的比例因子,因为当移动到极端经度时,点之间的角距离越来越大,从而极点在y轴上将为±无穷大。由于这种墨卡托投影,尤其是网络墨卡托投影通常在±〜85度处被截断。墨卡托的范围为[-180,85]和[180,-85],是正方形。

此限制已并入d3-geoMercator,其中“定义了默认的projection.clipExtent,以便将世界投影到一个正方形,裁剪成大约±85°的纬度。(docs)”

这意味着,如果要显示960 x 960像素的d3-geoMercator的完整范围,可以使用:

d3.geoMercator()
 .scale(960/Math.PI/2)  // 960 pixels over 2 π radians
 .translate([480,480])  // the center of the SVG/canvas

哪个给了我们

enter image description here

d3-geoMercator的默认中心为[0°,0°],因此,如果我们希望[0°,0°]位于SVG /画布的中间,我们可以平移中心,以便它在中间,翻译为[width/2,height/2]

现在我们正在显示整个世界,我们可以优化以仅显示我们想要的部分。最简单的方法可能只是从svg /画布的底部移开像素。使用上面的代码在画布/ svg高度为700像素(并保持960像素,使用相同的比例和平移)的情况下,我得到:

enter image description here

我没有从这张图片中删除南极洲-碰巧它是被剪掉而不必将其滤除的(这不一定是理想的做法:它仍然被绘制)。

因此,SVG /画布的宽度为960,高度为700,投影比例为960 / Math.PI / 2,平移值为[480,480],似乎是可以的。这些值将针对不同的视口大小一起缩放。

使用地图时,通常会有很多人盯着眼睛以获得所需的视觉效果,调整projection.translate()projection.center()可以帮助将地图移至所需的位置。但是我们可以通过计算来做到这一点。我将在这里讲一种使用projection.fitSize()的方法(尽管如果没有额外的步骤,这将无法解决所需的宽高比)。

Project.fitSize([width,height],geojson)接受一个数组,该数组指定SVG / canvas和geojson对象的尺寸,并调整投影比例并转换值,以便geojson功能包含在SVG / canvas中。 geojson功能可能是您要显示的世界的边界框,因此可以使用:

projection.fitSize([width,height], {
    type: "Polygon",
    coordinates: [[ 
      [-179.999,84] , 
      [-179.999,-57] , 
      [179.999,-57] , 
      [179.999,84], 
      [-179.999,84] 
     ]]
   })

格陵兰岛的北端以北约84度,南端约56度是南美洲的顶端。这样可以确保您想要看到的整个世界都可见。但是,如上所述,这并不考虑纵横比,因此,如果将上述范围限制为正方形尺寸,则仍将显示墨卡托的整个范围。