Prozentsatz des Polygons in einem Shapefile innerhalb des Polygons eines anderen

13

Ich bin ein Neuling, entschuldige mich, wenn dies offensichtlich ist / wurde bereits gefragt und beantwortet, aber ich konnte nichts finden.

Ich habe zwei Shapefiles: 1. Eine administrative Grenzschicht für eine Grafschaft in Großbritannien, bekannt als LSOA-Grenze, die 500 kleine Zonen enthält. 2. Eine Flutzone .

Idealerweise möchte ich herausfinden, welche der kleinen LSOA-Zonen ≥ 50% innerhalb der Flutzone liegen, und am Ende für jede der 500 LSOA-Zonen ein Ja / Nein oder 1/0 erhalten.

Aber ich weiß nicht, wie ich das machen soll. Ich dachte, ich könnte die beiden Shapefiles verbinden, aber es gibt kein gemeinsames Attribut zwischen ihnen. Dann dachte ich, ich könnte die Funktion Attribut nach Ort verbinden verwenden, die funktioniert und mir zeigt, welche LSOA sich in der Flutzone befinden, aber das sind fast alle (siehe Abbildung 2).

Ich denke, das ist ein SQL-Problem, aber ich weiß es nicht. Ich bin neu in QGIS und habe noch nie PostgreSQL verwendet.

Jede Hilfe wäre sehr dankbar. Ich kann Ihnen alle Informationen geben, die Sie als nette Leute brauchen, um mir zu helfen.

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

KJGarbutt
quelle

Antworten:

11

Dies ist eine relativ einfache Aufgabe mit den in QGIS enthaltenen Geoverarbeitungswerkzeugen.

  1. Berechnen Sie die Fläche Ihrer LSOA-Zonen.

    • Öffnen Sie die LSOA-Layer-Attributtabelle.
    • Bearbeitungsmodus aktivieren.
    • Öffnen Sie den Feldrechner.
    • Erstellen Sie ein neues Feld vom Typ "Dezimalzahl (reell)" mit dem Ausdruck "$ area".
    • Bearbeitungsmodus deaktivieren (Änderungen speichern).
  2. Verbinden Sie den Flutzonen-Layer zu einem einzelnen mehrteiligen Feature.

    • Vector > Geometry Tools > Singleparts to Multipart.
    • Wählen Sie "--- Alle zusammenführen ---" für das Feld Eindeutige ID.
  3. Schneiden Sie die LSOA-Zonenschicht mit der mehrteiligen Flutzonenschicht.

    • Vector > Geoprocessing Tools > Intersect.
    • Eingabeebene sind die LSOA-Zonen, Schnittfläche sind die Flutzonen.
  4. Die resultierende Ebene besteht aus den Teilen der LSOA-Zonen (mit den Attributen aus der Ebene der LSOA-Zonen), die sich mit der Ebene der Flutzonen überlappen. So berechnen Sie den Anteil jeder LSOA-Zone innerhalb einer Flutzone:

    • Berechnen Sie dann die Fläche der geschnittenen Features (wie in Schritt 1)
    • Fügen Sie ein weiteres Feld hinzu, indem Sie die ursprüngliche (Gesamt-) Fläche durch die Schnittfläche teilen. Das Ergebnis ist eine Dezimalstelle zwischen 0 und 1. Mit 100 multiplizieren, um einen Prozentsatz zu erhalten.
  5. Verbinden Sie die ursprüngliche LSOA-Ebene mit der gekreuzten Ebene, indem Sie die eindeutige ID verwenden, die beide Ebenen gemeinsam haben.

  6. Exportieren Sie die verbundene Ebene als neues Shapefile.

  7. Löschen Sie die duplizierten Attribute.

Et voilà!

Ohne Schritt 2 würde für jedes LSOA-Feature ein individuelles Feature für jedes unterschiedliche Flutzonen-Feature erstellt. Dies ist wahrscheinlich nicht das, was Sie wollen, wenn Sie nur an der Gesamtabdeckung für jede LSOA-Zone interessiert sind. Wenn Sie zwischen Fluss-, Gezeiten- und Überflutungen unterscheiden möchten (und die Daten der Überflutungszone dies unterstützen), können Sie einzelne Teile in mehrteilige konvertieren und das Feld "TYP" als eindeutige ID angeben.

Snorfalorpagus
quelle
Danke für deine Hilfe! Sehr geschätzt. Ich habe jedoch einige Probleme. Ich bin den Schritten gefolgt. Schritt 3, die Überschneidung, dauerte 10 Stunden. Als alles erledigt war, hatte ich nur ein leeres Shapefile: i.imgur.com/QIM6Gtg.png Gibt es etwas, das ich verpasst habe? Ich habe versucht, den Vorgang abzuschließen und Schritt 4 auszuführen, aber es sind keine Daten zum Berechnen der Schnittfläche vorhanden.
KJGarbutt
Ich hatte zuvor Probleme mit Überschwemmungen. Die Funktionen sind groß und kompliziert. In der Vergangenheit habe ich mich darum gekümmert, indem ich sie in kleinere Features aufgeteilt habe, damit der räumliche Index einen größeren Teil der Arbeit leisten kann. Erstellen Sie dazu ein Vektorraster in der gleichen Ausdehnung wie die Flutebene ( Vector > Research Tools > Vector Grid... Output grid as polygons) und schneiden Sie das Raster mit der Flutebene. Verwenden Sie dann in Schritt 3 die Ausgabe anstelle des Flood-Layers. Ich vermute, der Grund, warum der Layer leer war, liegt daran, dass er abgestürzt ist.
Snorfalorpagus
Danke noch einmal. Das einzige Problem ist jetzt, dass QGIS jedes Mal abstürzt, wenn ich versuche, das Vektorraster zu erstellen. Ich habe den Rat von hier aus befolgt , aber es stürzt jedes Mal ab. Ich habe die Parameter mehrmals geändert und versucht, nur das Shapefile der Flutzone zu verwenden, anstatt meine gesamte Projektdatei zu öffnen, und es schlägt jedes Mal fehl. Irgendwelche Ideen? ! Screenshot hier .
KJGarbutt
Die von Ihnen angegebenen X- und Y-Parameter sind viel zu klein. Probieren Sie etwas wie 1000 x 1000. Sie können auch dies mehrere Male tun, also tun 5000 x 5000 zuerst verwenden , um die Ausgabe zu erstellen 500 x 500. Siehe ähnliche Antwort hier: gis.stackexchange.com/a/66319/12420
Snorfalorpagus
Ich habe es mit Ihrer Hilfe fast geknackt! Wenn ich jedoch die ursprüngliche LSOA-Ebene mit der geschnittenen Ebene verbinde, gehen viele Daten verloren. Ich denke, das liegt daran, dass einige der erstellten Vektorgitterquadrate in den gleichen LSOA-Bereich fallen und daher jeweils den gleichen LSOA-Code haben. Daher erhalte ich beim Beitritt 2+ Prozentzahlen für jeden LSOA-Bereich, und anscheinend bekomme ich nur eine davon. Gibt es eine Möglichkeit, jeden Prozentsatz für jedes Vektorrasterfeldquadrat mit derselben LSOA zu summieren?
KJGarbutt
6

Sie können Spatialite und einige räumliche SQL-Funktionen verwenden.

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1
Cyrille
quelle
3

Dies scheint etwas zu sein, das viel einfacher gemacht werden könnte als die eingereichten Antworten. Ich würde persönlich ein einfaches Python-Skript verwenden:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

Hiermit werden nur Flutpolygone ausgewertet, die sich mit dem Begrenzungsrahmen jeder Begrenzungsebene überschneiden, sodass die Ausführung relativ schnell erfolgen sollte. Anschließend wird nur ein Feld in der vorhandenen Ebene aktualisiert (anstatt eines komplexen Vorgangs, bei dem eine neue Ebene erstellt und alte Werte kopiert werden dann löschen)

Jesse McMillan
quelle
2

Ich hatte das gleiche Problem wie KJ, als ich den Anweisungen von Snorfalorpagus unter Verwendung der "Intersect" -Methode in Schritt 3 gefolgt war. Die Berechnung dauerte eine ganze Weile, und ich hatte nichts mehr übrig.

Ich habe versucht, die gleichen Schritte zu befolgen, außer die "Clip" -Methode in QGIS anstelle von "Intersect" zu verwenden. In Ihrem Beispiel würden also die Teile der Bereiche übrig bleiben, die NICHT von der Flutzone abgedeckt werden. Dies schien aus irgendeinem Grund zu funktionieren, und ich konnte die Feldberechnung "Fläche" aus dem vorherigen Schritt sowie eine neue Berechnung "Fläche" für die verbleibenden Teile jedes Polygons verwenden, um den Prozentsatz jeder Fläche zu ermitteln, der NICHT war von der anderen Polygon-Ebene abgedeckt.

Das ist technisch gesehen das Gegenteil von dem, wonach Sie gefragt haben. Aber von dort aus ist es nur eine Frage der jeden Wert von 1 subtrahiert zu bekommen , was wird von der Flut Zone bedeckt.

Schmierfink
quelle