D3.js 绘制 geojson 不正确

Ser*_*nov 4 javascript openstreetmap geojson d3.js

我正在尝试可视化俄罗斯地区。我从拿到的数据在这里,验证在这里,一切都很好-图片

但是当我尝试绘制它时,我只收到一个大的黑色矩形。

var width = 700, height = 400;

var svg = d3.select(".graph").append("svg")
        .attr("viewBox", "0 0 " + (width) + " " + (height))
        .style("max-width", "700px")
        .style("margin", "10px auto");


d3.json("83.json", function (error, mapData) {
    var features = mapData.features;

    var path = d3.geoPath().projection(d3.geoMercator());

    svg.append("g")
            .attr("class", "region")
            .selectAll("path")
            .data(features)
            .enter()
            .append("path")
            .attr("d", path)
});
Run Code Online (Sandbox Code Playgroud)

示例 - http://ustnv.ru/d3/index.html Geojson 文件 - http://ustnv.ru/d3/83.json

And*_*eid 6

问题是坐标的缠绕顺序(请参阅此块)。大多数工具/实用程序/库/验证器并不真正关心缠绕顺序,因为它们将 geoJSON 视为包含笛卡尔坐标。D3 并非如此 - D3 使用椭球数学 - 这样做的好处包括能够轻松穿过反子午线并能够选择倒置的多边形。

使用椭球坐标的结果是错误的缠绕顺序将创建地球上所有不是您的目标的特征(倒多边形)。您的多边形实际上包含两种缠绕顺序的组合。您可以通过检查 svg 路径来看到这一点:

在此处输入图片说明

这里的一条路径似乎是准确绘制的,而它上面的另一条路径覆盖了整个星球——除了它应该占据的部分(它应该占据的空间被覆盖整个世界的其他路径覆盖)。

这可以很容易修复 - 您只需要重新排序坐标 - 但是由于您的功能包含同一集合中的两个绕组,因此使用turf.js 之类的库来创建正确的新数组会更容易伤口特征:

    var fixed = features.map(function(feature) {
        return turf.rewind(feature,{reverse:true});
    })
Run Code Online (Sandbox Code Playgroud)

请注意反向缠绕顺序 - 通过一个奇怪的怪癖,D3,这可能是最普遍的平台,其中缠绕顺序实际上并不遵循关于缠绕顺序的 geoJSON 规范(RFC 7946),它使用相反的缠绕顺序,请参阅此评论迈克·博斯托克:

我很失望 RFC 7946 将相反的缠绕顺序标准化为 D3、Shapefiles 和 PostGIS。而且我没有看到 D3 改变其行为的简单方法,因为它会破坏 D3 使用的所有现有(球形)GeoJSON。(来源

通过倒回每个多边形,我们得到了一个更有用的地图:

在此处输入图片说明

改进,但这些投影设置的功能有点小。

通过添加 fitSize 方法来缩放和平移,我们得到了一个更好看的地图(请参阅此处的块):

在此处输入图片说明