Узлы извлечения QGIS с М-значениями для линейных ссылок

10

У меня есть слой MultiLineStringZM в базе данных sqlite, и я пытаюсь визуализировать меры или m-значения в вершинах. Я попытался найти информацию о том, как это сделать в QGIS, и все, что мне удалось собрать, это то, что это невозможно напрямую из слоя линейных линий и что точки должны быть извлечены в отдельный слой.

Я использовал Vector-> Geometry Tools-> Extract nodesдля создания многоточечного слоя, представляющего вершины моего многострочного слоя, но процесс теряет m-значения вершин. Мне нужно сохранить m-значения, сохранив m-значение как атрибут точки или что-то еще?

Внутри у нас есть инструмент командной строки, который преобразует линейные строки в точечный шейп-файл с m-значениями, хранящимися в качестве атрибута в каждой точке, и я использовал это для проверки наличия m-значений, назначенных вершинам, и я мог бы использовать что если мне нужно, но если это возможно, было бы неплохо, если бы это можно было сделать непосредственно внутри QGIS.

РЕДАКТИРОВАТЬ - повторяя то, что я сказал выше, но еще раз подчеркивая тот факт, что у нас есть инструмент командной строки, который может достичь ожидаемых результатов, который использует библиотеки GDAL, поэтому решение, показывающее только частичный ответ в PyQGIS - не тот ответ, который я ищу. Я ищу встроенный инструмент, готовый плагин для QGIS или полный скрипт, который может извлекать (не создавать / генерировать) и визуализировать m-значения из геометрии MultiLineStringZM или LineStringZM.

Ти Джей Рокфеллер
источник
Вы можете использовать плагин LRS, чтобы получить значения m. Вам нужно будет извлечь узлы, а затем получить меры из линейной строки, используя плагин LRS или инструменты для измерения расстояния вдоль линии.
jbalk
@jbalk Я попробовал плагины LRS и QChainage, и оба этих плагина, похоже, настроены на генерацию мер через регулярные промежутки времени, а не для использования существующих мер, если я что-то упустил и просто неправильно использую плагины ,
Ти Джей Рокфеллер
Со страницы плагина LRS: - Плагин поддерживает калибровку, создание точечных и линейных событий и вычисление мер для точек - Вот сайт blazek.github.io/lrs Задайте вопрос о плагине LRS на этом сайте, если вы можете не понял это.
jbalk
Похоже, что вы ничего не можете сделать с плагином LRS, пока не откалибруете его, и для его калибровки вам понадобится точечный слой с мерами, сохраненными в качестве атрибута, и это именно то, что я пытаюсь получить из моего MultiLineStringZM Поэтому я не думаю, что это поможет в этой ситуации.
TJ Рокфеллер
Вы можете создавать точки каждые 1000 м вдоль линии, чтобы использовать их для калибровки. Или посмотрите на расстояние вдоль линейных инструментов в наборах инструментов SAGA и GRASS в QGIS, чтобы получить значения m.
jbalk

Ответы:

6

Из того, что я могу найти, похоже, не существует существующего решения для этой конкретной ситуации, но я все еще хотел иметь возможность сделать это в QGIS, поэтому я погрузился в сценарии Python.

Руководство по написанию алгоритмов обработки можно найти здесь https://docs.qgis.org/2.18/en/docs/user_manual/processing/scripts.html.

Чтобы использовать этот код, откройте панель инструментов Обработка, затем разверните Сценарии, затем разверните Инструменты. Выберите «Создать новый сценарий», скопируйте и вставьте приведенный ниже код в окно сценария (соблюдайте осторожность при копировании и вставке кода Python, поскольку пробел является синтаксически значимым. Если у вас возникли проблемы, поместите код в текстовый редактор, отображающий пробелы, и убедитесь, что чтобы оно правильно копировалось). Сохраните его, где хотите, и в верхней части окна есть кнопка «Выполнить скрипт». После того, как вы сохраните его, вы можете «Добавить сценарий из файла» и навсегда сохранить сценарий в разделе «Пользовательские сценарии».

Когда появится окно обработки, выберите слой, который содержит векторную геометрию, и выберите «Выполнить». Сценарий ведет себя так же, как «Узлы извлечения», за исключением того, что он добавляет столбец с именем MValuesи или в ZValuesзависимости от того, что доступно во входной геометрии.

##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
Ти Джей Рокфеллер
источник
4

С QGIS 3.0 или новее эта задача тривиальна. В «Панели инструментов обработки» (Открыть с помощью Ctrl + Alt + T или Обработка -> Панель инструментов) найдите «Извлечь вершины» и запустите этот алгоритм.

Выберите линию M или ZM или геометрию многоугольника в качестве входного слоя и запустите.

Вершины будут извлечены со значениями M и Z без изменений в зависимости от того, что находится в исходной геометрии.

Если значение M необходимо в качестве поля в таблице атрибутов, тогда калькулятор поля можно использовать с выражением, подобным m($geometry)

Ти Джей Рокфеллер
источник