d3.js 在 Mollweide 投影中绘制为圆弧的矩形特征
d3.js rectangle feature plotted as arc in Mollweide projection
我正在尝试在 Mollweide 投影下使用 d3.js 绘制一个矩形。但是,当我 运行 以下脚本时,矩形显示为弧形或弯曲矩形。我发现这种行为有些奇怪,因为 Mollweide 投影中的平行线只是直线。有人可以解释一下效果吗?同样的效果在其他纬度和其他投影(甚至 Equirectangular 投影)中也存在。
<!DOCTYPE html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v1.min.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
var mainSVG = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
var projection = d3.geoMollweide().scale(400).translate([250,750])
var path = d3.geoPath().projection(projection);
d3.json('test.json', function(error, vData) {
var features = vData.features;
mainSVG.selectAll('path')
.data(features)
.enter().append('path')
.attr('d', path)
.style('fill', 'red')
.style('stroke', 'black');
})
</script>
geojson 文件:
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "DN": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 7.6, 65.0 ], [ 60.4, 65.0 ], [ 60.4, 63.4 ], [ 7.6, 63.4 ], [ 7.6, 65.0 ] ] ] } }
]
}
结果图:
当我尝试绘制不同纬度的几个相邻矩形时,结果更加奇怪:
D3 路径遵循大圆弧,两点之间的最短距离。这两个点在椭圆体上的三维 space 中,因此它们之间的最短路径可能不对应于投影二维 space 中测量的它们之间的最短路径。
举一个极端的例子,想象一个点在北纬 85°,西经 90°,另一个点在北纬 85°,东经 90°。尽管处于同一平行线上,但两者之间的最短距离是在北极上空短途旅行。 D3 会将这条线绘制为到地图顶部的两条垂直线(在典型的等距柱状地图上:赤道在中间,北在顶部)而不是沿着 85 度平行线的水平线。
如果您希望在投影平面上的两点之间有明显的直线,请将顶点投影到投影平面上(svg 坐标 space),然后画一条连接这些投影点的线。这可以通过创建一个新的 geojson 来完成,其中每个 lat,long 对原始 geojson 已经被投影(projection([x,y])
),然后用空投影绘制:.attr(d, d3.geoPath(null))
我正在尝试在 Mollweide 投影下使用 d3.js 绘制一个矩形。但是,当我 运行 以下脚本时,矩形显示为弧形或弯曲矩形。我发现这种行为有些奇怪,因为 Mollweide 投影中的平行线只是直线。有人可以解释一下效果吗?同样的效果在其他纬度和其他投影(甚至 Equirectangular 投影)中也存在。
<!DOCTYPE html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v1.min.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
var mainSVG = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
var projection = d3.geoMollweide().scale(400).translate([250,750])
var path = d3.geoPath().projection(projection);
d3.json('test.json', function(error, vData) {
var features = vData.features;
mainSVG.selectAll('path')
.data(features)
.enter().append('path')
.attr('d', path)
.style('fill', 'red')
.style('stroke', 'black');
})
</script>
geojson 文件:
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "DN": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 7.6, 65.0 ], [ 60.4, 65.0 ], [ 60.4, 63.4 ], [ 7.6, 63.4 ], [ 7.6, 65.0 ] ] ] } }
]
}
结果图:
当我尝试绘制不同纬度的几个相邻矩形时,结果更加奇怪:
D3 路径遵循大圆弧,两点之间的最短距离。这两个点在椭圆体上的三维 space 中,因此它们之间的最短路径可能不对应于投影二维 space 中测量的它们之间的最短路径。
举一个极端的例子,想象一个点在北纬 85°,西经 90°,另一个点在北纬 85°,东经 90°。尽管处于同一平行线上,但两者之间的最短距离是在北极上空短途旅行。 D3 会将这条线绘制为到地图顶部的两条垂直线(在典型的等距柱状地图上:赤道在中间,北在顶部)而不是沿着 85 度平行线的水平线。
如果您希望在投影平面上的两点之间有明显的直线,请将顶点投影到投影平面上(svg 坐标 space),然后画一条连接这些投影点的线。这可以通过创建一个新的 geojson 来完成,其中每个 lat,long 对原始 geojson 已经被投影(projection([x,y])
),然后用空投影绘制:.attr(d, d3.geoPath(null))