[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