Fehler bei length()

Hallo,
wir haben eine Postgre Datenbank aufgesetzt und danach PostGIS installiert. Danach haben wir eine Datenbank erstellt und einen neuen Table (strasse_linestring), der auch auf die PostGIS-Methoden zugreifen kann. Nun haben wir den Table mit Daten, in folgendem Format, gefüttert:

49.78694444 9.93645278

D.h. wir haben von Strassen jeweils die Anfangs und Endpunkte und haben sie als Linestring in die Datenbank geschrieben.
In der Tabelle sind jetzt mehrere Strassen und wir wollen uns die Länge der Strassen anzeigen lassen. Allerdings liefert uns folgendes SQL-Statement

SELECT punkt, LENGTH ( geom ) AS laenge FROM strasse_linestring;

als Ergebnis:

punkt              laenge  
character var   double precision

Muenzstrasse   0,0023158127895372
...

Was sind jetzt diese 0,0023158127895372 und wie können wir uns m oder km ausgeben lassen? Oder sollten wir ein anderes Format wählen um die Daten in die Datenbank zu klopfen?
Wir haben über Google Earth nachgemessen und das Ergebniss müssten ca. 160m sein.
Schonmal Danke für die Hilfe

Bei der Koordinate die du eingegeben hast handelt es sich um eine geograpfische Koordinate. Also Länge und Breite. Das wird in ° angegeben. Du willst jetzt allerdings eine Distanz im metrischen System.
Wenn du einen Punkt eingibst, dann musst du zuerst das Koordinatensystem angeben, dann in ein metrisches System umrechnen und erst dann bekommst du die Distanz in Meter.

Das Koordinatensystem legst du mit folgendem Befehlfest:
SetSRID(the_geom, ID des Systems) (the_geom steht für den Namen deiner Geometry-Spalte)

Die ID wird auch EPSG-Nummer genannt.
In deinem Fall kannst du einfach deinen Table mit folgendem Befehl updaten:
UPDATE tablename set the_geom = SetSRID(the_geom, 4326)

Die metrische Länge bekommst du dann z.B. über folgenden Befehl:
select length(transform(the_geom, 32632)) from …

Die transformierst praktisch in ein metrisches System (hier UTM) und misst erst dann. Wenn du konform zum geltenden deutschen Koordinatensystem sein willst, dann musst du Gauss-Krüger statt UTM verwenden. Aber da weiß ich die EPSG-Nummer gerade nicht.

Ich hoffe ich habe jetzt keinen Quark erzählt. Aber wenn du es nach der Anleitung machst, dann solltest du die Distanz in Metern bekommen.

Hallo!

AFAIK wird in Deutschland gerade sukzessive auf UTM umgestellt, um ein europaweit einheitliches System herzustellen. Aber das wird wohl noch einge Zeit dauern, gängig ist immer noch Gauss-Krüger.
DIE EPSG-Nummer von GK sind 31466 für GK2 bis 31469 für GK5.

Grüssle Uwe

Schonmal vielen Dank für die Tipps. Ich hoffe es funktioniert :slight_smile:

Vielen Dank für die Antwort, das mit den SRID’s war der Stein der Weisen. Und jetzt habe ich auch endlich verstanden wofür die SRID’s gut sind :p

Dann würde ich vorschlagen, schreibe eine kurze Erklärung und poste sie hier, damit andere auch etwas von deinem Wissen haben :wink:

Die Antwort ist schlicht und ergrefeind, genau das was Maik geschrieben hat. Ich wollte aus geographischen Koordianten Längen berechnen, das geht aber nur wenn ich die SRID ändere mit Transform.
Nochmal Danke für die Hilfe

Nur so als Ergänzung und Hintergrund: Die SRID gibt über eine Code-Zahl (z.B. von EPSG) das geographische System an, in dem die Geodaten vorliegen. Darüber wird auch bestimmt ob in Grad, Metern oder sonstwas gemessen wird. Dies wiederum bedeutet, man kann mit Geodaten ohne ein solches angegebenes System z.B. keine Längen und Flächen berechnen, weil man ja die Maßeinheiten nicht kennt.

Grüssle und eine Schöne Woche
Uwe

Man sollte dringend immer das SRID angeben. Am besten schon dann, wenn man eine Geometrie einliest. Man kann viele Dinge zwar auch ohne SRID machen, alledings führt das zu Problemen sobald man irgendetwas macht bei dem aus den Koordinaten etwas berechnet wird, bzw. sobald man eine Maßzahl auf die Koordinaten anwenden will (z.B. bei einem Buffer). Wenn man konsquent mit SRIDs arbeitet erspart das einem im nachhinein sehr viel ärger.

Btw: Außer der Funktion DistanceSphere(geometry) geben alle Messfunktionen die Maßeinheit des SRIDs zurück. Zumindest meines Wissens. DistanceSphere(geometry) gibt Meter zurück.

Kann man den genauen Abstand zwischen einem POINT und einer GEOMETRY bestimmen? Mein momentaniger Ansatz ist, dass ich jeweils den Start POINT und den END POINT bei einer Multiline verwende. Das ist aber etwas ungenau. Gibt es da irgendwelche Lösungsansätze?

