D3 TopoJSON渲染神器
D3 TopoJSON rendering artifact
在我走得太远之前,我注意到我的 TopoJSON 中有一个相当奇怪的渲染工件,我无法解释。上面呈现的是在 TopoJSON World Atlas repository 上找到的官方 D3 发行版 countries-110m.json
。正如您所看到的,俄罗斯北部的一部分在加拿大北部出现倒置 left/right。在我开始制定计划 B 之前,我的代码中是否有任何内容导致了此问题?
async function drawMap() {
map_obj = await getRAWMapData(); // Map topojson
const geojson_obj = topojson.feature(map_obj, map_obj.objects.countries);
var projection = d3.geoIdentity().fitWidth(width, geojson_obj).reflectY(true); // Map Projection
var path = d3.geoPath().projection(projection);
paths = SVGmap.selectAll('path').data(geojson_obj.features).enter().append('path');
paths
.attr('d', path)
.attr('fill', '#ddd')
.attr('stroke', 'white')
.attr('stroke-linejoin', 'round');
}
drawMap();
问题
您正在使用球形数据并将其绘制在平面上(d3.geoIdentity),就好像数据是平面的一样。
俄罗斯在西半球有一部分领土 - 神器是路径渲染器从远东延伸到远西,然后又回来,因为绘制俄罗斯时路径数据穿过 anti-meridian .恒等变换“不知道”这应该包裹在一个球体后面——你只是获取纬度和经度并将其拉伸到屏幕上,就好像它是二维数据一样。
D3.geoIdentity() 拟合方法仅操纵数据的比例和平移 - 不考虑数据的 anti-meridian 或地理投影。
解决方案
使用投影 - D3 地理投影使用球面数学 - 它们切割穿过 anti-meridian 的特征(在本例中为 180 度 East/West)。在这种情况下,俄罗斯将由两个路径元素组成:一个在西方,一个在东方。这消除了在单个特征中连接两个部分所需的拉伸所产生的伪影。
所以,如果你想保持 plate carrée 的外观,你可以使用:
var projection = d3.geoEquirectangular().fitWidth...
任何 D3 投影都可以,d3.geoMercator 某些人在外观方面可能更熟悉。
另一种解决方案是找到已经穿过 anti-meridian 的预投影几何体 - 但此选项的灵活性远低于使用 D3 地理投影来投影数据。
在我走得太远之前,我注意到我的 TopoJSON 中有一个相当奇怪的渲染工件,我无法解释。上面呈现的是在 TopoJSON World Atlas repository 上找到的官方 D3 发行版 countries-110m.json
。正如您所看到的,俄罗斯北部的一部分在加拿大北部出现倒置 left/right。在我开始制定计划 B 之前,我的代码中是否有任何内容导致了此问题?
async function drawMap() {
map_obj = await getRAWMapData(); // Map topojson
const geojson_obj = topojson.feature(map_obj, map_obj.objects.countries);
var projection = d3.geoIdentity().fitWidth(width, geojson_obj).reflectY(true); // Map Projection
var path = d3.geoPath().projection(projection);
paths = SVGmap.selectAll('path').data(geojson_obj.features).enter().append('path');
paths
.attr('d', path)
.attr('fill', '#ddd')
.attr('stroke', 'white')
.attr('stroke-linejoin', 'round');
}
drawMap();
问题
您正在使用球形数据并将其绘制在平面上(d3.geoIdentity),就好像数据是平面的一样。
俄罗斯在西半球有一部分领土 - 神器是路径渲染器从远东延伸到远西,然后又回来,因为绘制俄罗斯时路径数据穿过 anti-meridian .恒等变换“不知道”这应该包裹在一个球体后面——你只是获取纬度和经度并将其拉伸到屏幕上,就好像它是二维数据一样。
D3.geoIdentity() 拟合方法仅操纵数据的比例和平移 - 不考虑数据的 anti-meridian 或地理投影。
解决方案
使用投影 - D3 地理投影使用球面数学 - 它们切割穿过 anti-meridian 的特征(在本例中为 180 度 East/West)。在这种情况下,俄罗斯将由两个路径元素组成:一个在西方,一个在东方。这消除了在单个特征中连接两个部分所需的拉伸所产生的伪影。
所以,如果你想保持 plate carrée 的外观,你可以使用:
var projection = d3.geoEquirectangular().fitWidth...
任何 D3 投影都可以,d3.geoMercator 某些人在外观方面可能更熟悉。
另一种解决方案是找到已经穿过 anti-meridian 的预投影几何体 - 但此选项的灵活性远低于使用 D3 地理投影来投影数据。