Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Jun 23, 2022. It is now read-only.
This repository was archived by the owner on Jun 23, 2022. It is now read-only.

aberrant node id #3

Copy link
Copy link
@verdy-p

Description

@verdy-p
Issue body actions

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.

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.