Hi! Firstly, thanks for the crate!
Currently in osmio, Lat/Lon is represented by a f32, but sometimes this is not precise enough for osm data, which is spec'd to 7 decimal places.
from https://wiki.openstreetmap.org/wiki/Node:
decimal number [...] with 7 decimal places
...
Do not use IEEE 32-bit floating point data type since it is limited to about 5 decimal places for the highest longitude.
My understanding is that the internal representation is a scaled 32bit integer
A 32-bit method used by the Rails port is to use an integer (by multiplying each coordinate in degrees by 1E7 and rounding it
So, as I understand it, 1.234567890
degrees would be stored as 12345678i32
Looks like libosmium also uses this representation internally.
My intuition is that the lon/lat types you've currently defined should become structs backed by an i32, with some in/out methods, including something like lat.to_f64()
(but probably not a lat.to_f32()
).
And, just to be clear, I expect that this would break a lot of consumers code, who are already coding around these things being f32's. For a lot of end user applications, the precision probably doesn't make a difference, but I think for a parsing library like this (and libosmium) it makes a lot of sense to respect the upstream precision model.
The 7 rounded decimal places for coordinates in degrees define the worst error of longitude to a maximum of ยฑ5.56595 millimeters on the Earth equator, i.e. it allows building maps with centimetric precision. With only 5 decimal places, the precision of map data would be only metric [(within a meter)], causing severe changes of shapes for important objects like buildings, or many zigzags or angular artefacts on roads.
What do you think @amandasaurus?
If you're interested in the concept, but don't have time for the work, this is something I'd be interested in working on.