Nós de extração QGIS com valores M para referência linear

10

Eu tenho uma camada MultiLineStringZM em um banco de dados sqlite e estou tentando visualizar as medidas ou valores m nos vértices. Tentei procurar informações sobre como fazer isso no QGIS, e tudo o que consegui reunir é que isso não é possível diretamente da camada de cadeia de linhas e que os pontos precisam ser extraídos para uma camada separada.

Eu usei Vector-> Geometry Tools-> Extract nodespara criar uma camada multiponto representando os vértices da minha camada de cadeia múltipla, mas o processo perde os valores m dos vértices. Eu preciso dos valores m preservados salvando o valor m como um atributo do ponto ou algo mais?

Internamente, temos uma ferramenta de linha de comando que converte cadeias de linhas em um shapefile de ponto com os valores m armazenados como um atributo em cada ponto, e eu usei isso para verificar se existem valores m atribuídos aos vértices, e eu poderia usar que, se for necessário, mas se possível, seria bom se isso pudesse ser feito diretamente dentro do QGIS.

EDIT - Repetindo o que disse acima, mas enfatizando novamente o fato de termos uma ferramenta de linha de comando que pode alcançar os resultados que estou procurando e que usam as bibliotecas GDAL, portanto, uma solução que mostra apenas uma resposta parcial em PyQGIS não é a resposta que estou procurando. Estou procurando uma ferramenta interna, um plug-in pronto para o QGIS ou um script completo que possa extrair (não criar / gerar) e visualizar valores m a partir de uma geometria MultiLineStringZM ou LineStringZM.

TJ Rockefeller
fonte
Você pode usar o plug-in LRS para obter os valores de m. Você precisaria extrair os nós e obter as medidas da cadeia de linhas usando o plug-in LRS ou a distância ao longo das ferramentas de linha.
jbalk
@jbalk Tentei os plug-ins LRS e QChainage, e esses dois parecem estar configurados para gerar medidas em intervalos regulares, não para usar medidas existentes, a menos que eu esteja perdendo alguma coisa e só estou usando os plug-ins incorretamente .
TJ Rockefeller
Na página do plug-in LRS: - O plug-in suporta calibração, criação de eventos pontuais e lineares e cálculo de medidas para pontos - Aqui está o site blazek.github.io/lrs Faça uma pergunta sobre o plug-in LRS neste site, se você puder descobrir isso.
jbalk
Parece que você não pode fazer nada com o plug-in LRS até calibrá-lo e, para calibrá-lo, você precisa de uma camada de pontos com medidas armazenadas como um atributo, exatamente o que estou tentando obter no meu MultiLineStringZM , então acho que não será útil nessa situação.
TJ Rockefeller
Você pode criar pontos a cada 1000m ao longo da sua linha para usar na calibração. Ou observe a distância ao longo das ferramentas de linha nas caixas de ferramentas SAGA e GRASS no QGIS para obter os valores de m.
jbalk

Respostas:

6

Pelo que pude descobrir, não parece haver uma solução existente para essa situação exata, mas eu ainda queria fazer isso no QGIS, então mergulhei no script python.

Um guia para escrever algoritmos de processamento pode ser encontrado aqui https://docs.qgis.org/2.18/en/docs/user_manual/processing/scripts.html

Para usar esse código, abra a caixa de ferramentas Processamento, expanda Scripts e, em seguida, expanda Ferramentas. Selecione "Criar novo script" e copie e cole o código abaixo na janela de script (tenha cuidado ao copiar e colar código python, pois o espaço em branco é sintaticamente significativo. Se estiver com problemas, insira o código em um editor de texto que mostre espaço em branco e verifique se copiado corretamente). Salve-o onde quiser e há um botão de executar script na parte superior da janela. Depois de salvá-lo, você pode "Adicionar script do arquivo" e colocar permanentemente o script em "Scripts do usuário".

Quando a janela de processamento aparecer, selecione a camada que contém a geometria do vetor e selecione executar. O script se comporta da mesma maneira que "Extrair nós", exceto que ele adiciona uma coluna chamada MValuese ou ZValuesdependendo do que está disponível na geometria de entrada.

##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
fonte
4

Com o QGIS 3.0 ou mais recente, esta tarefa é trivial. Na "Caixa de ferramentas de processamento" (abra com ctrl + alt + t ou Processando -> Caixa de ferramentas), procure por "Extrair vértices" e execute esse algoritmo.

Selecione sua geometria de linha ou polígono M ou ZM como a camada Entrada e execute.

Os vértices serão extraídos com os valores M e Z intactos, dependendo do que estiver na geometria original.

Se o valor M for necessário como um campo na tabela de atributos, a calculadora de campos poderá ser usada com uma expressão como m($geometry)

TJ Rockefeller
fonte