Як посилатися на інший шар у польовому калькуляторі?


26

Чи є спосіб вибрати атрибут з шару багатокутника і вставити значення у віртуальне поле точкового шару, використовуючи "в" в калькуляторі поля?

CASE
 WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END

введіть тут опис зображення


1
Чому б не використовувати для цього плагін "Інструмент точкового відбору"?
Якоб

Тому що мені потрібні динамічні оновлення під час створення нових точок або переміщення існуючих точок.
Місячне море

Вам буде краще писати цю взаємодію, а не покладатися на інструменти, які не використовуються.
nagytech

На жаль, я не маю жодного досвіду сценаріїв.
Місячне море

@LunarSea Я написав приклад нижче, щоб ви наслідували, але, можливо, вам доведеться налаштувати його відповідно до ваших потреб.
nagytech

Відповіді:


22

Просторові з'єднання доступні в польовому калькуляторі після встановлення плагіна refFunctions.

geomwithin(targetLayer,targetField)

Плагіни набагато простіші, ніж використання користувацького сценарію. Спасибі!
jpmc26

geomwithin ('targetLayer', 'targetField').
Раджа

19

Поле полезний калькулятор не підтримує просторових з'єднань між шарами функції. Але якщо ви подивитесь на публікацію NathanW у редакторі функцій для виразів qgis, ви зможете зрозуміти, що ми можемо скриптувати власну взаємодію з даними.

Наступний сценарій дозволить вам виразити те, що ви хочете. Це працює за допомогою ітерації через всі функції на полігоновому шарі, і якщо є просторове з'єднання, то посилаються табличні дані із зазначеного стовпця:

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

allfeatures = None
index = QgsSpatialIndex()
indexMade = 0
refLayer = None

@qgsfunction(args="auto", group='Custom')
def spatialJoinLookup(layerName, refColumn, defaultValue, geom, feature, parent):

    if geom is None:
        return defaultValue

    # globals so we don't create the index, refLayer more than once
    global allfeatures
    global index
    global indexMade
    global refLayer

    # Get the reference layer
    if refLayer is None:
        for layer in iface.mapCanvas().layers():
            if layerName == layer.name():
                refLayer = layer
                break
    if refLayer is None:
        raise Exception("Layer [" + layerName + "] not found")

    # Create the index if not exists
    if indexMade == 0:
        index = QgsSpatialIndex()
        allAttrs = layer.pendingAllAttributesList()
        layer.select(allAttrs)
        allfeatures = {feature.id(): feature for (feature) in refLayer.getFeatures()}
        for f in allfeatures.values():
            index.insertFeature(f)
        indexMade = 1

    # Use spatail index to find intersect 
    fid = None
    ids = index.intersects(geom.boundingBox())
    for id in ids:
        fid = id
        break # Only get the first match.
    if fid is not None:
        return allfeatures[fid].attribute(refColumn)

    # Default
    return defaultValue

Приклад багатошарового шару

Нижче наведено приклад багатокутного шару, який у вас може бути. Я також створив відповідний точковий шар, який ви побачите на фінальному зображенні.

введіть тут опис зображення

Використання вираження

Зауважте, якщо ви хочете використовувати окремий стовпець, ви повинні змінити другий аргумент, щоб він відповідав імені стовпця в наборі даних полігона. Наприклад, ви можете використовувати стовпець «AreaNumber», але вам доведеться відповідати типу стовпця в налаштуваннях калькулятора поля.

введіть тут опис зображення

Результат

Ви можете бачити, що значення стовпця за замовчуванням було застосовано там, де немає просторового з'єднання, а інші співпали з правильними даними. Зауважте, що сценарій, який я дав, приєднається лише до першого матчу. Вам потрібно було б створити іншу логіку бізнесу, якби ваші багатокутники перекривались.

введіть тут опис зображення


Дякую, ваш сценарій прекрасно працює, використовуючи "geom" замість "геометрії" в першому "if". З'єднання геометрії таким чином може бути дуже корисним, наприклад, для створення декількох міток на полігонах.
Місячне море

Вибачте, я не знаю, як я це пропустив. Сподіваємось, немає проблем з продуктивністю - я спробував це лише з дуже невеликим набором записів.
nagytech

Маючи лише 100+ балів, QGIS бореться з проблемами продуктивності. Додавання нової точкової функції - це справді біль, навіть якщо немає акустичної функції, яка відображається на гострому полотні. Інакше при збільшенні QGIS прискорюється. Я спробував `CASE WHEN $ scale <10000 THEN spaceJoinLookupI ('Polygons', 'AreaName', 'None', $ geometry) END ', але це не працює. Чи можна щось зробити, щоб поліпшити продуктивність?
Місячне море

@LunarSea Я оновив функцію використання просторового індексу. Це повинно бути розумно швидше.
nagytech

Спасибі за вашу допомогу. Просторове з'єднання зараз набагато швидше, але, на жаль, щось не працює належним чином. Я отримую різні результати за точками в одному і тому ж полігоні.
Місячне море

8

Це можна зробити в Field Calculator з функцією aggregate(). У точковому шарі створіть нове поле з виразом калькулятора поля таким чином:

aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)

Де layerназва полігонного шару написана як рядок, aggreagateє агрегованою функцією (може використовуватися також сума тощо), expressionполе з значень буде взято, concatenatorє приєднанням до рядка символів (повинні бути встановлені, навіть у цьому випадку) і filterфільтрує функції на основі на експресію (в цьому випадку перетинає геометрію шару з геометрією батьківського шару).

Для отримання додаткової інформації ознайомтеся з документацією щодо сукупності QGIS .

Для автоматичного оновлення можна використовувати віртуальні поля або ви можете встановити вираз як значення за замовчуванням у налаштуваннях форми атрибутів у властивостях шару ( документація щодо налаштування форми атрибутів ).

введіть тут опис зображення


3
Слід зазначити, що просторові функції (з geometry(@parent)) підтримуються лише з QGIS 3 і далі. На всякий випадок, коли хтось, хто читає це, все ще використовує 2.18 ...
she_weeds

Дякую. Працює як шарм.
spatialthoughts
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.