forked from geometalab/ArcGISConnector-QGIS-Plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
arcgiscon_plugin.py
247 lines (207 loc) · 12.1 KB
/
arcgiscon_plugin.py
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from builtins import object
from builtins import str
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QApplication
from qgis.core import QgsMapLayer, QgsProject, QgsMessageLog
from .arcgiscon_service import NotificationHandler, EsriUpdateService,\
FileSystemService
from .arcgiscon_controller import ArcGisConNewController, \
ArcGisConRefreshController, ConnectionSettingsController, QueryFeatureController
from .arcgiscon_image_controller import ImageController
from .layer_dialog_controller import LayerDialogController
from .arcgiscon_model import EsriRasterLayer
from uuid import uuid4
import os.path
from . import resources_rc
# import sys;
# sys.path.append(r'/Applications/liclipse/plugins/org.python.pydev_3.9.2.201502042042/pysrc')
# import pydevd
class ArcGisConnector(object):
# pydevd.settrace()
_iface = None
_newLayerAction = None
_newLayerActionText = None
_arcGisRefreshLayerAction = None
_arcGisRefreshLayerWithNewExtentAction = None
_arcGisTimePickerAction = None
_arcGisSaveImageAction = None
_pluginDir = None
_esriRasterLayers = None
_updateService = None
_qSettings = None
_legendActions = None
# Controllers
_settingsController = None
_imageController = None
_refreshController = None
_connectionController = None
_layerDialogController = None
_queryFeatureController = None
def __init__(self, iface):
self._iface = iface
self.initControllers()
self._pluginDir = os.path.dirname(__file__)
self._qSettings = QSettings()
locale_path = os.path.join(self._pluginDir,'i18n','arcgiscon_en.qm')
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
NotificationHandler.configureIface(iface)
self._esriRasterLayers = {}
self._iface.projectRead.connect(self._onProjectLoad)
self._updateService = EsriUpdateService.createService(iface)
self._updateService.finished.connect(self._updateServiceFinished)
QgsProject.instance().layerRemoved.connect(self._onLayerRemoved)
QgsProject.instance().writeProject.connect(self._onProjectInitialWrite)
QgsProject.instance().projectSaved.connect(self._onProjectSaved)
self._connectToRefreshAction()
def initControllers(self):
self._settingsController = ConnectionSettingsController(self._iface)
self._imageController = ImageController(self._iface)
self._refreshController = ArcGisConRefreshController(self._iface)
self._connectionController = ArcGisConNewController(self._iface)
self._layerDialogController = LayerDialogController(self._iface)
self._queryFeatureController = QueryFeatureController(self._iface)
# Register handler to event
self._connectionController.addEventHandler(self.handleLogin)
def handleLogin(self, sender, connection):
self._layerDialogController.showView(connection,
self._updateService,
self._esriRasterLayers,
[
self._arcGisRefreshLayerAction,
self._arcGisRefreshLayerWithNewExtentAction,
self._arcGisTimePickerAction,
self._arcGisSaveImageAction,
self._arcGisTimePickerAction,
self._arcGisSettingsAction
])
def initGui(self):
newLayerActionIcon = QIcon(':/plugins/ImageServerConnector/icons/logo.png')
self._newLayerActionText = QCoreApplication.translate('ArcGisConnector', 'Add ArcGIS ImageServer Layer..')
self._newLayerAction = QAction(
newLayerActionIcon,
self._newLayerActionText,
self._iface.mainWindow())
self._newLayerAction.triggered.connect(
lambda: self._connectionController.showView()
)
try:
self._iface.layerToolBar().addAction(self._newLayerAction)
except:
self._iface.addToolBarIcon(self._newLayerAction)
self._iface.dataSourceManagerToolBar().addSeparator()
self._iface.dataSourceManagerToolBar().addAction(self._newLayerAction)
self._iface.addRasterToolBarIcon(self._newLayerAction)
self._iface.insertAddLayerAction(self._newLayerAction)
self._arcGisRefreshLayerWithNewExtentAction = QAction( QCoreApplication.translate('ArcGisConnector', 'Refresh layer with current extent'))
self._arcGisSaveImageAction = QAction( QCoreApplication.translate('ArcGisConnector', 'Save layer image as..') )
self._arcGisTimePickerAction = QAction( QCoreApplication.translate('ArcGisConnector', 'Choose layer time extent..'))
self._arcGisSettingsAction = QAction( QCoreApplication.translate('ArcGisConnector', 'ArcGIS layer settings..'))
self._histogramDialogAction = QAction(QCoreApplication.translate('ArcGisConnector', 'Compute histogram from current extent..'))
self._iface.addCustomActionForLayerType(self._arcGisSaveImageAction, QCoreApplication.translate('ArcGisConnector', 'ImageServer Connector'), QgsMapLayer.RasterLayer, True)
self._iface.addCustomActionForLayerType(self._arcGisRefreshLayerWithNewExtentAction, QCoreApplication.translate('ArcGisConnector', 'ImageServer Connector'), QgsMapLayer.RasterLayer, True)
self._iface.addCustomActionForLayerType(self._arcGisTimePickerAction, QCoreApplication.translate('ArcGisConnector', 'ImageServer Connector'), QgsMapLayer.RasterLayer, True)
self._iface.addCustomActionForLayerType(self._arcGisSettingsAction, QCoreApplication.translate('ArcGisConnector', 'ImageServer Connector'), QgsMapLayer.RasterLayer, True)
self._iface.addCustomActionForLayerType(self._histogramDialogAction,
QCoreApplication.translate('ArcGisConnector', 'ImageServer Connector'),
QgsMapLayer.RasterLayer, True)
self._iface.mapCanvas().extentsChanged.connect(self._onExtentsChanged)
self._arcGisSaveImageAction.triggered.connect(self._onLayerImageSave)
self._arcGisRefreshLayerWithNewExtentAction.triggered.connect(lambda: self._refreshEsriLayer())
self._arcGisTimePickerAction.triggered.connect(self._chooseTimeExtent)
self._arcGisSettingsAction.triggered.connect(self._showSettingsDialog)
self._histogramDialogAction.triggered.connect(self._showComputeHistogram)
def _getCurrentLayer(self):
qgsLayers = self._iface.layerTreeView().selectedLayers()
for layer in qgsLayers:
for rasterLayer in self._esriRasterLayers.values():
if layer.id() == rasterLayer.qgsRasterLayer.id():
return rasterLayer
def _connectToRefreshAction(self):
for action in self._iface.mapNavToolToolBar().actions():
if action.objectName() == "mActionDraw":
action.triggered.connect(self._refreshAllEsriLayers)
def _refreshAllEsriLayers(self):
for layer in list(self._esriRasterLayers.values()):
self._refreshController.updateLayer(self._updateService, layer)
def _refreshAllVisibleLayers(self):
for layer in list(self._esriRasterLayers.values()):
self._refreshController.updateLayerWithNewExtent(self._updateService, layer)
def _showComputeHistogram(self):
rasterLayer = self._getCurrentLayer()
self._queryFeatureController.showHistogramDialog(rasterLayer)
def _refreshEsriLayer(self):
rasterLayer = self._getCurrentLayer()
self._refreshController.updateLayerWithNewExtent(self._updateService, rasterLayer)
def _onExtentsChanged(self):
if self._iface.mapCanvas().renderFlag():
self._refreshAllVisibleLayers()
def _onProjectLoad(self):
projectId = str(QgsProject.instance().readEntry("arcgiscon","projectid","-1")[0])
if projectId != "-1":
self._reconnectEsriLayers()
FileSystemService().removeDanglingFilesFromProjectDir([layer.connection.createSourceFileName() for layer in list(self._esriRasterLayers.values())], projectId)
self._updateService.updateProjectId(projectId)
def _onProjectInitialWrite(self):
projectId = str(QgsProject.instance().readEntry("arcgiscon","projectid","-1")[0])
if projectId == "-1" and self._esriRasterLayers:
projectId = uuid4().hex
for esriLayer in list(self._esriRasterLayers.values()):
newSrcPath = FileSystemService().moveFileFromTmpToProjectDir(esriLayer.connection.createSourceFileName(), projectId)
if newSrcPath is not None:
esriLayer.qgsRasterLayer.setDataSource(newSrcPath, esriLayer.qgsRasterLayer.name(),"ogr")
QgsProject.instance().writeEntry("arcgiscon","projectid",projectId)
self._updateService.updateProjectId(projectId)
def _onProjectSaved(self):
projectId = str(QgsProject.instance().readEntry("arcgiscon","projectid","-1")[0])
if projectId != "-1":
FileSystemService().removeDanglingFilesFromProjectDir([layer.connection.createSourceFileName() for layer in list(self._esriRasterLayers.values())], projectId)
def _reconnectEsriLayers(self):
layers = QgsProject.instance().mapLayers()
for qgsLayer in list(layers.values()):
if qgsLayer.customProperty('arcgiscon_connection_url', ''):
try:
esriLayer = EsriRasterLayer.restoreFromQgsLayer(qgsLayer)
self._esriRasterLayers[esriLayer.qgsRasterLayer.id()] = esriLayer
self._iface.addCustomActionForLayer(self._arcGisRefreshLayerAction, qgsLayer)
self._iface.addCustomActionForLayer(self._arcGisRefreshLayerWithNewExtentAction, qgsLayer)
except:
raise
def _onLayerImageSave(self):
rasterLayer = self._getCurrentLayer()
self._imageController.saveImage(rasterLayer.qgsRasterLayer.dataProvider().dataSourceUri())
def _chooseTimeExtent(self):
rasterLayer = self._getCurrentLayer()
self._refreshController.showTimePicker(rasterLayer, lambda: self._refreshEsriLayer())
def _showSettingsDialog(self):
rasterLayer = self._getCurrentLayer()
self._settingsController.showSettingsDialog(rasterLayer, lambda: self._refreshEsriLayer())
def _updateServiceFinished(self):
self._updateService.tearDown()
# move back to main GUI thread
self._updateService.moveToThread(QApplication.instance().thread())
def _onLayerRemoved(self, layer_id):
if layer_id in self._esriRasterLayers:
QgsMessageLog.logMessage("Deleting raster layer")
del self._esriRasterLayers[layer_id]
def unload(self):
FileSystemService().clearAllFilesFromTmpFolder()
self._iface.removePluginMenu(
QCoreApplication.translate('ArcGisConnector', 'arcgiscon'),
self._newLayerAction)
self._iface.removePluginRasterMenu(self._newLayerActionText, self._newLayerAction)
self._iface.removeToolBarIcon(self._newLayerAction)
self._iface.layerToolBar().removeAction(self._newLayerAction)
self._iface.removeCustomActionForLayerType(self._arcGisRefreshLayerAction)
self._iface.removeCustomActionForLayerType(self._arcGisSaveImageAction)
self._iface.removeCustomActionForLayerType(self._arcGisRefreshLayerWithNewExtentAction)
self._iface.removeCustomActionForLayerType(self._arcGisTimePickerAction)
self._iface.removeCustomActionForLayerType(self._arcGisSettingsAction)
self._iface.removeCustomActionForLayerType(self._histogramDialogAction)
self._iface.dataSourceManagerToolBar().removeAction(self._newLayerAction)