Węzły ekstrakcyjne QGIS z wartościami M dla odniesienia liniowego

10

Mam warstwę MultiLineStringZM w bazie danych sqlite i próbuję wizualizować miary lub wartości mw wierzchołkach. Próbowałem wyszukać informacje o tym, jak to zrobić w QGIS, a wszystko, co udało mi się zebrać, to to, że nie jest to możliwe bezpośrednio z warstwy liniowej i że punkty należy wyodrębnić do osobnej warstwy.

Użyłem Vector-> Geometry Tools->, Extract nodesaby utworzyć wielopunktową warstwę reprezentującą wierzchołki mojej warstwy wielościeżkowej, ale proces traci wartości m wierzchołków. Potrzebuję zachować wartości m, albo zapisując wartość m jako atrybut punktu, czy coś innego?

Wewnętrznie mamy narzędzie wiersza poleceń, które konwertuje znaczniki linii na plik kształtu punktu z wartościami m przechowywanymi jako atrybuty w każdym punkcie, i użyłem tego do sprawdzenia, czy do m wierzchołków przypisano wartości m, i mogłem użyć że jeśli będę musiał, ale jeśli to możliwe, byłoby miło, gdyby można to zrobić bezpośrednio w QGIS.

EDYCJA - Powtarzając to, co powiedziałem powyżej, ale ponownie podkreślając fakt, że mamy narzędzie wiersza poleceń, które może osiągnąć wyniki, których szukam, wykorzystujące biblioteki GDAL, więc rozwiązanie pokazujące tylko częściową odpowiedź w PyQGIS nie jest odpowiedzią, której szukam. Szukam wbudowanego narzędzia, wtyczki gotowej dla QGIS lub pełnego skryptu, który może wyodrębnić (nie tworzyć / generować) i wizualizować wartości m z geometrii MultiLineStringZM lub LineStringZM.

TJ Rockefeller
źródło
Możesz użyć wtyczki LRS, aby uzyskać wartości m. Musisz wyodrębnić węzły, a następnie uzyskać miary z oznaczenia linii za pomocą wtyczki LRS lub narzędzi odległości wzdłuż linii.
jbalk
@jbalk Wypróbowałem wtyczki LRS i QChainage i wydaje się, że obie te wtyczki są skonfigurowane do generowania miar w regularnych odstępach czasu, a nie do użycia istniejących miar, chyba że coś mi brakuje i po prostu używam wtyczek nieprawidłowo .
TJ Rockefeller
Ze strony wtyczki LRS: - Wtyczka obsługuje kalibrację, tworzenie punktualnych i liniowych zdarzeń oraz obliczanie miar punktów - Oto strona internetowa blazek.github.io/lrs Zadaj pytanie dotyczące wtyczki LRS na tej stronie, jeśli możesz nie zrozumiem.
jbalk
Wygląda na to, że nie możesz nic zrobić z wtyczką LRS, dopóki jej nie skalibrujesz, a aby ją skalibrować, potrzebujesz warstwy punktowej z pomiarami zapisanymi jako atrybut, a dokładnie tego próbuję uzyskać z mojego MultiLineStringZM , więc nie sądzę, aby to pomogło w tej sytuacji.
TJ Rockefeller
Możesz tworzyć punkty co 1000 m wzdłuż linii, aby użyć ich do kalibracji. Lub spójrz na odległość wzdłuż linii narzędzi w zestawach narzędzi SAGA i GRASS w QGIS, aby uzyskać wartości m.
jbalk

Odpowiedzi:

6

Z tego, co mogę znaleźć, nie wydaje się, aby istniało istniejące rozwiązanie dla tej dokładnej sytuacji, ale nadal chciałem móc to zrobić w QGIS, więc zdecydowałem się na skryptowanie w języku Python.

Przewodnik do pisania algorytmów przetwarzania można znaleźć tutaj https://docs.qgis.org/2.18/en/docs/user_manual/processing/scripts.html

