2

Why d3.js works only with GeoJSON that is left-hand formatted?

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Polygon",
          "coordinates": [
              [
                [0, 0], [10, 0], [0, 10], [0, 0]
              ]
            ]
          }
        }
      ]
    };

is supposedly well formed and not broken - https://geojsonlint.com/ shows it as followsenter image description here

while d3.js shows it as a hole in the world (filled area across entire world except that area)

enter image description here

My, likely bungled, d3 attempt code is hosted at https://matkoniecz.github.io/wat/valid.html (with correct GeoJSON). Version with points in reverse order, raising warnings elsewhere works: https://matkoniecz.github.io/wat/map.html

What is going on here? I am likely missing something but I run out of ideas. Maybe d3 is simply not supporting GeoJSON? And all examples that I found are broken/confusing because people who made them were unaware that GeoJSON is not supported?

Code is also posted below:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <div id="content">
      <svg width="800px" height="600px">
        <g class="generated_map" id="generated_map"></g>
      </svg>
    </div>
  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.2/d3.min.js"></script>
    <script>
    const width = 800;
    const height = 600;
    var geojson = {
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Polygon",
          "coordinates": [
              [
                //[-179, 80], [179, 0], [179, 80], [-179, 80] // works? why?
                //[0, 0], [10, 0], [0, 10], [0, 0] // hole in the world
                [0, 0], [0, 10], [10, 0], [0, 0]
              ]
            ]
          }
        }
      ]
    };

    var projection = d3.geoMercator().fitSize([width, height], geojson)

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

    function update(geojson) {
      var u = d3.select('#content g.generated_map')
        .selectAll('path')
        .data(geojson.features);

      u.enter()
        .append('path')
        .attr('d', geoGenerator)
        .attr("stroke", 'black')
        .attr("stroke-width", "1")
        .attr("fill", "blue")
    }
    update(geojson);
    </script>
</body>
</html>

1 Answer 1

2

You can look on parent forum about the issue details and related explanations https://stackoverflow.com/questions/49311001/d3-js-drawing-geojson-incorrectly

You can also find a recipe at https://observablehq.com/@john-guerra/d3-black-box-map to always change GeoJSON winding order using Turf.js

1
  • thanks! So I will need to convert from osm JSON to geoJSON to d3.geoJSON :) Commented Mar 30, 2021 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.