QGISで複数のポイントをラインに揃えますか?


11

ラインオブジェクトの周りに指定された許容値またはバッファーを使用して、ラインまたはレイヤー内のラインに複数のポイントを揃えたいのですが。添付のサンプルスケッチを参考にしてください。

この例では、BEFOREピクチャのラインに最も近いポイントはラインの5マップ単位以内にあり、最も外側のポイントは10マップ単位以上離れています。5マップ単位の許容誤差を使用して、AFTER画像の結果を達成するために、最も近いポイントを最も近いラインにスナップしたいと思います。

ここに画像の説明を入力してください


したがって、ポイントはラインの横方向に0マップ単位である必要がありますが、ポイントの元の位置に対してラインの縦方向にポイントが終了する場所を気にしますか?
ジョー

理想的なシナリオは、線に垂直なパスを使用してポイントを移動することです。ただし、意図はかなり小さな許容誤差を使用することです。ポイントが縦方向または横方向に線に向かって移動した場合、望ましい垂直位置からそれほどポイントがオフセットされません。
Ed Camden

これが最善の方法かどうかはわかりませんが、2つのデータセットを分析していくつかの点座標を生成するPythonコードを書くのが1つの方法と考えることができます。これがあなたが望むと思うなら、私に知らせてください、そして私はあなたに答えを提供できます。たとえば、すべてのポイントで、ラインからの緯度距離の絶対値<= 5単位の場合、横距離= 0です。x、y値を座標に変換するには、gdalライブラリをインポートする必要があります。コメントを参照してください: gis.stackexchange.com/questions/185445/...
ジョー・

PyQGISを使用すると、以前に考慮された5つのマップ単位の許容値とラインへの垂直パスに従ってポイントがスナップされるメモリレイヤーを作成できます。私の答えを見てください。
xunilk 2017

回答:


15

(リリースされていない)QGIS 3.0バージョンには、これを行うための組み込みツールがあります。QGIS Webサイトから毎晩のスナップショットを取得して、これを事前にテストできます。

これをする:

  1. 「ジオメトリをレイヤーにスナップ」処理アルゴリズムを実行する
  2. ポイントレイヤーを「入力レイヤー」として選択します
  3. 「参照レイヤー」としてラインレイヤーを選択します
  4. 適切な許容値(スナップ中にポイントを移動する最大距離)を入力します
  5. 動作を「最も近い点を優先する」に変更します

ここに画像の説明を入力してください

結果は次のとおりです。元のポイントは「x」として表示され、スナップされたポイントは緑のドットとして表示されます。ここでは許容値を使用して、一部の入力ポイントのみがスナップされるようにしています。

ここに画像の説明を入力してください


これはまさに私が必要とするものです。残念ながら、私の雇用者はLTRバージョンのQGISのみをインストールしており、テストバージョンのダウンロードとインストールはすべて制限されています。(ため息)私はそれが待つことの問題だと思います。これは標準/組み込み関数ですか、プラグインですか?
Ed Camden

C ++クラスの変更に依存する標準機能-これを手動で古いバージョンにコピーする方法はありません。OSGEO4Wを使用して別のマシンにインストールし、osgeo4wフォルダーをUSBスティックにコピーしてワークステーションで実行することもできます。私はそのアプローチで過去に運がありました。
ndawson 2017

1
古いバージョンについては、このプラグインを見てください。 docs.qgis.org/2.14/en/docs/user_manual/plugins/...
イルファン

プラグインはポイントのレイヤーをサポートしていないようです。
Mykola Kozyr 2017

7

これは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つのマップ単位の許容値とラインへの垂直パスに従ってポイントがスナップされたメモリレイヤーで作成されました。

ここに画像の説明を入力してください


2

フィールド計算機でrefFunctionsプラグインを使用してこれを行うこともできます。フィールド計算ツールを使用して、フィールドだけでなくレイヤージオメトリも更新できます。refFunctionsは、「geomdistance」関数を使用して、指定された距離(またはしきい値が必要ない場合は「geomnearest」)内で最も近い線を検索し、属性またはジオメトリを返します。「closest_point」関数は最も近い線を検索します特定のジオメトリ上のポイント。ポイントレイヤーの新しいジオメトリを計算するには、次のようにそれらをひもでつなぎます。

closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)

ジオメトリを直接更新する代わりに、スナップされたジオメトリを使用してフィールドを計算できます。カルバートポイントを異なるストリームレイヤーにスナップするために複数のジオメトリを保存し、使用する必要があるストリームラインに応じて、フィールドカリキュレーターでポイントジオメトリを簡単に更新できます。

これにはいくつかの制限があります。両方のレイヤーは同じCRSである必要があり、100,000を超えるポイントがある場合はgeomdistance関数でエラーが発生しますが、refFunctionsプラグインファイルを編集すると、この制限を変更できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.