[Talk-de] Genauigkeit der Koordinaten in der OSM-DB (Nachkommastellen)

Christian Müller cmue81 at gmx.de
Mi Jan 15 16:50:38 UTC 2025



> Gesendet: Mittwoch, 15. Januar 2025 um 13:15
> Von: "Frederik Ramm" <frederik at remote.org>
> An: "Christian Müller via Talk-de" <talk-de at openstreetmap.org>
> Betreff: Re: [Talk-de] Genauigkeit der Koordinaten in der OSM-DB (Nachkommastellen)
>
> Hallo Christian,
> 
> Wenn Du aber so tief einsteigen möchtest, dass Du genau analysierst, ob 
> und wann ein Wert zwischendurch vielleicht mal ein Float ist, dann 
> verlässt Du den Berech der "Referenz-Implementation" [..]
> [..] siehe https://wiki.openstreetmap.org/wiki/CGImap.
> 
> Es ist natürlich durchaus möglich, dass Deine Anmerkungen dort genauso 
> gelten, ich habe mir das nicht genau angeschaut.
> 

Danke.  Du merkst, dass ich diese Entwicklung nicht
im Detail verfolgt habe.  Die meisten meiner Aktivitäten
befassten sich in der Vergangenheit eher mit JOSM.


Falls CGImap anhand der Ruby-Implementation
geschrieben wurde, sind die Aussagen sicherlich
auch dort zutreffend.  Das DB-Schema und der
Umstand der Ganzzahlwandlung hin zu 4byte ints
für die PostgreSQL-DB  von inputseitig an die
API übergebenen Dezimalzahlen als String-Typ
machen da Vorgaben, die nicht allzu viel Spiel-
raum lassen.

Es würde mich überraschen, wenn man auf die
float64 Wandlung als Interim zwischen String-
Input und dem Ganzzahl-Typ für die DB ver-
zichtet hat.

Der Grund der Portierung ist/war die bessere
Performance und der geringere Speicherbedarf.

Auf diesem Weg wird niemand daran gedacht haben,
den nativen Maschinentyp zugunsten höherer Genauig-
keit durch einen stärker softwareabhängigen Daten-
typen zu ersetzen:

***************
https://github.com/zerebubuth/openstreetmap-cgimap/blob/80e60f04466eada14f92854da9ef54a9005edc53/src/backend/apidb/changeset_upload/node_updater.cpp#L33

.. double lat, double lon
siehe Funktionssignaturen von add_node,
modify_node

new_node.lat = round(lat * global_settings::get_scale());
[..]

entspricht der Ruby-Referenz ziemlich genau.

Wer hier double zugunsten höherer Genauigkeit
ersetzen will kann das wahlweise mit
mpdecimal / libmpdec++  (worauf auch python's Decimal basiert..)
oder z.B. num7 tun.  Referenzen:

* https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software
* https://www.bytereef.org/mpdecimal/doc/libmpdec++/decimal.html#_CPPv4NK7decimal6scalebERK7DecimalR7Context
* https://www.bytereef.org/mpdecimal/doc/libmpdec++/decimal.html#_CPPv4NK7decimal11to_integralER7Context


***************
https://github.com/zerebubuth/openstreetmap-cgimap/blob/80e60f04466eada14f92854da9ef54a9005edc53/include/cgimap/backend/apidb/changeset_upload/node_updater.hpp#L48

Interessanterweise sind die Felder lat
und lon bereits als int64_t deklariert.

***************
https://github.com/zerebubuth/openstreetmap-cgimap/blob/80e60f04466eada14f92854da9ef54a9005edc53/src/backend/apidb/changeset_upload/node_updater.cpp#L277

führt einen cast dieser Felder auf int,
also kleineren Typ durch (equiv. postgre
int4).  Mir ist unbekannt, ob das Postgre-
C++ Binding hier einen Überlauf erkennen
würde (Ausnahmebehandlung?); relevant, falls
in den global_settings eine größere SCALE
verwendet wird, ohne das DB-Schema ebenfalls
anzupassen.




Ab ruby 2.3.0 stand ein Weg zur Verfügung,
Ruby-Code vorzukompilieren, in bytecode für
die RubyVM;  dennoch langsamer als ein gut
optimiertes C++ Programm.  Der Memory-Foot-
print bei verschiedenen Ruby-Implementation-
en scheint stark zu variieren:

https://programming-language-benchmarks.vercel.app/ruby-vs-cpp
(peak-mem Wert)



Gruß







Mehr Informationen über die Mailingliste Talk-de