私はQGISを使用していますが、ポイントと道路網があります。特定のポイントを囲む道路名を自動的に抽出する必要があります。 多くの場合、ポイントは測定された距離の問題として、周囲の道路ではなく、周囲の道路に近いため、最近隣分析およびバッファーゾーンは機能しません。周囲の道路のみを抽出する方法についてのアイデアはありますか?
私はQGISを使用していますが、ポイントと道路網があります。特定のポイントを囲む道路名を自動的に抽出する必要があります。 多くの場合、ポイントは測定された距離の問題として、周囲の道路ではなく、周囲の道路に近いため、最近隣分析およびバッファーゾーンは機能しません。周囲の道路のみを抽出する方法についてのアイデアはありますか?
回答:
私のテストデータについて:
ソリューションI
2つの前提がある場合:
道路は建物の区画です。
メートル法のシステムで作業しています。
アイデアは、ポイントのX座標とY座標を増減することです。メートル法のシステム内で作業している場合は、ポイントの東に1m移動し、新しいポイントを作成して、元のポイントで線を作成できます。線が道路と交差するまで、さらに東に進みます。西の交差点を探すには、元のX座標から1mを引きます。Y座標についても同じです。北/東/南/西に道路がない場合、カウンターは1000(m)で停止します。1000m以上の距離内に道路がある可能性があることがわかったら、この値を変更する必要があります。
次のコードでタスクを解決できます。
編集済み
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "point":
startpoint = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "roads":
roads = lyr
startpoint_iter = startpoint.getFeatures()
for feature in startpoint_iter:
geom = feature.geometry()
if geom.type() == QGis.Point:
xy = geom.asPoint()
x,y = xy[0], xy[1]
line_start = QgsPoint(x,y)
def reached(direction, count_m):
road_reached = None
road = None
count=1
while road_reached < 1 and count <=count_m:
count += 1
if direction == 'N':
line_end = QgsPoint(x, y+count)
if direction == 'E':
line_end = QgsPoint(x+count,y)
if direction == 'S':
line_end = QgsPoint(x,y-count)
if direction == 'W':
line_end = QgsPoint(x-count,y)
line = QgsGeometry.fromPolyline([line_start,line_end])
for f in roads.getFeatures():
if line.intersects(f.geometry()):
road_reached = 1
road = f['name']
print road
reached('N', 1000)
reached('E', 1000)
reached('S', 1000)
reached('W', 1000)
東の道路eがポイントの近くの道路として認識されないことを示す別の例。
関数と出力を呼び出す方法:
>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d
ポイントを囲む道路が4本以上ある場合は、より多くの方向を見る必要があります(XとYの両方を変更します)。または、ラインの方位角を変更できます。つまり、0〜360°の範囲内で1度回転させることができます。
ソリューションII
コメントからインスピレーションを得て、Polygonize
最初に道路を走ることもできます。そのため、QGISのツールを使用できますProcessing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize
。一時レイヤーの名前をに変更しpolygon
ます。道路で完全に囲まれたポイントの道路名のみが必要だと仮定します。それ以外の場合は、ソリューションIを使用する必要があります。これは、すべての道路が接続されている(スナップされている)場合にのみ機能します!
まず、ポイントがポリゴンと交差する必要があります。これAND
は、囲み線の始点と終点の両方がポリゴンと交差する必要があるという考え方です。
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "point":
startpoint = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "polygon":
poly = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "roads":
roads = lyr
for h in startpoint.getFeatures():
for g in poly.getFeatures():
if h.geometry().intersects(g.geometry()):
poly_geom = g.geometry()
for f in roads.getFeatures():
geom = f.geometry().asPolyline()
start_point = QgsGeometry.fromPoint(QgsPoint(geom[0]))
end_point = QgsGeometry.fromPoint(QgsPoint(geom[-1]))
if poly_geom.intersects(start_point) and poly_geom.intersects(end_point):
print f['name']
出力:
road c
road b
road e
road f