Menciptakan poin yang sama dalam QGIS?


22

Saya mencoba membuat titik (layer baru) pada jarak tertentu di sepanjang jalan (layer yang ada) di QGIS. Membuat poin Reguler setiap meter di tingkat county menggunakan ArcGIS Desktop? memberikan solusi untuk ArcGIS. Bagaimana cara mencapai ini di QGIS? Menambahkan poin ke layer vektor titik menggunakan QGIS? menjelaskan cara membuat poin tetapi tidak melakukan apa pun tentang jarak.


(Saya menerapkan solusi yang diusulkan dengan ukuran panjang yang berbeda karena saya tidak tahu konversi). Solusi Nathans bekerja sampai batas tertentu, saya dapat ...

masukkan deskripsi gambar di sini. Di sini, proyeksi titik-titik berjarak sama ini berbeda dari garis aslinya.

Dengan saran @ underdark, saya mengerti

gambar inidi mana poin tampaknya tidak sama. Saya kira ada beberapa masalah proyeksi dengan keduanya yang tidak saya mengerti.



2
Beberapa poin. Pertama, garis harus dalam CRS yang diproyeksikan (bukan lat / lon). Kedua, apakah baris Anda benar-benar polyline? Saya tidak berpikir metode apa pun akan bekerja dengan baik pada garis yang terdiri dari serangkaian garis individu. Nick.
nhopton

Juga dengan kode saya, Anda tidak perlu menelepon import locatesaluran lebih dari sekali. Panggil saja sekali maka Anda bisa menelepon locate.pointsAlongLine(30)sebanyak yang Anda butuhkan
Nathan W

Metode lain (mengingat Sextant seperti yang disarankan oleh beberapa jawaban di sini adalah QGIS <2.0 saja), juga menggunakan plugin yang disebut QChainage.
andy

Jawaban:


14

Catatan: Sekarang ada plugin QGIS QChainage. Ia melakukan semua ini dan lebih banyak lagi. Kode di bawah ini kedaluwarsa dengan QGIS 2.0 dan di atasnya.

Berikut adalah beberapa kode Python yang dapat Anda tempelkan dalam file dan gunakan di dalam QGIS:

QGIS memang memiliki metode di dalamnya API untuk melakukan referensi liner namun saya tidak dapat membuatnya berfungsi dengan benar, tetapi saya akan menghubungi pembuat kode dan melihat apakah saya melakukan sesuatu yang salah.

Untuk saat ini Anda memerlukan pustaka Python yang indah , yang harus Anda instal karena berguna untuk digunakan. Ini juga memiliki dokumentasi yang bagus di http://toblerity.github.com/shapely/manual.html

Ini adalah bagian yang saya gunakan dalam contoh berikut http://toblerity.github.com/shapely/manual.html#interoperation .

Sebagian besar kode berikut adalah kode boilerplate QGIS hanya membuat fitur, lapisan, mengkonversi dari wkb dan wkt dan kembali. Bit inti adalah point = line.interpolate(currentdistance)yang mengembalikan titik pada jarak di sepanjang garis. Kami hanya membungkus ini dalam satu lingkaran sampai kami kehabisan garis.

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)

Salin dan tempel kode di atas ke dalam file, saya panggil loc.py saya, dalam ~./qgis/pythondirektori (karena berada di jalur Python) dan lakukan saja ini di konsol Python di dalam QGIS.

 import locate
 locate.pointsAlongLine(30)

Itu akan membuat layer titik baru dengan titik pada setiap 30 meter di sepanjang garis yang dipilih, seperti:

masukkan deskripsi gambar di sini

Catatan: Kode ini cukup kasar dan mungkin perlu dibersihkan.

EDIT: Build dev QGIS terbaru sekarang dapat melakukan ini secara asli.

Ubah loop sementara createPointsAtke:

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

dan Anda dapat menghapus

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

Terima kasih @Nathan. Saya tidak bisa mendapatkan paket Shapely untuk python saya. Saya menginstal python 2.7 tetapi installer Shapely mengatakan bahwa python 2.7 tidak ada dalam registri saya. Apakah ada cara lain untuk menginstal Shapely.
Stat-R

Saya mengikuti stackoverflow.com/questions/3652625/... dan mengetikkan dua baris di atas untuk memanggil locatedan menggunakannya tapi tetap saja saya tidak mendapatkan poin yang sama. Juga, saya orang baru di Python jadi saya tidak mengerti di mana harus menjalankan kode (1) python di direktori qgis atau (2) di C: \ Python27 \?
Stat-R

OS apa yang Anda pakai?
Nathan W

Windows 7 Professional
Stat-R

buat file python di C:\Users\{you user name}\.qgis\pythonkemudian restart QGIS jika terbuka, dan pergi ke `Plugins-> Python Console . Load a line layer, select a line a call import loc` danlocate.pointsAlongLine(30)
Nathan W

5

Anda bisa menggunakan alat plugin QGIS GRASS v.to.points untuk membuat poin sepanjang garis secara berkala

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

