Search code examples
d3.jsgeojsongeo

d3.geo.path rectangle wrapping the wrong way


This simple geojson rectangle is displayed correctly with some geojson viewers, I get a rectangle as expected. But when I do it with d3, the rectangle seems to wrap around.

var polygonData = {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [ -100, -20 ],
            [ -100, 20 ],
            [ 100, 20 ],
            [ 100, -20 ],
            [ -100, -20 ]
          ]
        ]
      },
      "properties": {}
    };
    
    var width = 1000;
    var height = 500;
    
    var projection = d3.geo.equirectangular()
      .scale(100)
      .translate([width / 2, height / 2])
      .rotate([0, 0])
	  .center([0, 0])
      .precision(0);
    
    var path = d3.geo.path()
	  	.projection(projection);

    var svg = d3.select("body").append("svg")
      .attr({
        width: width,
      	height: height
      });

    svg.append('path')
      .datum(polygonData)
      .attr({
        d: path,
        fill: 'orange',
        opacity: 0.5
      });
<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
  <style>
  </style>
</head>

<body>

</body>

Here is what I get with a geojson viewer:

geojson viewer

But here's what I get with the above d3 code:

geojson using d3

Reversing the winding order just fills the opposite shapes, it doesn't fix the problem. I guess its an antimeridian cutting issue. One fix is to add some intermediate points to force the path to not wrap around, but I would need to be able to automate this solution with more complex paths.

Any idea how I can use this geojson with d3 and force it to show it like other geojson viewers, as a simple rectangle across the map?


Solution

  • I don't think, there is anything to blame on D3; in my understanding it's those other GeoJSON viewers which are in error. As a human being living on a more or less planar surface one is easily tricked into believing that a polygon with four corners having carefully chosen coordinates like yours should look like a rectangle. On a sufficiently small scale and given a suitable projection this even holds true for spherical geometry. But as your points are almost half the globe apart, this won't be the case.

    To shed some light on this, I used an orthographic projection to display some geographic features along with your polygon:

    Orthographic projection

    From this view it becomes apparent that the line along the meridian is the first edge connecting points [-100,-20] and [-100,20]. From that point [-100,20] somewhere in Mexico to the northwest is the great arc, i.e. the shortest connection, to the next point [100,20] half way around the globe. The path is then similarly closed around the southern hemisphere. Thus, the outline of the polygon is the shortest path on the globe's surface connecting all of its points in the given order.

    Although your polygon is determined by its coordinates, its look will depend on the projection in use. Here is another view of the same polygon using a mercator projection:

    Mercator projection