Distanz zwischen Points in metern

Guten Tag,

erstmal vorweg: ich bin kein Experte für PGSQL oder GIS, habe mir jetzt aber einiges an Wissen angelesen und die Info die ich jetzt benötige ist für einen kurzen Proof-of-Konzept den ich ausarbeiten soll.

Es sieht so aus dass ich ene Tabelle habe welche unter anderem eine Geometry Spalte beinhaltet. Diese Tabell soll später Punkte welche überall auf der Welt verstreut sind beinhalten. Nun muss ich versuchen alle Punkte innerhalb eines bestimmten Umkreises(in metern) auszugeben (und schauen wie performant das Ganze ist).
Nach Lesen der PostGis Dokumentation und Newsgroup bin ich zum Entschluss gekommen dass ich dafür wohl SRID 2163 benötige. Daher habe ich meine tabelle damit umgewandelt:

select updategeometrysrid('positions', 'position', 2163);
select setsrid(position, 2163) from positions;

In Chapter 6 der Dokumentation habe ich dann gelesen dass ich wohl ST_DWithin(geometry, geometry, float)
dafür nutzen könnte.
Meine Query sieht zur Zeit so aus:

 SELECT AsText(position) FROM positions
  WHERE st_dwithin(position, GeomFromText('POINT(46.95757 11.917551)',2163),1)

Die zweite Position wird später dann dynamisch in die Query integriert. Nun ist es aber so dass diese Query
alle Zeilen zurückgibt, auch wenn ich den Float erhöhe oder erniedrige. Auserdem ist mir nicht ganz klar ob
dieser Float meter oder km oder was auch immer sind.

Auch gesehen habe ich die Funktion ST_distance_sphere(point, point). Nun gibt mir diese aber föllig falsche Werte
zurück. Ich bekomme 1.000045 , ich weiss aber dass die 2 Punkte mit welchen ich es probiert habe ca. 60km voneinander entfernt sind.

Ich habe die Vermutung dass das ganze momentan an den SRIDs scheitert, bzw. ich dort den Fehler habe. Und genau bei denen blicke ich auch nicht
ganz durch. Ich glaube zu Wissen dass diese die “Einheit” und den Bezugspunkt in welchem die Daten vorliegen angiebtg, und es für manche Funktionen
umwandlungen/projektionen benötigt.

Kann mir bitte jemand ein wenig Hilfestellung bzw. Erklärung bereitstellen?


Guten Tag und Danke im voraus.
Schildhans

Hallo!

Ich vermute, das hier Werte in Grad berechnet werden, warum auch immer. Da dein Beispielpunkt in Mitteleuropa liegt, versuche es man mit WGS84 mit SRID 4326, das wäre IMHO auch für weltweit verteilte Daten die bessere Wahl als ein nationales amerikanisches System, das auf hier nicht gängigen Parametern beruht. Da können auf diese Weise gewaltige Abweichungen entstehen, weil es nur für einen bestimmten Bereich des Globus optimiert ist. Irgendwas bei der Distanzberechnung ging auch nur mit WGS84 WIMRE, da müßte ich aber erst suchen.

Gruß Uwe

Hallo!

Danke für deine Hilfe. Ich habe jetzt die SRID auf 4326 umgestellt. Trotzdem stimmt die Rückgabe der Query immer noch nicht.
Folgende Query

 SELECT AsText(position) FROM positions
  WHERE st_dwithin(position, GeomFromText('POINT(46.707511 11.648735)',4326),1.0)

gibt mir alle Punkte in der Tabelle zurück.
Z.B. auch “POINT(46.957429 11.917581)” welcher laut Google Maps ca. 35km vom anderen entfernt ist.
Sollte der float 1.0 nun nicht die entfernung in Metern nehmen? Also alle Punkte innerhalb einem meter zurückgeben?

Hast du noch eine Idee was die Ursache dafür sein kann?

Die Daten liegen jetzt im richtigen format vor

