Newer
Older
# -*- coding: utf-8 -*-
"""
/***************************************************************************
EnMAPBox
A QGIS plugin
EnMAP-Box V3
-------------------
begin : 2015-08-20
git sha : $Format:%H$
copyright : (C) 2015 by HU-Berlin
email : bj@geo.hu-berlin.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
import os, sys, re, fnmatch, collections, copy, traceback, six
from qgis.core import *
#os.environ['PATH'] += os.pathsep + r'C:\OSGeo4W64\bin'
from osgeo import gdal, ogr, osr, gdal_array

Benjamin Jakimow
committed
#import console.console_output
#console.show_console()
#sys.stdout = console.console_output.writeOut()
#sys.stderr = console.console_output.writeOut()

Benjamin Jakimow
committed
print('Can not find QGIS instance')

Benjamin Jakimow
committed

Benjamin Jakimow
committed
import code
import codecs
from timeseriesviewer import jp, mkdir, DIR_SITE_PACKAGES, file_search, dprint
site.addsitedir(DIR_SITE_PACKAGES)
#I don't know why, but this is required to run this in QGIS
#todo: still required?
path = os.path.abspath(jp(sys.exec_prefix, '../../bin/pythonw.exe'))
if os.path.exists(path):
multiprocessing.set_executable(path)
sys.argv = [ None ]
#ensure that required non-standard modules are available
import pyqtgraph as pg

benjamin.jakimow@geo.hu-berlin.de
committed
@staticmethod
def fromMapCanvas(mapCanvas):
assert isinstance(mapCanvas, QgsMapCanvas)
extent = mapCanvas.extent()
crs = mapCanvas.mapSettings().destinationCrs()
return SpatialExtent(crs, extent)
def __init__(self, crs, *args):
assert isinstance(crs, QgsCoordinateReferenceSystem)
super(SpatialExtent, self).__init__(*args)
self.mCrs = crs
def setCrs(self, crs):
assert isinstance(crs, QgsCoordinateReferenceSystem)
self.mCrs = crs
def crs(self):
return self.mCrs
def toCrs(self, crs):
assert isinstance(crs, QgsCoordinateReferenceSystem)
if self.mCrs != crs:
trans = QgsCoordinateTransform(self.mCrs, crs)
box = trans.transformBoundingBox(box)
return SpatialExtent(crs, box)
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
def __copy__(self):
return SpatialExtent(self.crs(), QgsRectangle(self))
def combineExtentWith(self, *args):
if args is None:
return
elif isinstance(args[0], SpatialExtent):
extent2 = args[0].toCrs(self.crs())
self.combineExtentWith(QgsRectangle(extent2))
else:
super(SpatialExtent, self).combineExtentWith(*args)
def setCenter(self, centerPoint, crs=None):
if crs and crs != self.crs():
trans = QgsCoordinateTransform(crs, self.crs())
centerPoint = trans.transform(centerPoint)
delta = centerPoint - self.center()
self.setXMaximum(self.xMaximum() + delta.x())
self.setXMinimum(self.xMinimum() + delta.x())
self.setYMaximum(self.yMaximum() + delta.y())
self.setYMinimum(self.yMinimum() + delta.y())
def __cmp__(self, other):
if other is None: return 1
def __eq__(self, other):
s = ""
def __sub__(self, other):
raise NotImplementedError()
def __mul__(self, other):
raise NotImplementedError()

benjamin.jakimow@geo.hu-berlin.de
committed
def upperLeft(self):
return self.xMinimum(), self.yMaximum()
def lowerRight(self):
return self.xMaximum(), self.yMinimum()
def __repr__(self):
return '{} {} {}'.format(self.upperLeft(), self.lowerRight(), self.crs().authid())
from timeseriesviewer.ui.widgets import *
from timeseriesviewer.timeseries import TimeSeries, TimeSeriesDatum, SensorInstrument
columnames = ['date','sensor','ns','nl','nb','image','mask']
def __init__(self, TS, parent=None, *args):
super(QAbstractTableModel, self).__init__()
assert isinstance(TS, TimeSeries)
self.TS = TS
def rowCount(self, parent = QModelIndex()):
return len(self.TS)
def columnCount(self, parent = QModelIndex()):
return len(self.columnames)
def removeRows(self, row, count , parent=QModelIndex()):
self.beginRemoveRows(parent, row, row+count-1)
toRemove = self._data[row:row+count]
for i in toRemove:
self._data.remove(i)
self.endRemoveRows()
def getDateFromIndex(self, index):
if index.isValid():
i = index.row()
if i >= 0 and i < len(self.TS):
return self.TS.getTSDs()[i]
def getTimeSeriesDatumFromIndex(self, index):
if index.isValid():
i = index.row()
if i >= 0 and i < len(self.TS):
return None
def data(self, index, role = Qt.DisplayRole):
return None
value = None
ic_name = self.columnames[index.column()]
TSD = self.getTimeSeriesDatumFromIndex(index)
keys = list(TSD.__dict__.keys())
if role == Qt.DisplayRole or role == Qt.ToolTipRole:
if ic_name == 'name':
value = os.path.basename(TSD.pathImg)
elif ic_name == 'sensor':
if role == Qt.ToolTipRole:
value = TSD.sensor.getDescription()
else:
value = str(TSD.sensor)
elif ic_name == 'date':
value = '{}'.format(TSD.date)
elif ic_name == 'image':
value = TSD.pathImg
elif ic_name == 'mask':
value = TSD.pathMsk
elif ic_name in keys:
value = TSD.__dict__[ic_name]
else:
s = ""
elif role == Qt.BackgroundColorRole:
value = None
elif role == Qt.UserRole:
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
return value
#def flags(self, index):
# return Qt.ItemIsEnabled
def flags(self, index):
if index.isValid():
item = self.getTimeSeriesDatumFromIndex(index)
cname = self.columnames[index.column()]
if cname.startswith('d'): #relative values can be edited
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
else:
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
return flags
#return item.qt_flags(index.column())
return None
def headerData(self, col, orientation, role):
if Qt is None:
return None
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.columnames[col]
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
return col
return None
QAbstractItemModel.__init__(self)
#self.rootItem = TreeItem[]
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
def index(self, row, column, parent = QModelIndex()):
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QModelIndex()
def setData(self, index, value, role = Qt.EditRole):
if role == Qt.EditRole:
row = index.row()
return False
return False
def data(self, index, role=Qt.DisplayRole):
data = None
if role == Qt.DisplayRole or role == Qt.EditRole:
data = 'sampletext'
return data
def flags(self, QModelIndex):
return Qt.ItemIsSelectable
def rowCount(self, index=QModelIndex()):
#---------------------------------------------------------------------------
def columnCount(self, index=QModelIndex()):
return 1
class TimeSeriesDateViewManager(QObject):
def __init__(self, timeSeriesViewer):
assert isinstance(timeSeriesViewer, TimeSeriesViewer)
super(TimeSeriesDateViewManager, self).__init__()
self.TSV = timeSeriesViewer
self.TSDViews = list()

benjamin.jakimow@geo.hu-berlin.de
committed
self.mapViewManager = self.TSV.mapViewManager
self.mapViewManager.sigMapViewAdded.connect(self.addMapView)
self.mapViewManager.sigMapViewRemoved.connect(self.removeMapView)
self.mapViewManager.sigMapViewVisibility.connect(self.setMapViewVisibility)

benjamin.jakimow@geo.hu-berlin.de
committed
self.setSpatialExtent(self.TSV.TS.getMaxSpatialExtent())

benjamin.jakimow@geo.hu-berlin.de
committed
self.initTimeSeries(self.TSV.TS)
self.L = self.TSV.ui.scrollAreaSubsetContent.layout()
self.setSubsetSize(QSize(100,50))

benjamin.jakimow@geo.hu-berlin.de
committed
def activateMapTool(self, key):
for tsdv in self.TSDViews:
tsdv.activateMapTool(key)
def setSubsetSize(self, size):
assert isinstance(size, QSize)
self.subsetSize = size
for tsdv in self.TSDViews:
tsdv.setSubsetSize(size)
self.adjustScrollArea()

benjamin.jakimow@geo.hu-berlin.de
committed
def redraw(self):
for tsdv in self.TSDViews:
tsdv.redraw()
def adjustScrollArea(self):
m = self.L.contentsMargins()
n = len(self.TSDViews)
if n > 0:
refTSDView = self.TSDViews[0]
size = refTSDView.ui.size()
w = n * size.width() + (n-1) * (m.left()+ m.right())
h = max([refTSDView.ui.minimumHeight() + m.top() + m.bottom(),
self.TSV.ui.scrollAreaSubsets.height()-25])
self.L.parentWidget().setFixedSize(w,h)

benjamin.jakimow@geo.hu-berlin.de
committed
def initTimeSeries(self, TS):

benjamin.jakimow@geo.hu-berlin.de
committed
self.TS.sigTimeSeriesDatesAdded.connect(self.createTSDViews)
def setMaxTSDViews(self, n=-1):
self.nMaxTSDViews = n
#todo: remove views

benjamin.jakimow@geo.hu-berlin.de
committed
def setSpatialExtent(self, extent):
if extent:
assert isinstance(extent, SpatialExtent)
tsdviews = sorted(self.TSDViews, key=lambda t:t.TSD)
for tsdview in tsdviews:
tsdview.setSpatialExtent(extent)
def navToDOI(self, TSD):
assert isinstance(TSD, TimeSeriesDatum)
#get widget related to TSD
tsdviews = [t for t in self.TSDViews if t.TSD == TSD]
if len(tsdviews) > 0:
i = self.TSDViews.index(tsdviews[0])+1.5
n = len(self.TSDViews)
scrollBar = self.TSV.ui.scrollAreaSubsets.horizontalScrollBar()
smin = scrollBar.minimum()
smax = scrollBar.maximum()
v = smin + (smax - smin) * float(i) / n
scrollBar.setValue(int(round(v)))
def setMapViewVisibility(self, bandView, isVisible):
assert isinstance(bandView, MapViewDefinition)
assert isinstance(isVisible, bool)
for tsdv in self.TSDViews:
tsdv.setMapViewVisibility(bandView, isVisible)
def addMapView(self, bandView):
assert isinstance(bandView, MapViewDefinition)
w = self.L.parentWidget()
w.setUpdatesEnabled(False)
for tsdv in self.TSDViews:
tsdv.ui.setUpdatesEnabled(False)
for tsdv in self.TSDViews:
for tsdv in self.TSDViews:
tsdv.ui.setUpdatesEnabled(True)
w.setUpdatesEnabled(True)
def removeMapView(self, bandView):
assert isinstance(bandView, MapViewDefinition)

benjamin.jakimow@geo.hu-berlin.de
committed
def createTSDViews(self, timeSeriesDates):
for TSD in timeSeriesDates:
assert isinstance(TSD, TimeSeriesDatum)
tsdView = TimeSeriesDatumView(TSD)
tsdView.setSubsetSize(self.subsetSize)
tsdView.sigExtentsChanged.connect(self.setSpatialExtent)
for i, bandView in enumerate(self.mapViewManager):
tsdView.insertMapView(bandView)

benjamin.jakimow@geo.hu-berlin.de
committed
if self.extent:
tsdView.setSpatialExtent(self.extent)
self.addTSDView(tsdView)

benjamin.jakimow@geo.hu-berlin.de
committed
assert isinstance(TSD, TimeSeriesDatum)
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
tsdvs = [tsdv for tsdv in self.TSDViews if tsdv.TSD == TSD]
assert len(tsdvs) == 1
self.removeTSDView(tsdvs[0])
def removeTSDView(self, TSDV):
assert isinstance(TSDV, TimeSeriesDatumView)
self.TSDViews.remove(TSDV)
def addTSDView(self, TSDV):
assert isinstance(TSDV, TimeSeriesDatumView)
if len(self.TSDViews) < 10:
pass
bisect.insort(self.TSDViews, TSDV)
TSDV.ui.setParent(self.L.parentWidget())
self.L.addWidget(TSDV.ui)
self.adjustScrollArea()
#self.TSV.ui.scrollAreaSubsetContent.update()
#self.TSV.ui.scrollAreaSubsets.update()
s = ""

Benjamin Jakimow
committed

benjamin.jakimow@geo.hu-berlin.de
committed
sigRemoveMapView = pyqtSignal(object)
sigHideMapView = pyqtSignal()
sigShowMapView = pyqtSignal()

benjamin.jakimow@geo.hu-berlin.de
committed
sigTitleChanged = pyqtSignal(str)

Benjamin Jakimow
committed
def __init__(self, recommended_bands=None, parent=None, showSensorNames=True):
super(MapViewDefinition, self).__init__()
self.ui = MapViewDefinitionUI(self, parent=parent)

benjamin.jakimow@geo.hu-berlin.de
committed
self.setVisibility(True)

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui.actionRemoveMapView.triggered.connect(lambda: self.sigRemoveMapView.emit(self))
self.ui.sigHideMapView.connect(lambda : self.sigHideMapView.emit())
self.ui.sigShowMapView.connect(lambda: self.sigShowMapView.emit())
self.sensorViews = collections.OrderedDict()
self.mShowSensorNames = showSensorNames

benjamin.jakimow@geo.hu-berlin.de
committed
def setVisibility(self, isVisible):
self.ui.setVisibility(isVisible)
def visibility(self):
return self.ui.visibility()
self.mTitle = title
self.ui.labelName.setText(title)
self.sigTitleChanged.emit(self.mTitle)

benjamin.jakimow@geo.hu-berlin.de
committed
def title(self):
def showSensorNames(self, b):
assert isinstance(b, bool)
self.mShowSensorNames = b
for s,w in self.sensorViews.items():
w.showSensorName(b)
def removeSensor(self, sensor):
assert type(sensor) is SensorInstrument
if sensor in self.sensorViews.keys():
self.sensorViews[sensor].close()
self.sensorViews.pop(sensor)
return True
else:
return False
def hasSensor(self, sensor):
assert type(sensor) is SensorInstrument
return sensor in self.sensorViews.keys()

benjamin.jakimow@geo.hu-berlin.de
committed
w = MapViewRenderSettings(sensor)

benjamin.jakimow@geo.hu-berlin.de
committed
i = l.count()
sigSensorAdded = pyqtSignal(SensorInstrument)
sigSensorRemoved = pyqtSignal(SensorInstrument)
sigMapViewAdded = pyqtSignal(MapViewDefinition)
sigMapViewRemoved = pyqtSignal(MapViewDefinition)
sigMapViewVisibility = pyqtSignal(MapViewDefinition, bool)
def __init__(self, timeSeriesViewer):
assert isinstance(timeSeriesViewer, TimeSeriesViewer)
self.ui = self.TSV.ui
self.mapViewsDefinitions = []
self.mapViewButtons = dict()
def removeSensor(self, sensor):
assert isinstance(sensor, SensorInstrument)
removed = False
removed = removed and view.removeSensor(sensor)
if removed:
self.sigSensorRemoved(sensor)
def createMapView(self):
btnList = self.TSV.ui.dockMapViews.BVButtonList

benjamin.jakimow@geo.hu-berlin.de
committed
btn = QToolButton(btnList)
btnList.layout().insertWidget(btnList.layout().count() - 1, btn)
mapView = MapViewDefinition(parent=self.TSV.ui.dockMapViews.scrollAreaMapViews, showSensorNames=False)
mapView.sigRemoveMapView.connect(self.removeMapView)
mapView.sigShowMapView.connect(lambda : self.sigMapViewVisibility.emit(mapView, mapView.visibility()))
mapView.sigHideMapView.connect(lambda: self.sigMapViewVisibility.emit(mapView, mapView.visibility()))
#mapView.sigTitleChanged.connect(btn.setText)

benjamin.jakimow@geo.hu-berlin.de
committed
#bandView.setTitle('#{}'.format(len(self)))
self.mapViewButtons[mapView] = btn
self.mapViewsDefinitions.append(mapView)
mapView.addSensor(sensor)
btn.clicked.connect(lambda : self.showMapViewDefinition(mapView))
self.refreshMapViewTitles()
self.sigMapViewAdded.emit(mapView)
if len(self) == 1:
self.showMapViewDefinition(mapView)
def removeMapView(self, mapView):
assert isinstance(mapView, MapViewDefinition)
btn = self.mapViewButtons[mapView]
btnList = self.TSV.ui.dockMapViews.BVButtonList
idx = self.mapViewsDefinitions.index(mapView)

benjamin.jakimow@geo.hu-berlin.de
committed
self.mapViewsDefinitions.remove(mapView)
self.mapViewButtons.pop(mapView)

benjamin.jakimow@geo.hu-berlin.de
committed

benjamin.jakimow@geo.hu-berlin.de
committed
btn.setVisible(False)
btnList.layout().removeWidget(btn)
l = self.ui.dockMapViews.scrollAreaMapsViewDockContent.layout()
for d in self.recentMapViewDefinitions():
d.ui.setVisible(False)
l.removeWidget(d.ui)
l.removeWidget(mapView.ui)
mapView.ui.close()

benjamin.jakimow@geo.hu-berlin.de
committed
btn.close()
self.refreshMapViewTitles()
self.sigMapViewRemoved.emit(mapView)
if len(self) > 0:
#show previous mapViewDefinition
idxNext = max([idx-1, 0])
self.showMapViewDefinition(self.mapViewsDefinitions[idxNext])
def refreshMapViewTitles(self):
for i, mapView in enumerate(self.mapViewsDefinitions):
number = i+1
title = '#{}'.format(number)
mapView.setTitle(title)
btn = self.mapViewButtons[mapView]
btn.setText('{}'.format(number))
btn.setToolTip('Show definition for map view {}'.format(number))
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
s = ""

benjamin.jakimow@geo.hu-berlin.de
committed
def showMapViewDefinition(self, mapViewDefinition):
assert mapViewDefinition in self.mapViewsDefinitions
assert isinstance(mapViewDefinition, MapViewDefinition)
l = self.ui.dockMapViews.scrollAreaMapsViewDockContent.layout()

benjamin.jakimow@geo.hu-berlin.de
committed
for d in self.recentMapViewDefinitions():
d.ui.setVisible(False)
l.removeWidget(d.ui)

benjamin.jakimow@geo.hu-berlin.de
committed
l.insertWidget(l.count() - 1, mapViewDefinition.ui)
mapViewDefinition.ui.setVisible(True)
def recentMapViewDefinitions(self):
parent = self.ui.dockMapViews.scrollAreaMapsViewDockContent
return [ui.mapViewDefinition() for ui in parent.findChildren(MapViewDefinitionUI)]
def setMapViewVisibility(self, bandView, isVisible):
assert isinstance(bandView, MapViewDefinition)

benjamin.jakimow@geo.hu-berlin.de
committed
assert isinstance(isVisible, bool)
def __contains__(self, mapView):
return mapView in self.mapViewsDefinitions

benjamin.jakimow@geo.hu-berlin.de
committed
sigExtentsChanged = pyqtSignal(SpatialExtent)
def __init__(self, TSD, parent=None):
super(TimeSeriesDatumView, self).__init__()
self.mapCanvases = dict()
self.mapOrder = []
self.L = self.ui.layout()
self.wOffset = self.L.count()-1

benjamin.jakimow@geo.hu-berlin.de
committed
def activateMapTool(self, key):

benjamin.jakimow@geo.hu-berlin.de
committed
c.activateMapTool(key)
def setMapViewVisibility(self, bandView, isVisible):
self.mapCanvases[bandView].setVisible(isVisible)

benjamin.jakimow@geo.hu-berlin.de
committed
def setSpatialExtent(self, spatialExtent):
assert isinstance(spatialExtent, SpatialExtent)

benjamin.jakimow@geo.hu-berlin.de
committed
c.setSpatialExtent(spatialExtent)
def setSubsetSize(self, size):
assert isinstance(size, QSize)
assert size.width() > 5 and size.height() > 5
self.subsetSize = size
m = self.L.contentsMargins()
self.ui.labelTitle.setFixedWidth(size.width())
self.ui.line.setFixedWidth(size.width())
#apply new subset size to existing canvases
c.setFixedSize(size)
self.ui.setFixedWidth(size.width() + 2*(m.left() + m.right()))
#todo: improve size forecast
self.ui.setMinimumHeight((n+1) * size.height())
def setTimeSeriesDatum(self, TSD):
assert isinstance(TSD, TimeSeriesDatum)
self.TSD = TSD
self.ui.labelTitle.setText(str(TSD.date))
def removeMapView(self, bandView):
self.mapOrder.remove(bandView)
canvas = self.mapCanvases.pop(bandView)

benjamin.jakimow@geo.hu-berlin.de
committed
def redraw(self):

benjamin.jakimow@geo.hu-berlin.de
committed
c.refreshAllLayers()
def insertMapView(self, bandView, i=-1):
assert isinstance(bandView, MapViewDefinition)
assert bandView not in self.mapOrder
if len(self.mapCanvases) != len(self.mapOrder):

benjamin.jakimow@geo.hu-berlin.de
committed
s = ""
assert i >= -1 and i <= len(self.mapOrder)

benjamin.jakimow@geo.hu-berlin.de
committed
canvas = MapViewMapCanvas(self.ui)
canvas.setLayer(self.TSD.pathImg)
canvas.setFixedSize(self.subsetSize)

benjamin.jakimow@geo.hu-berlin.de
committed
canvas.extentsChanged.connect(lambda : self.sigExtentsChanged.emit(canvas.spatialExtent()))
self.mapCanvases[bandView] = canvas
self.mapOrder.insert(i, bandView)
self.L.insertWidget(self.wOffset + i, canvas)
def __lt__(self, other):
return self.TSD < other.TSD
class RenderJob(object):
def __init__(self, TSD, renderer, destinationId=None):
assert isinstance(TSD, TimeSeriesDatum)
assert isinstance(renderer, QgsRasterRenderer)
self.TSD = TSD
self.renderer = renderer
self.destinationId = destinationId
def __eq__(self, other):
if not isinstance(other, RenderJob):
return False
return self.TSD == other.TSD and \
self.renderer == other.renderer and \
self.destinationId == other.destinationId

benjamin.jakimow@geo.hu-berlin.de
committed
list2str = lambda ll : '\n'.join([str(l) for l in ll])

benjamin.jakimow@geo.hu-berlin.de
committed
class QgsInstanceInteraction(QObject):

benjamin.jakimow@geo.hu-berlin.de
committed
def __init__(self, iface, TSV_UI):
super(QgsInstanceInteraction, self).__init__()

benjamin.jakimow@geo.hu-berlin.de
committed
self.iface = iface
self.ui = TSV_UI
self.cbVectorLayer = TSV_UI.cbQgsVectorLayer

benjamin.jakimow@geo.hu-berlin.de
committed
def extent(self):

benjamin.jakimow@geo.hu-berlin.de
committed
def center(self):
s = ""

benjamin.jakimow@geo.hu-berlin.de
committed
def crs(self):
s = ""

benjamin.jakimow@geo.hu-berlin.de
committed
def getVectorLayerRepresentation(self):
if self.ui.gbQgsVectorLayer.isChecked():
lyr = self.cbVectorLayer.currentLayer()
alpha = self.ui.sliderQgsVectorTransparency.value()
return lyr
else:
return None
def __init__(self, iface):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
# Save reference to the QGIS interface
from timeseriesviewer.ui.widgets import TimeSeriesViewerUI

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui = TimeSeriesViewerUI()
if iface:
import timeseriesviewer
timeseriesviewer.QGIS_TSV_BRIDGE = QgsInstanceInteraction(iface, self.ui)
self.ui.setQgsLinkWidgets()
#init empty time series
self.TS = TimeSeries()
self.hasInitialCenterPoint = False

benjamin.jakimow@geo.hu-berlin.de
committed
self.TS.sigTimeSeriesDatesAdded.connect(self.datesAdded)
#init TS model
TSM = TimeSeriesTableModel(self.TS)
D = self.ui
#self.ICP = D.scrollAreaSubsetContent.layout()
#D.scrollAreaMapViews.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
#self.BVP = self.ui.scrollAreaMapViews.layout()
D.tableView_TimeSeries.setModel(TSM)
D.tableView_TimeSeries.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.mapViewManager = MapViewManager(self)
self.timeSeriesDateViewManager = TimeSeriesDateViewManager(self)
self.ValidatorPxX = QIntValidator(0,99999)
self.ValidatorPxY = QIntValidator(0,99999)
#connect actions with logic
#D.btn_showPxCoordinate.clicked.connect(lambda: self.showSubsetsStart())

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionSelectCenter.triggered.connect(lambda : self.timeSeriesDateViewManager.activateMapTool('selectCenter'))
D.actionSelectArea.triggered.connect(lambda : self.timeSeriesDateViewManager.activateMapTool('selectArea'))

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionZoomMaxExtent.triggered.connect(lambda : self.zoomTo('maxExtent'))
D.actionZoomPixelScale.triggered.connect(lambda: self.zoomTo('pixelScale'))
D.actionZoomIn.triggered.connect(lambda: self.timeSeriesDateViewManager.activateMapTool('zoomIn'))
D.actionZoomOut.triggered.connect(lambda: self.timeSeriesDateViewManager.activateMapTool('zoomOut'))
D.actionPan.triggered.connect(lambda: self.timeSeriesDateViewManager.activateMapTool('pan'))
D.actionAddMapView.triggered.connect(self.mapViewManager.createMapView)
D.actionAddTSD.triggered.connect(self.ua_addTSImages)
D.actionRemoveTSD.triggered.connect(self.removeTimeSeriesDates)
D.actionRedraw.triggered.connect(self.timeSeriesDateViewManager.redraw)

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionLoadTS.triggered.connect(self.loadTimeSeries)
D.actionClearTS.triggered.connect(self.clearTimeSeries)
D.actionSaveTS.triggered.connect(self.ua_saveTSFile)
D.actionAddTSExample.triggered.connect(self.ua_loadExampleTS)

benjamin.jakimow@geo.hu-berlin.de
committed
#connect buttons with actions
D.btnClearLabelList.clicked.connect(D.tbCollectedLabels.clear)

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionAbout.triggered.connect(lambda: AboutDialogUI(self.ui).exec_())
D.actionSettings.triggered.connect(lambda : PropertyDialogUI(self.ui).exec_())
D.actionFirstTSD.triggered.connect(lambda: self.setDOISliderValue('first'))
D.actionLastTSD.triggered.connect(lambda: self.setDOISliderValue('last'))
D.actionNextTSD.triggered.connect(lambda: self.setDOISliderValue('next'))
D.actionPreviousTSD.triggered.connect(lambda: self.setDOISliderValue('previous'))
D.sliderDOI.valueChanged.connect(self.setDOI)
D.actionSetSubsetSize.triggered.connect(lambda : self.timeSeriesDateViewManager.setSubsetSize(
D.actionSetExtent.triggered.connect(lambda: self.timeSeriesDateViewManager.setSpatialExtent(self.ui.spatialExtent()))
self.canvasCrs = QgsCoordinateReferenceSystem()

benjamin.jakimow@geo.hu-berlin.de
committed
def zoomTo(self, key):
if key == 'maxExtent':
ext = self.TS.getMaxSpatialExtent(self.ui.crs())
self.timeSeriesDateViewManager.setSpatialExtent(ext)

benjamin.jakimow@geo.hu-berlin.de
committed
elif key == 'pixelScale':
s = ""
def setDOISliderValue(self, key):
ui = self.ui
v = ui.sliderDOI.value()
if key == 'first':
v = ui.sliderDOI.minimum()
elif key == 'last':
v = ui.sliderDOI.maximum()
elif key =='next':
v = min([v+1,ui.sliderDOI.maximum()])
elif key =='previous':
v = max([v - 1, ui.sliderDOI.minimum()])
ui.sliderDOI.setValue(v)
def setDOI(self, i):

benjamin.jakimow@geo.hu-berlin.de
committed
assert i <= len(self.TS)
self.timeSeriesDateViewManager.navToDOI(TSD)
def icon(self):
return TimeSeriesViewer.icon()
D = self.ui

benjamin.jakimow@geo.hu-berlin.de
committed
l = len(self.TS.data)
D.sliderDOI.setMaximum(l)
#get meaningfull tick intervall
for tickInterval in [1,5,10,25,50,100,200]:
if (D.sliderDOI.size().width() / float(l) * tickInterval) > 5:
break
D.sliderDOI.setTickInterval(tickInterval)
if not self.hasInitialCenterPoint:
if len(self.TS.data) > 0:
extent = self.TS.getMaxSpatialExtent(self.canvasCrs)
self.timeSeriesDateViewManager.setSubsetSize(self.ui.subsetSize())
self.timeSeriesDateViewManager.setSpatialExtent(extent)

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui.setSpatialExtent(extent)
self.hasInitialCenterPoint = True
self.mapViewManager.createMapView()
self.mapViewManager.createMapView()

benjamin.jakimow@geo.hu-berlin.de
committed
if len(self.TS.data) == 0:
self.hasInitialCenterPoint = False

benjamin.jakimow@geo.hu-berlin.de
committed
def loadTimeSeries(self, path=None, n_max=None):
if path is None or path is False:
path = QFileDialog.getOpenFileName(self.ui, 'Open Time Series file', '')
if os.path.exists(path):
M = self.ui.tableView_TimeSeries.model()
def ua_saveTSFile(self):
path = QFileDialog.getSaveFileName(self.ui, caption='Save Time Series file')
if path is not None:
self.TS.saveToFile(path)
def ua_loadExampleTS(self):
from timeseriesviewer import PATH_EXAMPLE_TIMESERIES
if not os.path.exists(PATH_EXAMPLE_TIMESERIES):
QMessageBox.information(self.ui, 'File not found', '{} - this file describes an exemplary time series.'.format(path_example))

benjamin.jakimow@geo.hu-berlin.de
committed
self.loadTimeSeries(path=PATH_EXAMPLE_TIMESERIES)