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 TimeSeriesDatumViewManager(QObject):
def __init__(self, timeSeriesViewer):
assert isinstance(timeSeriesViewer, TimeSeriesViewer)
super(TimeSeriesDatumViewManager, self).__init__()
self.TSV = timeSeriesViewer
self.TSDViews = list()

benjamin.jakimow@geo.hu-berlin.de
committed
self.bandViewMananger = self.TSV.bandViewManager
self.bandViewMananger.sigBandViewAdded.connect(self.addBandView)
self.bandViewMananger.sigBandViewRemoved.connect(self.removeBandView)
self.bandViewMananger.sigBandViewVisibility.connect(self.setBandViewVisibility)

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 setBandViewVisibility(self, bandView, isVisible):
assert isinstance(bandView, BandView)
assert isinstance(isVisible, bool)
for tsdv in self.TSDViews:

benjamin.jakimow@geo.hu-berlin.de
committed
tsdv.setBandViewVisibility(bandView, isVisible)
def addBandView(self, bandView):
assert isinstance(bandView, BandView)
w = self.L.parentWidget()
w.setUpdatesEnabled(False)
for tsdv in self.TSDViews:
tsdv.ui.setUpdatesEnabled(False)
for tsdv in self.TSDViews:
tsdv.insertBandView(bandView)
for tsdv in self.TSDViews:
tsdv.ui.setUpdatesEnabled(True)
w.setUpdatesEnabled(True)
def removeBandView(self, bandView):
assert isinstance(bandView, BandView)
for tsdv in self.TSDViews:
tsdv.removeBandView(bandView)

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.bandViewMananger):
tsdView.insertBandView(bandView)
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
class BandView(QObject):

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

benjamin.jakimow@geo.hu-berlin.de
committed
#sigBandViewVisibility = pyqtSignal(bool)
sigHideBandView = pyqtSignal()
sigShowBandView = pyqtSignal()
sigTitleChanged = pyqtSignal(str)

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

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui = MapViewUI(parent)

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

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui.actionRemoveBandView.triggered.connect(lambda: self.sigRemoveBandView.emit(self))

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui.sigHideBandView.connect(lambda : self.sigHideBandView.emit())
self.ui.sigShowBandView.connect(lambda: self.sigShowBandView.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()
def setTitle(self, title):
self.ui.labelViewName.setText(title)

benjamin.jakimow@geo.hu-berlin.de
committed
self.sigTitleChanged.emit(self.ui.labelViewName.text())
def title(self):
return self.ui.labelViewName.text()
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)
w.showSensorName(False)

benjamin.jakimow@geo.hu-berlin.de
committed
l = self.ui.layout()
i = l.count()
l.insertWidget(i, w.ui)
class BandViewManager(QObject):
sigSensorAdded = pyqtSignal(SensorInstrument)
sigSensorRemoved = pyqtSignal(SensorInstrument)
sigBandViewAdded = pyqtSignal(BandView)
sigBandViewRemoved = pyqtSignal(BandView)
def __init__(self, timeSeriesViewer):
assert isinstance(timeSeriesViewer, TimeSeriesViewer)
super(BandViewManager, self).__init__()
self.TSV = timeSeriesViewer
self.bandViews = []

benjamin.jakimow@geo.hu-berlin.de
committed
self.bandViewButtons = dict()
self.recentBandViewDefinition = None
def removeSensor(self, sensor):
assert isinstance(sensor, SensorInstrument)
removed = False
for view in self.bandViews:
removed = removed and view.removeSensor(sensor)
if removed:
self.sigSensorRemoved(sensor)
def createBandView(self):

benjamin.jakimow@geo.hu-berlin.de
committed
btnList = self.TSV.ui.BVButtonList
btn = QToolButton(btnList)
btnList.layout().insertWidget(btnList.layout().count() - 1, btn)
bandView = BandView(parent=self.TSV.ui.scrollAreaBandViewsContent, showSensorNames=False)
bandView.sigRemoveBandView.connect(self.removeBandView)

benjamin.jakimow@geo.hu-berlin.de
committed
bandView.sigShowBandView.connect(lambda : self.sigBandViewVisibility.emit(bandView, bandView.visibility()))
bandView.sigHideBandView.connect(lambda: self.sigBandViewVisibility.emit(bandView, bandView.visibility()))
bandView.sigTitleChanged.connect(btn.setText)

benjamin.jakimow@geo.hu-berlin.de
committed
#bandView.setTitle('#{}'.format(len(self)))

benjamin.jakimow@geo.hu-berlin.de
committed
self.bandViewButtons[bandView] = btn
self.bandViews.append(bandView)
for sensor in self.TSV.TS.Sensors:
bandView.addSensor(sensor)

benjamin.jakimow@geo.hu-berlin.de
committed
btn.clicked.connect(lambda : self.showBandViewDefinition(bandView))
self.refreshBandViewTitles()
self.sigBandViewAdded.emit(bandView)
def removeBandView(self, bandView):
assert isinstance(bandView, BandView)

benjamin.jakimow@geo.hu-berlin.de
committed
btn = self.bandViewButtons[bandView]
btnList = self.TSV.ui.BVButtonList