select SRID(position) from positions limit 1;

gibt 4326 zurück.


Grüße
Schildhans

Moin!

Ich werd mal ein bisschen rumprobieren wenn ich heut dazu komm. So direkt fällt mir grad auch nix ein Montag morgens :wink:

Gruß Uwe

Hallo Uwe,

hast du es villeicht schon geschaft ein wenig rumzuprobieren?
Ich habe gerade mal willkürlich zwei Punkte (in Italien) hergenommen und mit st_distance und st_dwithin herumprobiert.

SELECT st_dwithin(GeomFromText('POINT(46.707511 11.648735)',4326), GeomFromText('POINT(45.707511 11.655735)',4326),1.1)

Aus der doc:
The distance is specified in units defined by the spatial reference system of the geometries. For this function to make sense, the source geometries must both be of the same coorindate projection, having the same SRID.
Das heisst bei mir müsste 1.1 meter angeben, sollte also false zurückgeben
da die Punkte mit Google Earth gemessen ca. 110 km voneinander entfernt sind.
Die query liefert aber true.
Also habe ich versucht mit st_Distance die distanz die laut postgis vorhanden ist auszugeben:

SELECT st_Distance(GeomFromText('POINT(46.707511 11.648735)',4326), GeomFromText('POINT(45.707511 11.655735)',4326))

Wieder aus der doc:
Returns the 2-dimensional minimum cartesian distance between two geometries in projected units.
Sollte in meinem fall also wieder meter sein.
Ich bekomme aber 1.00002449969988 was irgendie in keiner Relation zu dein 110km steht.

Hat jemand eine Idee wiso ich so komische Werte bekomme?

Ich müsste eigentlich nur simple queries ausführen wie:
welche punkte befinden sich im Umkreis von xx metern von Punkt y.
Welche distanz liegt zwischen punkte x und y.
Welches Punkt ist am nächsten zu Punkt x.
usw.

Die Queries an sich scheinen auch kein Problem zu sein (Indexe auf die Geometrie Daten muss ich mir halt noch anschauen), aber hier ist etwas an den Einheiten falsch, womit ich mich leider auch nach ettlichen stunden googlen nicht besser auskenne.

Ich habe in der Suche noch
http://www.pg-forum.de/postgis/2589-umkreissuche-srid-fragen.html
gefunden wo von Ungenauigkeiten der Funktion die Rede ist, bei mir scheint aber die Einheit die falsche zu sein.

Grüße
SchildHans

Hallo,
ersmal vorneweg ohne, dass ich mir die Postings groß durchgelesen habe:
POINT(46.707511 11.648735) liegt irgendwo am Horn von Afrika und nicht in Italien. Google gibt erst Hochwert dann Rechtwert an (Breite / Länge). PostGIS benutzt die geodätische Notation. Also erst Rechtswert dann Hochwert (Länge / Breite). Also hier bitte aufpassen!

SELECT st_Distance_Sphere(GeomFromText('POINT(46.707511 11.648735)',4326), 
GeomFromText('POINT(45.707511 11.655735)',4326)) 

st_Distance_Sphere gibt die Distanz in Metern aus. Bei mir 108905.869712278. Das soltle die Funktion sein, die du suchst.

SELECT st_Distance(GeomFromText('POINT(46.707511 11.648735)',4326), 
GeomFromText('POINT(45.707511 11.655735)',4326)) 

st_Distance gibt wie du ja richtig zitiert hast die Distance in map units aus. Bei EPSG 4326 (WGS84) sind das Grad. Also stimmt das Ergebnis von 1.00002449969988.

Was st_dwithin zurückgibt verstehe ich im moment auch nicht so ganz. Du kannst es aber folgendermaßen lösen:

SELECT st_Distance_Sphere(GeomFromText('POINT(46.707511 11.648735)',4326), 
GeomFromText('POINT(45.707511 11.655735)',4326)) <= xyz

Wobei xyz die zulässige Distanz in Metern ist.

Hallo,

