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

问题描述 投票:3回答:1

我玩过d3js(v5)地图,我正在尝试生成这张地图(截图是从随机网站上截取的),对于我的特殊情况,没有必要展示南极洲。

enter image description here

我在这里阅读了文档:https://github.com/d3/d3-geo#projections,并按照说明使用了geoMercator,得到了这个平面地图,由于某种原因在北部被截止。

enter image description here

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

javascript d3.js geo map-projections
1个回答
3
投票

你正在看的投影是Mercator投影。

使用d3.geoMercator(),比例值来自形成投影表面的圆柱的圆周。比例值是每弧度的像素数。默认值预计将圆柱体的360度拉伸超过960像素:960/Math.PI/2

对于垂直角距离,没有这样的缩放因子,当移动到极端经度时,点之间的角距离越来越夸大,使得极点在y轴上处于±无穷大。由于这个墨卡托,特别是网络墨卡托经常被截断在±85度。在[-180,85]和[180,-85]的范围内,墨卡托是方形的。

这个限制被合并到d3-geoMercator中,“定义一个默认的projection.clipExtent,使得世界被投影到一个正方形,被剪切到大约±85°纬度。(docs)”

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

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 / canvas的底部砍掉像素。使用上面的代码,画布/ svg高度为700像素(并保持960像素,使用相同的比例和翻译),我得到:

enter image description here

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

因此,宽度为960,高度为700,投影比例为960 / Math.PI / 2且平移为[480,480]的SVG / Canvas似乎没问题。对于不同的视图端口大小,这些值将一起缩放。

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

Project.fitSize([width,height],geojson)获取一个数组,指定SVG / canvas和geojson对象的尺寸,并调整投影比例和转换值,以便geojson功能包含在SVG /画布中。 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度大致是南美洲的尖端。这将确保您想要看到的世界的整个部分都是可见的。但是,如上所述,这不考虑方面,因此如果将上述范围约束为方形尺寸,您仍将显示墨卡托的完整范围。

© www.soinside.com 2019 - 2024. All rights reserved.