Зробіть оновлення рівня Qgis із зміненого джерела даних


13

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

Я хочу написати новий файл форми з різними значеннями атрибутів і оновити кольори карти Qgis. Крок 1 запускає цей процес, крок 2 - це перезавантаження шару із зміненого файлу форми. Її крок 2 Я тут хвилююся.

Інші запитання / чат-лист розсилки згадує про використання triggerRepaintна шарі - це не працює. Інші пропозиції включають setCacheImage(None)і знову це не працює. Шар в кінцевому підсумку оновлюється, але я дійсно не бачу логіки, а іноді це відбувається зненацька після того, як я нічого не зробив. А може, я щось зробив дві хвилини тому.

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

Я думаю, що це працювало краще в 2,8, але це 2,10, тож, можливо, десь є нова помилка.

Пов’язано, але не працює для мене в 2.10:

Як автоматично перезавантажити растрові шари, якщо джерело змінено в QGIS?

Інші речі, які я спробував:

  • layer.dataProvider().dataChanged.emit() - працював один раз, потім знову не на тому ж шарі

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

QgsVectorLayer( layer.source(), "layer copy", layer.providerType() )
layer.triggerRepaint()

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

Швидкий тест лише з растровим шаром (від GeoTIFF), і лише виклик, rlayer.triggerRepaint()здається, надійно оновить вигляд растра на полотні карти.


Можливо, вам доведеться опублікувати зразок коду.
Nathan W

@NathanW Більшість того, що я роблю, - це з шару gui - завантаження, стильового - тоді він просто отримує шар і ці кілька рядків у консолі Python. Мені не хочеться вставляти це в рамки плагіна, поки я не знаю, що зможу зробити принцип роботи! Я сподівався, що буде швидка відповідь ("call layer.updateFromNewDataYouFool ()"), але пізніше я заповнити це ще кодом (включаючи R-код для створення форм-файлів) пізніше.
Спайсмен

Щоб переконатися, ви спробували використати обидві команди згодом: layer.setCacheImage(None)і layer.triggerRepaint()?
Маттіас Кун

Так @MatthiasKuhn - хоча іноді це працює, але не часто. Я щойно написав модифікований файл файлів, зробив обидві речі на консолі Python (на правому шарі), візуального оновлення не було. Найпростіша річ, яка до цього часу працювала на 100%, - це створити новий об'єкт шару, що викидається, на основі оригінального джерела шару, як згадувалося вище, а потім triggerRepaint()на вихідному шарі. v 2.10.1-Піза
Spacedman

У мене є підозра, що це може бути пов’язано із впровадженням пулу з'єднань OGR. Чи можете ви виконати деякі тести, якщо є різниця, якщо ви заміните файл на диску або відредагуєте наявний файл?
Маттіас Кун

Відповіді:


5

Це пов'язано з впровадженням пулу з'єднань OGR. [1]

До QGIS 2.10 файл було відкрито для кожного доступу (наприклад, перефарбування).

Оскільки QGIS 2.10, ручка файлу залишається відкритою, а це означає, що якщо файл замінено, ручка все ще вказує на старий файл в системах на базі Unix.

QGIS 2.10: вирішення

На жаль, не існує API, який би примусив QGIS знову відкрити файл у QGIS 2.10. В якості вирішення проблеми можна використовувати некрасивий хакер:

layer.dataProvider().changeAttributeValues( { -1: { 0: 0 } } )
layer.triggerRepaint()

QGIS 2.12: рішення

Щойно я представив новий метод, який буде доступний починаючи з QGIS 2.12:

layer.dataProvider().forceReload()
layer.triggerRepaint()

Загальний підхід

Якщо у Вас є можливість управління як файл переписується ви можете відкрити існуючі файли з правами на запис і зміна вмісту замість повної заміни файлів (видалення / Recreate) на диску.

[1] Пул підключень був введений для значного прискорення доступу до певних джерел даних.


Схоже, найкраще рішення. .changeAttributeValuesВиховує «ПОМИЛКА 1: Спроба читання форми з функцією ідентифікатором (-1) з доступного діапазону.» але це нормально
Spacedman

2

Якщо ви панорумуєте або іншим чином оновіть карту, її слід оновити.

У цій статті йдеться про те, що в PyQGIS можна використовувати наступне:

myLayer.triggerRepaint()

Для оновлення всіх шарів можна використовувати наступну функцію:

def refresh_layers(self):
    for layer in qgis.utils.iface.mapCanvas().layers():
         layer.triggerRepaint()

Як я вже говорив у своєму запитанні і як згадувалося у посиланні, яке я дав, triggerRepaint()не працює. refresh()на карті полотно не працює. Установити кеш-зображення None(яке тепер застаріло в документах API) не працює. Я просто спробував усі ці речі на нещодавно зміненому шарі формфайлу, панорумував карту, вмикав і вимикав, не вийшло. "Дублює" шар, але він оновлюється миттєво. Ви самі пробували ці речі (2.10)?
Spacedman

Я думаю, що нам потрібно @ nathan-w, щоб відповісти на це. Я сам цього не пробував ...
Алекс Лейт

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