[Talk-de] Genauigkeit der Koordinaten in der OSM-DB (Nachkommastellen)
Christian Müller
cmue81 at gmx.de
Di Jan 14 00:40:25 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
Danke für den Link. Interessanterweise trifft das nicht
alle Strukturen der DB:
https://github.com/openstreetmap/openstreetmap-website/blob/5d76ec051e2c429b6647401674e13688c1251956/db/structure.sql#L1006
https://github.com/openstreetmap/openstreetmap-website/blob/5d76ec051e2c429b6647401674e13688c1251956/app/models/node.rb
(Wiederholung im header comment)
Dort ist zu erkennen, das für die Tabellen
* nodes (obige links), gps_points und notes
integer, aber für
* gpx_files, diary_entries (link unten)
double precision verwendet wird.
https://github.com/openstreetmap/openstreetmap-website/blob/5d76ec051e2c429b6647401674e13688c1251956/db/structure.sql#L716
Die Bedeutung/Länge des Typs integer im Kontext
SQL ist implementations-abhängig. Bei MS ACCESS
wurden beispielsweise 2 byte verwendet, bei MSSQL,
MySQL u.ä. 4 byte.
Quelle: https://www.w3schools.com/sql/sql_datatypes.asp
Bei Oracle ist INTEGER (entgegen ANSI) gar
ein Alias für NUMBER(38):
The INTEGER data type is an ANSI standard data type, which means it is in all SQL databases. However, in Oracle, it's a synonym for NUMBER(38). This means that if you declare an INTEGER column, Oracle is actually declaring a NUMBER column with 38 digits and 0 decimal places.
Quelle: https://www.databasestar.com/oracle-data-types/#Numeric_Data_Types
(dort erhält man den 4 byte Typ mit Alias BINARY_INTEGER)
Seit April 2009 wird für OSM PostgreSQL verwendet.
Quelle: https://wiki.openstreetmap.org/wiki/Database
Und laut dem dort angegebenen Schema, siehe
https://wiki.openstreetmap.org/wiki/File:OSM_DB_Schema_2016-12-13.svg
werden latitude und longitude der Tabelle nodes
als Spalten vom Typ "int4" definiert. Falls das
noch so ist, trifft diese Erläuterung zu:
"SQL only specifies the integer types integer (or int),
smallint, and bigint. The type names int2, int4, and int8
are extensions, which are also used by some other SQL
database systems."
Quelle: https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-INT
Mit int4 und dem Skalierungsfaktor 10.000.000 liegt demnach
der Maximalwert für eine Längen/Breitenangabe bei
2^31-1 / 1E7 = 2.147.483.647 / 1E7 = 214,7483647 (Grad)
Soll eine weitere Nachkommastelle abspeicherbar sein,
also der Skalierungsfaktor 1E8 verwendet werden, ändert
sich der Wertebereich unter Beibehaltung von int4 auf
-21,47483648 ≤ x ≤ 21,47483647
was weder für Breitengrad- (-90 ≤ x ≤ 90) noch Längen-
gradwerte (-180.0 ≤ x ≤ 90) ausreichend wäre.
Die ursprüngliche Rechnung, die sich auf die Mehrin-
anspruchnahme bei Verwendung von "float64" anstatt
"float32" bezog, ist also 1:1 übertragbar, falls das
DB-Schema statt "int4" die Typen "bigint" bzw. "int8"
zum Abspeichern von latitude und longitude einsetzen
würde.
Gruß
Mehr Informationen über die Mailingliste Talk-de