omniscale/imposm3

Coordinates in Imposm dataset does not match those in original data

rouen-sk opened this issue · 5 comments

I am using imposm-0.11.1-linux-x86-64 along with Osmosis for the same dataset, and there is following issue with created geometries:
It seems that Imposm import geometries with slightly changed coordinates. At first I thought this may be some rounding issue, but opposite is true: Imposm geometries have MORE decimal places than original data somehow?

For example, OSM node 1919896914 is part of administrative boundary of Czech Republic (way 302662933), and has coordinates POINT(16.9740102 50.4177556) (as seen on https://www.openstreetmap.org/node/1919896914) and also im my Osmosis-created postgis database.
In Imposm dataset (created from the same PBF), I don't have this point as standalone feature, but it is part of the admin area polygon, and when I find it (by dumping points of exterior ring of that admin area polygon), it looks like this: POINT(16.97401018797831 50.41775557053805)

This causes Imposm polygon to be a tiny bit "larger" on that side (country boundary is shifted few milimeters), but it is enough for some operations (like ST_Contains for some points) to give incorrect results.

Since I dont have tools to view raw PBF data right now, I can't know for sure, how the coordinates look like in source data. But OSM specification says coordinates should be 7-decimal places: https://wiki.openstreetmap.org/wiki/Node

Is there a way to force Imposm to use 7-decimal places for coordinates, so the resulting geometries would exactly match those imported with Osmosis (or other OSM-based datasets)?

To make it even worse, you can't even use workaround like this reliably: ST_GeomFromText(ST_AsText(geometry, 7), 4326) AS geometry
For example OSM node 658686588, in original data: POINT(16.9660466 50.4243161), in Imposm data POINT(16.966046541773153 50.424316086151975), for which the workaround will produce POINT(16.9660465 50.4243161) (notice the different last digit of longitude)

I also see this, for example with OSM ID 130159445, Imposm produces (51.4182744347945, -0.178266358100899) compared to OpenStreetMap source of (51.4182745, -0.1782663)

Maybe the pattern is that for lon, the result should be rounded down to the floor of 7th decimal, while for lat, it should be rounded up to the ceil of 7th decimal?

@rouen-sk :

Is there a way to force Imposm to use 7-decimal places for coordinates,
so the resulting geometries would exactly match those imported with Osmosis (or other OSM-based datasets)?

not tested .. but probably
You have to modify the inner cache conversion code, and add a 7digit rounding as you like.
probably 1 line change

const coordFactor float64 = 11930464.7083 // ((2<<31)-1)/360.0
func CoordToInt(coord float64) uint32 {
return uint32((coord + 180.0) * coordFactor)
}
func IntToCoord(coord uint32) float64 {
return float64((float64(coord) / coordFactor) - 180.0)
}

in original data: POINT(16.9660466 50.4243161), in Imposm data POINT(16.966046541773153 50.424316086151975)

example:

the 16.9660466 --> 16.966046541773153

>>> # CoordToInt  in Python3
>>> int( (16.9660466 + 180.0) * 11930464.7083 ) 
2349896467
>>> # IntToCoord
>>> ( 2349896467.0 / 11930464.7083) - 180
16.966046541773153
>>> 

the 50.4243161 --> 50.424316086151975

>>> int( (50.4243161 + 180.0) * 11930464.7083 ) 
2749069171
>>> (2749069171.0 / 11930464.7083) - 180
50.424316086151975

@ImreSamu yep, I was actually looking at that line exactly I tried to fix it, but I am not Go programmer, so I used ubuntu VM and could not compile the project in reasonable time (there were un-googleable dependencies failures) so I gave up.