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

transform-translate does not preserve geometric angles and distances #2774

Open
hadbn opened this issue Dec 17, 2024 · 5 comments · May be fixed by #2775
Open

transform-translate does not preserve geometric angles and distances #2774

hadbn opened this issue Dec 17, 2024 · 5 comments · May be fixed by #2775

Comments

@hadbn
Copy link
Contributor

hadbn commented Dec 17, 2024

When using this function, the translation is performed on each point independently, without considering the geometry of the feature as a whole.
As a result, the translation of a circle, for example, will no longer be a circle, which can be prejudicial.

Reproduced with Turf version 7.1 running at https://turf-sandbox.netlify.app/ with the following code :

const p = turf.point(  [-30., 40]);

//blue : original circle around p
const c0 = turf.circle(p, 1000);
const c0_col = turf.polygon(c0.geometry.coordinates, {fill: '#0FF'});

//red : transformTranslate of the blue circle
const c1 = turf.transformTranslate(c0, 1000, 30); //red
const c1_col = turf.polygon(c1.geometry.coordinates, {fill: '#ff0000'});

//green : circle around the transformTranslate of the center of the blue one
const p1 = turf.transformTranslate(p, 1000, 30);
const c11 = turf.circle(p1, 1000);
const c11_col = turf.polygon(c11.geometry.coordinates, {fill: '#00ff00'});

return turf.featureCollection([c0_col, c11_col, c1_col]);

image

It would be useful to add a parameter to the function, allowing the user to decide whether or not to keep the geometric properties of the feature given as input.

@smallsaucepan
Copy link
Member

Thanks @hadbn

This seems like a limitation of tranformTranslate. rhumb-translating individual points is bound to distort especially away from the equator. Best illustration I can think of is the red and blue lines are both 8000km long:

Screenshot 2024-12-20 at 23 12 53

Another probable example of this is at #2419

So, your PR seems like a good approach. However I don't think the user should have to opt in. The corrected behaviour should be the default.

Will get a second opinion though. What do you think @mfedderly @JamesLMilner @rowanwins. Can we just fix the bug and not treat this as something the user needs to opt in to? Perhaps we would need to clarify in the docs that translation uses the centroid as the reference point.

Or is this somehow the expected behaviour?

@hadbn
Copy link
Contributor Author

hadbn commented Jan 30, 2025

Did you have a chance to discuss that, @smallsaucepan @mfedderly @JamesLMilner and @rowanwins ?
If you have any suggestion or if you are willing to change the default behaviour, I can update the pull request I made.

@smallsaucepan
Copy link
Member

smallsaucepan commented Feb 2, 2025

Haven't heard further from anyone else. My inclination is for us to do two things:

  1. fix this so the default behaviour works and displays properly on a mercator projection, no additional option required
  2. use this function as a model for how we document whether an implementation supports mercator projection, spherical earth, or both

Would you be happy with the approach described in point 1?

For point 2 I'd like to see something like the below on the website eventually - map and / or globe indicating support for planar or spherical calculations. Maybe as text as well below the description.

Image

Note that we generate both the README.md files and the website content, so we can add some special handling to the parsing of the JSDoc description contents.

https://github.com/Turfjs/turf/blob/master/packages/turf-transform-translate/README.md
https://turfjs.org/docs/api/transformTranslate

Perhaps something like this could work?

/**
 * Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line
 * on the provided direction angle.
 *
 * [method:planar]
 * [method:spherical]
 *
 * @function
 * ...

transformTranslate would currently only be [method:planar].

This is something we ultimately hope to apply to all Turf functions.

@hadbn
Copy link
Contributor Author

hadbn commented Feb 13, 2025

I'm not sure to understand what you mean :

whether an implementation supports mercator projection, spherical earth, or both

From what I understand, Turf provides geometry calculation tools for georeferenced applications (manipulating longitude-latitude coordinates), but is agnostic as to how the results are represented. The distinction between mercator projection and spherical projection therefore only concerns the rendering engine used to display results.

In consequence I'm not sure what to do concerning that :

fix this so the default behaviour works and displays properly on a mercator projection

Does it correspond to the implementation I made on this PR : #2775 ? Should I delete the parameter aroundCenter and always consider it as true ?

Is there anything I don't understand ?

@smallsaucepan
Copy link
Member

but is agnostic as to how the results are represented. The distinction between mercator projection and spherical projection therefore only concerns the rendering engine used to display results

That's not entirely accurate. The distinction is still meaningful in the Turf space because we (for example) tell you if a point is on a line. However, the path your line takes along the ground depends on whether you lay out the intermediary points on a 2D projection or a spherical object.

Take a line from [0,0] to [50,50] for example. Today, booleanPointOnLine reports that yes a point at [25,25] is on that line. Which is intuitive enough if you're doing 2D math. It's halfway up the slope.

When calculated on a spherical surface though, [25,25] is not on that line. The point approx 1/50th along that line isn't [1,1] - it's closer to [0.709459,1.1035579].

So some Turf modules use 3D / spherical / great circle calculations, while others do 2D / mercator / rhumb calculations. That's partly history, and partly having to rely on third party libraries. That's what the documentation enhancements are meant to clarify.

Does that help identify the underlying issue? Broadly speaking I mean.

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

Successfully merging a pull request may close this issue.

2 participants