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 比较接近真实地球
美国定制
另外,还有几个投影,是基于美国的,如果想显示美国地图,可以使用
- d3.geoAlbers : 阿尔伯斯 是一个面积相等的圆锥体投影
d3.geoConicEqualArea
, 以美国为的视角进行了初始化。 - d3.geoAlbersUsa 以美国为中心的地图,针对大部分的州进行了优化,还提供了额外的操作方法。
总结
对于中国及各省市地图,我们平时看到的,或前端中使用到的的大部份应分应该是圆锥等面积投影,这里有一份国家行政区划图(集)编制规范.pdf,在 6.3 节处明确了我国地图的投影方式,有兴趣可自行阅读。
但实际上我们可以,我们也可以像定制美国地图投射器一样,定制自己的投射器:
- 简单版本:通过一个现有的投射器,修改初始化的 rotate, center, translate 等值,可以把一幅难看的图绘的还不错。
- 高端版本:如果具备一定的空间转换知识,也可以自行实现一个投射器,或是基于现有的投射器做少量扩展优化。