> 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. Das kann merkwürdige Effekte haben: >>> round(0.00000095*1e7) 10 >>> round(0.00000085*1e7) 8 >>> round(179.99999995*1e7) 1800000000 >>> round(179.99999985*1e7) 1799999998 >>> float(int(round(179.99999995*1e7)))/1e7 180.0 >>> float(int(round(179.99999985*1e7)))/1e7 179.9999998 >>> float(int(round((-3+.99999995)*1e7)))/1e7 -2.0 >>> float(int(round((-2+.99999995)*1e7)))/1e7 -1.0000001 Die letzten Zeilen simulieren (hier mit python) Wandlung zu int4 und Rückwandlung zu float für den Datenabruf. Für einen Nutzer wird dieses Phänomen so deutlich, dass manche Koordinaten nach Osten, manche leicht nach Westen verschoben werden, wenn ein hochge- ladener und anschließend wieder abgerufener Daten- satz Längenangaben ursprünglich so enthielt, dass sie nahe oder auf der Mitte zweier benachbarter, von der DB repräsentierbaren Werte lagen. (bei Editoren, welche keine höhere Präzision als die der DB bei der Erfassung und Darstellung ver- wenden oder zulassen ist das irrelevant) Mit der angesprochenen Präzision von 10 cm am Äquator, läge der Fehler der dadurch entsteht im ungünstigsten Fall bei 5 cm, rundungsbezogen wie angesprochen mal nach Osten, mal nach Westen ver- setzt. Dieses Problem bestünde bei der Einführung einer oder mehrerer weiterer Nachkommastellen fort, dann kleinere Distanzen betreffend. Die Ursache liegt darin begründet, dass nicht alle reellen Werte mit IEEE-Fließkommazahlen darstellbar sind. Da die Lücken nicht gleichverteilt sind, spielt es z.B. auch eine Rolle, ob vor oder nach der Skalierung gerundet wird: >>> float(int(round(3+.99999995, 7)*1e7))/1e7 3.9999999 >>> float(int(round((3+.99999995)*1e7)))/1e7 4.0 Anschauungsbeispiel(e): https://commons.wikimedia.org/wiki/File:FloatingPointPrecisionAugmented.png https://commons.wikimedia.org/wiki/File:Denormalized_numbers_on_a_line.svg Gruß _______________________________________________ Talk-de mailing list [email protected] https://lists.openstreetmap.org/listinfo/talk-de

