私はpythonを使用して、別のベクトルと> 90%重複している1つのベクトル内のポリゴンを抽出する方法を理解しようとしています。次に、これらのポリゴンのみを表示するベクター/マップが必要です。サンプル画像は私のレイヤーを示しています。90%を超える赤のすべての灰色のポリゴンが必要です。
私はこれをすべてpython(または同様に自動化された方法)で行う必要があります。同じ方法で処理するマップが1000個以下あります。
私はpythonを使用して、別のベクトルと> 90%重複している1つのベクトル内のポリゴンを抽出する方法を理解しようとしています。次に、これらのポリゴンのみを表示するベクター/マップが必要です。サンプル画像は私のレイヤーを示しています。90%を超える赤のすべての灰色のポリゴンが必要です。
私はこれをすべてpython(または同様に自動化された方法)で行う必要があります。同じ方法で処理するマップが1000個以下あります。
回答:
次のコードはQGISのPythonコンソールで動作します。これにより、90%を超えるポリゴンが赤い領域でオーバーラップするメモリレイヤーが生成されます。
mapcanvas = iface.mapCanvas()
layers = mapcanvas.layers()
#for polygon_intersects
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]
#for xwRcl
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]
selected_feats = []
for i, feat1 in enumerate(feats_lyr1):
area1 = 0
area2 = 0
for j, feat2 in enumerate(feats_lyr2):
if feat1.geometry().intersects(feat2.geometry()):
area = feat1.geometry().intersection(feat2.geometry()).area()
print i, j, area, feat2.attribute('class')
if feat2.attribute('class') == 1:
area1 += area
else:
area2 += area
crit = area1/(area1 + area2)
print crit
if crit > 0.9:
selected_feats.append(feat1)
epsg = layers[0].crs().postgisSrid()
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
"mem_layer",
"memory")
prov = mem_layer.dataProvider()
for i, feat in enumerate(selected_feats):
feat.setAttributes([i])
prov.addFeatures(selected_feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
次の2つのベクターレイヤーを使用してコードを試してみました。
結果を確証するために、QGISのPythonコンソールでコードを実行した後、インデックスが印刷されたI、関与する機能、交差領域内のフィールドの属性のJ polygons_intersects(灰色の領域のための赤色領域1及び2)と重複する基準。
0 0 9454207.56892 1
0 1 17429206.7906 2
0 2 10326705.2376 2
0 4 40775341.6814 1
0 5 26342803.0964 2
0 7 11875753.3216 2
0.432253120382
1 6 1198411.02558 2
1 7 1545489.96614 2
1 10 27511427.9909 1
0.90930850584
2 7 750262.940888 2
2 8 12012343.5859 1
0.941213972294
3 6 23321277.5158 2
0.0
作成されたメモリレイヤー(緑のフィーチャ)は、次の画像で確認できます。予想通りでした。
ここでは、Pythonを必要としないソリューションです。
次のようなクエリで新しい仮想レイヤーを追加します。
WITH r AS (
SELECT
Basins800.rowid AS idGray,
area(Basins800.geometry) AS areaGray,
area(Intersection(Basins800.geometry, Severity.geometry)) AS aeraInter,
Basins800.geometry AS geomGray
FROM Basins800, Severity
)
SELECT *, areaInterSum/areaGray AS overlap , geomGray
FROM (
SELECT
idGray,
areaGray,
sum(areaInter) AS areaInterSum,
geomGray
FROM r
GROUP BY idGray)
WHERE areaInterSum/areaGray > 0.9
と:
灰色のポリゴンでフィルターしたいレイヤーとしてのBasins800
重大度:赤いレイヤーが重なっています。
結果として、90%を超える灰色のすべての多角形だけが赤いポリゴンで重なり合った新しいレイヤーができ、新しいフィールドには重なり率が含まれます。
これがうまくいくことを願っています。必要に応じて、クエリの詳細を追加できます。
注:データには非常に小さなポリゴンが含まれています(ラスター処理から取得され、ラスターピクセルに対応しています(図では4つのポリゴンが表示されていますが、他に25個の小さなポリゴンがあります)。これにより、クエリの実行が非常に遅くなります(Intersection関数2つのレイヤから2つのフィーチャごとに1つのフィーチャを生成します)。
SeverityおよびBasins800シェープファイルへのリンクを見た後、必要なジオプロセスを理解することができました。私はコードを変更しました:
QGISを使用して、90%を超える別のベクターポリゴンレイヤーと重複しているポリゴンをプログラムで検索していますか
これを取得するため:
mapcanvas = iface.mapCanvas()
layers = mapcanvas.layers()
#for Severity
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]
#for Basins800
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]
selected_feats = []
print "processing..."
for i, feat1 in enumerate(feats_lyr1):
for j, feat2 in enumerate(feats_lyr2):
if feat1.geometry().intersects(feat2.geometry()):
area1 = feat1.geometry().intersection(feat2.geometry()).area()
area2 = feat1.geometry().area()
print i, j, area1, area2
crit = area1/area2
print crit
if crit > 0.9:
selected_feats.append(feat1)
epsg = layers[0].crs().postgisSrid()
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
"mem_layer",
"memory")
prov = mem_layer.dataProvider()
for i, feat in enumerate(selected_feats):
feat.setAttributes([i])
prov.addFeatures(selected_feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
QGISのPythonコンソールでこれらのシェープファイルを使用してコードを実行した後、数分でPiermaと同様の結果が得られました。メモリレイヤーには31個のフィーチャがありました(彼が取得した29個のポリゴンとは異なります)。
機能には1901 * 3528 = 6706728の相互作用があるため、結果をデバッグしません。ただし、コードは有望に見えます。