29

How can I compute the average between several latitude and longitude spots?

Should I just compute the Arithmetic mean for both lat and lng?

3
  • 3
    I think the appropriateness of averaging depends on your use case. If you are just clustering city restaurant locations for a web map, sure averaging will work most of the time. However you will get bugs in some places.. for a prototype or low budget app maybe that's ok. However, if you are doing something more serious or covering a wide area then you probably need to take projection nuances into account.
    – Glenn
    Mar 23, 2011 at 14:22
  • 1
    How were these points collected? Instead of asking how to average the coordinates, maybe ask if averaging is an appropriate way to compensate for measurement errors. This ebook has a lot of error definitions. Mar 23, 2011 at 14:40
  • Just a note that there are some edge cases where an 'average point' is not well-defined: e.g. anywhere along the equator could conceivably be the "average" of the N. and S. poles.
    – Dan S.
    Mar 24, 2011 at 20:28

3 Answers 3

19

For a simple mean, you do not want to average the longitude and latitude coordinates. This might work pretty well at lower latitudes, but at higher latitudes it will begin to give poor results and completely break down near the poles.

The method I've used for this type of thing is to convert the longitude/latitude coordinates to 3d cartesian coordinates (x,y,z). Average these (to give a cartesian vector), and then convert back again. Note that you probably do not need to normalize the vector, so the actual average process could be a simple sum.


Edit, here is my code:

The following converts cartesian coordinates to latitude/longitude (in degrees): Remove the RAD2DEG constants for radians.

Latitude = MPUtility.RAD2DEG * Math.Atan2(z, Math.Sqrt(x * x + y * y));
Longitude = MPUtility.RAD2DEG * Math.Atan2(-y, x);

And here we calculate cartesian coordinates from latitude/longitude (specified in radians):

private void CalcCartesianCoord()
{
    _x = Math.Sin(LatitudeRadians) * Math.Cos(LongitudeRadians);
    _y = Math.Sin(LatitudeRadians) * Math.Sin(LongitudeRadians);
    _z = Math.Cos(LatitudeRadians); 
}

Both are cut & pasted from real code, hence the mix of degrees and radians. There are properties here which do some of the conversions (eg. LatitudeRadians is a property that returns a radian value).

Note that optimization is possible: the duplicate sine calculations, for instance. Also the trig calculations might be cacheable if you call them a lot.

13
  • 1
    great point. I can't believe I forgot to mention that.. averaging near the poles and date line has bitten me before.
    – Glenn
    Mar 22, 2011 at 15:29
  • 3
    (+1) The problem is not confined to the poles and the +-180 degree meridian: when the latitudes of the points to be averaged vary considerably, a straight averaging of lat/lon coordinates is tantamount to using a Plate Carree projection, which introduces a variable metric distortion increasing with latitude. There are no numerical problems but the average is simply in the wrong location. For this reason the lat/lon calculations suggested in @Glenn's answer are rarely acceptable except for relatively small non-polar regions.
    – whuber
    Mar 22, 2011 at 16:15
  • @winwaed thanks, can you suggest some (Java) code snippet or good tutorial to do this ?
    – aneuryzm
    Mar 23, 2011 at 6:20
  • 1
    The math is at en.wikipedia.org/wiki/Spherical_coordinates under 'Cartesian Coordinates'. (my implementation is C# and partly optimized - plus I'm typing this at the dentists!!)
    – winwaed
    Mar 23, 2011 at 13:05
  • 1
    I think for precise engineering use cases you are very correct. However, unless extreme precision is required, averaging WGS84 lat, lng coordinates in city and even regional areas works pretty darn well and gives results that are acceptably accurate for most uses where averaging would be used.
    – Glenn
    Mar 23, 2011 at 14:10
6

Clustering Options: I think the conceptual buzz word that covers this type of operation is "clustering". Averaging is by far the simplest to implement and works well for most purposes. The only time I would use something else is if you are worried about outliers [Edit]-> or the poles or the international dateline. [Edit]--> also averaging, while it will give you something that looks close to the center of the cluster, will be a little bit off because of projection inaccuracies caused by the fact that degrees lat lng aren't always the same distance apart in km/miles. The larger the area you average over the more the distortion.

Here is a comparison of a few clustering options

Average (easy, fastest, inaccurate): just sum the lat values & divide by the count and do the same for the lng values. Be sure to look out for overflow if you are using an Int32 some systems (notably c#) will silently overflow back to the low numbers. You can avoid these erros by using floating point precision for your sum accumulator. One problem with this method is that outliers could skew your location. [Edit]-> Another is that math near the poles and international date line doesn't average well and will skew locations badly.

Nearest Neighbor (a little harder, slower, not outlier biased) Rather than averaging you could go with the actual lat lng location with the smallest average distance to all its neighbors. This is kind of like taking a "median". The down side is that this is computationally expensive because you compare every point to every other point and calculate the distance between them. For example, clustering 10,000 points would require 100 million distance calculations.. not that slow but it definitely doesn't scale well.

Grid Cell (needs a little extra setup, much faster, not outlier biased) This is similar to nearest neighbor but much faster. You could pick an arbitrary level of precision, say .01 deg lat lng (which is about 1km roughly at populated lattitudes) and group your points into .01 x .01 degree buckets. You could then pick the bucket with the most points in it and either take the average of those points or run a nearest neighbor analysis on just those points. I use this method a lot with really big datasets (hundreds of billions of records) and find it a nice balance between precision and speed.

Convex Hull Centroid (hard, slower, neat results): You could also draw a band around your points to define a shape that covers them all (see wikipedia), and then calculate the center point of this shape. Typical centroid functions aren't center weighted so you would need to so some kind of inverse nearest neighbor analysis using sample points inside your shape until you found the one furthest from the edges. This method is really more interesting because of the convex hull itself rather than the actual center finding algorithm which is neither fast nor particularly precise.. but the hull shape may have other useful applications with your data.

2
  • @winwaed makes a great point about averaging coordinates near the poles and I would also add the international date line. For example if you have one point on one side and one on another you get some bad averages (and also bounding boxes). This rarely comes up, but when it does it is a real pain to debug
    – Glenn
    Mar 22, 2011 at 15:27
  • @whuber makes a good point about center drifting when you average. While averaging will give you something that looks close to the center of the cluster, will be a little bit off because of projection inaccuracies caused by the fact that degrees lat lng aren't always the same distance apart in km/miles. The larger the area you average over the more the distortion.
    – Glenn
    Mar 23, 2011 at 14:17
0

Not sure what you're trying to achieve, but the point whose latitude is the avg of lattitudes of the original point set and longitude is the avg of longitudes of the original point set, will be the avg point of the original point set. [UPDATE]: In the above, avg is the arithmetic mean.

2
  • In your answer, avg = Arithmetic mean ?
    – aneuryzm
    Mar 22, 2011 at 10:55
  • 1
    Yes, correct. That's what I meant sorry for the lack of clarity. I updated the answer. But I'm not sure I'm bringing something terribly useful to the table here...
    – GuillaumeC
    Mar 22, 2011 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.