vielen vielen Dank für die Hilfe. Das bringt mich schon einiges weiter :slight_smile: .

Noch eine kurze Frage:
Wegen dem Hochwert vor Rechtwert:
Wenn ich z.B. Rom (Italien) als POINT in die Tabelle eintragen möchte müsste ich POINT(41.533995 12.290555) als Beispiel eingeben, was dann auch Longitude/Latitude eines GPS geräts entspricht, nur Google Earth und Co schreiben es umgekehrt, richtig?

Grüße
schildhans

Scheint wohl so. Wobei ich dachte, in meinem kleinen kml-Export Tool wäre es auch RW-HW gewesen und wurde auch korrekt gelesen.
Die Welt könnte so schön sein…

Grüssle Uwe

Wenn ich in PostGIS POINT(41.533995 12.290555) eingebe, dann lande ich in Äthiopien.
Bei Google ist es Rom. Hängt vielleicht aber auch mit irgendeinem Konfigparameter zusammen.

Mhhh, das bringt mich jetzt noch mehr durcheinander.
Gibt es den ein Programm (am besten für Linux, Windows habe ich aber auch) das sich zu meinem Postgresql verbinden kann, und die POINT() daten auf einer Landkarte anzeigen kann so wie er sie von Postgis bekommt und interpretiert? Ich würde nämlich gerne sicherstellen dass meine Koordinaten der Punkte nicht auf der falschen Hälfte der Erde zu finden sind.
Denn so wie ich es jetzt verstehe sollte POINT(12.290555 41.533995 ) in Postgis ROM sein, in Google Earth und Konsorten müsste ich aber 41.533995 , 12.290555 eingeben damit ich den gleichen Punkt habe.
Wenn das so stimmt habe ich ein größeres Problem, da meine Punkte in Postgis in der Form (41.XX 12.XX) sind, was ja nicht in Europa liegen soll.
Ich habe halt die Punkte in Google Earth gesucht und in Postgis gleich eingetragen.

Grüße
Schildhans

Jupp, gibt es natürlich:

z.B. QGIS (ist OpenSource) (lang: QuantumGIS)

Einfach Googlen. Der erste Hit ist dann die Homepage. Bzw. je nach Linux-Dist und Architektur sollte man es auch ohne Probleme über den jeweiligen Packagemanager bekommen.

Hi,

danke für deine Hilfe.
QGIS habe ich installiert, und die Punkte bekomme ich auch dargestellt (dauert bei 3000 halt ein wenig).
Nun aber noch 2 Fragen die mich beschäftigen:
Ich denke meine Punkte sind falsch (also lat/long vertauscht). Um das genau zu überprüfen würde ich gerne eine Ladkarte unter die Punkte legen, ist es möglich irgendwie online verfügbares Kartenmaterial dazu zu verwenden?
Und falls ich die Punkte tatsächlich falsch gespeichert habe müsste ich sie korrigieren, also von jedem Punkt die x und y Koordinate zu tauschen. Git es dafür PostGIS funktionen die mir dabei helfen das in einer Query zu erledigen?
Jede spalte der Tabelle mit den Geometrie Daten besitz auch eine eindeutige id, falls das hilft.


Schildhans

Hallo!

An Kartenmaterial und freien WMSen dürfte es mittlerweile einiges geben, z.B. bei Demis Homepage (oder so) oder bei der Nasa. Auch deutsche Behörden bieten mittlerweile einiges an freien Daten z.b. im Deutschlandviewer findest du in der Hilfe einige Adressen für deren Webservices.

Zur zweiten Frage:

Dieses SQL sollte deine Geometrien wieder ins richtige Eck setzen:

Update <geometrietabelle> set
   the_geom = geomfromtext('POINT('||st_y(the_geom)||' '||st_x(the_geom)||')', <srid>)

Prüfe den Geometrie-String aber vorher, das war jetzt aus dem Kopf in Ermangelung eines Handbuchs.

Gruß Uwe