Newer
Older
"""
Removes PlotStyle instances
:param plotStyles: TemporalProfilePlotStyle | [list-of-TemporalProfilePlotStyle]
"""
if isinstance(plotStyles, PlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
if len(plotStyles) > 0:
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()
if isinstance(plotStyle, TemporalProfile2DPlotStyle):
for pi in plotStyle.mPlotItems:
self.mPlotWidget.getPlotItem().removeItem(pi)
self.sigPlotStylesRemoved.emit(plotStyles)
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()
assert isinstance(plotStyle, TemporalProfile2DPlotStyle)
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
columnName = self.columNames[index.column()]
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfile2DPlotStyle):
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
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, TemporalProfile2DPlotStyle):
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'):
assert isinstance(sensorPlotSettings, TemporalProfile2DPlotStyle)
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, TemporalProfile2DPlotStyle):
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)

benjamin.jakimow@geo.hu-berlin.de
committed
self.baseTitle = self.windowTitle()
self.stackedWidget.currentChanged.connect(self.onStackPageChanged)
self.stackedWidget.setCurrentWidget(self.page2D)

benjamin.jakimow@geo.hu-berlin.de
committed
if OPENGL_AVAILABLE:
#from pyqtgraph.opengl import GLViewWidget
#self.plotWidget3D = GLViewWidget(parent=self.page3D)
self.plotWidget3D = ViewWidget3D(parent=self.frame3DPlot)
self.plotWidget3D.setObjectName('plotWidget3D')
size = self.labelDummy3D.size()
l.addWidget(self.plotWidget3D)
self.plotWidget3D.setSizePolicy(self.labelDummy3D.sizePolicy())
self.labelDummy3D.setVisible(False)
l.removeWidget(self.labelDummy3D)
self.plotWidget3D.setBaseSize(size)
self.splitter3D.setSizes([100, 100])
#pi = self.plotWidget2D.plotItem
#ax = DateAxis(orientation='bottom', showValues=True)
#pi.layout.addItem(ax, 3,2)

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

benjamin.jakimow@geo.hu-berlin.de
committed
self.menuTPSaveOptions = QMenu()
self.menuTPSaveOptions.addAction(self.actionSaveTPCoordinates)
self.menuTPSaveOptions.addAction(self.actionSaveTPCSV)
self.menuTPSaveOptions.addAction(self.actionSaveTPVector)
self.btnSaveTemporalProfiles.setMenu(self.menuTPSaveOptions)
def onStackPageChanged(self, i):
w = self.stackedWidget.currentWidget()
title = self.baseTitle
if w == self.page2D:
title = '{} | 2D'.format(title)

benjamin.jakimow@geo.hu-berlin.de
committed
elif w == self.page3D:
title = '{} | 3D'.format(title)

benjamin.jakimow@geo.hu-berlin.de
committed
elif w == self.pagePixel:
title = '{} | Coordinates'.format(title)

benjamin.jakimow@geo.hu-berlin.de
committed
self.setWindowTitle(title)
NEXT_COLOR_HUE_DELTA_CON = 10
NEXT_COLOR_HUE_DELTA_CAT = 100
def nextColor(color, mode='cat'):
"""
Reuturns another color
:param color:
:param mode:
:return:
"""
assert mode in ['cat','con']
assert isinstance(color, QColor)
hue, sat, value, alpha = color.getHsl()
if mode == 'cat':
hue += NEXT_COLOR_HUE_DELTA_CAT
elif mode == 'con':
hue += NEXT_COLOR_HUE_DELTA_CON
if sat == 0:
sat = 255
value = 128
alpha = 255
s = ""
while hue > 360:
hue -= 360
return QColor.fromHsl(hue, sat, value, alpha)
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.tableView2DProfiles = ui.tableView2DProfiles
self.tableView2DProfiles.setSortingEnabled(False)
self.tableView2DProfiles.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.plotSettingsModel3D = PlotSettingsModel3D()
#self.plotSettingsModel3D.sigPlotStylesRemoved.connect(self.updatePlot3D)
#self.plotSettingsModel3D.sigPlotStylesAdded.connect(self.updatePlot3D)
#self.plotSettingsModel3D.sigPlotStylesAdded.connect(self.updatePlot3D)
self.plotSettingsModel3D.rowsInserted.connect(self.onRowsInserted3D)
self.ui.tableView3DProfiles.setModel(self.plotSettingsModel3D)
self.ui.tableView3DProfiles.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.delegateTableView3D = PlotSettingsModel3DWidgetDelegate(self.ui.tableView3DProfiles)
self.delegateTableView3D.setItemDelegates(self.ui.tableView3DProfiles)

