QGIS'te eşit puan oluşturmak?


22

QGIS'te yol boyunca belirli bir mesafede noktalar (yeni katman) oluşturmaya çalışıyorum. ArcGIS Desktop kullanarak her sayaçta düzenli puanlar oluşturmak? ArcGIS için çözüm sunar. Bunu QGIS'de nasıl başarmalı? QGIS kullanarak vektör katmanına nokta ekleme Nasıl puan oluşturulacağını açıklar ancak mesafe ile ilgili hiçbir şey yapmaz.


(Önerilen çözümleri farklı uzunluklarda ölçümlerle uygulamıştım, çünkü dönüşümü bilmiyordum) @ Nathans'ın çözümü bir dereceye kadar çalıştı ...

görüntü tanımını buraya girin. Burada, bu eşitlikçi noktaların izdüşümü orijinal çizgiden farklıdır.

@ Underdark'in önerisiyle, anladım

Bu görüntüpuanların eşit olmadığı görülüyorsa. Sanırım ikisi de anlamadığım bazı projeksiyon sorunları var.



2
Birkaç puan. İlk olarak, hattın öngörülen bir CRS'de olması gerekir (enlem / boylam değil). İkincisi, hattınız gerçek bir çok satırlı mı? Herhangi bir yöntemin, bir dizi tekil satır içeren bir satırda düzgün çalışacağını sanmıyorum. Nick.
nhopton

Ayrıca kodumla, import locatehattı bir defadan fazla aramanıza gerek yok . Tam o Arayabileceğin kez diyoruz locate.pointsAlongLine(30)İhtiyacınız olduğu kadar
Nathan W

