Werte benachbarter Polygone mit QGIS zusammenfassen?

11

Ich hoffe, dass Sie mir bei folgendem Problem helfen können: Ich habe eine Vektorebene (Polygon). Ich möchte der Ebene ein Attribut hinzufügen, das - für jedes Polygon - die Werte eines bestimmten Feldes aller benachbarten Polygone summiert.

Um ein konkreteres Beispiel zu geben: Ich habe eine Polygonebene von Bezirken, die Informationen zur Bevölkerung enthält. Nun möchte ich für jeden Bezirk wissen, wie viele Menschen in all seinen Nachbarbezirken leben.

Da ich mehr als 300 Distrikte habe, kann ich dies nicht für jeden Distrikt von Hand tun.

Gibt es eine Möglichkeit, dies in QGIS effizienter zu machen?

Alex
quelle

Antworten:

8

Dies geschieht am besten mit Spatialite und SQL.

Zuerst müssen Sie Ihre Daten in eine Spatialite-Datenbank laden, was mit dem im Lieferumfang von QGIS enthaltenen DBManager-Plugin möglich ist. Klicken Sie auf Importieren Layer/File button.

Mit Ihren Daten in einer Datenbank können Sie dann die folgende Abfrage über die SQLSchaltfläche ausführen . Sie müssen nur die Namen der Spalten und Tabellen ändern, um sie Ihren Daten anzupassen.

SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours, 
        a1.pop, 
        a1.name, 
        a1.id, 
        a1.geomm FROM areas a1
LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id 
                            AND intersects(a2.geomm, a1.geomm)
GROUP BY a1.id

Teilen Sie dem Abfragetool Ihre eindeutige ID-Spalte (ID) und Geometriespalte (Geomm) mit und klicken Sie dann auf Laden.

Sie sollten so etwas haben, sobald Sie es natürlich beschriften

Geben Sie hier die Bildbeschreibung ein

Die Aufschlüsselung der Abfragen

Wir verbinden die Ebene mit sich selbst mit:

LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id 
                            AND intersects(a2.geomm, a1.geomm)

aber nur dort, wo sich die Geometrien schneiden und die IDs nicht gleich sind, sonst erhalten wir zweimal denselben Datensatz für jedes Polygon. Wir verwenden auch a, LEFT OUTER JOINdamit wir die Datensätze einschließen, die nicht beitreten, dh keine Nachbarn haben.

Im ausgewählten Teil:

SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours, 
            a1.pop, 
            a1.name, 
            a1.id, 
            a1.geomm

Wir verwenden COALESCE, um die NULLS(keine Nachbarn) in eine umzuwandeln, 0sonst bleiben sie einfach NULL.

Dann machen wir nur GROUP BY a1.idso, dass wir für jedes Polygon einen einzigen Datensatz bekommen.

Nathan W.
quelle
Nathan, vielen Dank für deine Antwort und hilfreichen Erklärungen. Es funktionierte sogar für einen total räumlichen und SQL-Anfänger!
Alex
+1 Der Abschnitt "Aufschlüsselung der Abfragen" ist gut gemacht und sehr hilfreich.
whuber
@ Alex gute Sachen. Vergessen Sie nicht, die Schaltfläche Akzeptieren anzukreuzen.
Nathan W
2

Eine andere Möglichkeit, dies zu tun, ist in GRASS (mithilfe der GRASS-Toolbox oder direkt in GRASS). Im folgenden Beispiel ist die Schicht EA eine Vektorebene mit Ländern und in der Attributtabelle eine Spalte mit der Bevölkerung pro Land. In diesem Beitrag finden Sie eine ausführlichere Erklärung.

Schritt 1) ​​Erstellen Sie eine neue Ebene mit einer Attributtabelle, die mit Grenzen verknüpft ist, wobei zwei Spalten mit IDs von Polygonen links und rechts an die Grenzlinie grenzen

v.category EA out=EAc layer=2 type=boundary option=add
v.db.addtable EAc layer=2 col="left integer,right integer"
v.to.db EAc option=sides col=left,right layer=2 type=boundary

Schritt 2) Führen Sie eine SQL aus, um eine Tabelle zu erstellen, die die Länder-IDs mit der Summe der Bevölkerung aller Nachbarländer verknüpft:

db.execute sql="CREATE TABLE tmp AS
SELECT ID, sum(pop) as population FROM (
SELECT DISTINCT EAc_2.left as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.right = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
UNION
SELECT DISTINCT EAc_2.right as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.left = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
) GROUP BY ID"

Schritt 3) Verbinden Sie die neue Tabelle tmp mit der ursprünglichen Attributtabelle.

v.db.join map=EA@ConsStat layer=1 column=cat otable=tmp ocolumn=ID

Die Attributtabelle Ihrer Vektorebene sollte jetzt eine zusätzliche Spalte mit der summierten Bevölkerung aller Nachbarländer enthalten.

Ecodiv
quelle
2

Tolle Antwort von @Nathan . Ich habe versucht, dies mit Pyqgis und formschön zu tun. Schauen Sie sich diesen Beitrag an, um den Scirpt herunterzuladen und in QGIS auszuführen. Ein Vorteil dieser Methode wäre, dass Sie die Ergebnisse als Teil der Attributtabelle erhalten.

Geben Sie hier die Bildbeschreibung ein

räumliche Gedanken
quelle