benjamin.jakimow@geo.hu-berlin.de
committed
# self.mSelectionModel.currentChanged.connect(self.onCurrentSelectionChanged)
self.plot2D = ui.plotWidget2D

benjamin.jakimow@geo.hu-berlin.de
committed
pi = self.plot2D.getPlotItem()
pi.getViewBox().sigMoveToDate.connect(self.sigMoveToDate)
pi.getAxis('bottom').setLabel(LABEL_TIME)
pi.getAxis('left').setLabel(LABEL_DN)
self.plot2Dvline = pg.InfiniteLine(angle=90, movable=False)
self.plot2Dhline = pg.InfiniteLine(angle=0, movable=False)
#self.plot2DLabel = pg.TextItem(text='LABEL')
self.plot2DLabel = pg.LabelItem(justify='right')
#pi.setContentsMargins(0.1, 0.1, 0.1, 0.1)
pi.addItem(self.plot2Dvline, ignoreBounds=True)
pi.addItem(self.plot2Dhline, ignoreBounds=True)
self.plot2D.addItem(self.plot2DLabel, ignoreBounds=True)
self.proxy2D = pg.SignalProxy(self.plot2D.scene().sigMouseMoved, rateLimit=60, slot=self.onMouseMoved2D)
self.plot3D = ui.plotWidget3D
## Add a grid to the view
if OPENGL_AVAILABLE:
import pyqtgraph.opengl as gl
self.glGridItem = gl.GLGridItem()
self.glGridItem.setDepthValue(10) # draw grid after surfaces since they may be translucent
self.glPlotDataItems = [self.glGridItem]
self.plot3D.addItem(self.glGridItem)
self.tpCollection = TemporalProfileCollection()
self.tpCollectionListModel = TemporalProfileCollectionListModel(self.tpCollection)
self.ui.tableViewTemporalProfiles.setModel(self.tpCollection)
self.ui.tableViewTemporalProfiles.selectionModel().selectionChanged.connect(self.onTemporalProfileSelectionChanged)
self.ui.tableViewTemporalProfiles.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.ui.cbTemporalProfile3D.setModel(self.tpCollectionListModel)
#self.pxCollection.sigPixelAdded.connect(self.requestUpdate)
#self.pxCollection.sigPixelRemoved.connect(self.clear)
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)

