1

I am trying to find the straight distance from a point C to the beach. Beach line is defined by points A and B and with the Haversine formula I get the distance from C (my marker in Google Maps) to a point D in the AB beach line perpendicular to C.

Everything works fine but the point D is not the right one. I use this code to find D:

function get_perp(C){
        var A = { lat:33.345678, lng:-117.518921 };
        var B = { lat:33.100678, lng:-117.318492 };

        t = ((C.lat-A.lat)*(B.lat-A.lat)+(C.lng-A.lng)*(B.lng-A.lng))/((B.lat-A.lat)*(B.lat-A.lat)+(B.lng-A.lng)*(B.lng-A.lng));

        var D = { lat:0,lng:0};
        D.lat = A.lat + t*(B.lat-A.lat);
        D.lng = A.lng + t*(B.lng-A.lng);

        return D;
}

Returned D point is indeed a point on the line but it is not perpendicular to C. It is when the AB line is horizontal or vertical, but when it is not the angle between AB and CD is not right.

I've tried another functions I've found here but all of them cause the same result.

In this fiddle it is the whole process and if you zoom enough you can see the AB and CD lines are not perpendicular: Shortest distance from AB to C

EDIT: playing with it in geogebra I can see the function is OK in finding the point. The error happens then when google maps api represents the point. Geogebra

