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

Projection.stream only supports points with x and y (no z) #96

Open
ekh64 opened this issue Apr 11, 2017 · 4 comments
Open

Projection.stream only supports points with x and y (no z) #96

ekh64 opened this issue Apr 11, 2017 · 4 comments
Labels

Comments

@ekh64
Copy link

ekh64 commented Apr 11, 2017

I was working to implement your Map Pan & Zoom IV example without baking in the projection to the json file.

As a result I've been playing around with projection.stream, and discovered that, unlike geoTransform, when I pass in a stream, the point function only receives x and y params, whereas the geoTransform receives x, y, and z params.

So when I write the following:

const geoTransform({
  point: function(x, y, z) {
    if (z >= area) this.stream.point(x * scale + translate[0], y * scale + translate[1]);
  }
});
geoPath().projection({ stream: s => projection.stream(simplify.stream(s)) })

my projection doesn't render because z is undefined in the point function. Alternatively reversing the order the streams are called has the same result. But either stream called individually works as expected (simplify.stream calls the point function with three params and projection.stream(s) renders my map, but without dynamic simplification.

@mbostock
Copy link
Member

mbostock commented Apr 11, 2017

Hmm. We’d need to change all the parts of the projection pipeline to pass along z (transformRadians, preclip, projectResample, postclip), which is a bit of a pain, especially since it presumably adds a small amount of overhead to the common case where z is not needed.

Another option would be to call d3.geoProject on load instead of using projection.stream; then you save your projected GeoJSON and you don’t need to reproject on pan & zoom; you just apply your transform and dynamic simplification. And you don’t lose z.

If you’re using topojson.presimplify to compute z, it takes a topology as input and after d3.geoProject you have individual GeoJSON features. So you’d also need to call topojson.topology to construct a new topology after projecting.

I’m not sure if there’s a better way to do it at the moment.

@ekh64
Copy link
Author

ekh64 commented Apr 12, 2017

Thanks for the advice, I'll try out those suggestions. Really appreciate the fast response.

@gmaclennan
Copy link

I'm wondering where the best place is to highlight this in the docs? I spent a while scratching my head over this before browsing the issues and finding this. Perhaps under the docs for projection.stream()?

projection.stream(stream) <>

Returns a projection stream for the specified output stream. Any input geometry is projected before being streamed to the output stream. A typical projection involves several geometry transformations: the input geometry is first converted to radians, rotated on three axes, clipped to the small circle or cut along the antimeridian, and lastly projected to the plane with adaptive resampling, scale and translation. a projection stream, unlike a transform stream, only accepts 2D [x, y] coordinates, not 3D [x, y, z] coordinates

@mbostock
Copy link
Member

More precisely, the geometry stream implemented by projection.stream accepts an arbitrary number of dimensions as input, but only observes and outputs the first two dimensions (x and y). You could implement a geometry stream that transforms more than two dimensions, meaning that is supported by the stream interface, but it’s not currently supported by d3.geoProjection implementation.

@Fil Fil added the idea label Jul 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants