Mehr

Finden der nächsten Nachbarn zwischen zwei Tabellen mit Punktpositionen in SpatiaLite?

Finden der nächsten Nachbarn zwischen zwei Tabellen mit Punktpositionen in SpatiaLite?


Ich habe heute angefangen mit SpatiaLite zu spielen und bin schon auf ein Problem gestoßen.

Für jede in tableOne gespeicherte Punktposition möchte ich einen nächstgelegenen Punkt (Luftlinie) aus tableTwo auswählen.

Bisher habe ich eine ungeschickte Lösung gefunden, die VIEW verwendet:

CREATE VIEW testview AS SELECT A.id , B.myValue, Distance(A.Geometry, B.Geometry) AS distance FROM tableOne AS A, tableTwo AS B WHERE distance < 10000 ORDER BY A.Id, distance;

Und dann:

SELECT * FROM testview WHERE distance = (SELECT MIN(distanz) FROM testview AS t WHERE t.id = testview.id)

scheint den Job zu machen.

Zwei Fragen:

Gibt es eine Möglichkeit, eine solche Abfrage durchzuführen, ohne eine VIEW zu erstellen?

Gibt es eine andere Möglichkeit, diese Abfrage für eine bessere Leistung zu optimieren? In einem realen Szenario wird tableOne Hunderttausende Datensätze haben und tableTwo - 1,3 Millionen.


Ich habe gerade dieses SQL getestet und es funktioniert:

SELECT g1.OGC_FID As id1, g2.OGC_FID As id2, MIN(ST_Distance(g1.GEOMETRY,g2.GEOMETRY)) AS DIST FROM table_01 As g1, table_02 As g2 WHERE g1.OGC_FID <> g2.OGC_FID( UND ST_Expand( g1.Geometrie,50),g2.Geometrie) GRUPPE NACH id1 AUFTRAG NACH id1

Wie Sie hier lesen können, "Der naive Weg, eine Nächster-Nachbar-Abfrage durchzuführen, besteht darin, die Kandidatentabelle nach dem Abstand von der Abfragegeometrie zu ordnen und dann den Datensatz mit dem kleinsten Abstand zu nehmen".

Mit freundlichen Grüßen,

Andrea


Wenn Sie die Entfernungen zwischen allen Punktkombinationen nicht berechnen möchten, können Sie einen räumlichen Index für eine der Tabellen verwenden:

SELECT A.id , B.myValue, MIN(Distance(A.Geometry, B.Geometry)) AS distance FROM tableOne AS A, tableTwo AS B WHERE A.ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'A' AND search_frame = BuildCircleMbr(ST_X(B.Geometry), ST_Y(B.Geometry), 10000)) GRUPPE NACH A.id, B.myValue

Seit Version 4.4.0 unterstützt SpatiaLite einen virtuellen KNN-Tabellenindex für Nearest Neighbour-Probleme. Hier ist eine Abfrage, die die nächste Linie in einer Linienfolgentabelle zu jedem Punkt in einer Punkttabelle findet.

SELECT k.* FROM knn k, Punkte p WHERE f_table_name = 'linestrings' AND ref_geometry = p.geometry AND max_items = 1;

So können Sie Ihre Abfrage vereinfachen.

SELECT A.id , B.myValue, MIN(Distance(A.Geometry, B.Geometry)) AS Abstand FROM tableOne AS A, tableTwo AS B GROUP BY A.id, B.myValue

Für eine allgemeinere Lösung könnte es sich lohnen, diese PostGIS Nearest Neighbor-Funktion zu konvertieren: http://blog.mackerron.com/2011/03/postgis-nearest-neighbour/


Schau das Video: Spatialite GUI - SQLIte - Create a New Empty SQLite Database - Part II