views:

2129

answers:

5

In a system level programming language like C, C++ or D, what is the best type/encoding for storing latitude and longitude?

The options I see are:

  • IEEE-754 FP as degrees or radians
  • degrees or radians stored as a fixed point value in an 32 or 64 bit int
  • mapping of an integer range to the degree range: -> deg = (360/2^32)*val
  • degrees, minutes, seconds and fractional seconds stored as bit fields in an int
  • a struct of some kind.

The easy solution (FP) has the major down side that it has highly non uniform resolution (somewhere in England it can measure in microns, over in Japan, it can't). Also this has all the issues of FP comparison and whatnot. The other options require extra effort in different parts of the data's life cycle. (generation, presentation, calculations etc.)

One interesting option is a floating precision type that where as the Latitude increase it gets more bits and the Longitude gets less (as they get closer together towards the poles).

Related questions that don't quite cover this:


BTW: 32 bits gives you an E/W resolution at the equator of about 0.3 in. This is close to the scale that high grade GPS setups can work at (IIRC they can get down to about 0.5 in in some modes)

I don't have a specific use in mind right now but have worked with this kind of thing before and expect to again, at some point.

+6  A: 

The easiest way is just to store it as a float/double in degrees. Positive for N and E, negative for S and W. Just remember that minutes and seconds are out of 60 (so 31 45'N is 31.75). Its easy to understand what the values are by looking at them and, where necessary, conversion to radians is trivial.

Calculations on latitudes and longitudes such as the Great Circle distance between two coordinates rely heavily on trigonometric functions, which typically use doubles. Any other format is going to rely on another implementation of sine, cosine, atan2 and square root, at a minimum. Arbitrary precision numbers (eg BigDecimal in Java) won't work for this. Something like the int where 2^32 is spread uniformly is going to have similar issues.

The point of uniformity has come up in several comments. On this I shall simply note that the Earth, with respect to longitude, isn't uniform. One arc-second longitude at the Arctic Circle is a shorter distance than at the Equator. Double precision floats give sub-millimetre precision anywhere on Earth. Is this not sufficient? If not, why not?

It'd also be worth noting what you want to do with that information as the types of calculations you require will have an impact on what storage format you use.

cletus
a valid point, but not addressing what I was hoping to have addressed.
BCS
this answer is what I would have given also - think you need to clarify your question if it does not answer it.
frankodwyer
I agree that this answers the question as asked. Most commercial systems that I've used employ FP degrees or radians internally. The lack or uniformity is a function of the definitions of lattitude and longitude, not the way they're stored.
Ken Paul
Do not forget that the math functions in C (and most languages) expect arguments in radians. Any system storing the value in degrees will need to convert to radians before using the math functions. That doesn't mean that storing in degrees is wrong; indeed, it is probably best. But be aware.
Jonathan Leffler
+2  A: 

Longitudes and latitudes are not generally known to any greater precision than a 32-bit float. So if you're concerned about storage space, you can use floats. But in general it's more convenient to work with numbers as doubles.

Radians are more convenient for theoretical math. (For example, the derivative of sine is cosine only when you use radians.) But degrees are typically more familiar and easier for people to interpret, so you might want to stick with degrees.

John D. Cook
a valid point, but not addressing what I was hoping to have addressed. (I've edited the question to clarify)
BCS
What resolution do you require?
cletus
@cletus, Uniform resolution is more of interest than high resolution but 32 bits uniformly spread is within an order of magnitude of anything I see needing.
BCS
Bear in mind that when it comes to longitude at least, the *earth* isn't uniform. 1 second of longitude at the Arctic Circle is a different distance than at the Equator. Why do you want/need uniformity?
cletus
FP works because most of the time the resolution that number is known to is proportional to it's magnitude. for Lat/Long the the zero point is totally arbitrary so that proportionality is not there. It seems bad to use n-bits and then in some places burn some of them for useless resolution.
BCS
+1  A: 

Might the problems you mentioned with floating point values become an issue? If the answer is no, I'd suggest just using the radians value in double precision - you'll need it if you'll be doing trigonometric calculations anyway.

If there might be an issue with precision loss when using doubles or you won't be doing trigonometry, I'd suggest your solution of mapping to an integer range - this will give you the best resolution, can easily be converted to whatever display format you're locale will be using and - after choosing an appropriate 0-meridian - can be used to convert to floating point values of high precision.

PS: I've always wondered why there seems to be no one who uses geocentric spherical coordinates - they should be reasonably close to the geographical coordinates, and won't require all this fancy math on spheroids to do computations; for fun, I wanted to convert Gauss-Krüger-Koordinaten (which are in use by the German Katasteramt) to GPS coordinates - let me tell you, that was ugly: one uses the Bessel ellipsoid, the other WGS84, and the Gauss-Krüger mapping itself is pretty crazy on it's own...

Christoph
For "fun"?! Sicko! :-)
cletus
I have no idea what you said. So +1
Greg Dean
@Greg: Gauss-Krüger coordinates are derived from cylinder projections but 'enhanced' so that you get meaningful results when using your ruler on a map (for certain values of 'meaningful' ;)). It all began when I thought: hey, this shouldn't be too complicated...
Christoph
A: 

0.3 inch resolution is getting down to the point where earthquakes over a few years make a difference. You may want to reconsider why you believe you need such fine resolution worldwide.

Some of the spreading centres in the Pacific Ocean change by as much as 15 cm/year.

Greg Hewgill
0.3in is for uniform cases. with a 32bit FP who known what you get as lots (most?) of values are no longer valid.
BCS
A: 

If by "storing" you mean "holding in memory", the real question is: what are you going to do with them?

I suspect that before these coordinates do anything interesting, they will have been funnelled as radians through the functions in math.h. Unless you plan on implementing quite a few transcendental functions that operate on Deg/Min/Secs packed into a bit field.

So why not keep things simple and just store them in IEEE-754 degrees or radians at the precision of your requirements?

natevw
For in memory, yah, not much will beat IEEE. On the other hand If you are storing lots of points (say high resolution vector maps) on disk or shipping them across a wire...
BCS