在 d3js 中寻找具有特定投影的世界地图
Looking for a world map with a specific projection in d3js
我玩过 d3js (v5) 地图,
我正在尝试生成这张地图(屏幕截图取自随机网站),
对于我的特殊情况,不需要呈现南极洲。
我已阅读此处的文档:https://github.com/d3/d3-geo#projections,
并按照说明使用 geoMercator,得到了这张平面地图,由于某种原因,它在北上 处有 截止点。
获取第一张地图布局的正确方法是什么?
有什么建议吗?
您正在查看的投影是 Mercator 投影。
对于d3.geoMercator()
,比例值是从构成投影面的圆柱体的周长导出的。比例值是每弧度的像素数。默认值预期将圆柱体的 360 度拉伸超过 960 像素:960/Math.PI/2
。
对于垂直angular距离,没有这样的比例因子,当一个人移动到极端经度时,点与点之间的angular距离越来越大,以至于极点将在±无穷大在 y 轴上。由于这个墨卡托,尤其是 web 墨卡托经常被截断在 ±~85 度。范围为 [-180,85] 和 [180,-85],墨卡托是正方形。
此限制已纳入 d3-geoMercator
,其中 "Defines a default projection.clipExtent such that the world is projected to a square, clipped to approximately ±85° latitude. (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
这给了我们:
d3-geoMercator默认的中心是[0°,0°],所以如果我们想让[0°,0°]在SVG/canvas的中间,我们平移中心,使其位于中间,平移为 [width/2,height/2]
现在我们正在展示整个世界,我们可以优化以仅展示我们想要的部分。最简单的方法可能只是从 svg/canvas 的底部去掉像素。使用上面的代码,canvas/svg 高度为 700 像素(并保持 960 像素,使用相同的缩放和平移)我得到:
我没有从这张图片中删除南极洲 - 它只是碰巧被切断而不必过滤掉它(这不一定是理想的做法:它仍然被绘制)。
因此,SVG/Canvas 宽度 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 度大致是南美洲的尖端。这将确保您想要看到的整个世界部分都是可见的。但是,如上所述,这不考虑方面,因此如果您将上述范围限制为方形尺寸,您仍将显示墨卡托的完整范围。
我玩过 d3js (v5) 地图, 我正在尝试生成这张地图(屏幕截图取自随机网站), 对于我的特殊情况,不需要呈现南极洲。
我已阅读此处的文档:https://github.com/d3/d3-geo#projections, 并按照说明使用 geoMercator,得到了这张平面地图,由于某种原因,它在北上 处有 截止点。
获取第一张地图布局的正确方法是什么? 有什么建议吗?
您正在查看的投影是 Mercator 投影。
对于d3.geoMercator()
,比例值是从构成投影面的圆柱体的周长导出的。比例值是每弧度的像素数。默认值预期将圆柱体的 360 度拉伸超过 960 像素:960/Math.PI/2
。
对于垂直angular距离,没有这样的比例因子,当一个人移动到极端经度时,点与点之间的angular距离越来越大,以至于极点将在±无穷大在 y 轴上。由于这个墨卡托,尤其是 web 墨卡托经常被截断在 ±~85 度。范围为 [-180,85] 和 [180,-85],墨卡托是正方形。
此限制已纳入 d3-geoMercator
,其中 "Defines a default projection.clipExtent such that the world is projected to a square, clipped to approximately ±85° latitude. (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
这给了我们:
d3-geoMercator默认的中心是[0°,0°],所以如果我们想让[0°,0°]在SVG/canvas的中间,我们平移中心,使其位于中间,平移为 [width/2,height/2]
现在我们正在展示整个世界,我们可以优化以仅展示我们想要的部分。最简单的方法可能只是从 svg/canvas 的底部去掉像素。使用上面的代码,canvas/svg 高度为 700 像素(并保持 960 像素,使用相同的缩放和平移)我得到:
我没有从这张图片中删除南极洲 - 它只是碰巧被切断而不必过滤掉它(这不一定是理想的做法:它仍然被绘制)。
因此,SVG/Canvas 宽度 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 度大致是南美洲的尖端。这将确保您想要看到的整个世界部分都是可见的。但是,如上所述,这不考虑方面,因此如果您将上述范围限制为方形尺寸,您仍将显示墨卡托的完整范围。