Saya menggunakan dmax sebagai 100 dan proyeksi yang dihasilkan untuk masing-masing adalah sebagai berikut. (Saya tidak tahu bagaimana CRS ditugaskan dengan sendirinya.)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

Sekarang juga seperti ini: QGIS -> Sextante -> GRASS -> v.to.points
markusN

5

Jika Anda ingin merencanakan rantai dengan interval tetap di sepanjang garis jalan, Anda bisa menggunakan plug-in 'Profil dari garis' untuk melakukan ini. Anda memerlukan DEM di bawah lapisan garis jalan, tetapi prosedurnya cepat dan sangat sederhana. Nick.

masukkan deskripsi gambar di sini


ini adalah metode yang cukup bagus dan mudah juga, terima kasih!
Shepherdjo

2

Waspadalah bahwa model data Shapely (Python) / GEOS (C ++) didefinisikan dalam sebuah bidang. Jadi, jika titik Anda terdiri dari posisi GPS (lintang, bujur) menggunakan shapely.geometry.LineString.interpolate(distance)metode ini akan menampilkan posisi GPS pada jarak euclidean di sepanjang yang diberikan LineString.

Shapely's interpolate()didasarkan pada geos::linearref::LengthIndexedLinekelas GEOS menggunakan extractPointmetode ini.

Seharusnya interpolasi spasi sama di bidang lintang-bujur cukup untuk aplikasi mengingat jarak yang relatif kecil. Secara umum, bagaimanapun, kita harus mempertimbangkan jarak pada bola untuk aplikasi GIS (sebagaimana didefinisikan dalam WGS84 ).

Saya bisa memikirkan dua solusi menggunakan modul Shapely:

  • LineStringproperti adalah semua poin yang diberikan dan kurva interpolasi linier di sepanjang mereka. Mungkin Anda dapat menulis anggota yang mengakses kurva interpolasi dan menerapkan garis integral berikut menggantikan jarak euclidean. Saya suka pendekatan ini karena menggunakan kurva kontinu piece-wise titik yang diinginkan dapat diperoleh dengan menghitung persimpangan lingkaran yang berdekatan di sepanjang kurva dengan jari-jari r = radian_measure(arc_length) = arc_length / R, di mana R sama dengan jari-jari Bumi pada posisi yang diberikan.
  • kode metode interpolasi Anda sendiri (tanpa menyentuh kode Shapely) menggunakan fungsi jarak yang sesuai (mis. rumus haversine).

Untuk mencapai ini saya ingin merujuk pada pertanyaan StackOverflow berikut dan jawaban ini khususnya:

Adalah mungkin untuk menghasilkan titik yang sama sepanjang kurva. Tetapi harus ada definisi lebih dari apa yang Anda inginkan untuk jawaban nyata. Maaf, tapi kode yang saya tulis untuk tugas ini ada di MATLAB, tapi saya bisa menjelaskan ide-ide umum. Ada tiga kemungkinan.

Pertama, apakah poin yang benar-benar berjarak sama dari tetangga dalam hal jarak Euclidean sederhana? Untuk melakukan itu akan melibatkan menemukan persimpangan pada titik mana pun pada kurva dengan lingkaran jari-jari tetap. Kemudian cukup melangkah di sepanjang kurva.

Selanjutnya, jika Anda bermaksud jarak ke jarak rata-rata sepanjang kurva itu sendiri, jika kurva adalah linear satu demi satu, masalahnya lagi mudah dilakukan. Ikuti saja kurva, karena jarak pada segmen garis mudah diukur.

Akhirnya, jika Anda ingin kurva menjadi spline kubik, sekali lagi ini tidak terlalu sulit, tetapi sedikit lebih banyak pekerjaan. Kuncinya adalah:

  • Hitung arclength linear piecewise dari titik ke titik di sepanjang kurva. Sebut saja t. Hasilkan sepasang splines kubik, x (t), y (t).

  • Bedakan x dan y sebagai fungsi t. Karena ini adalah segmen kubik, ini mudah. Fungsi turunan akan menjadi
    kuadratik piecewise

  • Gunakan pemecah ode untuk bergerak di sepanjang kurva, mengintegrasikan fungsi diferensial arclength. Di MATLAB, ODE45 bekerja dengan baik.

Dengan demikian, seseorang terintegrasi

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

Sekali lagi, di MATLAB, ODE45 dapat diatur untuk mengidentifikasi lokasi-lokasi di mana fungsi melintasi titik-titik tertentu.

Jika keterampilan MATLAB Anda untuk tugas itu, Anda dapat melihat kode di interparc untuk penjelasan lebih lanjut. Ini adalah kode yang dikomentari dengan cukup baik.

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


1

Sextante memiliki alat yang mungkin cocok untuk Anda. Sextante dapat diunduh dari repositori plugin Qgis.

Cari:
"Tools for Line Layers"
"Lines to equispaced points"


Plugin ini sepertinya tidak tersedia untuk QGIS 2 atau 3.
Martin Burch
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.