Nodos de extracto QGIS con valores M para referencia lineal

10

Tengo una capa MultiLineStringZM en una base de datos sqlite, y estoy tratando de visualizar las medidas o los valores m en los vértices. He intentado buscar información sobre cómo hacer esto en QGIS, y todo lo que he podido recopilar es que esto no es posible directamente desde la capa de cadena lineal y que los puntos deben extraerse en una capa separada.

He usado Vector-> Geometry Tools-> Extract nodespara crear una capa multipunto que representa los vértices de mi capa multilínea, pero el proceso pierde los valores m de los vértices. ¿Necesito preservar los valores m guardando el valor m como un atributo del punto o algo más?

Internamente tenemos una herramienta de línea de comando que convierte las cadenas de líneas en un archivo de forma de punto con los valores m almacenados como un atributo en cada punto, y lo he usado para verificar que hay valores m asignados a los vértices, y podría usar eso si tengo que hacerlo, pero si es posible, sería bueno si esto se pudiera hacer directamente dentro de QGIS.

EDITAR : repitiendo lo que he dicho anteriormente, pero volviendo a enfatizar el hecho de que tenemos una herramienta de línea de comandos que puede lograr los resultados que estoy buscando que usa las bibliotecas GDAL, por lo que una solución que muestra solo una respuesta parcial en PyQGIS no es la respuesta que estoy buscando. Estoy buscando una herramienta integrada, un complemento listo para QGIS o un script completo que pueda extraer (no crear / generar) y visualizar valores m de una geometría MultiLineStringZM o LineStringZM.

TJ Rockefeller
fuente
Puede usar el complemento LRS para obtener los valores m. Debería extraer los nodos, luego obtener las medidas de la cadena de líneas utilizando el complemento LRS o la distancia a lo largo de las herramientas de línea.
jbalk
@jbalk He probado los complementos LRS y QChainage, y ambos complementos parecen estar configurados para generar medidas a intervalos regulares, no para usar medidas existentes, a menos que me falte algo y simplemente esté usando los complementos incorrectamente .
TJ Rockefeller
Desde la página del complemento LRS: - El complemento admite la calibración, la creación de eventos puntuales y lineales y el cálculo de medidas para puntos - Aquí puede consultar el sitio web blazek.github.io/lrs Si puede, haga una pregunta sobre el complemento LRS. No te des cuenta.
jbalk
Parece que no puede hacer nada con el complemento LRS hasta que lo calibre, y para calibrarlo, necesita una capa de puntos con medidas almacenadas como un atributo, que es exactamente lo que estoy tratando de obtener de mi MultiLineStringZM , así que no creo que sea útil en esta situación.
TJ Rockefeller
Puede crear puntos cada 1000m a lo largo de su línea para usarlos para la calibración. O mire la distancia a lo largo de las herramientas de línea en las cajas de herramientas SAGA y GRASS dentro de QGIS para obtener los valores m.
jbalk

Respuestas:

6

Por lo que puedo encontrar, no parece haber una solución existente para esta situación exacta, pero todavía quería poder hacer esto en QGIS, así que me lancé a las secuencias de comandos de Python.

Puede encontrar una guía para escribir algoritmos de procesamiento aquí https://docs.qgis.org/2.18/en/docs/user_manual/processing/scripts.html

Para usar este código, abra la caja de herramientas Procesamiento, luego expanda Scripts, luego expanda Herramientas. Seleccione "Crear nuevo script" y copie y pegue el código a continuación en la ventana del script (tenga cuidado al copiar y pegar el código de Python ya que el espacio en blanco es sintácticamente significativo. Si tiene problemas, coloque el código en un editor de texto que muestre espacios en blanco y asegúrese de que copió correctamente). Guárdelo donde quiera y hay un botón de ejecutar script en la parte superior de la ventana. Después de guardarlo, puede "Agregar secuencia de comandos del archivo" y tener la secuencia de comandos permanentemente en "Secuencias de comandos de usuario".

Cuando aparezca la ventana de procesamiento, seleccione la capa que contiene la geometría del vector y seleccione ejecutar. La secuencia de comandos se comporta de la misma manera que "Extraer nodos", excepto que agrega una columna llamada MValuesy ZValuesdependiendo de lo que esté disponible en la geometría 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
fuente
4

Con QGIS 3.0 o más reciente, esta tarea es trivial. En el "Cuadro de herramientas de procesamiento" (Abrir con ctrl + alt + to Procesamiento -> Cuadro de herramientas) busque "Extraer vértices" y ejecute ese algoritmo.

Seleccione su geometría de línea o polígono M o ZM como la capa de entrada y ejecútelo.

Los vértices se extraerán con los valores M y Z intactos dependiendo de lo que esté en la geometría original.

Si el valor M es necesario como un campo en la tabla de atributos, entonces la calculadora de campo se puede usar con una expresión como m($geometry)

TJ Rockefeller
fuente