"...interactive-group-element.component.scss" did not exist on "c9695810146f978e2f5ca583a4c00cc26dd7dfba"
Newer
Older
# -*- coding: utf-8 -*-
"""
/***************************************************************************

Benjamin Jakimow
committed
EO Time Series Viewer
-------------------
begin : 2017-08-04
git sha : $Format:%H$
copyright : (C) 2017 by HU-Berlin
email : benjamin.jakimow@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. *
* *
***************************************************************************/
"""
# noinspection PyPep8Naming
import os, sys, pickle, datetime
from qgis.gui import *
from qgis.core import *

Benjamin Jakimow
committed
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtXml import *
from qgis.PyQt.QtGui import *
from .timeseries import *
from .utils import SpatialExtent, SpatialPoint, px2geo, loadUI, nextColor

Benjamin Jakimow
committed
from .externals.qps.plotstyling.plotstyling import PlotStyle, PlotStyleButton, PlotStyleDialog
from .externals.pyqtgraph import ScatterPlotItem, SpotItem, GraphicsScene
from .externals.qps.externals.pyqtgraph.GraphicsScene.mouseEvents import MouseClickEvent, MouseDragEvent
from .externals import pyqtgraph as pg
from .sensorvisualization import SensorListModel
import numpy as np
#import OpenGL
from eotimeseriesviewer.temporalprofiles3d import *
except Exception as ex:
print('unable to import OpenGL based packages:\n{}'.format(ex))
def getTextColorWithContrast(c):
assert isinstance(c, QColor)
if c.lightness() < 0.5:
return QColor('white')
else:
return QColor('black')
def selectedModelIndices(tableView):
assert isinstance(tableView, QTableView)
result = {}
sm = tableView.selectionModel()
m = tableView.model()
if isinstance(sm, QItemSelectionModel) and isinstance(m, QAbstractItemModel):
for idx in sm.selectedIndexes():
assert isinstance(idx, QModelIndex)
if idx.row() not in result.keys():
result[idx.row()] = idx
return result.values()
def __init__(self, *args, **kwds):
# menu creation is deferred because it is expensive and often
# the user will never see the menu anyway.
self.menu = None
def boundingRect(self):
return super(_SensorPoints,self).boundingRect()
def paint(self, p, *args):
super(_SensorPoints, self).paint(p, *args)
# On right-click, raise the context menu
def mouseClickEvent(self, ev):
if ev.button() == QtCore.Qt.RightButton:
if self.raiseContextMenu(ev):
ev.accept()
def raiseContextMenu(self, ev):
menu = self.getContextMenus()
# Let the scene add on to the end of our context menu
# (this is optional)
menu = self.scene().addParentContextMenus(self, menu, ev)
pos = ev.screenPos()
menu.popup(QtCore.QPoint(pos.x(), pos.y()))
return True
# This method will be called when this item's _children_ want to raise
# a context menu that includes their parents' menus.
def getContextMenus(self, event=None):
if self.menu is None:
self.menu = QMenu()
self.menu.setTitle(self.name + " options..")
green = QAction("Turn green", self.menu)
green.triggered.connect(self.setGreen)
self.menu.addAction(green)
self.menu.green = green
blue = QAction("Turn blue", self.menu)
blue.triggered.connect(self.setBlue)
self.menu.addAction(blue)
self.menu.green = blue
alpha = QWidgetAction(self.menu)
alphaSlider = QSlider()
alphaSlider.setOrientation(QtCore.Qt.Horizontal)
alphaSlider.setMaximum(255)
alphaSlider.setValue(255)
alphaSlider.valueChanged.connect(self.setAlpha)
alpha.setDefaultWidget(alphaSlider)
self.menu.addAction(alpha)
self.menu.alpha = alpha
self.menu.alphaSlider = alphaSlider
return self.menu
class SensorPixelDataMemoryLayer(QgsVectorLayer):
def __init__(self, sensor, crs=None):
assert isinstance(sensor, SensorInstrument)
if crs is None:
crs = QgsCoordinateReferenceSystem('EPSG:4862')
uri = 'Point?crs={}'.format(crs.authid())
super(SensorPixelDataMemoryLayer, self).__init__(uri, 'Pixels_sensor_' + sensor.name(), 'memory', False)
self.mSensor = sensor
#initialize fields
assert self.startEditing()
# standard field names, types, etc.
fieldDefs = [('pxid', QVariant.String, 'integer'),
('date', QVariant.String, 'char'),
('doy', QVariant.Int, 'integer'),
('geo_x', QVariant.Double, 'decimal'),
('geo_y', QVariant.Double, 'decimal'),
('px_x', QVariant.Int, 'integer'),
('px_y', QVariant.Int, 'integer'),
]
# one field for each band
for b in range(sensor.nb):
fName = 'b{}'.format(b + 1)
fieldDefs.append((fName, QVariant.Double, 'decimal'))
# initialize fields
for fieldDef in fieldDefs:
field = QgsField(fieldDef[0], fieldDef[1], fieldDef[2])
self.addAttribute(field)
self.commitChanges()
def sensor(self):
return self.mSensor
def nPixels(self):
raise NotImplementedError()
def dates(self):
raise NotImplementedError()
class PlotSettingsModel3D(QAbstractTableModel):
#sigSensorAdded = pyqtSignal(SensorPlotSettings)
sigVisibilityChanged = pyqtSignal(TemporalProfile2DPlotStyle)
sigPlotStylesAdded = pyqtSignal(list)
sigPlotStylesRemoved = pyqtSignal(list)
def __init__(self, parent=None, *args):
#assert isinstance(tableView, QTableView)
super(PlotSettingsModel3D, self).__init__(parent=parent)
self.mTimeSeries = None
self.cnID = 'ID'
self.cnExpression = LABEL_EXPRESSION_3D
self.cnTemporalProfile = 'Coordinate'
self.cnStyle = 'Style'
self.cnSensor = 'Sensor'
self.columnNames = [self.cnTemporalProfile, self.cnSensor, self.cnStyle, self.cnExpression]
self.mPlotSettings = []
#assert isinstance(plotWidget, DateTimePlotWidget)
self.sortColumnIndex = 0
self.sortOrder = Qt.AscendingOrder
self.sort(0, Qt.AscendingOrder)
def hasStyleForSensor(self, sensor):
assert isinstance(sensor, SensorInstrument)
for plotStyle in self.mPlotSettings:
assert isinstance(plotStyle, TemporalProfile3DPlotStyle)
if plotStyle.sensor() == sensor:
return True
return False
def onSensorRemoved(self, sensor):
assert isinstance(sensor, SensorInstrument)
self.removePlotStyles([s for s in self.mPlotSettings if s.sensor() == sensor])
def __len__(self):
return len(self.mPlotSettings)
def __iter__(self):
return iter(self.mPlotSettings)
def __getitem__(self, slice):
return self.mPlotSettings[slice]
def __contains__(self, item):
return item in self.mPlotSettings
def columnIndex(self, name):
return self.columnNames.index(name)
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, TemporalProfile3DPlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
for plotStyle in plotStyles:
assert isinstance(plotStyle, TemporalProfile3DPlotStyle)
if i is None:
i = len(self.mPlotSettings)
if len(plotStyles) > 0:
self.beginInsertRows(QModelIndex(), i, i + len(plotStyles)-1)
for j, plotStyle in enumerate(plotStyles):
assert isinstance(plotStyle, TemporalProfile3DPlotStyle)
self.mPlotSettings.insert(i+j, plotStyle)
self.endInsertRows()
self.sigPlotStylesAdded.emit(plotStyles)
def removePlotStyles(self, plotStyles):
"""
Removes PlotStyle instances
:param plotStyles: TemporalProfilePlotStyle | [list-of-TemporalProfilePlotStyle]
"""
if isinstance(plotStyles, TemporalProfile3DPlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
if len(plotStyles) > 0:
for plotStyle in plotStyles:
assert isinstance(plotStyle, TemporalProfile3DPlotStyle)
if plotStyle in self.mPlotSettings:
idx = self.plotStyle2idx(plotStyle)
self.beginRemoveRows(QModelIndex(), idx.row(),idx.row())
self.mPlotSettings.remove(plotStyle)
self.endRemoveRows()
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)
def rowCount(self, parent = QModelIndex()):
return len(self.mPlotSettings)
def removeRows(self, row, count , parent = QModelIndex()):
self.beginRemoveRows(parent, row, row + count-1)
toRemove = self.mPlotSettings[row:row + count]
for tsd in toRemove:
self.mPlotSettings.remove(tsd)
def plotStyle2idx(self, plotStyle):
assert isinstance(plotStyle, TemporalProfile3DPlotStyle)
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()]
def columnCount(self, parent = QModelIndex()):
return len(self.columnNames)
def data(self, index, role = Qt.DisplayRole):
if role is None or not index.isValid():
return None
value = None
columnName = self.columnNames[index.column()]
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfile3DPlotStyle):
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:
tp = plotStyle.temporalProfile()
if isinstance(tp, TemporalProfile):
value = tp.name()
else:
value = 'undefined'
elif role == Qt.EditRole:
if columnName == self.cnExpression:
value = plotStyle.expression()
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.cnStyle:
value = plotStyle
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))
columnName = self.columnNames[index.column()]
if value is None:
return False
result = False
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfile3DPlotStyle):
"""
if role in [Qt.DisplayRole]:
if columnName == self.cnExpression and isinstance(value, str):
plotStyle.setExpression(value)
result = True
elif columnName == self.cnStyle:
if isinstance(value, PlotStyle):
plotStyle.copyFrom(value)
result = True
"""
if role == Qt.CheckStateRole:
if columnName == self.cnTemporalProfile:
plotStyle.setVisibility(value == Qt.Checked)
result = True
if role == Qt.EditRole:
if columnName == self.cnSensor:
plotStyle.setSensor(value)
result = True
elif columnName == self.cnExpression:
plotStyle.setExpression(value)
result = True
elif columnName == self.cnTemporalProfile:
plotStyle.setTemporalProfile(value)
result = True
elif columnName == self.cnStyle:
#set the style and trigger an update
lastItemType = plotStyle.itemType()
lastExpression = plotStyle.expression()
plotStyle.copyFrom(value)
if lastItemType != plotStyle.itemType() or \
lastExpression != plotStyle.expression():
plotStyle.updateDataProperties()
else:
plotStyle.updateStyleProperties()
def flags(self, index):
if index.isValid():
stype = self.idx2plotStyle(index)
columnName = self.columnNames[index.column()]
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
if columnName in [self.cnTemporalProfile]:
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:
return self.columnNames[col]
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
return col
return None
class PlotSettingsModel2D(QAbstractTableModel):
# sigSensorAdded = pyqtSignal(SensorPlotSettings)
sigVisibilityChanged = pyqtSignal(TemporalProfile2DPlotStyle)
sigDataChanged = pyqtSignal(TemporalProfile2DPlotStyle)
sigPlotStylesAdded = pyqtSignal(list)
sigPlotStylesRemoved = pyqtSignal(list)
def __init__(self, parent=None, *args):
super(PlotSettingsModel2D, self).__init__(parent=parent)
self.cnID = 'ID'
self.cnSensor = 'Sensor'
self.cnExpression = LABEL_EXPRESSION_2D
self.cnStyle = 'Style'
self.cnTemporalProfile = 'Coordinate'
self.columnNames = [self.cnTemporalProfile, self.cnSensor, self.cnStyle, self.cnExpression]
self.mPlotSettings = []

