-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdata_wizard.py
More file actions
231 lines (201 loc) · 8.74 KB
/
Copy pathdata_wizard.py
File metadata and controls
231 lines (201 loc) · 8.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# -*- coding: utf-8 -*-
"""
/***************************************************************************
Data_Wizard – QGIS Plugin
Erzeugt IB-Tool-Eingabedaten aus ATKIS Basis-DLM SHP-Dateien.
***************************************************************************/
"""
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.core import Qgis, QgsTask, QgsApplication, QgsMessageLog
from .resources import * # noqa: F401,F403 - registers Qt resources (icons) as a side effect
from .data_wizard_dialog import Data_WizardDialog
import os.path
class _AtkisTask(QgsTask):
"""Führt die ATKIS-Verarbeitung in einem Hintergrund-Thread aus."""
def __init__(self, *, source_dir, hu_path, target_dir, study_area_path,
hu_function_field, iface, on_finished=None):
super().__init__("ATKIS Verarbeitung", QgsTask.CanCancel)
self.source_dir = source_dir
self.hu_path = hu_path
self.target_dir = target_dir
self.study_area_path = study_area_path
self.hu_function_field = hu_function_field
self.iface = iface
self.on_finished = on_finished
self.exception = None
def run(self):
"""Läuft im Hintergrund-Thread."""
try:
from .processor import process_atkis
def log(msg):
QgsMessageLog.logMessage(msg, "Data Wizard", Qgis.Info)
process_atkis(self.source_dir, self.hu_path, self.target_dir,
study_area_path=self.study_area_path,
hu_function_field=self.hu_function_field,
feedback=log, task=self)
return True
except Exception as e:
self.exception = e
QgsMessageLog.logMessage(str(e), "Data Wizard", Qgis.Critical)
return False
def finished(self, result):
"""Läuft im Haupt-Thread – sicher für UI-Zugriff.
Wird garantiert aufgerufen, während dieses Task-Objekt selbst noch
lebt (Qt ruft es direkt als Abschluss der Task auf) - daher der
richtige Ort, um den Laufend-Zustand beim Plugin zurückzusetzen,
statt das (ggf. später vom TaskManager zerstörte) Task-Objekt aus
einem späteren Plugin-Aufruf heraus erneut abzufragen.
"""
if self.on_finished:
self.on_finished()
if result:
self.iface.messageBar().pushMessage(
"Data Wizard",
QCoreApplication.translate(
'Data_Wizard',
"Done – HU.gpkg, RN.gpkg and AUX_L.gpkg in: {}"
).format(self.target_dir),
level=Qgis.Success,
duration=8)
elif self.isCanceled():
self.iface.messageBar().pushMessage(
"Data Wizard",
QCoreApplication.translate('Data_Wizard', "Processing cancelled."),
level=Qgis.Info,
duration=5)
else:
msg = str(self.exception) if self.exception else QCoreApplication.translate(
'Data_Wizard', "Unknown error")
self.iface.messageBar().pushMessage(
"Data Wizard",
QCoreApplication.translate('Data_Wizard', "Error: {}").format(msg),
level=Qgis.Critical,
duration=10)
class Data_Wizard:
"""QGIS Plugin Implementation."""
def __init__(self, iface):
self.iface = iface
self.plugin_dir = os.path.dirname(__file__)
locale = QSettings().value('locale/userLocale')[0:2]
locale_path = os.path.join(
self.plugin_dir, 'i18n',
'Data_Wizard_{}.qm'.format(locale))
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
QCoreApplication.installTranslator(self.translator)
self.actions = []
# Gleicher Menütitel wie IBTool selbst, damit beide Aktionen im
# selben Untermenü landen: Erweiterungen -> IB-Tool -> Data Wizard
self.menu = self.tr(u'&IB-Tool')
self.first_start = None
self.task = None
# Eigener Laufend-Status statt self.task.status() abzufragen: Qt
# kann das zugrunde liegende C++-Objekt einer abgeschlossenen Task
# zerstören, auch während self.task (die Python-Referenz) noch
# existiert - ein späterer Zugriff auf self.task.status() würfe
# dann "wrapped C/C++ object ... has been deleted".
self._task_running = False
def tr(self, message):
return QCoreApplication.translate('Data_Wizard', message)
def add_action(self, icon_path, text, callback,
enabled_flag=True, add_to_menu=True,
add_to_toolbar=True, status_tip=None,
whats_this=None, parent=None):
icon = QIcon(icon_path)
action = QAction(icon, text, parent)
action.triggered.connect(callback)
action.setEnabled(enabled_flag)
if status_tip is not None:
action.setStatusTip(status_tip)
if whats_this is not None:
action.setWhatsThis(whats_this)
if add_to_toolbar:
self.iface.addToolBarIcon(action)
if add_to_menu:
self.iface.addPluginToMenu(self.menu, action)
self.actions.append(action)
return action
def initGui(self):
icon_path = ':/plugins/data_wizard/icon.png'
self.add_action(
icon_path,
text=self.tr(u'Data Wizard'),
callback=self.run,
parent=self.iface.mainWindow())
self.first_start = True
def unload(self):
for action in self.actions:
self.iface.removePluginMenu(self.menu, action)
self.iface.removeToolBarIcon(action)
def _on_task_finished(self):
"""Von _AtkisTask.finished() im Haupt-Thread aufgerufen, sobald die
Verarbeitung endet (Erfolg, Abbruch oder Fehler)."""
self._task_running = False
def run(self):
if self.first_start:
self.first_start = False
self.dlg = Data_WizardDialog()
self.dlg.show()
result = self.dlg.exec_()
if not result:
return
if self._task_running:
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("A process is already running – please wait."),
level=Qgis.Warning, duration=5)
return
source_dir = self.dlg.get_source_dir()
hu_path = self.dlg.get_hu_file()
hu_function_field = self.dlg.get_hu_function_field()
study_area_path = self.dlg.get_study_area_file()
target_dir = self.dlg.get_target_dir()
if not source_dir or not hu_path or not target_dir:
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Please specify source folder, building footprint file, "
"and target folder."),
level=Qgis.Warning, duration=5)
return
if not os.path.isdir(source_dir):
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Source folder not found: {}").format(source_dir),
level=Qgis.Warning, duration=5)
return
if not os.path.isfile(hu_path):
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Building footprint file not found: {}").format(hu_path),
level=Qgis.Warning, duration=5)
return
if not os.path.isdir(target_dir):
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Target folder not found: {}").format(target_dir),
level=Qgis.Warning, duration=5)
return
if study_area_path and not os.path.isfile(study_area_path):
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Study area file not found: {}").format(study_area_path),
level=Qgis.Warning, duration=5)
return
self.task = _AtkisTask(
source_dir=source_dir,
hu_path=hu_path,
target_dir=target_dir,
study_area_path=study_area_path or None,
hu_function_field=hu_function_field,
iface=self.iface,
on_finished=self._on_task_finished)
self._task_running = True
QgsApplication.taskManager().addTask(self.task)
self.iface.messageBar().pushMessage(
"Data Wizard",
self.tr("Processing running in background – see Task Manager and "
"log messages."),
level=Qgis.Info, duration=5)