Aby użyć tego kodu, otwórz Przybornik przetwarzania, następnie rozwiń Skrypty, a następnie rozwiń Narzędzia. Wybierz „Utwórz nowy skrypt”, a następnie skopiuj i wklej poniższy kod do okna skryptu (zachowaj ostrożność podczas kopiowania i wklejania kodu python, ponieważ białe znaki są istotne pod względem składniowym. Jeśli masz problemy, umieść kod w edytorze tekstu, który pokazuje białe znaki i upewnij się że skopiował poprawnie). Zapisz go gdziekolwiek chcesz, a na górze okna znajduje się przycisk wykonania skryptu. Po zapisaniu możesz „Dodaj skrypt z pliku” i na stałe mieć skrypt pod „Skrypty użytkownika”.

Kiedy pojawi się okno przetwarzania, wybierz warstwę zawierającą geometrię wektorową i wybierz Uruchom. Skrypt zachowuje się tak samo jak „Wyodrębnij węzły”, z tym wyjątkiem, że dodaje kolumnę o nazwie MValuesi lub w ZValueszależności od tego, co jest dostępne w geometrii wejściowej.

##input_layer=vector
##output_layer=output vector

from qgis.core import QgsWKBTypes, QgsField, QgsVectorFileWriter, QgsFeature, QgsGeometry
from PyQt4.QtCore import QVariant

def addVertices( geometry, writer, inFeature ):
    coordinateSequence = geometry.coordinateSequence()
    for rings in coordinateSequence:
        for points in rings:
            for point in points:
                feature = QgsFeature( fields )
                feature.setGeometry( QgsGeometry( point ) )
                type = point.wkbType()
                attributes = inFeature.attributes()
                if QgsWKBTypes.hasM( type ):
                    attributes.append( point.m() )
                if QgsWKBTypes.hasZ( type ):
                    attributes.append(point.z())
                feature.setAttributes( attributes )
                writer.addFeature( feature )
    return

inlayer = processing.getObject( input_layer )
provider = inlayer.dataProvider()
fields = provider.fields()
geomType = QgsWKBTypes.Type(inlayer.wkbType())
outputGeomType = QgsWKBTypes.Point

if QgsWKBTypes.hasM( geomType ):
    outputGeomType = QgsWKBTypes.addM( outputGeomType )
    fields.append( QgsField( "MValue", QVariant.Double ) )

if QgsWKBTypes.hasZ( geomType ):
    outputGeomType = QgsWKBTypes.addZ( outputGeomType )
    fields.append( QgsField( "ZValue", QVariant.Double ) )

layer_options = 'SHPT=' + QgsWKBTypes.displayString(outputGeomType)
writer = QgsVectorFileWriter( output_layer, 'UTF-8', fields,  outputGeomType , inlayer.crs(), layerOptions=[layer_options] )

features = inlayer.getFeatures()
featureCount = inlayer.featureCount()
featureIndex = 0

for f in features:
    percent = ( featureIndex/float( featureCount ) ) * 100
    progress.setPercentage( percent )
    g = f.geometry().geometry()
    addVertices( g, writer, f )
    featureIndex +=1

del writer
TJ Rockefeller
źródło
4

W przypadku QGIS 3.0 lub nowszego to zadanie jest banalne. W „Processing Toolbox” (Otwórz za pomocą Ctrl + Alt + T lub Processing -> Toolbox) wyszukaj „Extract Vertices” i uruchom ten algorytm.

Wybierz geometrię linii lub wielokąta M lub ZM jako warstwę wejściową i uruchom.

Wierzchołki zostaną wyodrębnione z nienaruszonymi wartościami M i Z w zależności od tego, co jest w oryginalnej geometrii.

Jeśli wartość M jest potrzebna jako pole w tabeli atrybutów, wówczas można użyć kalkulatora pola z wyrażeniem podobnym m($geometry)

TJ Rockefeller
źródło