Benjamin Jakimow
committed
self.mIconSize = QSize(25, 25)
self.dataChanged.connect(self.signaler)
def __len__(self):
return len(self.mPlotSettings)
def __iter__(self):
return iter(self.mPlotSettings)
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 signaler(self, idxUL, idxLR):
if idxUL.isValid():
plotStyle = self.idx2plotStyle(idxUL)
cname = self.columnNames[idxUL.column()]
if cname in [self.cnSensor,self.cnStyle]:
self.sigVisibilityChanged.emit(plotStyle)
if cname in [self.cnExpression]:
self.sigDataChanged.emit(plotStyle)
"""
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, TemporalProfile2DPlotStyle)
expression = p.expression()
#remove leading & tailing "
bandKeys = regBandKey.findall(expression)
for bandIndex in [bandKey2bandIndex(key) for key in bandKeys]:
bandIndices.add(bandIndex)
return bandIndices
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, TemporalProfile2DPlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
for plotStyle in plotStyles:
assert isinstance(plotStyle, TemporalProfile2DPlotStyle)
if i is None:
i = len(self.mPlotSettings)
if len(plotStyles) > 0:
self.beginInsertRows(QModelIndex(), i, i + len(plotStyles)-1)
for j, plotStyle in enumerate(plotStyles):
assert isinstance(plotStyle, TemporalProfile2DPlotStyle)
plotStyle.sigExpressionUpdated.connect(lambda s = plotStyle: self.onStyleUpdated(s))
self.mPlotSettings.insert(i+j, plotStyle)
self.endInsertRows()
self.sigPlotStylesAdded.emit(plotStyles)
def onStyleUpdated(self, style):
idx = self.plotStyle2idx(style)
r = idx.row()
self.dataChanged.emit(self.createIndex(r, 0), self.createIndex(r, self.columnCount()))
s = ""
def removePlotStyles(self, plotStyles):
"""
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()
self.sigPlotStylesRemoved.emit(plotStyles)
def rowCount(self, parent = QModelIndex()):
return len(self.mPlotSettings)
def removeRows(self, row, count , parent = QModelIndex()):
self.beginRemoveRows(parent, row, row + count-1)
toRemove = self.mPlotSettings[row:row + count]
for tsd in toRemove:
self.mPlotSettings.remove(tsd)
self.endRemoveRows()
def plotStyle2idx(self, plotStyle):
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.columnNames[index.column()]
if isinstance(plotStyle, TemporalProfile2DPlotStyle):
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:
tp = plotStyle.temporalProfile()
if isinstance(tp, TemporalProfile):
else:
value = 'undefined'
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))
columnName = self.columnNames[index.column()]
result = False
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfile2DPlotStyle):
if columnName == self.cnExpression:
plotStyle.setExpression(value)
plotStyle.updateDataProperties()
result = True
elif columnName == self.cnStyle:
if isinstance(value, PlotStyle):
plotStyle.copyFrom(value)
plotStyle.updateStyleProperties()
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)
elif columnName == self.cnTemporalProfile:
plotStyle.setTemporalProfile(value)
if result:
#save plot-style
self.savePlotSettings(plotStyle, index='DEFAULT')
self.dataChanged.emit(index, index)
def savePlotSettings(self, sensorPlotSettings, index='DEFAULT'):
return
def restorePlotSettings(self, sensor, index='DEFAULT'):
return None
def flags(self, index):
if index.isValid():
columnName = self.columnNames[index.column()]
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
if columnName in [self.cnTemporalProfile]:
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