Başka bir yöntem (burada bazı cevaplar tarafından önerildiği gibi Sextant'a verilen QGIS <2,0 olduğu için), QChainage adlı eklentiyi kullanmaktır.
andy

Yanıtlar:


14

Not: Artık bir QGIS eklentisi var QChainage. Tüm bunları ve daha fazlasını yapar. Aşağıdaki kod QGIS 2.0 ve üstü ile güncel değil.

İşte bir dosyaya yapıştırabileceğiniz ve QGIS içinde kullanabileceğiniz bir Python kodu:

QGIS 'in API referansında liner referanslama yapması gerekiyor, ancak düzgün çalışmasını sağlayamadım, ancak kodun yazarıyla görüşüp yanlış bir şey yapıp yapmadığımı göreceğim.

Şimdilik , yine de kurmanız gereken düzgün Python kütüphanesine ihtiyacınız olacak , çünkü etrafta olması kolay. Ayrıca, http://toblerity.github.com/shapely/manual.html adresinde harika belgelere sahiptir.

Bu, aşağıdaki örnekte kullandığım bölümdür: http://toblerity.github.com/shapely/manual.html#interoperation .

Aşağıdaki kodların çoğu, sadece özellikleri, katmanları oluşturan, wkb ve wkt ve geri dönüştüren QGIS boyler kodudur. Çekirdek bit, point = line.interpolate(currentdistance)bir çizgi boyunca bir mesafeden bir nokta döndürür. Çizgiyi bitirene kadar bunu sadece bir döngüye sardık.

import qgis
from qgis.core import *
from PyQt4.QtCore import QVariant
from shapely.wkb import loads
from shapely.wkt import dumps

vl = None
pr = None

def createPointsAt(distance, geom):
    if distance > geom.length():
        print "No Way Man!"
        return

    length = geom.length()
    currentdistance = distance
    feats = []  

    while currentdistance < length: 
        line = loads(geom.asWkb())
        point = line.interpolate(currentdistance)
        fet = QgsFeature()
        fet.setAttributeMap( { 0 : currentdistance } )
        qgsgeom = QgsGeometry.fromWkt(dumps(point))
        fet.setGeometry(qgsgeom)
        feats.append(fet)
        currentdistance = currentdistance + distance

    pr.addFeatures(feats)
    vl.updateExtents()

def pointsAlongLine(distance):
    global vl
    vl = QgsVectorLayer("Point", "distance nodes", "memory")
    global pr
    pr = vl.dataProvider()  
    pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
    layer = qgis.utils.iface.mapCanvas().currentLayer()
    for feature in layer.selectedFeatures():
        geom = feature.geometry()
        createPointsAt(distance, geom)

    QgsMapLayerRegistry.instance().addMapLayer(vl)

Yukarıdaki kodu kopyalayıp yapıştırın, ~./qgis/pythondizininde (çünkü Python yolunda) locate.py çağırdım ve bunu sadece QGIS içindeki Python konsolunda yapın.

 import locate
 locate.pointsAlongLine(30)

Bu, seçilen çizgiler boyunca her 30 metrede bir nokta içeren yeni bir nokta katmanı yaratacaktır:

görüntü tanımını buraya girin

Not: Kod oldukça kabacadır ve biraz temizlenmesi gerekebilir.

EDIT: En son QGIS dev inşa bunu şimdi yerel olarak yapabilir.

While döngüsünü şuraya değiştirin createPointsAt:

 while currentdistance < length: 
    point = geom.interpolate(distance)
    fet = QgsFeature()
    fet.setAttributeMap( { 0 : currentdistance } )
    fet.setGeometry(point)
    feats.append(fet)
    currentdistance = currentdistance + distance

ve kaldırabilirsiniz

from shapely.wkb import loads
from shapely.wkt import dumps

@Nathan teşekkürler. Python'umun Shapely paketini alamadım. Python 2.7'yi yükledim ama Shapely installer python 2.7'nin kayıt defterimde olmadığını söylüyor. Shapely'yi kurmanın başka bir yolu var mı?
Stat-R

Stackoverflow.com/questions/3652625/… 'i takip ettim locateve onu aramak ve kullanmak için yukarıdaki iki satırı yazdım ama yine de eşit puanları alamadım. Ayrıca, Python'da bir yeniyim, bu yüzden qgis dizinindeki (1) python kodunu veya (2) C: \ Python27 \ 'de kodunu nerede çalıştıracağımı anlamadım.
Stat-R,

Hangi işletim sistemi kullanıyorsunuz?
Nathan W

Windows 7 Professional
Stat-R

içinde piton dosyası oluşturmak C:\Users\{you user name}\.qgis\pythondaha sonra yeniden başlatma QGIS açıksa ve Eklentiler-> Python Konsolu `gidin . Load a line layer, select a line a call ithalat locate` velocate.pointsAlongLine(30)
Nathan W

5

Düzenli aralıklarla çizgiler boyunca noktalar oluşturmak için QGIS GRASS eklentisi v.to.points aracını kullanabilirsiniz.

# convert line to points; dmax = distance between points
v.to.points -i -v -t in=road out=road_pts type=line dmax=90

Dmax'ı 100 olarak kullandım ve her biri için elde edilen projeksiyonlar aşağıdaki gibidir. (CRS'nin kendisine nasıl atandığını bilmiyorum.)CRS of Original Shape file, the line = EPSG:26915 - NAD83 / UTM zone 15N, CRS of Grass line vector obtained using v.in.ogr = EPSG:4269 - NAD83, CRS of Grass points vector obtained using v.to.points = EPSG:4326 - WGS 84
Stat-R

Şimdi ayrıca böyle: QGIS -> Sextante -> GRASS -> v.to.points
markusN 11:12

5

Eğer bir yol hattı boyunca zincirleme sabit aralıklarla çizmek isterseniz, bunu yapmak için 'Hattan Profil' eklentisini kullanabilirsiniz. Yol çizgi katmanı altında bir DEM'e ihtiyacınız vardır, ancak işlem hızlı ve kolaydır. Nick.

görüntü tanımını buraya girin


Bu da çok iyi ve kolay bir yöntemdir, teşekkürler!
Shepherdjo

2

Düzgün (Python) / GEOS (C ++) veri modelinin düzlemde tanımlandığına dikkat edin. Yani puanlarınız GPS pozisyonlarından oluşuyorsa (enlem, boylam) shapely.geometry.LineString.interpolate(distance)metodu kullanarak , verilen öklid mesafesindeki bir GPS pozisyonunu verecektir LineString.