Sollte über DISTANCE(geom,geom) gehen, das berechnet den kürzesten Abstand zwischen zwei Geometrien. Oder Max_Distance(line,line) den grössten Abstand zwischen Linien.

Schönes WE

Uwe

@gisman

Das ist ja mein Problem; Mit DISTANCE(geom,geom) kann ich ja nur entweder nur Polygone oder Punkte miteinander vergleiche, aber ich bäruchte etwas womit ich Punkte und Polygone vergleiche. In meinem Fall wäre das Polygon eine MultineLine und da mit Start und Endpunkt zu rechnen ist zu ungenau. Ich verwende gerade Distance_Spheroid und da habe ich das gleiche Problem,

Hm, distance_sheroid() verlangt ausdrücklich nach 2 Punkten, bei Distance() ist allgemeingültig geometry angegeben :confused: .
Ich hab grad keine Zeit, aber ich werds mal ausprobieren heut nachmittag.
Du könntest höchstens den Multilinestring in eine Liste von Linestrings zerlegen.

Bis denne
Uwe

Ich benutze halt DISTANCE_SPHERE um ein genaues metrisches Mass zu erhalten.

Inzwischen bin ich noch auf ein ganz anders Problem gestoßen, was sich Performance nennt. Da ich recht viele Datensätze verwalte und der Rechendaufwand von DISTANCE _SPHERE ziemlich hoch ist, kann das ganze Stunden dauern. Zwar werfe ich einiges mit the_geom && the_geom raus, aber es bleiben trotzdem noch zuviele zu vergleichende Datensätze übrig.

SELECT the_geom FROM geom_table WHERE the_geom
&& ‘BOX3D(90900 190900, 100100 200100)’::box3d AND
distance( the_geom, GeomFromText( ‘POINT(100000 200000)’, -1 )
) < 100

Im Grund würde ich auch gerne das Beispiel von der PostGIS Doku verwenden, um die Indizierung mit GIST voll ausnützen zu können, aber ich kann nicht die BOX3D fest definieren, da sich das ganze nicht auf einen Punkt oder Polygon festlegt.

Im grunde bräuchte ich sowas:

SELECT * FROM tab_punk punkt, tab_flaeche flaeche WHERE punkt.the_geom
&& (flaeche.the_geom + 50) <= Das wäre die Fläche für den Intersect, die man einfach um die benötigten 50m erweitert
distance_sphere( punkt.the_geom, flaeche.the_geom, Sphere )
) < 50

Also wenn ich das richtig verstanden habe möchtest du mit dem Befehl “(flaeche.the_geom + 50)” die Ränder der Fläche um 50m nach außen verlegen. Das machst du am besten mit
“buffer(flaeche.the_geom, 50)”. Zumindest, wenn du in einem metrischen Koordinatensystem bist. Gegebenenfalls musst du es noch mit Transform(geometry, EPSG-Nummer) umprojezieren und danach wieder zurücktransformieren.

Statt der BOX könntest du es vielleicht auch mit envelope(geometry) versuchen. Das könnte unter umständen schneller sein. Ich habe es allerdings nicht ausprobiert.

Was ich allgemein gerade nicht verstehe. Warum eigentlich BOX3D? Du benutzt doch 2d-Koordinaten. Oder stehe ich gerade irgendwie auf dem Schlauch?

Hab es vorerst so gelöst, ist aber immer noch nicht optimal:

SELECT distinct point.poi_name, point.poi_id
FROM poi point LEFT JOIN
(SELECT point.poi_name as ppoi_name, point.poi_id as ppoi_id FROM poi point, streets line WHERE
Expand(line.the_geom, 0.01) && point.the_geom AND
(DISTANCE_SPHEROID(point.the_geom, StartPoint(line.the_geom), ‘SPHEROID[“WGS 84”,6378137,298.257223563]’) < 50.00 OR DISTANCE_SPHEROID(point.the_geom, Centroid(line.the_geom), ‘SPHEROID[“WGS 84”,6378137,298.257223563]’) < 50.00 OR DISTANCE_SPHEROID(point.the_geom, EndPoint(line.the_geom), ‘SPHEROID[“WGS 84”,6378137,298.257223563]’) < 50.00) ) As ce
ON (ce.ppoi_name = point.poi_name and ce.ppoi_id = point.poi_id)
WHERE ce.ppoi_name IS NULL GROUP BY point.poi_name, point.poi_id;

Ich bin gerade am grübeln, inwiefern diese Expand Funktion arbeitet. Sie vergrößert ja um die geometry die bounding box. Allerding verstehe ich das Attribut nicht, die den Umfang der zu expandierenden Box vorgibt. Desto kleiner die Zahl desto größer der Umfang? Welche Einheit ist das?

Also die Einheit sollte die Einheit deines SRIDs sein. Also bei geographischen Koordianten Grad und bei metrischen Systemen eben Meter.
Das eine kleinere Zahl einen größeren Umfang bedeutet kann ich mir irgendwie nicht vorstellen. Und ich habe jetzt auch auf die schnelle keine Quelle gefunden, die so etwas besagen würde. Ich würde zuerst überprüfen ob du vielleicht im falschen SRID bist.