Newer
Older
class DateTimeViewBox(pg.ViewBox):
"""
Subclass of ViewBox
"""
sigMoveToDate = pyqtSignal(np.datetime64)
def __init__(self, parent=None):
"""
Constructor of the CustomViewBox
"""
super(DateTimeViewBox, self).__init__(parent)
#self.menu = None # Override pyqtgraph ViewBoxMenu
#self.menu = self.getMenu() # Create the menu
#self.menu = None
def raiseContextMenu(self, ev):
pt = self.mapDeviceToView(ev.pos())
print(pt.x(), pt.y())
date = num2date(pt.x())
menu = QMenu(None)
a = menu.addAction('Move to {}'.format(date))
a.setData(date)
a.triggered.connect(lambda : self.sigMoveToDate.emit(date))
self.scene().addParentContextMenus(self, menu, ev)
menu.exec_(ev.screenPos().toPoint())
class DateTimePlotWidget(pg.PlotWidget):
"""
Subclass of PlotWidget
"""
def __init__(self, parent=None):
"""
Constructor of the widget
"""
super(DateTimePlotWidget, self).__init__(parent, viewBox=DateTimeViewBox())
axisItems={'bottom':DateTimeAxis(orientation='bottom')},
self.setCentralItem(self.plotItem)
self.xAxisInitialized = False
class PlotSettingsModel(QAbstractTableModel):
#sigSensorAdded = pyqtSignal(SensorPlotSettings)
sigVisibilityChanged = pyqtSignal(TemporalProfilePlotStyle)
sigDataChanged = pyqtSignal(TemporalProfilePlotStyle)
regBandKey = re.compile("(?<!\w)b\d+(?!\w)", re.IGNORECASE)
regBandKeyExact = re.compile('^' + regBandKey.pattern + '$', re.IGNORECASE)
def __init__(self, temporalProfileCollection, plotWidget, parent=None, *args):
#assert isinstance(tableView, QTableView)
super(PlotSettingsModel, self).__init__(parent=parent)
assert isinstance(temporalProfileCollection, TemporalProfileCollection)
self.cnID = 'ID'
self.cnSensor = 'sensor'
self.cnExpression = LABEL_DN
self.cnStyle = 'style'
self.cnTemporalProfile = 'px'
self.columNames = [self.cnTemporalProfile, self.cnSensor, self.cnStyle, self.cnExpression]
self.mPlotSettings = []
self.mPlotDataItems = []
#assert isinstance(plotWidget, DateTimePlotWidget)
self.mPlotWidget = plotWidget
self.sortColumnIndex = 0
self.sortOrder = Qt.AscendingOrder
assert isinstance(self.tpCollection.TS, TimeSeries)
#self.tpCollection.TS.sigSensorAdded.connect(self.addPlotItem)
#self.tpCollection.TS.sigSensorRemoved.connect(self.removeSensor)
self.sort(0, Qt.AscendingOrder)
self.dataChanged.connect(self.signaler)
def __iter__(self):
return iter(self.mPlotSettings)

benjamin.jakimow@geo.hu-berlin.de
committed
def __getitem__(self, slice):
return self.mPlotSettings[slice]
def __contains__(self, item):
return item in self.mPlotSettings
def testSlot(self, *args):
print(('TESTSLOT', args))
def columnIndex(self, name):
return self.columNames.index(name)
def signaler(self, idxUL, idxLR):
if idxUL.isValid():
plotStyle = self.idx2plotStyle(idxUL)
cname = self.columNames[idxUL.column()]
if cname in [self.cnSensor,self.cnStyle]:
self.sigVisibilityChanged.emit(plotStyle)
if cname in [self.cnExpression]:
self.sigDataChanged.emit(plotStyle)
def requiredBandsIndices(self, sensor):
"""
Returns the band indices required to calculate the values for
the different PlotStyle expressions making use of sensor
:param sensor: SensorInstrument for which the band indices are to be returned.
:return: [list-of-band-indices]
"""
bandIndices = set()
assert isinstance(sensor, SensorInstrument)
for p in [p for p in self.mPlotSettings if p.sensor() == sensor]:
assert isinstance(p, TemporalProfilePlotStyle)
expression = p.expression()
#remove leading & tailing "
bandKeys = PlotSettingsModel.regBandKey.findall(expression)
for bandIndex in [bandKey2bandIndex(key) for key in bandKeys]:

benjamin.jakimow@geo.hu-berlin.de
committed
def insertPlotStyles(self, plotStyles, i=None):
"""
Inserts PlotStyle
:param plotStyles: TemporalProfilePlotStyle | [list-of-TemporalProfilePlotStyle]
:param i: index to insert, defaults to the last list position
"""
if isinstance(plotStyles, TemporalProfilePlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
for plotStyle in plotStyles:
assert isinstance(plotStyle, TemporalProfilePlotStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
self.beginInsertRows(QModelIndex(), i, i + len(plotStyles)-1)
for j, plotStyle in enumerate(plotStyles):
assert isinstance(plotStyle, TemporalProfilePlotStyle)
self.mPlotSettings.insert(i+j, plotStyle)
self.endInsertRows()
def removePlotStyles(self, plotStyles):
"""
Removes PlotStyle instances
:param plotStyles: TemporalProfilePlotStyle | [list-of-TemporalProfilePlotStyle]
"""
if isinstance(plotStyles, PlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
for plotStyle in plotStyles:
assert isinstance(plotStyle, PlotStyle)
if plotStyle in self.mPlotSettings:
idx = self.plotStyle2idx(plotStyle)
self.beginRemoveRows(QModelIndex(), idx.row(),idx.row())
self.mPlotSettings.remove(plotStyle)
self.endRemoveRows()
def sort(self, col, order):
if self.rowCount() == 0:
return
colName = self.columnames[col]
r = order != Qt.AscendingOrder
#self.beginMoveRows(idxSrc,
if colName == self.cnSensor:
self.mPlotSettings.sort(key = lambda sv:sv.sensor().name(), reverse=r)
elif colName == self.cnExpression:
self.mPlotSettings.sort(key=lambda sv: sv.expression(), reverse=r)
elif colName == self.cnStyle:
self.mPlotSettings.sort(key=lambda sv: sv.color, reverse=r)
def rowCount(self, parent = QModelIndex()):
return len(self.mPlotSettings)
def removeRows(self, row, count , parent = QModelIndex()):
for tsd in toRemove:
self.endRemoveRows()
if plotStyle in self.mPlotSettings:
i = self.mPlotSettings.index(plotStyle)
return self.createIndex(i, 0)
else:
return QModelIndex()
def idx2plotStyle(self, index):
if index.isValid() and index.row() < self.rowCount():
return self.mPlotSettings[index.row()]
return None
def columnCount(self, parent = QModelIndex()):
def data(self, index, role = Qt.DisplayRole):
if role is None or not index.isValid():
return None
value = None
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
columnName = self.columNames[index.column()]
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfilePlotStyle):
sensor = plotStyle.sensor()
#print(('data', columnName, role))
if role == Qt.DisplayRole:
if columnName == self.cnSensor:
if isinstance(sensor, SensorInstrument):
value = sensor.name()
else:
value = '<Select Sensor>'
elif columnName == self.cnExpression:
value = plotStyle.expression()
elif columnName == self.cnTemporalProfile:
value = plotStyle.temporalProfile().name()
#elif role == Qt.DecorationRole:
# if columnName == self.cnStyle:
# value = plotStyle.createIcon(QSize(96,96))
elif role == Qt.CheckStateRole:
if columnName == self.cnTemporalProfile:
value = Qt.Checked if plotStyle.isVisible() else Qt.Unchecked
elif role == Qt.UserRole:
value = plotStyle
if columnName == self.cnSensor:
value = plotStyle.sensor()
elif columnName == self.cnExpression:
value = plotStyle.expression()
elif columnName == self.cnStyle:
value = plotStyle
elif columnName == self.cnTemporalProfile:
value == plotStyle.temporalProfile()
else:
value = plotStyle
#print(('get data',value))
return value
def setData(self, index, value, role=None):
if role is None or not index.isValid():
return False
#print(('Set data', index.row(), index.column(), value, role))

benjamin.jakimow@geo.hu-berlin.de
committed
if value is None:
return False
result = False
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfilePlotStyle):
if role in [Qt.DisplayRole]:
if columnName == self.cnExpression:
plotStyle.setExpression(value)
result = True
elif columnName == self.cnStyle:
if isinstance(value, PlotStyle):
result = True
if role == Qt.CheckStateRole:
if columnName == self.cnTemporalProfile:
plotStyle.setVisibility(value == Qt.Checked)
result = True
if role == Qt.EditRole:
if columnName == self.cnExpression:
plotStyle.setExpression(value)
result = True
elif columnName == self.cnStyle:
plotStyle.copyFrom(value)
result = True
elif columnName == self.cnSensor:
plotStyle.setSensor(value)
result = True
elif columnName == self.cnTemporalProfile:
plotStyle.setTemporalProfile(value)
result = True
if result:
#save plot-style
self.dataChanged.emit(index, index)
return result
def savePlotSettings(self, sensorPlotSettings, index='DEFAULT'):
return
#todo
assert isinstance(sensorPlotSettings, TemporalProfilePlotStyle)
#todo: avoid dumps
id = 'SPS.{}.{}'.format(index, sensorPlotSettings.sensor().id())
d = pickle.dumps(sensorPlotSettings)
SETTINGS.setValue(id, d)
def restorePlotSettings(self, sensor, index='DEFAULT'):
assert isinstance(sensor, SensorInstrument)
id = 'SPS.{}.{}'.format(index, sensor.id())
sensorPlotSettings = SETTINGS.value(id)
if sensorPlotSettings is not None:
try:
sensorPlotSettings = pickle.loads(sensorPlotSettings)
s = ""
except:
sensorPlotSettings = None
pass
if isinstance(sensorPlotSettings, TemporalProfilePlotStyle):
return sensorPlotSettings
else:
def flags(self, index):
if index.isValid():
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
flags = flags | Qt.ItemIsUserCheckable
if columnName in [self.cnTemporalProfile, self.cnSensor, self.cnExpression, self.cnStyle]: #allow check state
flags = flags | Qt.ItemIsEditable
return flags
#return item.qt_flags(index.column())
return Qt.NoItemFlags
def headerData(self, col, orientation, role):
if Qt is None:
return None
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
return col
return None
class ProfileViewDockUI(QgsDockWidget, loadUI('profileviewdock.ui')):
def __init__(self, parent=None):
super(ProfileViewDockUI, self).__init__(parent)
self.setupUi(self)
#self.line.setVisible(False)
#self.listWidget.setVisible(False)
self.stackedWidget.setCurrentWidget(self.page2D)
if OPENGL_AVAILABLE:
l = self.labelDummy3D.parentWidget().layout()
l.removeWidget(self.labelDummy3D)
from pyqtgraph.opengl import GLViewWidget
l.addWidget(self.plotWidget3D)
#pi = self.plotWidget2D.plotItem
#ax = DateAxis(orientation='bottom', showValues=True)
#pi.layout.addItem(ax, 3,2)
self.baseTitle = self.windowTitle()
self.TS = None
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(100)
self.progressBar.setValue(0)
self.progressInfo.setText('')
self.pxViewModel2D = None
self.pxViewModel3D = None
self.tableView2DProfiles.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.tableView2DProfiles.setSortingEnabled(True)
self.tableViewTemporalProfiles.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.tableViewTemporalProfiles.setSortingEnabled(True)
def dateDOY(date):
if isinstance(date, np.datetime64):
date = date.astype(datetime.date)
return date.timetuple().tm_yday
def daysPerYear(year):
if isinstance(year, np.datetime64):
year = year.astype(datetime.date)
if isinstance(year, datetime.date):
year = year.timetuple().tm_year
return dateDOY(datetime.date(year=year, month=12, day=31))
def date2num(d):
#kindly taken from https://stackoverflow.com/questions/6451655/python-how-to-convert-datetime-dates-to-decimal-years
if isinstance(d, np.datetime64):
d = d.astype(datetime.datetime)
assert isinstance(d, datetime.date)
yearDuration = daysPerYear(d)
yearElapsed = d.timetuple().tm_yday
fraction = float(yearElapsed) / float(yearDuration)
if fraction == 1.0:
fraction = 0.9999999
return float(d.year) + fraction
def num2date(n, dt64=True):
n = float(n)
if n < 1:
n += 1
year = int(n)
fraction = n - year
yearDuration = daysPerYear(year)
yearElapsed = fraction * yearDuration
import math
doy = round(yearElapsed)
if doy < 1:
doy = 1
try:
date = datetime.date(year, 1, 1) + datetime.timedelta(days=doy-1)
except:
s = ""
if dt64:
return np.datetime64(date)
else:
return date
#return np.datetime64('{:04}-01-01'.format(year), 'D') + np.timedelta64(int(yearElapsed), 'D')
def depr_date2num(d):
d2 = d.astype(datetime.datetime)
o = d2.toordinal()
#assert d == num2date(o)
return o
if n < 1:
n = 1
return np.datetime64('{:04}-{:02}-{:02}'.format(d.year,d.month,d.day), 'D')
class TemporalProfile(QObject):
_mNextID = 0
@staticmethod
def nextID():
n = TemporalProfile._mNextID
TemporalProfile._mNextID += 1
return n
def __init__(self, timeSeries, spatialPoint):
super(TemporalProfile, self).__init__()
assert isinstance(spatialPoint, SpatialPoint)
self.mUpdated = False
self.mName = '#{}'.format(self.mID)
self.mLoaded = self.mLoadedMax = 0
self.initMetadata()
self.updateLoadingStatus()
def initMetadata(self):
for tsd in self.mTimeSeries:
assert isinstance(tsd, TimeSeriesDatum)
meta = {'doy':tsd.doy,
'date':str(tsd.date)}
sigNameChanged = pyqtSignal(str)
def setName(self, name):
if name != self.mName:
self.mName = name
self.sigNameChanged.emit(self.mName)
def name(self):
return self.mName
def plot(self):
import pyqtgraph as pg
for sensor in self.mTimeSeries.sensors():
assert isinstance(sensor, SensorInstrument)
plotStyle = TemporalProfilePlotStyle(self)
plotStyle.setSensor(sensor)
pi = TemporalProfilePlotDataItem(plotStyle)
pi.setClickable(True)
pw = pg.plot(title=self.name())
pw.getPlotItem().addItem(pi)
pi.setColor('green')
pg.QAPP.exec_()
assert isinstance(tsd, TimeSeriesDatum)
assert isinstance(values, dict)
if tsd not in self.mData.keys():
self.mData[tsd] = {}
self.mData[tsd].update(values)
self.updateLoadingStatus()
self.mUpdated = True
def resetUpdated(self):
self.mUpdated = False
def updated(self):
return self.mUpdated
def qgsFieldFromKeyValue(self, key, value):
t = type(value)
if t in [int, float] or np.isreal(value):
fLen = 0
fPrec = 0
fComm = ''
fType = ''
f = QgsField(key, QVariant.Double, 'double', 40, 5)
else:
f = QgsField(key, QVariant.String, 'text', 40, 5)
return f
def dataFromExpression(self, sensor, expression, dateType='date'):
assert dateType in ['date','doy']
x = []
y = []
if not isinstance(expression, QgsExpression):
expression = QgsExpression(expression)
assert isinstance(expression, QgsExpression)
expression = QgsExpression(expression)
fields = QgsFields()
sensorTSDs = sorted([tsd for tsd in self.mData.keys() if tsd.sensor == sensor])
for tsd in sensorTSDs:
data = self.mData[tsd]
for k, v in data.items():
if v is not None and fields.fieldNameIndex(k) == -1:
fields.append(self.qgsFieldFromKeyValue(k, v))
for i, tsd in enumerate(sensorTSDs):
assert isinstance(tsd, TimeSeriesDatum)
data = self.mData[tsd]
context = QgsExpressionContext()
scope = QgsExpressionContextScope()
f = QgsFeature()
f.setFields(fields)
f.setValid(True)
if v is None:
continue
idx = f.fieldNameIndex(k)
field = f.fields().field(idx)
if field.typeName() == 'text':
v = str(v)
else:
v = float(v)
scope.setFeature(f)
context.appendScope(scope)
#value = expression.evaluatePrepared(f)
value = expression.evaluate(context)
if value in [None, NULL]:
s = ""
else:
if dateType == 'date':
x.append(date2num(tsd.date))
elif dateType == 'doy':
x.append(tsd.doy)
y.append(value)
#return np.asarray(x), np.asarray(y)
return x, y
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
def data(self, tsd):
assert isinstance(tsd, TimeSeriesDatum)
if self.hasData(tsd):
return self.mData[tsd]
else:
return {}
def loadingStatus(self):
"""
Returns the loading status in terms of single pixel values.
nLoaded = sum of single band values
nLoadedMax = potential maximum of band values that might be loaded
:return: (nLoaded, nLoadedMax)
"""
return self.mLoaded, self.mLoadedMax
def updateLoadingStatus(self):
"""
Calculates and the loading status in terms of single pixel values.
nMax is the sum of all bands over each TimeSeriesDatum and Sensors
"""
self.mLoaded = self.mLoadedMax
for tsd in self.mTimeSeries:
assert isinstance(tsd, TimeSeriesDatum)
self.mLoadedMax += tsd.sensor.nb
if self.hasData(tsd):
self.mLoaded += len([k for k in self.mData[tsd].keys() if k.startswith('b')])
def hasData(self,tsd):
assert isinstance(tsd, TimeSeriesDatum)
return tsd in self.mData.keys()
def __repr__(self):
return 'TemporalProfile {}'.format(self.mCoordinate)
class SpectralTemporalVisualization(QObject):
sigShowPixel = pyqtSignal(TimeSeriesDatum, QgsPoint, QgsCoordinateReferenceSystem)
"""
Signalizes to move to specific date of interest
"""
sigMoveToDate = pyqtSignal(np.datetime64)
def __init__(self, ui):
super(SpectralTemporalVisualization, self).__init__()
assert isinstance(ui, ProfileViewDockUI), 'arg ui of type: {} {}'.format(type(ui), str(ui))
self.ui = ui
if DEBUG:
import timeseriesviewer.pixelloader
timeseriesviewer.pixelloader.DEBUG = True
self.pixelLoader = PixelLoader()
self.pixelLoader.sigPixelLoaded.connect(self.onPixelLoaded)
self.pixelLoader.sigLoadingStarted.connect(lambda: self.ui.progressInfo.setText('Start loading...'))
self.plot_initialized = False
self.TV.setSortingEnabled(False)
self.plot2D = ui.plotWidget2D
self.plot2D.getPlotItem().getViewBox().sigMoveToDate.connect(self.sigMoveToDate)
self.plot2D.getPlotItem().getAxis('bottom').setLabel(LABEL_TIME)
self.plot2D.getPlotItem().getAxis('left').setLabel(LABEL_DN)
self.plot3D = ui.plotWidget3D
self.plot3D.setCameraPosition(distance=50)
## Add a grid to the view
if OPENGL_AVAILABLE:
import pyqtgraph.opengl as gl
self.glGridItem = gl.GLGridItem()
self.glGridItem.scale(2, 2, 1)
self.glGridItem.setDepthValue(10) # draw grid after surfaces since they may be translucent
self.glPlotDataItem = []
self.plot3D.addItem(self.glGridItem)
self.tpCollection = TemporalProfileCollection()
self.tpCollectionListModel = TemporalProfileCollectionListModel(self.tpCollection)
self.ui.tableViewTemporalProfiles.setModel(self.tpCollection)
self.ui.cbTemporalProfile3D.setModel(self.tpCollectionListModel)
#self.pxCollection.sigPixelAdded.connect(self.requestUpdate)
#self.pxCollection.sigPixelRemoved.connect(self.clear)
self.plotSettingsModel = None
self.pixelLoader.sigLoadingStarted.connect(self.clear)
self.pixelLoader.sigLoadingFinished.connect(lambda : self.plot2D.enableAutoRange('x', False))
# self.VIEW.setItemDelegateForColumn(3, PointStyleDelegate(self.VIEW))
self.plotData2D = dict()
self.plotData3D = dict()
self.updateRequested = True
self.updateTimer = QTimer(self)
self.updateTimer.timeout.connect(self.onDataUpdate)
self.sigMoveToDate.connect(self.onMoveToDate)
self.initActions()
def createNewPlotStyle(self):
l = len(self.tpCollection)
if l > 0:
temporalProfile = self.tpCollection[0]
plotStyle = TemporalProfilePlotStyle(temporalProfile)
plotStyle.sigExpressionUpdated.connect(self.updatePlot2D)
sensors = self.TS.Sensors.keys()
if len(sensors) > 0:
plotStyle.setSensor(sensors[0])
self.plotSettingsModel.insertPlotStyles([plotStyle])
pdi = plotStyle.createPlotItem(self.plot2D)
assert isinstance(pdi, TemporalProfilePlotDataItem)
self.plot2D.getPlotItem().addItem(pdi)
#self.plot2D.getPlotItem().addItem(pg.PlotDataItem(x=[1, 2, 3], y=[1, 2, 3]))
#plotItem.plot().sigPlotChanged.emit(plotItem)
self.updatePlot2D()
def initActions(self):
self.ui.btnAddView.setDefaultAction(self.ui.actionAddView)
self.ui.btnRemoveView.setDefaultAction(self.ui.actionRemoveView)
self.ui.btnRefresh2D.setDefaultAction(self.ui.actionRefresh2D)
self.ui.btnRefresh3D.setDefaultAction(self.ui.actionRefresh3D)
self.ui.actionRefresh2D.triggered.connect(self.updatePlot2D)
self.ui.actionRefresh3D.triggered.connect(self.updatePlot3D)
self.ui.actionAddView.triggered.connect(self.createNewPlotStyle)
#todo: self.ui.actionRemoveView.triggered.connect(self.plotSettingsModel.createPlotStyle)
def setTimeSeries(self, TS):
assert isinstance(TS, TimeSeries)
self.TS = TS
self.plotSettingsModel = PlotSettingsModel(self.tpCollection, self.plot2D, parent=self)
self.plotSettingsModel.sigVisibilityChanged.connect(self.setVisibility)
self.plotSettingsModel.sigDataChanged.connect(self.requestUpdate)
self.plotSettingsModel.rowsInserted.connect(self.onRowsInserted)
# self.plotSettingsModel.modelReset.connect(self.updatePersistantWidgets)
self.TV.setModel(self.plotSettingsModel)
self.delegate = PlotSettingsWidgetDelegate(self.TV, self.TS, self.tpCollectionListModel)
self.delegate.setItemDelegates(self.TV)
def onMoveToDate(self, date):
dt = np.asarray([np.abs(tsd.date - date) for tsd in self.TS])
i = np.argmin(dt)
self.sigMoveToTSD.emit(self.TS[i])
def onPixelLoaded(self, nDone, nMax, d):
self.ui.progressBar.setValue(nDone)
self.ui.progressBar.setMaximum(nMax)
if d.success():
t = 'Last loaded from {}.'.format(bn)
else:
t = 'Failed loading from {}.'.format(bn)
if d.info and d.info != '':
t += '({})'.format(d.info)
if DEBUG:
print(t)
# QgsApplication.processEvents()
def requestUpdate(self, *args):
self.updateRequested = True
#next time
def updatePersistentWidgets(self):

benjamin.jakimow@geo.hu-berlin.de
committed
model = self.TV.model()
if isinstance(model, PlotSettingsModel):
colExpression = model.columnIndex(model.cnExpression)
colStyle = model.columnIndex(model.cnStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
for row in range(model.rowCount()):
idxExpr = model.createIndex(row, colExpression)
idxStyle = model.createIndex(row, colStyle)
#self.TV.openPersistentEditor(idxExpr)
#self.TV.openPersistentEditor(idxStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
#self.TV.openPersistentEditor(model.createIndex(start, colStyle))
s = ""
def onRowsInserted(self, parent, start, end):
model = self.TV.model()
if isinstance(model, PlotSettingsModel):
colExpression = model.columnIndex(model.cnExpression)
colStyle = model.columnIndex(model.cnStyle)
while start <= end:
idxExpr = model.createIndex(start, colExpression)
idxStyle = model.createIndex(start, colStyle)
self.TV.openPersistentEditor(idxExpr)
self.TV.openPersistentEditor(idxStyle)
start += 1
#self.TV.openPersistentEditor(model.createIndex(start, colStyle))
s = ""
def onObservationClicked(self, plotDataItem, points):
for p in points:
tsd = p.data()
def clear(self):
#first remove from pixelCollection
self.plotData2D.clear()
self.plotData3D.clear()
pi = self.plot2D.getPlotItem()
plotItems = pi.listDataItems()
for p in plotItems:
p.clear()
p.update()
if len(self.TS) > 0:
rng = [self.TS[0].date, self.TS[-1].date]
rng = [date2num(d) for d in rng]
self.plot2D.getPlotItem().setRange(xRange=rng)
if self.plot3D:
pass
def loadCoordinate(self, spatialPoints=None, LUT_bandIndices=None):
"""
Loads a temporal profile for a single or multiple geometries.
:param spatialPoints: SpatialPoint | [list-of-SpatialPoints]
"""
if not isinstance(self.plotSettingsModel, PlotSettingsModel):
return False
if not self.pixelLoader.isReadyToLoad():
return False
assert isinstance(self.TS, TimeSeries)
#Get or create the TimeSeriesProfiles which will store the loaded values
tasks = []
TPs = []
theGeometries = []
# Define a which (new) bands need to be loaded for each sensor
if LUT_bandIndices is None:
LUT_bandIndices = dict()
for sensor in self.TS.Sensors:
LUT_bandIndices[sensor] = self.plotSettingsModel.requiredBandsIndices(sensor)
assert isinstance(LUT_bandIndices, dict)
for sensor in self.TS.Sensors:
assert sensor in LUT_bandIndices.keys()
#update new / existing points
if isinstance(spatialPoints, SpatialPoint):
spatialPoints = [spatialPoints]
for spatialPoint in spatialPoints:
assert isinstance(spatialPoint, SpatialPoint)
TP = self.tpCollection.fromSpatialPoint(spatialPoint)
if not isinstance(TP, TemporalProfile):
TP = TemporalProfile(self.TS, spatialPoint)
self.tpCollection.insertTemporalProfiles(TP)
TPs.append(TP)
theGeometries.append(TP.mCoordinate)
TP_ids = [TP.mID for TP in TPs]
#each TSD is a Task
#a Task defines which bands are to be loaded
for tsd in self.TS:
#do not load from invisible TSDs
if not tsd.isVisible():
continue
#which bands do we need to load?
requiredIndices = set(LUT_bandIndices[tsd.sensor])
if len(requiredIndices) == 0:
continue
else:
s = ""
missingIndices = set()
for TP in TPs:
assert isinstance(TP, TemporalProfile)
existingBandKeys = [k for k in TP.data(tsd).keys() if PlotSettingsModel.regBandKeyExact.search(k)]
existingBandIndices = set([bandKey2bandIndex(k) for k in existingBandKeys])
need2load = requiredIndices.difference(existingBandIndices)
missingIndices = missingIndices.union(need2load)
if len(missingIndices) > 0:
task = PixelLoaderTask(tsd.pathImg, theGeometries,
bandIndices=missingIndices,
temporalProfileIDs=TP_ids)
tasks.append(task)
if len(tasks) > 0:
aGoodDefault = 2 if len(self.TS) > 25 else 1
self.pixelLoader.setNumberOfProcesses(SETTINGS.value('profileloader_threads', aGoodDefault))
if DEBUG:
print('Start loading for {} geometries from {} sources...'.format(
len(theGeometries), len(tasks)
))
self.pixelLoader.startLoading(tasks)
else:
if DEBUG:
print('Data for geometries already loaded')
def setVisibility(self, sensorPlotStyle):
assert isinstance(sensorPlotStyle, TemporalProfilePlotStyle)
self.setVisibility2D(sensorPlotStyle)
def setVisibility2D(self, sensorPlotStyle):
self.plot2D.update()