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

Frederik Ramm frederik at remote.org
Mi Jan 15 12:15:30 UTC 2025


Hallo Christian,

ich habe Dich mit meinem Link zur Ruby-Dokumentation da ein bisschen in 
die falsche Richtung geschickt. Die Ruby-basierte Webseite ist zwar 
unsere "Referenz-Implementation", was die API-Funktionen anbetrifft und 
auch solche Fragen wie "was für ein Datenbanktyp wird für die 
Eigenschaft X genutzt".

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" und musst in den 
Code gucken, der in der Praxis auf openstreetmap.org eingesetzt wird. 
Das ist aber für die allermeisten daten-bezogenen API-Funktionen (nicht 
für alle) inzwischen "cgimap", welches in C++ und nicht in Ruby 
geschrieben ist, 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.

Bye
Frederik

On 15/01/2025 10:05, Christian Müller via Talk-de wrote:
> 
>> Gesendet: Montag, 13. Januar 2025 um 11:45
>> 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)
>>
>> In OSM werden die Daten intern nicht als float-Werte gespeichert,
>> sondern als Ganzzahlen, und vorher mit 1E7 multipliziert:
>>
>> https://github.com/openstreetmap/openstreetmap-website/blob/5d76ec051e2c429b6647401674e13688c1251956/app/models/concerns/geo_record.rb#L17-L20
> 
> 
> Bevor die Wandlung in eine Ganzzahl erfolgt,
> führt die API mit den Upload-Daten das hier
> durch:
> 
> https://github.com/openstreetmap/openstreetmap-website/blob/914fff9d4dec3d502d524f5b0f60797f66f8af65/app/models/node.rb#L91
> (node.lat = OSM.parse_float...)
> 
> https://github.com/openstreetmap/openstreetmap-website/blob/914fff9d4dec3d502d524f5b0f60797f66f8af65/lib/osm.rb#L510
> (parse_float def)
> 
> 
> Float(..) in der Funktion parse_float
> wandelt eingehende Längen- und Breitengradwerte,
> die als Zeichenkette an die API übermittelt werd-
> en in den Ruby-Typ Float (laut Ruby-Dok ist das
> nativ float64)
> 
> 
> Neben der in der vorigen mail bereits erwähnten
> "Alternative mittels Zeichenkettenoperationen"
> zur Wandlung dieser Werte in das von der DB
> verwendete Ganzzahlformat, bestünde noch die
> 
> Alternative mittels Decimal (in Ruby BigDecimal):
> --------------------------------------------------
> 
>>>> def to_int(l):
> ...   r = Decimal(l) * Decimal('1e7')
> ...   r = r.quantize(Decimal('1.'), rounding=ROUND_HALF_UP)
> ...   return int(r)
> ...
> 
>>>> to_int(1.67772165)
> 16777217
>>>> to_int(1.67772175)
> 16777217
> 
>>>> Decimal(1.67772175) * Decimal('1e7')
> Decimal('16777217.49999999900637703831')
> 
>>>> to_int('1.67772175')
> 16777218
> 
> Quellen:
> https://docs.python.org/3/library/decimal.html
> https://ruby-doc.org/stdlib-3.1.0/libdoc/bigdecimal/rdoc/BigDecimal.html
> 
> 
> Die letzten beiden Beispiele unterscheiden
> sich darin, welcher Typ dem Konstruktur von
> Decimal übergeben wird.  Beim ersten wird das
> Literal 1.67772175 zunächt in den nativen
> Fließkommazahltyp gewandelt und dessen Wert
> von Decimal übernommen.  Dieser Zwischenschritt
> enfällt, wenn Decimal direkt mit der Zeichenket-
> te konstruiert wird (die bei der OSM-API während
> des Uploads so vorliegt..).
> 
> 
> Die Ruby-Dokumentation, siehe letzte Quellen-
> angabe, zu BigDecimal schreibt:
> 
> "Decimal arithmetic is also useful for general
> calculation, because it provides the correct
> answers people expect–whereas normal binary
> floating point arithmetic often introduces
> subtle errors because of the conversion between
> base 10 and base 2."
> 
> 
> Für Java existieren Angaben, dass BigDecimal
> um den Faktor 1000 langsamer sein kann, als
> Double.  Außerdem wäre der Speicherbedarf etwas
> höher, während die API die Anfrage bearbeitet.
> 
> Im Kontext Ruby lassen sich ad hoc keine brauch-
> baren Benchmarks finden, aber es ist anzunehmen,
> dass die Situation ähnlich ist.
> 
> 
> Man könnte im Ruby-Code beide (bzw. alle drei)
> Varianten parallel implementieren und auf einem
> Testserver messen, ob der Unterschied produktiv
> relevant wäre.
> 
> Falls sich herausstellt, dass der Einsatz von
> Float für die Performance nicht kritisch ist,
> kann man die Wiedergabetreue von Werten, die
> an die DB übermittelt wurden, erhöhen. Ob das
> beim praktischen Einsatz bemerkt würde, ist
> eine andere Frage.
> 
> Der Effekt müsste sich unabhängig davon ein-
> stellen, wie groß SCALE gewählt wird, also
> auch unter Beibehaltung des derzeitigen Werts
> samt 'int4'-Typ für die Datenhaltung (mini-
> male) Vorteile bringen.
> 
> 
> Gruß
> 
> 
> 
> 
> _______________________________________________
> Talk-de mailing list
> Talk-de at openstreetmap.org
> https://lists.openstreetmap.org/listinfo/talk-de

-- 
Frederik Ramm  ##  eMail frederik at remote.org  ##  N49°00'09" E008°23'33"



Mehr Informationen über die Mailingliste Talk-de