[Talk-de] Genauigkeit der Koordinaten in der OSM-DB (Nachkommastellen)
Christian Müller
cmue81 at gmx.de
Di Jan 14 06:39:01 UTC 2025
> 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
>
> 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ß
Mehr Informationen über die Mailingliste Talk-de