benjamin.jakimow@geo.hu-berlin.de
committed
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
def onMouseMoved2D(self, evt):
pos = evt[0] ## using signal proxy turns original arguments into a tuple
plotItem = self.plot2D.getPlotItem()
if plotItem.sceneBoundingRect().contains(pos):
mousePoint = plotItem.vb.mapSceneToView(pos)
x = mousePoint.x()
y = mousePoint.y()
index = int(mousePoint.x())
self.plot2DLabel.setText('Refreshed {}'.format(mousePoint.x(), mousePoint.y()))
#if index > 0 and index < len(data1):
# label.setText(
# "<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y1=%0.1f</span>, <span style='color: green'>y2=%0.1f</span>" % (
# mousePoint.x(), data1[index], data2[index]))
self.plot2Dvline.setPos(mousePoint.x())
self.plot2Dhline.setPos(mousePoint.y())
return
vb = plotItem.vb
if plotItem.sceneBoundingRect().contains(pos):
mousePoint = vb.mapSceneToView(pos)
self.vLine.setPos(mousePoint.x())
self.hLine.setPos(mousePoint.y())
info = '{:0.2f}, {:0.2f}'.format(mousePoint.x(), mousePoint.y())
self.tbCursorLocationValue.setText(info)
"""
self.mlabel.setText(
"<span style='font-size: 12pt'>{}</span>".format(info)
"""
else:
self.tbCursorLocationValue.setText('')
self.mlabel.setText('')
def selected2DPlotStyles(self):
result = []
m = self.ui.tableView2DProfiles.model()
for idx in selectedModelIndices(self.ui.tableView2DProfiles):
result.append(m.idx2plotStyle(idx))
return result
def selectedTemporalProfiles(self):
result = []
m = self.ui.tableViewTemporalProfiles.model()
for idx in selectedModelIndices(self.ui.tableViewTemporalProfiles):
result.append(m.idx2tp(idx))
return result
def removePlotStyles(self, plotStyles):
m = self.ui.tableView2DProfiles.model()
m.removePlotStyles(plotStyles)
def removeTemporalProfiles(self, temporalProfiles):
m = self.ui.tableViewTemporalProfiles.model()
if isinstance(m, TemporalProfileCollection):
m.removeTemporalProfiles(temporalProfiles)
def createNewPlotStyle(self):
l = len(self.tpCollection)
if l > 0:
temporalProfile = self.tpCollection[0]
plotStyle = TemporalProfile2DPlotStyle(temporalProfile)
plotStyle.sigExpressionUpdated.connect(self.updatePlot2D)
sensors = self.TS.Sensors.keys()
if len(sensors) > 0:
plotStyle.setSensor(sensors[0])
if len(self.plotSettingsModel2D) > 0:
lastStyle = self.plotSettingsModel2D[-1]
assert isinstance(lastStyle, TemporalProfile2DPlotStyle)
markerColor = nextColor(lastStyle.markerBrush.color())
plotStyle.markerBrush.setColor(markerColor)
self.plotSettingsModel2D.insertPlotStyles([plotStyle])
pdi = plotStyle.createPlotItem(self.plot2D)
assert isinstance(pdi, TemporalProfilePlotDataItem)

benjamin.jakimow@geo.hu-berlin.de
committed
pdi.sigClicked.connect(self.onProfileClicked2D)
pdi.sigPointsClicked.connect(self.onPointsClicked2D)
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()

benjamin.jakimow@geo.hu-berlin.de
committed
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
def onProfileClicked2D(self, pdi):
if isinstance(pdi, TemporalProfilePlotDataItem):
sensor = pdi.mPlotStyle.sensor()
tp = pdi.mPlotStyle.temporalProfile()
if isinstance(tp, TemporalProfile) and isinstance(sensor, SensorInstrument):
info = ['Sensor:{}'.format(sensor.name()),
'Coordinate:{}, {}'.format(tp.mCoordinate.x(), tp.mCoordinate.y())]
self.ui.tbInfo2D.setPlainText('\n'.join(info))
def onPointsClicked2D(self, pdi, spottedItems):
if isinstance(pdi, TemporalProfilePlotDataItem) and isinstance(spottedItems, list):
sensor = pdi.mPlotStyle.sensor()
tp = pdi.mPlotStyle.temporalProfile()
if isinstance(tp, TemporalProfile) and isinstance(sensor, SensorInstrument):
info = ['Sensor: {}'.format(sensor.name()),
'Coordinate: {}, {}'.format(tp.mCoordinate.x(), tp.mCoordinate.y())]
for item in spottedItems:
pos = item.pos()
x = pos.x()
y = pos.y()
date = num2date(x)
info.append('Date: {}\nValue: {}'.format(date, y))
self.ui.tbInfo2D.setPlainText('\n'.join(info))
def onTemporalProfileSelectionChanged(self, selected, deselected):

