> Gesendet: Montag, 13. Januar 2025 um 11:45 > Von: "Frederik Ramm" <[email protected]> > An: "Christian Müller via Talk-de" <[email protected]> > 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 > > Bye > Frederik
In derselben ruby Datei finden sich ab Zeile 40 Umrechnungsfunktionen für Fließkommaeingabewerte, welche die Funktion "round" nach der Skalierung verwenden. Nachtrag: Details zu Python's round() ====================================== The rounding half to even strategy is the strategy that Python’s built-in round() function uses, and it’s the default rounding rule in the IEEE-754 standard. This strategy works under the assumption that there’s an equal probability of rounding a tie in a dataset down or up. In practice, this is usually the case. Quelle: https://realpython.com/python-rounding/#better-rounding-strategies-in-python Daraus resultieren die Fragen, ob diese Rundungs- strategie auch bei ruby verwendet wird, und ob sie für Geoanwendungen sinnvoll ist. Am Quelltext allein lässt sich nicht zweifelsfrei erkennen, ob Skalierung und Rundung bei den Setter- Funktionen mit double oder single precision erfolgen. self.latitude = (l * SCALE).round Zum Beispiel würden sowohl 179.99999995 als auch 179.99999985 unter Verwendung von single floats schon vor der Rundung in 180 gewandelt werden, leicht nachprüfbar u. a. mittels https://www.h-schmidt.net/FloatConverter/IEEE754.html oder https://evanw.github.io/float-toy/ (zusätzlich mit float64 support) Die Ruby-Dokumentation schreibt "Float objects represent inexact real numbers using the native architecture's double-precision floating point representation." Quelle(n): https://ruby-doc.org/core-2.5.9/Float.html https://rubyapi.org/3.3/o/float ..womit l vor der Wandlung nach int4 als float64 be- handelt werden dürfte. Die round Funktion ist konfigurierbar: If keyword argument half is given, and self is equidistant from the two candidate values, the rounding is according to the given half value: :up or nil: round away from zero: Quelle(n): https://rubyapi.org/3.3/o/float#method-i-round Python ist/war also ungeeignet für eine Simulation, da es standardmäßig "half to even" als Rundungsstrategie, statt "round away from zero" einsetzt: Verschiebungen finden also westlich von Greenwich im ungünstigsten Fall um 5cm nach Westen, und östlich von Greenwich um 5cm nach Osten statt. (".. wenn hochgeladene und anschließend wieder abge- rufene Längenangaben mittig zweier benachbarter, von der DB repräsentierbaren Werte lagen") Der Zeitpunkt der Rundung (vor/nach Multiplikation mit SCALE) ist damit ein- hergehend, /praktisch/ weniger entscheidend, als wenn float32 benutzt würde. Dennoch kann man hier überlegen, ob eine Rundung vor Skalierung besser wäre, da nach IEEE zum nächstgelegenen, repräsentierbaren Wert gerundet wird und diese nahe 0 dichter gelegen sind, als bei größeren Zahlen, die nach der Skalierung vorliegen. Siehe dazu u. a. https://en.wikipedia.org/wiki/Floating-point_arithmetic#Rounding_modes Gruß _______________________________________________ Talk-de mailing list [email protected] https://lists.openstreetmap.org/listinfo/talk-de

