Объединение нескольких строк по полю значения

Dec 09 2020

Как я могу присоединиться к этим строкам в зависимости от поля Trigger. Условие таково: поля должны быть расположены в порядке возрастания после поля fid от 1до 68. Таким образом, я хочу объединить все свои строки, начиная с первой, у которой есть триггер 1, и следующих, которые имеют значение, 0останавливаются на первом значении 1и начинаются снова.

Изменить: я понимаю. Но как я могу решить эту проблему? Как соединить эти строки? Спусковой крючок относится к углу. Если он равен 0, то угол между двумя сегментами меньше x градусов, а если он равен 1, угол больше x градусов. Итак, я хочу, чтобы первая строка не была триггером, я хочу присоединить ее к первой строке, которая является триггером.

Ответы

3 MrXsquared Dec 09 2020 at 19:48

Чтобы дать вам представление о том, как это можно сделать, вот решение на Python для добавления нового поля groupid, которое вы можете использовать для растворения ваших строк:

# Change your settings here:
layername = 'line' 
triggerfield = 'Trigger' # field must already exist
groupfieldname = 'mygroup' # will be added if does not exist
newlineindicator = 1

#####
# no changes needed below #
#####
layer = QgsProject.instance().mapLayersByName(layername)[0] # get the layer
layer.startEditing() # start editing the layer
layer.dataProvider().addAttributes([QgsField(groupfieldname,QVariant.Int)]) # add a group field
layer.commitChanges() # save new added field to prevent crash when searching for it later
layer.startEditing() # start editing the layer again
groupid = 0 # initialize groupid
fieldindex = layer.fields().indexFromName(groupfieldname) # get fieldindex of groupfield

for feat in layer.getFeatures(): # itereate over layer
    if feat[triggerfield] == newlineindicator: # if a new trigger appears, increase groupcounter
        groupid += 1
    attrs = { fieldindex : groupid } # prepare attributes
    layer.dataProvider().changeAttributeValues({ feat.id() : attrs }) # assign current groupid to current feature
layer.commitChanges() # save changes

Результат:

3 Babel Dec 09 2020 at 21:08

Существует способ напрямую создать значение поля, используя выражение QGIS в калькуляторе поля, чтобы сгруппировать вместе все те функции, которые вы хотите объединить. В зависимости от значения этого поля вы можете использовать функцию Aggregateдля объединения объектов с одинаковым значением (см. Второй снимок экрана ниже). Шаги ботов должно быть легко автоматизировать с помощью модели.

Взяв вашу структуру данных и имена полей, выражение выглядит следующим образом (объяснение работы выражения см. Ниже):

array_last (
    array_sort (
        array_foreach (
            array_remove_all ( 
                array_agg ( 
                    if ( 
                        "trigger" = 1, 
                        "fid" , 
                        0
                    ) 
                ) ,
            0) ,
        if (
            if ( 
                "trigger" = 1, 
                "fid" , 
                0 
                ) = @element, 
                @element, 
                if (
                    "fid" > @element ,  
                    @element,0
                )
        )
        ) 
    )
)

Затем вы можете использовать это поле вместе с функцией, Menu Processing / Toolbox / Aggregateчтобы объединить эти функции вместе.

Чтобы объяснить идею выражения: для лучшего понимания назовем «начальный сегмент» соединенной линии, которую вы наконец хотите получить « головой », а последующие сегменты, которые присоединяются к ней, « хвостами ».

  1. Получите fid-значения голов , назовем это " идентификаторами групп ". Конечная цель - назначить каждый хвостовой сегмент голове (или: каждому хвосту следует присвоить значение идентификатора группы следующей меньшей головы : 2 и 3 должны быть присвоены 1, 5 и 6 до 4 и т. Д.) A) Если триггер равен 1 ( голова ), получите значение идентификатора: это идентификатор группы . В противном случае (для хвостов ) установите значение 0. б) Объедините эти значения, создав массив. c) Удалите все 0 значений из массива. Таким образом, мы получаем массив идентификаторов групп (= идентификатор голов ): [1,4,7,9,12]. Наконец, мы хотим назначить каждую функцию одному из этих значений из массива.

  2. Теперь переберите все функции слоя с каждым из этих идентификаторов групп из массива с выражением array_foreach: a) Для функций с триггером = 1 ( головки ) у нас нет проблем, они уже имеют правильный идентификатор группы (соответствующий их fid) b) В остальных случаях ( хвосты , trigger = 0) мы должны присвоить новые значения. Таким образом, мы сравниваем каждое входное значение из массива (список всех идентификаторов групп ) с fid и сохраняем идентификатор группы, если он меньше, чем fid (так как мы хотим присвоить следующее меньшее значение). В противном случае мы устанавливаем его в 0. Так что ни в коем случае не будет получено значение из массива больше, чем fid.

  3. Отсортируйте массив, чтобы убедиться, что у нас есть значения в правильном порядке (от наименьшего к наибольшему) - чтобы удалить конечные нули из последней публикации (см. Снимок экрана ниже). Без установки порядка сортировки мы получаем значение по умолчанию ascending=true.

  4. Получите последнее значение из отсортированного массива, таким образом, последний (самый большой) идентификатор группы, который (помните шаг 2b) ни в коем случае не превышает fid И (в случае trigger = 1) равен fid (шаг 2a) И всегда число из массива, который мы создали в 1.

См. Снимок экрана с промежуточными результатами шагов 1 и 2:

Теперь легко использовать агрегатную функцию с полем, созданным, как описано выше.