benjamin.jakimow@geo.hu-berlin.de
committed
nSelected = len(selected)
self.ui.actionRemoveTemporalProfile.setEnabled(nSelected > 0)
self.ui.btnSaveTemporalProfiles.setEnabled(nSelected > 0)
def onPlot2DSelectionChanged(self, selected, deselected):
self.ui.actionRemoveView.setEnabled(len(selected) > 0)
self.ui.actionRemoveView.setEnabled(False)
self.ui.actionRemoveTemporalProfile.setEnabled(False)
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.btnRemoveTemporalProfile.setDefaultAction(self.ui.actionRemoveTemporalProfile)
self.ui.btnReset3DCamera.setDefaultAction(self.ui.actionReset3DCamera)
self.ui.actionRefresh2D.triggered.connect(self.updatePlot2D)
self.ui.actionRefresh3D.triggered.connect(self.updatePlot3D)

benjamin.jakimow@geo.hu-berlin.de
committed
self.ui.btnLoadProfile1.setDefaultAction(self.ui.actionLoadProfileRequest)
self.ui.btnLoadProfile2.setDefaultAction(self.ui.actionLoadProfileRequest)
self.ui.btnLoadProfile3.setDefaultAction(self.ui.actionLoadProfileRequest)
self.ui.actionAddView.triggered.connect(self.createNewPlotStyle)
self.ui.actionRemoveView.triggered.connect(lambda:self.removePlotStyles(self.selected2DPlotStyles()))
self.ui.actionRemoveTemporalProfile.triggered.connect(lambda :self.removeTemporalProfiles(self.selectedTemporalProfiles()))
self.ui.actionReset3DCamera.triggered.connect(self.reset3DCamera)
self.tpCollection.sigMaxProfilesChanged.connect(self.ui.sbMaxTP.setValue)
self.ui.sbMaxTP.valueChanged.connect(self.tpCollection.setMaxProfiles)

