Creazione di punti equidistanti in QGIS?


22

Sto cercando di creare punti (nuovo livello) a distanza specifica lungo la strada (livello esistente) in QGIS. Creare punti regolari ogni metro a livello di contea usando ArcGIS Desktop? fornisce una soluzione per ArcGIS. Come raggiungere questo obiettivo in QGIS? Aggiunta di punti al livello vettoriale punti usando QGIS? spiega come creare punti ma non fa nulla per la distanza.


(Ho applicato le soluzioni proposte con diverse misure di lunghezze perché non conoscevo la conversione) La soluzione di @ Nathans ha funzionato in una certa misura, ho ottenuto ...

inserisci qui la descrizione dell'immagine. Qui, la proiezione di questi punti equidistanti è diversa dalla linea originale.

Con il suggerimento di @ underdark, ho capito

questa immaginedove i punti non sembrano essere equidistanti. Immagino che ci sia qualche problema di proiezione con entrambi che non capisco.



2
Un paio di punti. In primo luogo, la linea deve essere in un CRS proiettato (non lat / lon). In secondo luogo, la tua linea è una vera polilinea? Non credo che nessun metodo funzionerà correttamente su una linea che comprende una stringa di singole linee. Nick.
nhopton,

Anche con il mio codice, non è necessario chiamare la import locatelinea più di una volta. Basta chiamarlo una volta, quindi puoi chiamare tutto locate.pointsAlongLine(30)ciò di cui hai bisogno
Nathan W,

Un altro metodo (dato che Sestante come suggerito da alcune risposte qui è solo QGIS <2.0), è anche quello di usare il plugin chiamato QChainage.
andy,

Risposte:


14

Nota: ora è disponibile un plug-in QGIS QChainage. Fa tutto questo e altro. Il codice seguente non è aggiornato con QGIS 2.0 e versioni successive.

Ecco del codice Python che puoi inserire in un file e usare all'interno di QGIS:

QGIS ha un metodo nella sua API per fare riferimento al liner ma non sono riuscito a farlo funzionare correttamente, ma contatterò l'autore del codice e vedrò se stavo facendo qualcosa di sbagliato.

Per ora avrai bisogno della formosa libreria Python, che dovresti comunque installare perché è utile avere in giro. Ha anche un'ottima documentazione su http://toblerity.github.com/shapely/manual.html

Questa è la sezione che sto usando nell'esempio seguente http://toblerity.github.com/shapely/manual.html#interoperation .

La maggior parte del codice seguente è il codice QGIS del boilerplate semplicemente creando le funzionalità, i layer, convertendo da wkb e wkt e viceversa. Il bit principale è quello point = line.interpolate(currentdistance)che restituisce un punto a distanza lungo una linea. Lo avvolgiamo in un ciclo fino a quando non finiamo la linea.

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)

Copia e incolla il codice sopra in file, ho chiamato mio Locate.py, nella ~./qgis/pythondirectory (perché è nel percorso Python) e basta fare questo nella console Python all'interno di QGIS.

 import locate
 locate.pointsAlongLine(30)

Ciò creerà un nuovo livello punti con punti ogni 30 metri lungo le linee selezionate, in questo modo:

inserisci qui la descrizione dell'immagine

Nota: il codice è piuttosto approssimativo e potrebbe essere necessario ripulirlo.

EDIT: l'ultimo build di sviluppo QGIS ora può farlo nativamente.

Cambia il ciclo while in createPointsAt:

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

e puoi rimuovere il file

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

Grazie @ Nathan. Non sono riuscito a ottenere il pacchetto Shapely per il mio python. Ho installato Python 2.7 ma il programma di installazione di Shapely dice che Python 2.7 non è nel mio registro. C'è un altro modo per installare Shapely.
Stat-R

Ho seguito stackoverflow.com/questions/3652625/… e ho digitato le due righe sopra per chiamarlo locatee usarlo ma non ho ancora ottenuto i punti equidistanti. Inoltre, sono un neofita in Python, quindi non ho capito dove eseguire il codice (1) python nella directory qgis o (2) quello in C: \ Python27 \?
Stat-R,

Su quale sistema operativo sei?
Nathan W,

Windows 7 Professional
Stat-R,

crea il file python C:\Users\{you user name}\.qgis\pythone riavvia QGIS se aperto, e vai su `Plugin-> Python Console . Load a line layer, select a line a call import individuare` elocate.pointsAlongLine(30)
Nathan W

5

