[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