benjamin.jakimow@geo.hu-berlin.de
committed
self.bandViewButtons.pop(bandView)
bandView.ui.setVisible(False)
btn.setVisible(False)
btnList.layout().removeWidget(btn)
self.TSV.BVP.removeWidget(bandView.ui)
bandView.ui.close()

benjamin.jakimow@geo.hu-berlin.de
committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
btn.close()
self.refreshBandViewTitles()
self.sigBandViewRemoved.emit(bandView)
def refreshBandViewTitles(self):
for i, bandView in enumerate(self.bandViews):
bandView.setTitle('#{}'.format(i + 1))
def showBandViewDefinition(self, bandView):
assert bandView in self.bandViews
if self.recentBandViewDefinition == bandView:
return
l = self.TSV.BVP
assert l.rowCount() == 2
assert l.columnCount() == 2
toRemove = l.itemAtPosition(0,0)
if toRemove:
oldBandViewUI = toRemove.widget()
oldBandViewUI.setVisible(False)
l.removeWidget(oldBandViewUI)
l.addWidget(bandView.ui, 0,0)
bandView.ui.setVisible(True)
self.recentBandViewDefinition = bandView
print(('show ', l.itemAtPosition(0,0).widget().labelViewName.text()))
def setBandViewVisibility(self, bandView, isVisible):
assert isinstance(bandView, BandView)
assert isinstance(isVisible, bool)
def __len__(self):
return len(self.bandViews)
def __iter__(self):
return iter(self.bandViews)
def __getitem__(self, key):
return self.bandViews[key]
def __contains__(self, bandView):
return bandView in self.bandViews
class TimeSeriesDatumView(QObject):

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

benjamin.jakimow@geo.hu-berlin.de
committed
def activateMapTool(self, key):
for c in self.bandViewCanvases.values():
c.activateMapTool(key)
def setBandViewVisibility(self, bandView, isVisible):
self.bandViewCanvases[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()))
n = len(self.bandViewCanvases)
#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))
c.setLayer(self.TSD.pathImg)
def removeBandView(self, bandView):

benjamin.jakimow@geo.hu-berlin.de
committed
canvas = self.bandViewCanvases.pop(bandView)

benjamin.jakimow@geo.hu-berlin.de
committed
def redraw(self):
for c in self.bandViewCanvases.values():
c.refreshAllLayers()
def insertBandView(self, bandView, i=-1):
assert isinstance(bandView, BandView)

benjamin.jakimow@geo.hu-berlin.de
committed
if len(self.bandViewCanvases) != len(self.bandViewOrder):
s = ""

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.bandViewCanvases[bandView] = canvas
self.bandViewOrder.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.scrollAreaBandViewsContent.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
self.BVP = self.ui.scrollAreaBandViewsContent.layout()
D.tableView_TimeSeries.setModel(TSM)
D.tableView_TimeSeries.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.bandViewManager = BandViewManager(self)
self.timeSeriesViewManager = TimeSeriesDatumViewManager(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.timeSeriesViewManager.activateMapTool('selectCenter'))
D.actionSelectArea.triggered.connect(lambda : self.timeSeriesViewManager.activateMapTool('selectArea'))
D.actionZoomMaxExtent.triggered.connect(lambda : self.zoomTo('maxExtent'))
D.actionZoomPixelScale.triggered.connect(lambda: self.zoomTo('pixelScale'))
D.actionZoomIn.triggered.connect(lambda: self.timeSeriesViewManager.activateMapTool('zoomIn'))
D.actionZoomOut.triggered.connect(lambda: self.timeSeriesViewManager.activateMapTool('zoomOut'))
D.actionPan.triggered.connect(lambda: self.timeSeriesViewManager.activateMapTool('pan'))
D.actionAddBandView.triggered.connect(self.bandViewManager.createBandView)
D.actionAddTSD.triggered.connect(self.ua_addTSImages)
D.actionRemoveTSD.triggered.connect(self.removeTimeSeriesDates)

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionRedraw.triggered.connect(self.timeSeriesViewManager.redraw)
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.timeSeriesViewManager.setSubsetSize(
self.ui.subsetSize()))

benjamin.jakimow@geo.hu-berlin.de
committed
D.actionSetExtent.triggered.connect(lambda: self.timeSeriesViewManager.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.timeSeriesViewManager.setSpatialExtent(ext)
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)
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.timeSeriesViewManager.setSubsetSize(self.ui.subsetSize())
self.timeSeriesViewManager.setSpatialExtent(extent)
self.ui.setSpatialExtent(extent)
self.hasInitialCenterPoint = True
if len(self.bandViewManager) == 0:
# add two empty band-views by default

benjamin.jakimow@geo.hu-berlin.de
committed
self.bandViewManager.createBandView()
self.bandViewManager.createBandView()
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)

benjamin.jakimow@geo.hu-berlin.de
committed
self.qgsCanvas.setMapTool(self.RectangleMapTool)

benjamin.jakimow@geo.hu-berlin.de
committed
self.qgsCanvas.setMapTool(self.PointMapTool)

benjamin.jakimow@geo.hu-berlin.de
committed
def setSpatialSubset(self, spatialExtent):
#keep specified CRS but translate extent
oldExtent = self.ui.spatialExtent()

benjamin.jakimow@geo.hu-berlin.de
committed
self.timeSeriesViewManager.setSpatialExtent(extent)

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