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:

I added also some test on @turf/helpers to highlight the issue.
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.
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.
Going to close this issue, however feel free to continue the discussion if you have more questions/comments.
@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?
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).
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).
https://github.com/Turfjs/turf/commit/709eff00c1de771c39b04932ab5c55f93d60a6ee#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)
const dx = distance(point([-120, 0]), point([-120.5, 0]));
const dy = distance(point([-120, 0]), point([-120, 0.5]));
@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?
@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).
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?
@DenisCarriere 馃憤
Meanwhile should we maybe create a bug issue for degreesToDistance and distanceToDegrees to point out this unexpected behaviour to users?
Yep, we can reopen this issue and tag it as a bug.
@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
@DenisCarriere any thoughts on the conversion to lengthToDegrees, lengthToRadians and radiansToLength on a future major release?
I'd remove the bug label here btw.
@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.
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?
@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');
lengthToDegrees, lengthToRadians and radiansToLength renamed in #1055earthRadius converted with #1012
Most helpful comment
@guanzo if you have just a point you can use
@turf/destination