benjamin.jakimow@geo.hu-berlin.de
committed
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
from timeseriesviewer.temporalprofiles import saveTemporalProfiles
DEF_PATH = None
self.ui.actionSaveTPCoordinates.triggered.connect(
lambda: saveTemporalProfiles(self.tpCollection[:],
QFileDialog.getSaveFileName(
self.ui, 'Save Temporal Profile Coordinates',
DEF_PATH, 'ESRI Shapefile (*.shp);;Geopackage (*.gpkg);;Textfile (*.csv *.txt)'
), mode='coordinate'
)
)
self.ui.actionSaveTPCSV.triggered.connect(
lambda: saveTemporalProfiles(self.tpCollection[:],
QFileDialog.getSaveFileName(
self.ui, 'Save Temporal Profiles to Text File.',
DEF_PATH,
'Textfile (*.csv *.txt)'
), mode ='all'
)
)
self.ui.actionSaveTPVector.triggered.connect(
lambda: saveTemporalProfiles(self.tpCollection[:],
QFileDialog.getSaveFileName(
self.ui, 'Save Temporal Profiles to Vector File.',
DEF_PATH,
'ESRI Shapefile (*.shp);;Geopackage (*.gpkg)'
), mode = 'all'
)
)
#todo: self.ui.actionRemoveView.triggered.connect(self.plotSettingsModel.createPlotStyle)
def reset3DCamera(self, *args):
if OPENGL_AVAILABLE:
self.plot3D.setCameraPosition((0,0,0), distance=10, elevation=10)
assert isinstance(TS, TimeSeries)
self.TS = TS
self.plotSettingsModel2D = PlotSettingsModel2D(self.tpCollection, self.plot2D, parent=self)
self.plotSettingsModel2D.sigVisibilityChanged.connect(self.setVisibility)
self.plotSettingsModel2D.sigDataChanged.connect(self.requestUpdate)
self.plotSettingsModel2D.rowsInserted.connect(self.onRowsInserted2D)
self.plotSettingsModel3D.connectTimeSeries(self.TS)
# self.plotSettingsModel.modelReset.connect(self.updatePersistantWidgets)
self.tableView2DProfiles.setModel(self.plotSettingsModel2D)
#self.tableView2DProfilesSelectionModel = QItemSelectionModel(self.mModel)
self.tableView2DProfiles.selectionModel().selectionChanged.connect(self.onPlot2DSelectionChanged)
#self.tableView2DProfilesSelectionModel.selectionChanged.connect(self.onPlot2DSelectionChanged)
#self.tableView2DProfilesSelectionModel.setSelectionModel(self.mSelectionModel)
self.delegateTableView2D = PlotSettingsModel2DWidgetDelegate(self.tableView2DProfiles, self.TS, self.tpCollectionListModel)
self.delegateTableView2D.setItemDelegates(self.tableView2DProfiles)
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)
def requestUpdate(self, *args):
self.updateRequested = True
#next time
def onRowsInserted2D(self, parent, start, end):
model = self.tableView2DProfiles.model()
if isinstance(model, PlotSettingsModel2D):
colExpression = model.columnIndex(model.cnExpression)
colStyle = model.columnIndex(model.cnStyle)
while start <= end:
idxExpr = model.createIndex(start, colExpression)
idxStyle = model.createIndex(start, colStyle)
self.tableView2DProfiles.openPersistentEditor(idxExpr)
self.tableView2DProfiles.openPersistentEditor(idxStyle)
start += 1
#self.TV.openPersistentEditor(model.createIndex(start, colStyle))
s = ""
def onRowsInserted3D(self, parent, start, end):
model = self.ui.tableView3DProfiles.model()
if isinstance(model, PlotSettingsModel3D):
colStyle = model.columnIndex(model.cnStyle)
while start <= end:
idxStyle = model.createIndex(start, colStyle)
self.ui.tableView3DProfiles.openPersistentEditor(idxStyle)
start += 1
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.plotSettingsModel2D, PlotSettingsModel2D):
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.plotSettingsModel2D.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, i=0)
if len(self.tpCollection) == 1:
if len(self.plotSettingsModel2D) == 0:
self.createNewPlotStyle()
if len(self.plotSettingsModel3D) == 0:
#todo: individual 3D style
pass
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)

benjamin.jakimow@geo.hu-berlin.de
committed
need2load = TP.missingBandIndices(tsd, requiredIndices=requiredIndices)
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, TemporalProfile2DPlotStyle)
self.setVisibility2D(sensorPlotStyle)
def setVisibility2D(self, sensorPlotStyle):
self.plot2D.update()
if sensorView is None:
for sv in self.plotSettingsModel2D.items:
self.setData(sv)
else:
assert isinstance(sensorView, TemporalProfile2DPlotStyle)
self.setData2D(sensorView)
def onDataUpdate(self):
for plotSetting in self.plotSettingsModel2D:
assert isinstance(plotSetting, TemporalProfile2DPlotStyle)
if plotSetting.temporalProfile().updated():
for pdi in plotSetting.mPlotItems:
assert isinstance(pdi, TemporalProfilePlotDataItem)
pdi.updateDataAndStyle()

