d3-geo:投射器介绍

d3-geo 库, 是 d3 工具包提供一个地理位置计算及转换操作库,主要包括了:

  • Projections : 投影器,将 GEOJSON 数据投射到平面上显示出来。
  • Path : 对 geojson 里面的 feature 进行计算,生成路径,进行测量,裁切, 等操作

投影

由于此包涉及到一些专业的地理知识,我也不是很懂,只能通俗的打个比方:

1): 当你站在北京正中央(center)上空很高的地方,手上拿一个照相机,镜头中心对着正下方的位置。

2): 缩放(scale) 镜头,直到北京的宽度或高度刚好能紧贴(fitSize) 你相机上的显示屏,然后卡擦。

由于你是在正中心上方,所以你应该会得到一张这样的照片:

照片

北京相片:刚好居中

在 d3 的投影里面,相片中北京,则是 GeoJson 里面的数据信息,通过d3投影到显示屏上的数据。

地理投影

但是,我们再多想一步,相片中的北京,是真实的北京的形状吗?直觉可能会告诉我们:是的,下图是我的想像:

照片

理想情况:北京被同等比例压缩在相机中了

然而,这只是个理想情况,北京的地貌刚好被等比压缩到相片中,而这种理想情况是有一个前提假设的:地球是平的

而实际上,地球是圆形,我们实际拍北京,应该是球面上的一部分,可能是这样:

照片

真实情况,不可忽略的球面

在这种情况下,相片中最左边的1%,在实际中可能占到2%,由此则产生了偏差,如果照片上的地图用于测量等用途,就无法使用了。

在地理学上,还有很多的因素需要考虑,不同的地图会对应不同的实际应用场景。

对应到 d3-geo 库中,则对应了各种投影算法,通常没有一个算法能满足所有的需求。

而且很多投影算法都非常专业,仅特定行业才会使用,所以需要了解的并不多。

由于:3D转平面显示,由于视角上信息的丢失
通常如果无法保证 A-B 的 距离与真实世界的距离或真实面积成等比关系,至多取其一。

在实际编程中,可以想像投影器就是你的照相机,因为他们的常用方法很像:

  • projection(point) 把经纬度转换成为平面坐标
  • projection.invert(point) 把平面坐标转换为经纬度
  • projection.scale([scale]) 缩放
  • projection.center([center]) 设置中心点 (对焦)
  • projection.rotate([angles]) 旋转相机
  • projection.translate([translate]) 移动画布的位置
  • projection.fitExtent(extent, object) 自动优化,至剧中
  • projection.fitSize(size, object) 自动优化,至居中 (orgin=[0,0])

其它还有一些不常用的:由于很少用,所以不清楚具体作用

  • projection.stream(stream) 生成一个projection 流,用于构造自定义的投影算法
  • projection.preclip([preclip])
  • projection.postclip([postclip])
  • projection.clipAngle([angle])
  • projection.clipExtent([extent])
  • projection.angle([angle])
  • projection.reflectX([reflect])
  • projection.reflectY([reflect])
  • projection.precision([precision])

球体投影系列

球体投影, 主要使用不同的计算方式,将整个地球直接投射到一个平面上

d3.geoAzimuthalEqualArea : 方位等面积

照片

d3.geoAzimuthalEqualArea : 优先保证球面上的各区域的面积相等

d3.geoAzimuthalEquidistant : 方位等距离

照片

d3.geoAzimuthalEqualArea : 优先保证球面上的距离比相等

d3.geoGnomonic : 球心投射法

照片

d3.geoGnomonic :球心投射法, 将照相机放在地心内往外拍的效果

d3.geoOrthographic : 正交投射法

照片

d3.geoOrthographic : 正交投射法,可使投影边缘的变形不致过大

d3.geoStereographic : 球极平面投影

照片

d3.geoStereographic : 南极和北极都可以显示出来

d3.geoEqualEarth : 同等地球

照片

d3.geoEqualEarth : 将球的表面均匀外翻

圆锥体投影系列

圆锥体投影,是先通过一定的计算,将将球体投影到圆锥体上,然后再将圆锥体展开,则得到一个平面图形。

d3.geoConicConformal : 普通圆锥体投影

照片

d3.geoConicConformal 圆锥体规则投影,直接展开圆锥

d3.geoConicEqualArea : 圆锥体投影下,面积比例相等

照片

d3.geoConicEqualArea 圆锥体投影,优先保证面积比例相等

d3.geoConicEquidistant :

照片

d3.geoConicConformal 圆锥体投影,优先保证面积比例相等

圆柱体投影系列

圆柱体投影 ,和圆锥体一样,先通过一定的计算,将将球体投影到圆柱体上,然后再将圆锥体展开,则得到一个平面图形。

d3.geoEquirectangular : 等矩形

照片

d3.geoEquirectangular 圆柱上展开后,切割的每块矩形,面积相等

d3.geoMercator : 墨卡托投影

照片

d3.geoMercator 以佛兰德斯地理学家、地图学家 墨卡托 命名的投影方法

d3.geoNaturalEarth1 : 真实地球

照片

d3.geoNaturalEarth1 比较接近真实地球

美国定制

另外,还有几个投影,是基于美国的,如果想显示美国地图,可以使用

  1. d3.geoAlbers : 阿尔伯斯 是一个面积相等的圆锥体投影 d3.geoConicEqualArea, 以美国为的视角进行了初始化。
  2. d3.geoAlbersUsa 以美国为中心的地图,针对大部分的州进行了优化,还提供了额外的操作方法。

总结

对于中国及各省市地图,我们平时看到的,或前端中使用到的的大部份应分应该是圆锥等面积投影,这里有一份国家行政区划图(集)编制规范.pdf,在 6.3 节处明确了我国地图的投影方式,有兴趣可自行阅读。

但实际上我们可以,我们也可以像定制美国地图投射器一样,定制自己的投射器:

  1. 简单版本:通过一个现有的投射器,修改初始化的 rotate, center, translate 等值,可以把一幅难看的图绘的还不错。
  2. 高端版本:如果具备一定的空间转换知识,也可以自行实现一个投射器,或是基于现有的投射器做少量扩展优化。