-
Notifications
You must be signed in to change notification settings - Fork 1
aberrant node id #3
Description
The formula exposed to compute node id is totally aberrant, a complete non-sense.
It is not at all an "hash" but a should just be a transform of 2D coordinates in a rounding grid into a cell-number inside that grid.
The "layer" parameter brings nothing except a change of scaling for node ids.
The final rounding is misplaced as well (it is applied to the scaled id, but individual coordinates on the grid were still not rounded.
A more correct formula is simply:
round(mod(lat, 360), precision) + round(mod(lon, 360) , precision) * 360*10^precision
(the "layer" multiplier is simply removed, it should not even have been a multiplier but an additive constant, multiple of 360360100^precision.
I just hope that such formula has never been used to import geometries into OSM with false connections connecting random numbers at completely unrelated 2D coordinates.
But the best formula is:
ST_quad(round(mod(lat, 360)/360*2^zoom), round(mod(lon, 360)/360*2^zoom))
where both coordinates in degrees are first reduced in the range from 0.0 inclusive to 360.0 exclusive, then reduced to the range 0.0 inclusive to 1.0 by dividing them by 360, then multipled by 2^zoom to bring them to the range from 0.0 inclusive to 2^zoom exclusive before rounding t hem to integers; then both coordinates are interleaved bit by bit using ST_quad.
This still leaves the possibility that points may have two node ids for antipodic positions. To solve it, latitudes should be reduced to an interval large of 180 degrees: depending on the paritty of the interval number, the latitude and longitude are kept, otherwise the opposite latitude is taken and 180 is added to the longitude:
longitude /= 360.0, latitude /= 360.0;
if (fmod(latitude, 2.0) > 1.0) latitude = 0.5 - latitude, longitude += 0.5;
longitude = round(fmod(longitude, 1.0) * 2^zoom);
latitude = round(fmod(latitude, 1.0) * 2^zoom);
then:
nodeid = ST_quad(longitude, latitude, zoom);
(where the second parameter of ST_quad is the total of bits to in each coordinate to interleave, so that the result is an integer with 2*zoom bits), or simply:
nodeid = longitude+latitude*2^zoom;
If you want you can add 2^(zoom*2) * layer with layer in {0, 1, 2, ...} to the result to generate separate numbered layers of nodes.