ラインオブジェクトの周りに指定された許容値またはバッファーを使用して、ラインまたはレイヤー内のラインに複数のポイントを揃えたいのですが。添付のサンプルスケッチを参考にしてください。
この例では、BEFOREピクチャのラインに最も近いポイントはラインの5マップ単位以内にあり、最も外側のポイントは10マップ単位以上離れています。5マップ単位の許容誤差を使用して、AFTER画像の結果を達成するために、最も近いポイントを最も近いラインにスナップしたいと思います。
ラインオブジェクトの周りに指定された許容値またはバッファーを使用して、ラインまたはレイヤー内のラインに複数のポイントを揃えたいのですが。添付のサンプルスケッチを参考にしてください。
この例では、BEFOREピクチャのラインに最も近いポイントはラインの5マップ単位以内にあり、最も外側のポイントは10マップ単位以上離れています。5マップ単位の許容誤差を使用して、AFTER画像の結果を達成するために、最も近いポイントを最も近いラインにスナップしたいと思います。
回答:
(リリースされていない)QGIS 3.0バージョンには、これを行うための組み込みツールがあります。QGIS Webサイトから毎晩のスナップショットを取得して、これを事前にテストできます。
これをする:
結果は次のとおりです。元のポイントは「x」として表示され、スナップされたポイントは緑のドットとして表示されます。ここでは許容値を使用して、一部の入力ポイントのみがスナップされるようにしています。
これはPyQGISで提供できます。次の状況の場合:
次のコードは、5マップ単位の許容範囲を考慮して、QGISのPythonコンソールで実行されました。
from math import sqrt
registry = QgsMapLayerRegistry.instance()
points = registry.mapLayersByName('points')
line = registry.mapLayersByName('line')
feat_points = [ feat for feat in points[0].getFeatures() ]
feat_line = line[0].getFeatures().next()
new_points = []
for feat in feat_points:
pt = feat.geometry().asPoint()
sqrdist, point, vertex = feat_line.geometry().closestSegmentWithContext(pt)
if sqrt(sqrdist) <= 5:
new_points.append(point)
else:
new_points.append(pt)
epsg = points[0].crs().postgisSrid()
uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
'new_points',
'memory')
prov = mem_layer.dataProvider()
feats = [ QgsFeature() for i in range(len(new_points)) ]
for i, feat in enumerate(feats):
feat.setAttributes([i])
feat.setGeometry(QgsGeometry.fromPoint(new_points[i]))
prov.addFeatures(feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
これは、以前に考慮された5つのマップ単位の許容値とラインへの垂直パスに従ってポイントがスナップされたメモリレイヤーで作成されました。
フィールド計算機でrefFunctionsプラグインを使用してこれを行うこともできます。フィールド計算ツールを使用して、フィールドだけでなくレイヤージオメトリも更新できます。refFunctionsは、「geomdistance」関数を使用して、指定された距離(またはしきい値が必要ない場合は「geomnearest」)内で最も近い線を検索し、属性またはジオメトリを返します。「closest_point」関数は最も近い線を検索します特定のジオメトリ上のポイント。ポイントレイヤーの新しいジオメトリを計算するには、次のようにそれらをひもでつなぎます。
closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)
ジオメトリを直接更新する代わりに、スナップされたジオメトリを使用してフィールドを計算できます。カルバートポイントを異なるストリームレイヤーにスナップするために複数のジオメトリを保存し、使用する必要があるストリームラインに応じて、フィールドカリキュレーターでポイントジオメトリを簡単に更新できます。
これにはいくつかの制限があります。両方のレイヤーは同じCRSである必要があり、100,000を超えるポイントがある場合はgeomdistance関数でエラーが発生しますが、refFunctionsプラグインファイルを編集すると、この制限を変更できます。