Як створити атлас на основі атрибутів точки?


9

По суті, я хочу створити атлас на основі категоріального поля в точковому шарі.

тобто у мене є точковий рівень працівників, що надають послуги з догляду за дітьми, з категоричним полем "Забезпечення". Я класифікував кожну функцію в цьому полі з "Клубом після школи", "Клубом для сніданку" тощо, і тепер я хочу створити набір карт, які повторюються по кожній категорії та показують лише бали для кожної категорії. Одна карта клубів після школи, одна карта клубів для сніданків тощо. Екстенси можуть бути дещо різними.

Я міг би це зробити по черзі, але, схоже, має бути спосіб створення атласу на основі розширень кожної категорії? (Я відчуваю, що я пропускаю щось очевидне :))

Або альтернативно, чи існує спосіб автоматизації створення багатокутного шару і використання його як прихованого покриття для атласу?

EDIT: Я досяг певного прогресу в цьому - ви можете використовувати стиль на основі правил, щоб увімкнути та вимкнути функції, що відповідають поточній функції покриття атласу. насправді це добре працює, якщо все, що ви хочете зробити, це показати інший набір балів. Зараз я дивлюся на прив’язання цього списку до кольорової гами та реактивної легенди.


1
Це в основному дублікат gis.stackexchange.com/questions/155143
Chris W

Дякую Крісу, але не впевнений, чи так. Це, здається, запитує, чи можна зробити під атлас для кожної області в оригінальному атласі? наприклад, 4 області, по 4 сторінки? (Хоча я і намагався дотримуватися того, про що мене просили)
JonoPatterson

1
Ні, в основному ви обидва бажаєте створити серію карт. Серія показує однакові масштаби карти та базову інформацію, але різні функції в кожній. У моєму коментарі йдеться про посилання та їх посилання на ArcGIS через те, що називається запитами на визначення сторінок - тобто на кожній сторінці атласу / картотеки є запит на визначення, який визначає, які шари / функції відображаються на цій сторінці. Він хоче серію серій, де ви просто хочете одну серію. Однак я не знаю, чи QGIS ще пропонує такий функціонал (я думав, що прочитав відповідь / коментар, що це не так, але зараз не можу знайти це).
Кріс Ш

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

Так, ваш мертвий. Це також є повторенням цього gis.stackexchange.com/questions/121802/… - тому мені, можливо, доведеться вдатися до цього вручну.
JonoPatterson

Відповіді:


9

Я нарешті вирішив це для своїх цілей, тому ось рішення, яке я придумав, якщо це комусь допоможе:

Напишіть сценарій python (мій в кінці цього), який по суті робить це:

  1. визначте унікальні категорії у цікавому полі точкового шару
  2. для кожної категорії виберіть усі відповідні точки та встановіть масштаб цього набору
  3. для кожної міри генеруйте новий багатокутник у чистому шарі покриття атласу з ключовим атрибутом "CategoryName"

Це дало мені шар покриття атласу з одним многокутником для кожної цікавої категорії, який виглядає приблизно так: Атласний покривний шар

Налаштуйте атлас і друкуйте композитора, як зазвичай, залишаючи лише питання про вимкнення та ввімкнення функцій.

Для цього потрібно трохи спроб і помилок, щоб опрацювати точний набір варіантів:

  1. Наведений нижче вираз дозволяє отримати значення, яке зараз міститься у полі CategoryName для поточної функції атласу

    attribute ($atlasfeature, 'CategoryName') 
    
  2. Використовуйте це для створення стильового стилю для точкового шару по лініях

    attribute ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
    
  3. У мене також було правило гарантувати, що всі інші стануть прозорими

    attribute ($atlasfeature, 'CategoryName') IS NOT PointCategory
    

Показані правила

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

Кінцевий набір атласу:

Атлас на основі функцій

Редагувати - як було запропоновано, ось мій сценарій:

    from PyQt4.QtCore import *

#main script----------------------------------------------
    #set up the layer references - you will need to change this
targetlayer=QgsMapLayerRegistry.instance().mapLayer("AtlasExtents20150727154732521")
eylayer = QgsMapLayerRegistry.instance().mapLayer("Early_Years_Providers20150727152919862")

#establish the unique categories 
names = getUniqueAttributes(eylayer, 'Mapping_La')

#get a set of boxes
boxset = getBoundings(eylayer, names)

#ensure layer is emptied, then add bounding boxes
deleteBoxes(targetlayer)
createBoxes(targetlayer, boxset)
 #end main script----------------------------------------------   


 #------functions-------#
#gets unique set of attributes - returns a set()
def getUniqueAttributes(layer, fieldname):
    values = set()
    for feature in layer.getFeatures():
        values.add(feature[fieldname])
    return values

#quickly selects all points on a layer, given a query 
def selectionQuick(layer, queryitem):
    layer.removeSelection ()

    #hardcoded field name
    expr = QgsExpression( "\"Mapping_La\" = '" + queryitem +"'")
    it = layer.getFeatures( QgsFeatureRequest( expr ) )
    ids = [i.id() for i in it]
    layer.setSelectedFeatures( ids )

#for a set of unique items, get bounding boxes 
def getBoundings(layer, itemset):
    bboxes = {}
    for itemname in itemset:
        selectionQuick(layer,itemname)
        box = layer.boundingBoxOfSelected()
        bboxes[itemname] = box
    return bboxes

#for a layer create a bunch of boxes
def createBoxes(layer, boxes):
    id=0
    for boxkey in boxes:
        id = id +1
        box=boxes[boxkey]
        feat = QgsFeature(layer.pendingFields())
        geom = QgsGeometry.fromRect(box)
        feat.setAttribute('id', id)
        #hardcoded field name
        feat.setAttribute('CareType', boxkey)
        feat.setGeometry(geom)
        (res, outFeats) = layer.dataProvider().addFeatures([feat])

def deleteBoxes(layer):
        ids = [f.id() for f in layer.getFeatures()]
        layer.dataProvider().deleteFeatures( ids )

3
@JonoPatterson, якщо ви зараз також поділитесь своїм сценарієм python, згаданим у початку, це була б найкраща відповідь коли-небудь;)
Бернд В.

Гаразд це зробить, хоча його грубо n готово, тому йому знадобляться певні зміни (не робили жодного кодування роками!). Який найкращий спосіб це зробити - просто вставити в кодову скриньку?
JonoPatterson

@JonoPatterson Дякую за сценарій Для мене як для початківця це вже дуже добре виглядає :). Я впевнений, що мені це знадобиться незабаром.
Бернд В.

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