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

degreesToDistance different for Latitude and Longitude #684

Closed
stebogit opened this issue Apr 22, 2017 · 17 comments
Closed

degreesToDistance different for Latitude and Longitude #684

stebogit opened this issue Apr 22, 2017 · 17 comments

Comments

@stebogit
Copy link
Collaborator

Looking at @turf/helpers distanceToRadians and distanceToDegrees methods I noticed that if you move a point E-W or N-S of the same amount of degrees and calculate the distance between the original point and the moved point, you actually get two different distances.
Is that for some reason correct?
If so, why?
Then, how could you create for example a square from a point' that actually looks like a square? Using @turf/bearing`, due to #681, at 90˚ the end points are not at the same latitude, while varying the coordinates you don't get a square:

screen shot 2017-04-22 at 12 14 46 am

I added also some test on @turf/helpers to highlight the issue.

@DenisCarriere
Copy link
Member

Web Mercator

if you move a point E-W or N-S of the same amount of degrees and calculate the distance between the original point and the moved point, you actually get two different distances.

The Leaflet map you have in the background is using Web Mercator projection which is an equidistance projection (distances are equal only in meters NOT degrees).

Because of the earth's curvature, calculating the distance of 1 degree North does NOT equal 1 degree West. The map you are showing is accurate to represent those points the way they are.

If you decided to visualize the same thing using a Geodetic map projection (WGS84) then those two points will "look" like they have an equal distance.

Square

how could you create for example a square from a point' that actually looks like a square?

I don't think using @turf/bearing would be the appropriate tool to create a square. You could convert your LatLng coordinates to Meters, apply your distance calculations to get your 4 corners and then convert your 4 coordinates back Meters to LatLng.

@DenisCarriere
Copy link
Member

Going to close this issue, however feel free to continue the discussion if you have more questions/comments.

@stebogit
Copy link
Collaborator Author

stebogit commented Apr 24, 2017

@DenisCarriere does that mean the output of @turf/point-grid, which creates new points by coordinates (i.e. degrees right?), if represented on a Geodetic map would not then result to be a square, and distances between rows not equals?
In fact the xFactor and the yFactor used to generate new points are different.

What about the (failing) tests I added (those function did not have any tests BTW)? Are they maybe incorrect?

@DenisCarriere
Copy link
Member

Those tests are not really failing, it's just a precision issue, converting degrees to meters and meters back to degrees will have some very minor different decimals (< 10cm).

Also the distance measurement of 0.5 degree from West to East is NOT the same distance as 0.5 degree from South to North at based on the given latitude.

The higher/lower in latitude, the greater the distortion (curvature of the earth).

Solution

You might want to consider using cheap-ruler and add an extra latitude param, this library is only intended for city scale distance measurements (not across oceans). We can bring this up as it's own separate issue (would require a major version change to @turf/distance).

Tests Failing

709eff0#diff-53d607b71ed5b9cdaec1b6400fb83a8eR327

const dx = distance(point([-120, 47]), point([-120.5, 47]));
const dy = distance(point([-120, 47]), point([-120, 47.5]));

t.equal(distanceToDegrees(dx), .5, 'degrees conversion fails');
//=0.34099
t.equal(distanceToDegrees(dy), .5, 'degrees conversion fails');
//=0.5
# distanceToDegrees
not ok 51 degrees conversion fails
  ---
    operator: equal
    expected: 0.5
    actual:   0.34099872320736135
    at: Test.t (/home/travis/build/Turfjs/turf/packages/turf-helpers/test.js:327:7)
  ...
not ok 52 degrees conversion fails
  ---
    operator: equal
    expected: 0.5
    actual:   0.5000001787820836
    at: Test.t (/home/travis/build/Turfjs/turf/packages/turf-helpers/test.js:328:7)

Test Passing with latitude 0

const dx = distance(point([-120, 0]), point([-120.5, 0]));
const dy = distance(point([-120, 0]), point([-120, 0.5]));

@stebogit
Copy link
Collaborator Author

stebogit commented Apr 30, 2017