Benjamin Jakimow
committed
class PlotSettingsTableView(QTableView):

Benjamin Jakimow
committed
def __init__(self, *args, **kwds):
super(PlotSettingsTableView, self).__init__(*args, **kwds)
pal = self.palette()
cSelected = pal.color(QPalette.Active, QPalette.Highlight)
pal.setColor(QPalette.Inactive, QPalette.Highlight, cSelected)
self.setPalette(pal)

Benjamin Jakimow
committed
def contextMenuEvent(self, event: QContextMenuEvent):
"""
Creates and shows the QMenu
:param event: QContextMenuEvent
"""

Benjamin Jakimow
committed
indices = self.selectionModel().selectedIndexes()

Benjamin Jakimow
committed
indices2 = [self.model().mapToSource(idx) for idx in indices]

Benjamin Jakimow
committed
if len(indices2) > 0:
menu = QMenu(self)
a = menu.addAction('Set Style')
a.triggered.connect(lambda *args, i=indices2: self.onSetStyle(i))

Benjamin Jakimow
committed
menu.popup(QCursor.pos())

Benjamin Jakimow
committed
def onSetStyle(self, indices):

Benjamin Jakimow
committed
if len(indices) > 0:
refStyle = None

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

Benjamin Jakimow
committed
model = self.model().sourceModel()
assert isinstance(model, PlotSettingsModel2D)

