Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convenience “unstitch” for getting back WGS84? #113

Open
mbostock opened this issue Sep 7, 2017 · 1 comment
Open

Convenience “unstitch” for getting back WGS84? #113

mbostock opened this issue Sep 7, 2017 · 1 comment

Comments

@mbostock
Copy link
Member

mbostock commented Sep 7, 2017

Currently to convert D3 and TopoJSON spherical coordinates to equirectangular WGS84 used by standard GeoJSON, you need to project through d3.geoEquirectangular with a scale of 180 / π, and then through d3.geoIdentity to flip the y-axis. For example:

topo2geo countries=- -i world/110m.json \
  | geoproject 'd3.geoEquirectangular().scale(180 / Math.PI).translate([0, 0])' \
  | geoproject 'd3.geoIdentity().reflectY(true)' \
  > countries.json

It’d be nice if there were a single built-in projection, say d3.geoWgs84, that did this in one go.

@mbostock mbostock changed the title Convenience projection for getting back WGS84? Convenience projection for getting back WGS84 (unstitch)? Sep 12, 2017
@mbostock mbostock changed the title Convenience projection for getting back WGS84 (unstitch)? Convenience “unstitch” for getting back WGS84? Sep 12, 2017
@Fil
Copy link
Member

Fil commented Jan 30, 2023

geoproject is not really suitable for this, unless we have a way to opt out of its handling of the polygons' winding order (e.g. d3/d3-geo-projection#185).

It might be interesting to think about this together with the rewind utility https://observablehq.com/@fil/rewind (#138).

My current script for this task is a bit complicated, since it applies geoproject (to apply clipAntemeridian), then fixes the shortcomings:

function unstitch(a) {
  a = JSON.parse(JSON.stringify(a)); // deep copy
  a = d3.geoProject(
    a,
    d3
      .geoEquirectangular()
      .scale(180 / Math.PI)
      .translate([0, 0])
  );

  // flip polygons
  for (const f of a.features) {
    if (f.geometry.type === "Polygon")
      f.geometry.coordinates.forEach((ring) =>
        ring.forEach((point) => (point[1] *= -1))
      );
    else if (f.geometry.type === "MultiPolygon")
      f.geometry.coordinates.forEach((poly) =>
        poly.forEach((ring) => ring.forEach((point) => (point[1] *= -1)))
      );
  }

  // fix winding order (for Fiji in 50m)
  return rewind(a);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants