[OSM-Devserver] PostGIS nächstes Objekt

Jochen Topf jochen at remote.org
Mo Nov 8 22:37:49 CET 2010


On Mon, Nov 08, 2010 at 10:01:05PM +0100, Alexander Matheisen wrote:
> ich würde gerne für ein bestimmtes Obejekt (erstmal nur Punkte) den
> nächsten Punkt mit einem bestimmten Tag herausfinden.
> 
> Dazu habe ich folgendes versucht, bzw. nach Beispielen zusammmen
> gebastelt, was aber irgendwie nicht so ganz will;
> mache ich so ein Request, kommt kein Ergebnis, vorsichtshalber breche
> ich immer nach ca. 10s ab, um die DB nicht noch zum Absturz zu bringen:
> 
> SELECT h.tags->'name' AS name,
> ST_Distance(ST_SetSRID(ST_Point(51.1983858,6.6872327),4326),ST_SetSRID(h.way,4326)) AS distance FROM planet_point AS s, planet_point AS h WHERE s.osm_id = 330447462 AND h.tags->'amenity' = 'pub' ORDER BY distance LIMIT 1;
> 
> Die Koordinaten und die ID sind von einem bekannten Punkt, der gesuchte
> nächste Punkt hat dann das Tag amenity=pub.
> 
> Was ist falsch oder ist so eine Frage wirklich ziemlich langsam? Gibt es
> einfachere oder bessere Methoden?

Ja, solche Abfragen können sehr aufwändig sein. Lies mal nach, was der 
EXPLAIN-Befehl macht. Damit kannst Du Dir anzeigen lassen, was er versucht
auszuführen. Die Ausgabe ist am Anfang etwas schwer zu verstehen, aber
mit der Zeit kommt man da rein.

Was mir jetzt schonmal auffällt, ist das Du das "planet_point AS s" ja garnicht
brauchst. Ist sicher noch ein überbleibsel von vorher.

Aber davon abgesehen ist bei sowas immer die Frage, welche Indizes er hat auf
den Tabellen und welche er benutzt. Wenn auf h.tags ein Index ist, dann wird er
den hier verwenden nehme ich an. Das heisst aber, dass weltweit alle
amenity=pub durchgegangen werden müssen und bei jedem wird der Abstand berechnet.

Vielversprechender erscheint es mir auf den Geometrieindex zu setzen. 
ST_Distance() benutzt den aber nicht. Stattdessen muss man mit && arbeiten.
Hier ist z.B. erklärt, wie das generell geht:
http://www.postgis.org/documentation/manual-1.3/ch04.html#id2572814

Du willst wahrscheinlich sowas erreichen: Finde erstmal alle Punkte in einer
Bounding Box von, sagen wir, ca. 10km. Dann finde darin alle Pubs. Das sind
dann nur noch sehr wenige. Und nur für die wird nochmal der Abstand berechnet.
Wenn Du natürlich auch aus der Antarktis den nächsten Pub finden willst, dann
geht das so nicht. Aber meist kann man den Bereich ja schon sehr einschränken.

Jochen
-- 
Jochen Topf  jochen at remote.org  http://www.remote.org/jochen/  +49-721-388298