Benjamin Jakimow
committed
colStyle = model.columnIndex(model.cnStyle)

Benjamin Jakimow
committed
for idx in indices:
style = self.model().sourceModel().idx2plotStyle(idx)
if isinstance(style, PlotStyle):
refStyle = style
break
if isinstance(refStyle, PlotStyle):
newStyle = PlotStyleDialog.getPlotStyle(plotStyle=refStyle)
if isinstance(newStyle, PlotStyle):
for idx in indices:
assert isinstance(idx, QModelIndex)
idxStyle = model.createIndex(idx.row(), colStyle)
model.setData(idxStyle, newStyle, role=Qt.EditRole)

Benjamin Jakimow
committed
class PlotSettingsModel2DWidgetDelegate(QStyledItemDelegate):
"""

Benjamin Jakimow
committed
"""
def __init__(self, tableView, temporalProfileLayer, parent=None):
assert isinstance(tableView, QTableView)
assert isinstance(temporalProfileLayer, TemporalProfileLayer)
super(PlotSettingsModel2DWidgetDelegate, self).__init__(parent=parent)
self._preferedSize = QgsFieldExpressionWidget().sizeHint()
self.mTableView = tableView
self.mTemporalProfileLayer = temporalProfileLayer
self.mTimeSeries = temporalProfileLayer.timeSeries()

