I am using d3 to render a world map with clickable countries. The countries are from a geojson file, and I have no problems loading a particular continent, region or the entire world, using this site: https://geojson-maps.ash.ms/
However, the data from that site does not have any capitals in their geojson files. So instead I looked at https://www.naturalearthdata.com/, which clearly shows that one should be able to render a region with cities on it. I take their files and convert them to geojson via https://mapshaper.org/, but for some reason I ONLY get cities, as single dots against a blank background. There is not a single map I can find which provides a map of countries with capitals/cities inside country borders.
This leads me to wonder whether I am somehow supposed to combine a geojson file of countries with a geojson file of capitals, and render one on top of the other. In that case, how is that possible? Or is there some other solution? I attach the code where I render my world map (which works fine):
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)
})
I have a solution now, posting it here in case it helps anyone else:
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)
})