@DenisCarriere I'm still not sure about the result of the function.
If we assume the earth is a sphere (do we?) then any variation in degrees on a meridian (North-South) should correspond to an equal distance, as meridians are always equals circles. However the distance between two meridians (East-West variations in degrees) should actually depend on the latitude, as parallels are circles with different radii (smaller at higher latitudes).
Therefore I'd say the conversion distanceToDegrees (and also degreesToDistance) should then depend on the latitude as well, i.e. it should have it as input.
Otherwise the output of these turf-helpers functions is only valid at 0 latitude (like the modified test) or for North-South variations.
I added few tests in turf-distance to support this.

Any thoughts?

@DenisCarriere
Copy link
Member

@stebogit Totally agree that including a latitude as parameter is a must to calculate the distance properly (distances that span large areas will have distortions).

👍 Including a new latitude param with default value of 0, that way there should be no issues with backwards compatibility (future major releases could be changed to a required param).

@DenisCarriere
Copy link
Member

I don't remember if I've had this conversation with someone before, but why aren't we using @mapbox/cheap-ruler in Turf?

@mourner Any objections to this?

@stebogit
Copy link
Collaborator Author

stebogit commented May 2, 2017

@DenisCarriere 👍
Meanwhile should we maybe create a bug issue for degreesToDistance and distanceToDegrees to point out this unexpected behaviour to users?

@DenisCarriere
Copy link
Member

Yep, we can reopen this issue and tag it as a bug.

@stebogit
Copy link
Collaborator Author

stebogit commented May 4, 2017

@DenisCarriere I believe the issue here is just the name of the function(s), and also some confusion on my side.
The concept of distance, by definition, implies the presence of two points, while here distanceToDegrees, distanceToRadians and radiansToDistance simply convert a length (on a sphere) to a different unit of measurement.
In fact we are just passing to the functions a length (not two points), and the result of the conversion (like any unit conversion) does not depend on the position on the surface.

What causes confusion (at least to me, sorry) is the name of the functions and the fact that in the additional test I added I was actually measuring a distance (in fact using turf-distance) between two points, apart of a certain angle in degrees, and I was expecting the conversion to give me back the result in degrees. In this case though the distance between two points (along the geodesics of the spherical Earth) does depend on the latitude, but not necessarily the conversion of its length in degrees (that is true only on meridians or the equator).
Also, my bad, there is no degreesToDistance function, because that would actually be turf-distance.

Therefore the values returned by the functions under discussion are correct, but I would strongly suggest (in the next major release) to change the names for example to lengthToDegrees, lengthToRadians and radiansToLength.

What do you think?

While I was thinking about this whole thing and trying to understand the issue I modified turf-helpers and added radians2degrees and degrees2radians which I found useful.
Let me know if you'd like me to create a PR for that.

cc: @mourner @rowanwins

@stebogit
Copy link
Collaborator Author

stebogit commented May 8, 2017

@DenisCarriere any thoughts on the conversion to lengthToDegrees, lengthToRadians and radiansToLength on a future major release?
I'd remove the bug label here btw.

@DenisCarriere DenisCarriere removed the bug label May 9, 2017
@DenisCarriere
Copy link
Member

@stebogit I'm 👍 with the method renaming, pretty sure these methods are only used internally. We can include these changes in v5.0 and update the earthRadiusIn factor at the same time.

@guanzo
Copy link

guanzo commented Jun 14, 2017

Hey guys i tried to follow this conversation but geospatial discussion goes over my head :/. If I had a lat/lng pair and wanted to change the position by 1 mile in any direction, which function should i use?

@stebogit
Copy link
Collaborator Author

stebogit commented Jun 14, 2017

@guanzo if you have just a point you can use @turf/destination

var pt = turf.point([lng, lat]); // note the order
var destinationPoint = turf.destination(pt, 1, yourDirectionAngle, 'miles');

@stebogit
Copy link
Collaborator Author

stebogit commented Nov 8, 2017

@stebogit stebogit closed this as completed Nov 8, 2017
@Gefyaqiilah
Copy link

@stebogit can you tellme how you create a line with arrow like that ?

@stebogit
Copy link
Collaborator Author

@Gefyaqiilah I just edited a screenshot with Preview on Mac, nothing done with turf

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

No branches or pull requests

4 participants