Shapely , yöntemi kullanarak interpolate()GEOS geos::linearref::LengthIndexedLinesınıfına dayanıyor extractPoint.

Sözde enlem-boylam düzlemindeki eşit aralıklı enterpolasyon, nispeten küçük mesafeleri dikkate alan uygulamalar için yeterlidir. Bununla birlikte, genel olarak, bir kişi, CBS uygulamaları için ( WGS84'te tanımlandığı gibi ) bir küre üzerindeki mesafeyi dikkate almalıdır .

Shapely modülünü kullanarak iki geçici çözüm düşünebilirim:

  • LineStringözelliklerin tümü verilen noktalardır ve bunların etrafındaki doğrusal-enterpolasyonlu eğrilerdir. Belki enterpolasyonlu eğrilere erişen bir üyeyi yazabilir ve öklid mesafesini değiştirerek aşağıdaki satırı integral uygulayabilirsiniz. Parçalı-sürekli sürekli eğri kullanılarak, r = radian_measure(arc_length) = arc_length / RR'nin verilen konumdaki yarıçapı eşitlediği yarıçap ile bitişik çemberlerin kesişimlerini hesaplayarak istenen noktaları elde etmek isterim .
  • Uygun bir mesafe fonksiyonu (örn. haversine formülü) kullanarak kendi enterpolasyon yönteminizi kodlayın (Şekil koduna dokunmadan).

Bunu başarmak için aşağıdaki StackOverflow sorusuna ve özellikle bu cevaba bakınız :

Eğri boyunca eşit noktaların üretilmesi mümkündür. Fakat gerçek bir cevap için ne istediğinin daha fazla tanımı olmalı. Üzgünüz, ama bu görev için yazdığım kod MATLAB’da. Ancak genel fikirleri açıklayabilirim. Üç olasılık var.

İlk olarak, basit bir Öklid mesafesi açısından komşulardan gerçekten eşitlik alması gereken noktalar var mı? Bunu yapmak için, eğri üzerinde herhangi bir noktada sabit yarıçapı olan bir daire bulunan kesişme noktasını bulmak gerekir. Sonra sadece eğri boyunca adım.

Sonra, eğri boyunca mesafe boyunca ortalama mesafe hedefliyorsanız, eğri parçalı bir doğrusal çizgiyse, sorunu tekrar yapmak kolaydır. Sadece eğri boyunca ilerleyin, çünkü bir çizgi parçasındaki mesafeyi ölçmek kolaydır.

Son olarak, eğrinin kübik bir eğri olması niyetindeyseniz, yine bu inanılmaz zor değil, ama biraz daha fazla iş. İşin püf noktası:

  • Parçalı doğrusal yayını, eğri boyunca noktadan noktaya hesaplayın. Ona t de. Bir çift kübik spline üret, x (t), y (t).

  • X ve y'yi t'nin işlevleri olarak ayırt edin. Bunlar kübik kesimler olduğundan, bu kolaydır. Türev fonksiyonlar parçalı olarak
    ikinci dereceden olacaktır .

  • Diferansiyel arclength işlevini bütünleştirerek eğri boyunca hareket etmek için bir ode çözücü kullanın. MATLAB'da ODE45 iyi çalıştı.

Böylece, bir bütünleşir

sqrt((x')^2 + (y')^2)

Yine, MATLAB'da, ODE45, işlevin belirli noktaları geçtiği yerleri tanımlamak için ayarlanabilir.

MATLAB becerileriniz görevdeyse , daha fazla açıklama için interparc'taki koda bakabilirsiniz . Oldukça iyi yorumlanmış bir koddur.

3 : http://www.mathworks.com/matlabcentral/fileexchange/34874-interparc


1

Sextante'un işe yarayabilecek bir aracı var. Sextante, Qgis eklenti havuzundan indirilebilir.

Bakın:
"Çizgi Katmanları için Araçlar"
"Eşitlenmiş noktalara yönelik çizgiler"


Bu eklenti QGIS 2 veya 3 için mevcut görünmüyor
Martin Burch
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.