benjamin.jakimow@geo.hu-berlin.de
committed
plotSetting.temporalProfile().resetUpdatedFlag()
for i in self.plot2D.getPlotItem().dataItems:
i.updateItems()
if not self.plot2D.xAxisInitialized:
x0 = x1 = None
for plotSetting in self.plotSettingsModel2D:
assert isinstance(plotSetting, TemporalProfile2DPlotStyle)
for pdi in plotSetting.mPlotItems:
assert isinstance(pdi, TemporalProfilePlotDataItem)
if pdi.xData.ndim == 0 or pdi.xData.shape[0] == 0:
continue
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
if x0 is None:
x0 = pdi.xData.min()
x1 = pdi.xData.max()
else:
x0 = min(pdi.xData.min(), x0)
x1 = max(pdi.xData.max(), x1)
if x0 is not None:
self.plot2D.getPlotItem().setXRange(x0, x1)
self.plot2D.xAxisInitialized = True
@QtCore.pyqtSlot()
def updatePlot3D(self):
if OPENGL_AVAILABLE:
from pyqtgraph.opengl import GLViewWidget
import pyqtgraph.opengl as gl
assert isinstance(self.plot3D, GLViewWidget)
w = self.plot3D
#we need the data from all bands
del self.glPlotDataItems[:]
for i in w.items:
w.removeItem(i)
idx = self.ui.cbTemporalProfile3D.currentIndex()
if idx >= 0:
tp = self.ui.cbTemporalProfile3D.itemData(idx, role=Qt.UserRole)
assert isinstance(tp, TemporalProfile)
#1. ensure that data from all bands will be loaded
LUT_bandIndices = dict()
for sensor in self.TS.sensors():
assert isinstance(sensor, SensorInstrument)
LUT_bandIndices[sensor] = list(range(sensor.nb))
self.loadCoordinate(tp.mCoordinate, LUT_bandIndices=LUT_bandIndices)
#2. visualize already loaded data
LUTStyle = {}
for style in self.plotSettingsModel3D:
assert isinstance(style, TemporalProfile3DPlotStyle)
LUTStyle[style.sensor()] = style
dataPos = []
x0 = x1 = y0 = y1 = z0 = z1 = 0
for iDate, tsd in enumerate(tp.mTimeSeries):
bandKeys = sorted([k for k in data.keys() if k.startswith('b') and data[k] != None], key=lambda k: bandKey2bandIndex(k))
if len(bandKeys) < 2:
continue
t = date2num(tsd.date)
x = []
y = []
z = []
for i, k in enumerate(bandKeys):
x.append(i)
y.append(t)
z.append(data[k])
x = np.asarray(x)
y = np.asarray(y)
z = np.asarray(z)
if iDate == 0:
x0, x1 = (x.min(), x.max())
y0, y1 = (y.min(), y.max())
z0, z1 = (z.min(), z.max())
else:
x0, x1 = (min(x.min(), x0), max(x.max(), x1))
y0, y1 = (min(y.min(), y0), max(y.max(), y1))
z0, z1 = (min(z.min(), z0), max(z.max(), z1))
if tsd.sensor in LUTStyle.keys():
style = LUTStyle[tsd.sensor]
else:
style = TemporalProfile3DPlotStyle(tsd.sensor)
dataPos.append((x,y,z, style))
xyz = [(x0,x1),(y0,y1),(z0,z1)]
l = len(dataPos)
for iPos, pos in enumerate(dataPos):
x,y,z, style = pos
assert isinstance(style, TemporalProfile3DPlotStyle)
if not style.isVisible():
continue
arr = np.asarray((x,y,z), dtype=np.float64).transpose()
for i, m in enumerate(xyz):
arr[:, i] = (arr[:,i] - m0)/(m1-m0)
plt = gl.GLLinePlotItem(pos=arr,
#color=pg.glColor((i, n * 1.3)),
#color=pg.glColor(255,123,123,125),
#color=pg.glColor((iPos, l * 1.3)),
color=pg.glColor(style.color()),
self.glPlotDataItems.append(plt)
for i, item in enumerate(self.glPlotDataItems):
w.addItem(item)
#self.glGridItem.scale(0.1,0.1,0.1, local=False)
#w.setBackgroundColor(QColor('black'))
#w.setCameraPosition(pos=(0.0, 0.0, 0.0), distance=1.)
w.addItem(self.glGridItem)
w.update()
"""
for sensor, values in data.items():
if len(values['z']) > 0:
x = values['x']
y = values['y']
z = values['z']
p2 = gl.GLSurfacePlotItem(x=x, y=y, z=z, shader='normalColor')
p2.translate(-10, -10, 0)
w.addItem(p2)
"""
@QtCore.pyqtSlot()
def updatePlot2D(self):
if isinstance(self.plotSettingsModel2D, PlotSettingsModel2D):