javascriptmathlatitude-longitude

Lat/Long equation in Javascript


I am trying to find an equation for finding the lat/long point between two lat/long points in Javascript. It would work something like this.

getMiddle(lat1, lng1, lat2, lng2) <= would return [lat3, lat3] halfway distance wise (going around the earth obviously).

I found this:

Link

Date: 10/11/2001 at 11:41:08 From: Doctor Rick Subject: Re: Determining lat and long of a point between two given points

Hi, Chuck.

This will probably be a little more complicated than you think. The easiest way for me to do it is to think in terms of vectors. Some of the items in our Archives on the topic of latitude and longitude use the vector approach, so you can see them for background. For example:

Distance Between Two Points on the Earth
Link

Let's call the two points A and B, and choose a rectangular coordinate system in which the equator is in the x-y plane and the longitude of point A is in the x-z plane. Let lat1 be the latitude of A, let lat2 be the latitude of B, and let dlat be the longitude of B minus the longitude of A. Finally, use distance units such that the radius of the earth is 1. Then the vectors from the center of the earth to A and B are

A = (cos(lat1), 0, sin(lat1)) B = (cos(lat2)*cos(dlon), cos(lat2)*sin(dlon), sin(lat2))

Point C, the midpoint of the shortest line between A and B, lies along the sum of vectors A and B. (This works because A and B have the same length, so the sum of the vectors is the diagonal of a rhombus, and this diagonal bisects the angle.)

A+B = (cos(lat1)+cos(lat2)*cos(dlon), cos(lat2)*sin(dlon), sin(lat1)+sin(lat2))

To get the actual vector C, we need to scale this vector to length R so it ends at the surface of the earth. Thus we have to divide it by |A+B|, that is, the length of vector A+B. That would get pretty messy. But we can find the latitude lat3 and longitude difference (lon3-lon1) by looking at ratios of the coordinates of A+B, and these ratios are the same whether we scale the vector or not. To see this, look back at the formula for vector B. Knowing that vector, we can recover lat2 and dlon:

dlon = tan^-1(B_y/B_x) lat2 = tan^-1(B_z/sqrt(B_x^2+B_y^2))

Here, B_x, B_y, and B_z are the x, y, and z coordinates of vector B.

We can do the same thing with vector A+B to find the latitude and longitude of point C:

dlon3 = tan^-1(cos(lat2)*sin(dlon)/ (cos(lat1)+cos(lat2)*cos(dlon))) lat3 = tan^-1((sin(lat1)+sin(lat2))/ sqrt((cos(lat1)+cos(lat2)*cos(dlon))^2+ (cos(lat2)*sin(dlon))^2))

That's the formula you seek. Since both formulas involve division, we must consider the special cases. The longitude calculation fails when C_x = 0, that is, when C is 90 degrees away from A in longitude, so dlon3 will be +90 or -90; the sign depends on the sign of dlon. The latitude calculation fails when C_x and C_y are both zero, thus we know that in this case, lat3 = 0. A complete algorithm will check for these cases, but they won't occur if you're interested only in the continental US.

When I plug in the latitudes and longitudes for LA and NYC, I get:

LA 34.122222 118.4111111 NYC 40.66972222 73.94388889 midpt 39.54707861 97.201534

I hope this is helpful to you.

  • Doctor Rick, The Math Forum Link

Which I believe has the answer but not as Javascript.

This is what I am working with:

image of the 3D globe

I have spent some time creating map point and determining distance between them, but to find a midway point between them has been difficult for me. Converting equations I have found so far has been unsuccessful.

Once I can find the midpoint I want to use recursion + (how many points I need between two points based on distance) to build properly spaced dotted lines.

Any help on this piece would be greatly appreciated.


Solution

  • Answer in python: http://code.activestate.com/recipes/577713-midpoint-of-two-gps-points/

    Additionally: For those wanting to go straight to profit (yes I know I patched Math. Borrowed shamelessly from here: https://nickthecoder.wordpress.com/2012/04/15/radian-and-degree-conversion-in-javascript/)

    getMidpoint: function(lat1, lng1, lat2, lng2) {
        Math.degrees = function(rad) {
            return rad * (180 / Math.PI);
        }
        Math.radians = function(deg) {
            return deg * (Math.PI / 180);
        }
        lat1 = Math.radians(lat1);
        lng1 = Math.radians(lng1);
        lat2 = Math.radians(lat2);
        lng = Math.radians(lng2);
        bx = Math.cos(lat2) * Math.cos(lng - lng1)
        by = Math.cos(lat2) * Math.sin(lng - lng1)
        lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + bx) * (Math.cos(lat1) + bx) + Math.pow(by, 2)));
        lon3 = lng1 + Math.atan2(by, Math.cos(lat1) + bx);
        return [Math.round(Math.degrees(lat3), 5), Math.round(Math.degrees(lon3), 5)]
    }