0

I have a series of GeoJSON files downloaded from a gazeteer being rendered via the following code:

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
/* CSS goes here. */
.label {
  fill: #000;
  font-size: 10px;
  font-weight: 300;
  text-anchor: middle;
}
div.tooltip-mappiece {
     position: absolute;
     text-align: center;
     padding: 10px;
     background: white;
     color: #000;
     border: 1px solid #000;
     border-radius: 5px;
     pointer-events: none;
     height: 15px;
     width: 150px;
}
</style>
</head>
<body>
    
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>

<script>
var width = 960, height = 800;
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var projection = d3.geoAlbers().translate([width / 2, height / 2]).center([23,42]).scale(100);
var div = d3.select("body").append("div").attr("class", "tooltip-mappiece").style("opacity", 0);

var files = [
    {filename:"topo-arcticsea.json",name:"ArcticSea",color:"#88AED0",link:""},
    {filename:"topo_atlantic_antartic.json",name:"AtlanticAntartic",color:"#88AED0",link:""},
    {filename:"topo_atlantic_eastern_central.json",name:"AtlanticEasternCentral",color:"#88AED0",link:""},
    {filename:"topo_atlantic_northeast.json",name:"AtlanticNortheast",color:"#88AED0",link:""},
    {filename:"topo_atlantic_northwest.json",name:"AtlanticNorthwest",color:"#88AED0",link:""},
    {filename:"topo_atlantic_southeast.json",name:"AtlanticSoutheast",color:"#88AED0",link:""},
    {filename:"topo_atlantic_southwest.json",name:"AtlanticSouthwest",color:"#88AED0",link:""},
    {filename:"topo_atlantic_western_central.json",name:"AtlanticWesternCentral",color:"#88AED0",link:""},
    {filename:"topo_indian_antartic_southern_ocean.json",name:"IndianAntarticSouthernOcean",color:"#88AED0",link:""},
    {filename:"topo_indian_ocean_eastern.json",name:"IndianOceanEastern",color:"#88AED0",link:""},
    {filename:"topo_indian_ocean_western.json",name:"IndianOceanWestern",color:"#88AED0",link:""},
    {filename:"topo_mediterranean_black_sea.json",name:"MediterraneanBlackSea",color:"#88AED0",link:""},
    {filename:"topo_pacific_antarctic.json",name:"PacificAntarctic",color:"#88AED0",link:""},
    {filename:"topo_pacific_eastern_central.json",name:"PacificEasternCentral",color:"#88AED0",link:""},
    {filename:"topo_pacific_northeast.json",name:"PacificNortheast",color:"#88AED0",link:""},
    {filename:"topo_pacific_northwest.json",name:"PacificNorthwest",color:"#88AED0",link:""},
    {filename:"topo_pacific_southeast.json",name:"PacificSoutheast",color:"#88AED0",link:""},
    {filename:"topo_pacific_southwest.json",name:"PacificSouthwest",color:"#88AED0",link:""},
    {filename:"topo_pacific_western_central.json",name:"PacificWesternCentral",color:"#88AED0",link:""},
    {filename:"topo_africa.json",name:"Africa",color:"#77a361",link:""},
    {filename:"topo_antarctica.json",name:"Antarctica",color:"#bad0ae",link:""},
    {filename:"topo_asia.json",name:"Asia",color:"#80a96b",link:""},
    {filename:"topo_europe.json",name:"Europe",color:"#9bbb8a",link:""},
    {filename:"topo_north_america.json",name:"NorthAmerica",color:"#7ca666",link:""},
    {filename:"topo_south_america.json",name:"SouthAmerica",color:"#adc79f",link:""},
    {filename:"topo_australia.json",name:"Australia",color:"#92b580",link:""},
];


getJSONFile = function(filename,callback,metadata){
    d3.json(files[i].filename, function(error,file){callback(error,file,metadata)});
}

for(var i = 0; i < files.length; i++){
    getJSONFile(files[i].filename,
        function(error,file,metadata){
            if(metadata.type == "continent"){
                var subobj = metadata.continent;
            }else{
                var subobj = metadata.name;
            }
        if (error) return console.error(error);
        var path = d3.geo.path().projection(projection);
        svg.append("path")
            .datum(topojson.feature(file, file.objects[metadata.name]))
            .attr("d",path)
            .attr("fill", metadata.color)
            .attr("stroke", "black")
            .on("mouseover", function(){
                d3.select(this)
                .style("fill", metadata.color)
                .style("fill-opacity","0.85");

                div.transition()
                .duration('5')
                .style("opacity", 1)

                div.html(metadata.name)
                .style("left", (d3.event.pageX + 10) + "px")
                .style("top", (d3.event.pageY - 15) + "px");;
            })
            .on("mouseout", function(){
                d3.select(this)
                .style("fill",metadata.color)
                .style("fill-opacity","1.0")

                div.transition()
               .duration('5')
               .style("opacity", 0)

      });
    },
    files[i]);
}
</script>

Most of the files render fine, but two do not:

Image of the rendered map areas showing gap and missing piece

Both render as expected if loaded into an online geojson preview tool. Similar questions (first example; second example) suggest the issue is normally related to needing projection, but all files are using the same projection here, so I don't see how a few specific ones could cause issues. If the problem is with the files themselves, then I don't understand why they are rendering without issue in other tools.

Anyone know what might be going on and how to fix the issue?

Sarah Vela
  • 144
  • 3
  • 1
    The issue on the gap is that D3 uses spherical geometry while most every other tool for geojson does not - any line connecting to points is rendered along the shortest distance on earth, not the shortest distance in pixels. The gap is a product of connecting points in this manner (parallels are not the shortest distance between points, while all three points on the north side of the gap are on the same parallel). – Andrew Reid May 11 '22 at 18:45
  • 1
    The issue with Australia is likely a winding order issue: with spherical geometry if you wind the wrong way, you fill everything in the world except your feature (see [here](https://stackoverflow.com/a/49311635/7106086)). Both problems can be solved by using [d3.geoIdentity()](https://github.com/d3/d3-geo#geoIdentity) as your projection with a flip on the y axis (`d3.geoIdentity().reflectY()`) and [fitSize](https://github.com/d3/d3-geo#projection_fitSize) to scale the map. I can expand if needed in an answer. – Andrew Reid May 11 '22 at 18:46

0 Answers0