Benjamin Jakimow
committed
self.mSensorLayers = {}

Benjamin Jakimow
committed
def paint(self, painter: QPainter, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex):

Benjamin Jakimow
committed
if index.column() == 2:
style = self.style(index)
h = self.mTableView.verticalHeader().defaultSectionSize()
w = self.mTableView.horizontalHeader().defaultSectionSize()
if h > 0 and w > 0:
px = style.createPixmap(size=QSize(w, h))
label = QLabel()
label.setPixmap(px)
painter.drawPixmap(option.rect, px)
#QApplication.style().drawControl(QStyle.CE_CustomBase, label, painter)
else:
super(PlotSettingsModel2DWidgetDelegate, self).paint(painter, option, index)
else:
super(PlotSettingsModel2DWidgetDelegate, self).paint(painter, option, index)

Benjamin Jakimow
committed
def sortFilterProxyModel(self)->QSortFilterProxyModel:
return self.mTableView.model()

Benjamin Jakimow
committed
def plotSettingsModel(self)->PlotSettingsModel2D:
return self.sortFilterProxyModel().sourceModel()

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

Benjamin Jakimow
committed
def setItemDelegates(self, tableView):
assert isinstance(tableView, QTableView)
model = self.plotSettingsModel()
assert isinstance(model, PlotSettingsModel2D)
for c in [model.cnSensor, model.cnExpression, model.cnStyle, model.cnTemporalProfile]:
i = model.columnNames.index(c)
tableView.setItemDelegateForColumn(i, self)

Benjamin Jakimow
committed
def getColumnName(self, index):
assert index.isValid()
model = self.plotSettingsModel()
assert isinstance(model, PlotSettingsModel2D)
return model.columnNames[index.column()]

Benjamin Jakimow
committed
def sizeHint(self, options, index):
s = super(ExpressionDelegate, self).sizeHint(options, index)
exprString = self.tableView.model().data(index)
l = QLabel()
l.setText(exprString)
x = l.sizeHint().width() + 100
s = QSize(x, s.height())
return self._preferedSize

Benjamin Jakimow
committed
def exampleLyr(self, sensor):
# if isinstance(sensor, SensorInstrument):
if sensor not in self.mSensorLayers.keys():

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

Benjamin Jakimow
committed
crs = QgsCoordinateReferenceSystem('EPSG:4862')
uri = 'Point?crs={}'.format(crs.authid())
lyr = QgsVectorLayer(uri, 'LOCATIONS', 'memory')
f = sensorExampleQgsFeature(sensor)
assert isinstance(f, QgsFeature)
assert lyr.startEditing()
for field in f.fields():
lyr.addAttribute(field)
lyr.addFeature(f)
lyr.commitChanges()
self.mSensorLayers[sensor] = lyr
return self.mSensorLayers[sensor]

Benjamin Jakimow
committed
def createEditor(self, parent, option, index):
cname = self.getColumnName(index)
model = self.plotSettingsModel()
pmodel = self.sortFilterProxyModel()

Benjamin Jakimow
committed
w = None
if index.isValid() and isinstance(model, PlotSettingsModel2D):

Benjamin Jakimow
committed

Benjamin Jakimow
committed
plotStyle = model.idx2plotStyle(pmodel.mapToSource(index))

Benjamin Jakimow
committed

Benjamin Jakimow
committed
if isinstance(plotStyle, TemporalProfile2DPlotStyle):
if cname == model.cnExpression:

Benjamin Jakimow
committed

Benjamin Jakimow
committed
w = QgsFieldExpressionWidget(parent=parent)
w.setExpressionDialogTitle('Values')
w.setToolTip('Set an expression to specify the image band or calculate a spectral index.')
w.fieldChanged[str, bool].connect(lambda n, b: self.checkData(index, w, w.expression()))
w.setExpression(plotStyle.expression())