È possibile utilizzare lo strumento v.to.points del plug-in QGIS GRASS per creare punti lungo le linee a intervalli regolari

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

Ho usato dmax come 100 e le proiezioni risultanti per ognuna sono le seguenti. (Non so come il CRS venga assegnato da solo.)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

Ora anche così: QGIS -> Sestante -> ERBA -> v.to.points
markusN

5

Se si desidera tracciare la catena a intervalli fissi lungo una linea stradale, è possibile utilizzare il plug-in "Profilo da linea" per eseguire questa operazione. È necessario un DEM sotto il livello della linea stradale, ma la procedura è rapida e molto semplice. Nick.

inserisci qui la descrizione dell'immagine


anche questo è un metodo abbastanza buono e facile, grazie!
Shepherdjo,

2

Attenzione che il modello di dati Shapely (Python) / GEOS (C ++) è definito in un piano. Quindi, se i tuoi punti consistono in posizioni GPS (latitudine, longitudine) usando il shapely.geometry.LineString.interpolate(distance)metodo, verrà emessa una posizione GPS alla distanza euclidea lungo il dato LineString.

Shapely's interpolate()si basa sulla geos::linearref::LengthIndexedLineclasse GEOS usando il extractPointmetodo.

Presumibilmente l'interpolazione equidistanziata nel piano latitudine-longitudine è sufficiente per applicazioni che considerano distanze relativamente piccole. In generale, tuttavia, si dovrebbe considerare la distanza su una sfera per le applicazioni GIS (come definito in WGS84 ).

Mi vengono in mente due soluzioni alternative usando il modulo Shapely:

  • LineStringle proprietà sono tutte indicate da punti e curve interpolate linearmente lungo di esse. Forse puoi scrivere un membro che accede alle curve interpolate e implementare il seguente integrale di linea sostituendo la distanza euclidea. Immagino questo approccio perché usando la curva continua a livello di pezzo i punti desiderati possono essere ottenuti calcolando le intersezioni dei cerchi adiacenti lungo la curva con il raggio r = radian_measure(arc_length) = arc_length / R, dove R è uguale al raggio della Terra in una data posizione.
  • codifica il tuo metodo di interpolazione (senza toccare il codice Shapely) usando un'apposita funzione di distanza (es. formula haversine).

Per raggiungere questo obiettivo, vorrei fare riferimento alla seguente domanda StackOverflow e questa risposta in particolare:

È possibile generare punti equidistanti lungo la curva. Ma ci deve essere una maggiore definizione di ciò che vuoi per una vera risposta. Siamo spiacenti, ma il codice che ho scritto per questa attività è in MATLAB, ma posso descrivere le idee generali. Vi sono tre possibilità.

Primo, i punti devono essere veramente equidistanti dai vicini in termini di una semplice distanza euclidea? Fare ciò implicherebbe la ricerca dell'intersezione in qualsiasi punto della curva con un cerchio di un raggio fisso. Quindi fai un passo lungo la curva.

Successivamente, se si intende la distanza per indicare la distanza lungo la curva stessa, se la curva è lineare a tratti, il problema è di nuovo facile da eseguire. Basta fare un passo lungo la curva, poiché la distanza su un segmento di linea è facile da misurare.

Infine, se intendi che la curva sia una spline cubica, di nuovo questo non è incredibilmente difficile, ma è un po 'più di lavoro. Ecco il trucco è:

  • Calcola la lunghezza lineare lineare a tratti da un punto all'altro lungo la curva. Chiamalo t. Genera una coppia di spline cubiche, x (t), y (t).

  • Differenzia xey come funzioni di t. Dal momento che si tratta di segmenti cubici, questo è facile. Le funzioni derivate saranno
    quadratiche a tratti .

  • Usa un risolutore di ode per muoverti lungo la curva, integrando la funzione di arclength differenziale. In MATLAB, ODE45 ha funzionato bene.

Pertanto, si integra

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

Ancora una volta, in MATLAB, ODE45 può essere impostato per identificare le posizioni in cui la funzione attraversa determinati punti specificati.

Se le tue abilità MATLAB sono all'altezza dell'attività, puoi consultare il codice in interparc per ulteriori spiegazioni. È un codice ragionevolmente ben commentato.

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


1

Sextante ha uno strumento che potrebbe funzionare per te. Sextante può essere scaricato dal repository dei plugin di Qgis.

Cerca:
"Strumenti per i livelli di linea"
"Linee a punti equispaziati"


Questo plugin non sembra essere disponibile per QGIS 2 o 3.
Martin Burch il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.