D3 world-50m.json投影填充不正确

时间:2017-08-09 13:39:57

标签: javascript json d3.js map-projections

我对world-50m.json文件的投影有效,但是当我用一种颜色填充它时,有几个国家在边缘被切断,在整个地图上创建水平填充部分/线。

这实际上在d3-geo示例投影中可见:https://github.com/d3/d3-geo/blob/master/test/data/world-50m.json

enter image description here

是否有其他没有这些截止国家的JSON文件?或者也许我可以省略填充中的特定多边形?不太确定我如何找到问题所在的每个国家/地区。虽然大多数都很小,如果省略也不会错过,但主要的一个似乎是俄罗斯。

以下是我的参考代码:

var w = 960,
    h = 660,
    active = d3.select(null);

var projection = d3.geoMercator()
    .scale(150)
    .translate([w/2, h/2])
    .precision(.1);

var path = d3.geo.path()
    .projection(projection);

var countries = svg.append("svg:g").attr("id", "countries");

d3.json("world-50m.json", function(error, us) {
  mapFeatures = topojson.feature(us, us.objects.countries).features;
  mapFeatures.type = "countries";
  drawMap();
});

function drawMap() {
  countries.selectAll("path")
        .data(mapFeatures)
        .enter().append("svg:path")
        .attr("d", path)
        .attr("class", "feature")
        .attr("data-id", function(d) { return d.id; })
        .style("fill", "blue")
        .style("stroke", "white")
        .style("stroke-width", ".2px");
};

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

这个解决方案在上面的评论中有详细说明,是在@Andrew Reid和@altocumulus的帮助下完成的。

观察到的问题是由于d3 v3和d3 v4语法之间的路径和投影调用不匹配而未被d3正确处理的 Antimeridian Cutting 的实例。

此问题已通过将geo.path()更改为geoPath()来解决不匹配问题并使d3能够正确地渲染地图并使用其反钓鱼切割支持来解决。

以下是正确的代码:

var w = 960,
    h = 660,
    active = d3.select(null);

var projection = d3.geoMercator()
    .scale(150)
    .translate([w/2, h/2])
    .precision(.1);

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

var countries = svg.append("svg:g").attr("id", "countries");

d3.json("world-50m.json", function(error, us) {
  mapFeatures = topojson.feature(us, us.objects.countries).features;
  mapFeatures.type = "countries";
  drawMap();
});

function drawMap() {
  countries.selectAll("path")
        .data(mapFeatures)
        .enter().append("svg:path")
        .attr("d", path)
        .attr("class", "feature")
        .attr("data-id", function(d) { return d.id; })
        .style("fill", "blue")
        .style("stroke", "white")
        .style("stroke-width", ".2px");
};