Benjamin Jakimow
committed
if isinstance(plotStyle.sensor(), SensorInstrument):
w.setLayer(self.exampleLyr(plotStyle.sensor()))

Benjamin Jakimow
committed

Benjamin Jakimow
committed
elif cname == model.cnStyle:
w = PlotStyleButton(parent=parent)
w.setPlotStyle(plotStyle)
w.setToolTip('Set style.')
w.sigPlotStyleChanged.connect(lambda: self.checkData(index, w, w.plotStyle()))

Benjamin Jakimow
committed
elif cname == model.cnSensor:
w = QComboBox(parent=parent)
m = SensorListModel(self.mTimeSeries)
w.setModel(m)

Benjamin Jakimow
committed
elif cname == model.cnTemporalProfile:
w = QgsFeatureListComboBox(parent=parent)
w.setSourceLayer(self.mTemporalProfileLayer)
w.setIdentifierField(FN_ID)
w.setDisplayExpression('to_string("{}")+\' \'+"name"'.format(FN_ID))
w.setAllowNull(False)
else:
raise NotImplementedError()
return w

Benjamin Jakimow
committed
def checkData(self, index, w, value):
assert isinstance(index, QModelIndex)
model = self.mTableView.model()
if index.isValid() and isinstance(model, PlotSettingsModel2D):
plotStyle = model.idx2plotStyle(index)
assert isinstance(plotStyle, TemporalProfile2DPlotStyle)
if isinstance(w, QgsFieldExpressionWidget):
assert value == w.expression()
assert w.isExpressionValid(value) == w.isValidExpression()

Benjamin Jakimow
committed
if w.isValidExpression():
self.commitData.emit(w)
else:
s = ""
#print(('Delegate commit failed',w.asExpression()))
if isinstance(w, PlotStyleButton):

Benjamin Jakimow
committed
self.commitData.emit(w)

Benjamin Jakimow
committed
def style(self, proxyIndex:QModelIndex)->PlotStyle:
model = self.plotSettingsModel()
index = self.sortFilterProxyModel().mapToSource(proxyIndex)
return model.data(index, role=Qt.UserRole)

Benjamin Jakimow
committed
def setEditorData(self, editor, proxyIndex):

Benjamin Jakimow
committed
model = self.plotSettingsModel()
index = self.sortFilterProxyModel().mapToSource(proxyIndex)
w = None
if index.isValid() and isinstance(model, PlotSettingsModel2D):
cname = self.getColumnName(proxyIndex)
if cname == model.cnExpression:
lastExpr = model.data(index, Qt.DisplayRole)
assert isinstance(editor, QgsFieldExpressionWidget)
editor.setProperty('lastexpr', lastExpr)
editor.setField(lastExpr)

Benjamin Jakimow
committed
elif cname == model.cnStyle:
style = model.data(index, Qt.UserRole)
assert isinstance(editor, PlotStyleButton)
editor.setPlotStyle(style)

Benjamin Jakimow
committed
elif cname == model.cnSensor:
assert isinstance(editor, QComboBox)
m = editor.model()
assert isinstance(m, SensorListModel)
sensor = index.data(role=Qt.UserRole)
if isinstance(sensor, SensorInstrument):
idx = m.sensor2idx(sensor)
editor.setCurrentIndex(idx.row())

Benjamin Jakimow
committed
elif cname == model.cnTemporalProfile:
assert isinstance(editor, QgsFeatureListComboBox)
value = editor.identifierValue()
if value != QVariant():
plotStyle = index.data(role=Qt.UserRole)
TP = plotStyle.temporalProfile()
editor.setIdentifierValue(TP.id())
else:
s = ""
else:
raise NotImplementedError()

Benjamin Jakimow
committed
def setModelData(self, w, model, proxyIndex):
index = self.sortFilterProxyModel().mapToSource(proxyIndex)
cname = self.getColumnName(proxyIndex)
model = self.plotSettingsModel()

Benjamin Jakimow
committed
if index.isValid() and isinstance(model, PlotSettingsModel2D):
if cname == model.cnExpression:
assert isinstance(w, QgsFieldExpressionWidget)
expr = w.asExpression()