【问题标题】:Cannot add capitals to geojson world map无法将大写字母添加到geojson世界地图
【发布时间】:2020-12-23 18:13:46
【问题描述】:

我正在使用 d3 渲染带有可点击国家/地区的世界地图。这些国家/地区来自 geojson 文件,使用此站点加载特定大陆、地区或整个世界都没有问题: https://geojson-maps.ash.ms/

但是,来自该站点的数据在其 geojson 文件中没有任何大写字母。因此,我查看了https://www.naturalearthdata.com/,它清楚地表明应该能够渲染一个带有城市的区域。我获取他们的文件并通过https://mapshaper.org/ 将它们转换为geojson,但由于某种原因,我只得到城市,作为空白背景下的单点。我找不到一张地图,其中提供了国家/地区首都/城市位于国家边界内的国家/地区地图。

这让我想知道我是否应该以某种方式将国家的 geojson 文件与首都的 geojson 文件结合起来,并在另一个之上渲染。在那种情况下,这怎么可能?还是有其他解决方案?我附上了渲染世界地图的代码(效果很好):

const data = await d3.json("world.geo.json")

var topology = topojson.topology({ foo: data });

const countries = topojson.feature(topology, topology.objects.foo).features

let targetCountries = countries
selectCountry()

svg.selectAll(".country")
    .data(countries) /* binder selectAll till enter() */
    .enter().append("path")
    .attr("class", "country")
    .attr("d", path)
    .on("mouseover", function (d) {
        d3.select(this).classed("targeted", true)
    })
    .on("mouseout", function (d) {
        d3.select(this).classed("targeted", false)
    })

【问题讨论】:

  • 如何添加城市?您只展示了如何添加显然正确加载的国家/地区。另外,你能分享一个你的城市文件样本吗?
  • 我忘了添加前一行: const data = await d3.json("europe.geo.json") 这是添加文件的地方。我可以将文件更改为大写字母之一,但这只是创建了一个没有国家/地区的大写字母的地图。我需要将不同文件中的首都和国家/地区渲染到同一个 svg 元素上,但我不知道该怎么做。
  • 您可以使用 Promise.all() 一次加载多个 CSV:*.com/questions/21842384/…
  • 你绝对应该这样组合文件,就像你selectAll .country,你也可以selectAll .capital
  • 您能否向我展示一个针对您所描述内容的最低工作解决方案,包括我上面的代码?我对此很陌生,并没有自己编写上述所有代码。以及是否可以用同样的方式加载多个json文件(我之前没遇到过csv)?

标签: d3.js geojson topojson geography


【解决方案1】:

我现在有一个解决方案,在这里发布以防它帮助其他人:

const data = await Promise.all([d3.json("world.geo.json"), d3.json("capitals_0yl.json")])

var topology = topojson.topology({ foo: data[0], bar: data[1] });

const countries = topojson.feature(topology, topology.objects.foo).features
const cities = topojson.feature(topology, topology.objects.bar).features

let combined = d3.merge([countries, cities])

svg.selectAll(".country")
    .data(combined) /* binder selectAll till enter() */
    .enter().append("path")
    .attr("class", "country")
    .attr("d", path)
    .on("mouseover", function (d) {
        d3.select(this).classed("targeted", true)
    })
    .on("mouseout", function (d) {
        d3.select(this).classed("targeted", false)
    })

【讨论】: