Erhalten Sie Dual Graph von QGIS?

8

Ich habe eine .shp-Datei, und ich muss das duale Diagramm aus dieser Datei abrufen (dh jeder Polygonschwerpunkt sollte ein Scheitelpunkt werden, und zwei Scheitelpunkte werden verknüpft, wenn die zugehörigen Polygone benachbart sind).

Ich habe es geschafft, die Zentroide aus den Polygonen meiner Akte zu erhalten.

Wie kann ich Linien zwischen den Eckpunkten hinzufügen, die tatsächlich verbunden werden sollen?

Alexandre
quelle
Suchen Sie ein sofort einsatzbereites Tool in QGIS oder ein Skript?
Whyzar
An diesem Punkt ist jede Lösung eine gute Lösung für mich.
Alexandre
Ich kann völlig verstehen, dass ein sofort einsatzbereites Tool in QGIS möglicherweise nicht verfügbar ist. Wenn Sie ein Skript möchten, müssen Sie zumindest einen Versuch zeigen, ein Skript zu erstellen, bei dem geholfen werden kann.
Whyzar
Welche Form möchten Sie die Linien? Als eine Reihe von Linienmerkmalen mit wenig Verknüpfung zu den ursprünglichen Polygonen?
Spacedman

Antworten:

12

Sie können Python nur (Versionen 2.7.x und 3.x) ohne QGIS verwenden:

Geben Sie hier die Bildbeschreibung ein

1) Mit Fiona , formschönen und itertools

import fiona
from shapely.geometry import MuliPolygon, LineString, mapping
Multi = MultiPolygon([shape(poly['geometry']) for poly in fiona.open("polygons.shp")])
# creation of the dual graph shapefile
import itertools
# schema of the dual graph shapefile
schema = {'geometry': 'LineString','properties': {'test': 'int'}}
with fiona.open('dual_graph.shp','w','ESRI Shapefile', schema) as e:
   for poly1,poly2 in  itertools.combinations(Multi, 2):
       if poly1.touches(poly2):
           e.write({'geometry':mapping(LineString([poly1.centroid, poly2.centroid])), 'properties':{'test':1}})

Geben Sie hier die Bildbeschreibung ein

2) mit GeoPandas , formschönen und itertools

import geopandas as gpd 
polygon = gpd.GeoDataFrame.from_file("polygons.shp")
geoms = polygon['geometry'].tolist()
dual = gpd.GeoDataFrame(gpd.GeoSeries([LineString([poly1.centroid, poly2.centroid]) for poly1,poly2 in  itertools.combinations(geoms, 2) if poly1.touches(poly2)]),columns=['geometry'])
dual.to_file("dual_graph2.shp")

3) Ich nehme an, Sie können dasselbe mit PyQgis und itertools tun (Python 2.7 für 2.x-Versionen und 3.x für 3.x-Versionen).

Gen
quelle
Der erste Code funktioniert gut! Ich könnte einfach hinzufügen, dass es "als e:" anstelle von "als e ::" sein sollte, und dass ich in meinem Fall (ich wollte keine Kanten zwischen Polygonen, die nur einen Punkt teilen) die Bedingung "(poly1.intersection" hinzugefügt habe (poly2)). geom_type! = "Point" "auf die if-Schleife.
Alexandre