Alvaro
  • 182
  • 2
  • 13
  • That is interesting. Definitely a precision error or rounding error of some sort. Or maybe something to do with the trig functions. – Robert Harvey Nov 21 '18 at 19:50
  • I've tried four different approaches and all of them return the very same point coordinates, always on the line but not the nearest/perpendicular to C. – Alvaro Nov 21 '18 at 20:19
  • If I were to guess, I'd say that the precision error is occurring somewhere in here: `t = ((C.lat-A.lat)*(B.lat-A.lat)+(C.lng-A.lng)*(B.lng-A.lng))/((B.lat-A.lat)*(B.lat-A.lat)+(B.lng-A.lng)*(B.lng-A.lng));` – Robert Harvey Nov 21 '18 at 20:23
  • I've been playing around in geogebra with the function and it's right! It always returns the exact perpendicular point so the error is when the google maps api places that point in the line. I honestly don't know why. I've edited and put the geogebra link. – Alvaro Nov 21 '18 at 23:41
  • 1
    See this [answer](https://stackoverflow.com/a/53147219/3871028), easy to port to javascript – Ripi2 Nov 22 '18 at 17:24
  • Thanks @Ripi2, I'm not sure if this solves the problem with the point representation in Google Maps API but I bookmark your solution to improve the distance calculation. – Alvaro Nov 23 '18 at 12:58
  • I'm using this code, It works but could you please add explanation what is 't' and 'D' and from where is it equation and why it works :)? – Davidos Apr 12 '21 at 16:26

2 Answers2

1

You make your calculations using plane geometry approach but they are wrong for spherical geometry. (C.f.: note that you found distance with Haversine formula, not Pythagorean formula).

At this page you can find algorithm and JS code to find cross-track distance and along-track distance (that might be used to find D point using bearing from the first point and this distance)

Cross-track distance
Here’s a new one: I’ve sometimes been asked about distance of a
point from a great-circle path (sometimes called cross track
error).

Formula:    dxt = asin( sin(δ13) ⋅ sin(θ13−θ12) ) ⋅ R
where   δ13 is (angular) distance from start point to third point
θ13 is (initial) bearing from start point to third point
θ12 is (initial) bearing from start point to end point
R is the earth’s radius
JavaScript: 
var δ13 = d13 / R;
var dXt = Math.asin(Math.sin(δ13)*Math.sin(θ13-θ12)) * R;
Here, the great-circle path is identified by a start point and 
an end point – depending on what initial data you’re working from,
you can use the formulæ above to obtain the relevant distance 
and bearings. The sign of dxt tells you which side of the path
the third point is on.

The along-track distance, from the start point to the closest 
point on the path to the third point, is

Formula:    dat = acos( cos(δ13) / cos(δxt) ) ⋅ R
where   δ13 is (angular) distance from start point to third point
δxt is (angular) cross-track distance
R is the earth’s radius
JavaScript: 
var δ13 = d13 / R;
var dAt = Math.acos(Math.cos(δ13)/Math.cos(dXt/R)) * R;
MBo
  • 77,366
  • 5
  • 53
  • 86
  • Thanks @MBo, but the problem is before I use Haversine. In the [fiddle](http://jsfiddle.net/alvarop/yknL1h6t/) I don't even use it. I calculate the point with the get_perp() function, its coordinates are _euclideanly_ right but when representing it in maps api it's not where it should. – Alvaro Nov 22 '18 at 08:50
  • Is saw that fiddle. Again - it is completely wrong to apply plane approaches to spherical coordinates. `get_perp()` is not valid here. Also note that the shortest way between points on the earth is not straight line on the map (excuding equal longitude case) – MBo Nov 22 '18 at 09:13
  • I know you must be right, problem can't be other than plane/spherical discrepancy. But I can't see why google then paints any AB line as a straight line, shouldn't it be curved? And why if I put near AB points over a straight street and then choose a C point over a perpendicular street it doesn't get it right either, even in very very short distances, where I suppose Earth curvature doesn't matter that much [image](https://imgur.com/a/aKUNB7x). – Alvaro Nov 22 '18 at 09:31
  • @MBo: IMO the distance between the points is not sufficient to explain the anomaly shown by the OP. We are inside a square of less than 1°. –  Nov 22 '18 at 09:47
  • Shortest path is great circle arc, it should be curved for far points. But gmap draws connecting line straight on the map (not geodesics/loxodrome/smth else) - I checked for 9000 km airplane route – MBo Nov 22 '18 at 09:48
  • @Yves Daoust But 1 degree arc length by longitude and latitude differs in cos(lat) times. It is one of possible reasons. – MBo Nov 22 '18 at 09:50
  • @MBo: this effect is of the second order, on a delta of about 0.0045 radians. –  Nov 22 '18 at 10:04
  • @Yves Daoust But there might be another factors - projection does not show angles as-is and so on. So I think that gmap picture cannot prove or disprove that calculation is correct/wrong. – MBo Nov 22 '18 at 10:09
  • API lines are indeed great circle arcs [California-Morocco](http://jsfiddle.net/alvarop/uek1h05t/2/), completely imperceptible in my case with less than 1' lat difference from A to B, even less in long. – Alvaro Nov 22 '18 at 10:53
  • OK. Title says that your primary goal is to find correct distance from point to point-point line. Correct approach is described in my citation. Why GMap shows weird things? - it is the secondary question, I hope. – MBo Nov 22 '18 at 11:01
  • Exact phrasing is "shortest to a line", not "correct". So you should convert the points to 3D Cartesian coordinates and compute the Euclidean distance to a straight line, not to a great arc. ;-) –  Nov 22 '18 at 11:12
  • I just wanted to calculate the distance from any selected house to the beach, what I seemed to do right, problem came when I thought about representing that distance so the client knows how it was measured. Then I saw the angle wasn't right in the representation and I'm thinking to just say "xxx meters approx." and don't paint the line because... you know, lawyers :) – Alvaro Nov 22 '18 at 11:33
1

As far as I can see, your formula for D is correct, and the linear approximation is justified at such a small scale (deltas about a quarter of a degree; relative errors due to non-linearity should be on the order of 10^-5).

What you see can be due to the fact that the map projection is not conformant (does not preserve angles), so that the angle is not displayed as right. But the point is correct.

Do you know which projection they use ?


Bingo, the angle is right, just a display artifact due to the projection.

enter image description here

  • I googled it and it seems Google Maps changed the projection used 3 months ago. Now they use an azimuthal perspective projection (aka vertical perspective projection). Projection before was [Web Mercator](https://en.wikipedia.org/wiki/Web_Mercator_projection). But I don't really know if GMaps API still uses Mercator since if you zoom all the way out with the API you can't see the sphere of the Earth, as happens in Google Maps now. – Alvaro Nov 22 '18 at 10:37
  • @Alvaro: if you can display the meridians and parallels, you'll soon know. –  Nov 22 '18 at 10:53
  • IMO, correction for Earth curvature is unnecessary. –  Nov 22 '18 at 11:10
  • Just saw your edit... so, this means vertical distances are represented longer than horizontal distances? If so, objects like street roundabouts shouldn't appear oval-shaped? – Alvaro Nov 22 '18 at 11:48
  • @Alvaro: the red rectangle is 0.1° lat and long. –  Nov 22 '18 at 14:35