Birden çok noktayı QGIS'deki çizgiye hizalamak mı istiyorsunuz?


11

Çizgi nesneleri etrafında belirtilen bir tolerans veya arabellek kullanarak bir çizgi veya bir katman içindeki çizgiler birden çok noktayı hizalamak istiyorum. Lütfen ekteki örnek taslağa bakınız.

Bu örnek uğruna, resim öncesi çizgiye en yakın noktalar çizginin 5 harita biriminde, en dıştaki noktalar ise 10 harita biriminin üzerindedir. AFTER resminde sonuca ulaşmak için 5 harita birimine tolerans kullanarak en yakın noktaları en yakın çizgiye oturtmak istiyorum.

resim açıklamasını buraya girin


Yani noktanın çizginin yanal olarak 0 harita birimi olması gerekir, ancak noktanın orijinal konumuna göre noktanın çizginin boyuna nerede bittiği umurunda mısınız?
Joe

İdeal senaryo, noktaları çizgiye dik bir yol kullanarak hareket ettirmek olacaktır. Bununla birlikte, amaç oldukça küçük toleranslar kullanmaktır. Noktalar boyuna veya enlem olarak, çizgiye doğru hareket ettirilirse, noktaları tercih edilen bir dik pozisyondan o kadar fazla kaydırmayacaktır.
Ed Camden

Bunun en iyi yol olup olmadığından emin değilim, ancak düşünebileceğim bir yol, iki veri kümesini analiz etmek ve bazı nokta koordinatları üretmek için bazı python kodu yazmaktır. İstediğini düşündüğün buysa, bana haber ver ve sana bir cevap verebilirim. Örneğin, her nokta için, <dist 5 satırından lat dist mutlak değeri, o zaman yanal mesafe = 0 ise, x, y değerlerini koordinatlara dönüştürmek için bir gdal kütüphanesi içe aktarmanız gerekir. Yorumlara bakın: gis.stackexchange.com/questions/185445/…
Joe

PyQGIS ile, 5 harita biriminin daha önce kabul edilen toleransına ve çizgiye dik bir yola göre noktaların tutturulduğu bir bellek katmanı üretilebilir. Cevabımı gör.
xunilk

Yanıtlar:


15

Bunu (yayınlanmamış) QGIS 3.0 sürümünde yapmak için yerleşik bir araç vardır. Bunu önceden test etmek için QGIS web sitesinden her gece bir anlık görüntü alabilirsiniz.

Bunu yapmak için:

  1. "Geometrileri katmana yapıştırma" işleme algoritmasını çalıştırın
  2. Puan katmanınızı "giriş katmanı" olarak seçin
  3. Çizgi katmanını "referans katmanı" olarak seçin
  4. Uygun bir tolerans girin (yapışma sırasında noktaları hareket ettirmek için maksimum mesafe)
  5. Davranışı "En yakın noktayı tercih et" olarak değiştirin

resim açıklamasını buraya girin

İşte orijinal noktaları "x" ve koparılan noktaları yeşil noktalar olarak gösteren sonuç. Burada bir tolerans kullandım, böylece giriş noktalarının sadece bir kısmı koptu.

resim açıklamasını buraya girin


Tam da ihtiyacım olan şey bu. Ne yazık ki işverenim yalnızca QGIS'in LTR sürümlerini yüklüyor ve test sürümlerini indirip yüklememiz yasak. (iç çeker) Sanırım bu bir bekleme meselesi. Bu standart / yerleşik bir işlev mi yoksa bir eklenti mi?
Ed Camden

C ++ sınıflarındaki değişikliklere dayanan standart işlevsellik - bunu el ile eski bir sürüme kopyalamanın bir yolu yoktur. Farklı bir makineye OSGEO4W kullanarak yüklemeyi ve ardından iş istasyonunuzda çalıştırmak için osgeo4w klasörünü bir USB çubuğuna kopyalamayı deneyebilirsiniz. Geçmişte bu yaklaşımda şansım vardı.
ndawson

1
Eski sürüm için bu eklentiye bir göz atın. docs.qgis.org/2.14/en/docs/user_manual/plugins/…
iRfAn

eklenti noktaların katmanlarını desteklemiyor gibi görünüyor.
Mykola Kozyr

7

Bu PyQGIS ile karşılanabilir . Sonraki durum için:

resim açıklamasını buraya girin

QGIS'in Python Konsolunda 5 harita biriminin toleransı dikkate alınarak aşağıdaki kod çalıştırıldı:

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)

Önceden düşünülen 5 harita biriminin toleransına ve çizgiye dik bir yola göre noktaların tutturulduğu bir bellek katmanı üretildi.

resim açıklamasını buraya girin


2

Bunu refFunctions eklentisi ile Alan Hesaplayıcıda da yapabilirsiniz. Alan Hesaplayıcı'yı kullanarak alanların yanı sıra katman geometrisini de güncelleyebilirsiniz. refFunctions size belirli bir mesafe içinde (veya eşik istemiyorsanız "geomnearest") en yakın çizgiyi bulmak için bir "geomdistance" işlevi verir ve bir öznitelik veya geometri döndürür ve "closest_point" işlevi en yakın olanı bulur belirli bir geometri üzerine gelin. Nokta katmanınız için yeni geometrileri hesaplamak üzere bunları birbirine bağlayın:

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

Geometriyi doğrudan güncellemek yerine, yerine eğri geometri ile bir alan hesaplayabilirsiniz. Menfez noktalarını farklı akış katmanlarına yapıştırmak için birden fazla geometri depolarım ve hangi akış çizgilerini kullanmam gerektiğine bağlı olarak Alan Hesaplayıcıdaki nokta geometrisini kolayca güncelleyebilirim.

Bununla ilgili bazı sınırlamalar vardır, her iki katmanın da aynı CRS olması gerekir ve 100.000'den fazla noktanız varsa geomdistance işlevi size bir hata verecektir, ancak refFunctions eklenti dosyasını düzenlerseniz bu sınırı değiştirebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.