-
Notifications
You must be signed in to change notification settings - Fork 953
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
transformTranslate distorts the polygon shape #2419
Comments
@just-ajs though without seeing much details, from your little code I believe the issue could be due to mercator projection when you translate your polygon way up north. |
Hi @just-ajs. Do you still have the geojson used to generate the screenshots above? Would you mind attaching them to this issue so we can reproduce it? |
The implementation seems to translate each vertex of the shape individually instead of really moving the shape. I had the exact same issue in my naive implementation and was therefore looking for an existing library doing this job for me. Alas, turfjs does the same thing. You see what's going on in this notebook. |
Hi @jtheisen. Would you mind making your notebook public? Can't access it currently. |
@smallsaucepan Sorry, it's public now. |
Thanks @jtheisen. Can access it now. From what I can see this is the expected behaviour. transformTranslate currently only works on a 2d projection. What looks distorted on a globe: Looks as expected when projected in 2D: The problem reported by OP is definitely an issue, though that distortion only occurs when the geometry is also moved laterally. We see that with the green square: Hope that helps to explain what you're seeing. Any remaining questions though, please drop us a node. |
@smallsaucepan thanks for the response. I still believe this is ultimately the same issue for both me and @just-ajs, it's just that translating a rectangle straight north happens to not distort it when projected equirectangularly. I believe what the function is doing internally is simple moving all points of the shape along the Rhumb lines, which will never really preserve shapes under any projection, even Mercator itself (where the Rhumb lines are straight) - I may be mistaken though, I'm not very familiar with this. I would recommend two things. At the very least, update the documentation for this function. Currently, the page doesn't mention any projection at all, so I think it's reasonable to assume that it would translate the shape on the sphere, and we agree that's not what it's doing. As a second much more distant suggestion I wonder why the semantics I was expecting aren't offered as well. I've searched around a bit and I can't find a library implementation of this anywhere (in js). This is needed for example in those "see how big this country is when placed here next to this other on the globe" type of renderings (You could also draw two things on top of each other and use two different projections, one rotated. That works, but I use observable.Plot, and that doesn't let me use two projections in one chart). Implementation-wise, it would probably have to transform the coords into 3-vectors, then rotate them together, and then convert each of them back. (That would move them along great circles, not Rhumb lines though.) Maybe there's also some tricky stuff with meridian cutting again. |
To those souls who find this issue and need a solution, here's a way to do this using threejs: function makeRotateSphere(x, y, z, a) {
const f = (2 * Math.PI) / 360;
const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(new THREE.Vector3(x, y, z), a * f);
const v = new THREE.Vector3();
const s = new THREE.Spherical(1, 0, 0);
return function rotate([longitude, latitude]) {
const polar0 = 90 - latitude;
const azimu0 = longitude;
s.radius = 1;
s.phi = polar0 * f;
s.theta = azimu0 * f;
v.setFromSpherical(s);
v.applyQuaternion(quaternion);
s.setFromVector3(v);
return [s.theta / f, 90 - s.phi / f];
};
}
|
Hi @jtheisen.
Agree that does seem to be the root of the problem with the skewing shown in the original post. What I was getting at though was fixing the skewing won't necessarily fix your issue as well. Even when operating correctly the kind of translation offered (planar) would still give you coords that render as a narrowing polygon if laid out on a sphere. Understand that isn't what you want. Unfortunately though Turf doesn't currently offer both planar and spherical implementations for many functions.
It's just resourcing. Over time Turf has become a mix of planar and spherical implementations, and making that cohesive takes time, especially with it being a volunteer run project.
For sure. Would you like to contribute by submitting a PR to add some clarifying notes? |
@smallsaucepan Sure, I made a pull request in the doc repo: |
Btw, I was more puzzled about this kind of thing not being anywhere to be found in the js world, not specifically in turfjs. I kind of expected it to be in d3. |
Oh, got you. Not sure why it isn't elsewhere. Might be more people in that space turn to python or a similar science-y language first. Thanks for submitting that PR. Would you mind though adding those lines in the Turfjs/turf repo instead? The docs in turf-www are generated automatically from the comments in the code. https://github.com/Turfjs/turf/blob/master/packages/turf-transform-translate/index.ts Then we can do a doc generation run and that will go out to the website. |
There's a new pull request, #2831, and I've removed the old one. |
Awesome. Thank you! |
Turf 6.5.0
TransformTranslate distorts the shape when translated across bigger distances, this is visible in this example, when used transformTransalte with parameters 2000, 66.
const leningrTranslated = transformTranslate(leningr.data, 2000, 66);
The original shape:
![image](https://user-images.githubusercontent.com/35227625/227900140-eb1dd03b-8df7-4eb1-8b6e-2b113ef9ab6f.png)
And transformed shape:
![image](https://user-images.githubusercontent.com/35227625/227900233-c816a1ee-9d49-4639-9322-5243c941ce9e.png)
The text was updated successfully, but these errors were encountered: