Newer
Older
# -*- coding: utf-8 -*-
"""
/***************************************************************************

Benjamin Jakimow
committed
EO Time Series Viewer
-------------------
begin : 2015-08-20
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 sys, os
from qgis.core import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *

Benjamin Jakimow
committed
from eotimeseriesviewer.timeseries import TimeSeries, SensorInstrument, TimeSeriesDatum, TimeSeriesSource
from eotimeseriesviewer.utils import loadUI
class SensorDockUI(QgsDockWidget, loadUI('sensordock.ui')):
def __init__(self, parent=None):
super(SensorDockUI, self).__init__(parent)
self.setupUi(self)
self.TS = None
def setTimeSeries(self, timeSeries):
from eotimeseriesviewer.timeseries import TimeSeries
from eotimeseriesviewer.sensorvisualization import SensorTableModel
assert isinstance(timeSeries, TimeSeries)
self.TS = timeSeries

Benjamin Jakimow
committed
self.mSensorModel = SensorTableModel(self.TS)
self.mSortedModel = QSortFilterProxyModel()
self.mSortedModel.setSourceModel(self.mSensorModel)
self.sensorView.setModel(self.mSortedModel)
self.sensorView.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
s = ""
class SensorTableModel(QAbstractTableModel):
def __init__(self, TS, parent=None, *args):
super(SensorTableModel, self).__init__()
assert isinstance(TS, TimeSeries)

Benjamin Jakimow
committed
# define column names
self.mCN_Name = "name"
self.mCN_Band = "bands"
self.mCN_Dates = "dates"
self.mCN_Images = "images"
self.mCN_WL = "wavelength"
self.mCN_ID = "id"
self.mColumNames = [self.mCN_Name, self.mCN_Band, self.mCN_Dates, self.mCN_Images,
self.mCN_WL, self.mCN_ID]
self.TS = TS
self.TS.sigSensorAdded.connect(self.addSensor)
self.TS.sigSensorRemoved.connect(self.removeSensor)

Benjamin Jakimow
committed
self.TS.sigTimeSeriesDatesAdded.connect(self.onTimeSeriesSourceChanges)
self.TS.sigTimeSeriesDatesRemoved.connect(self.onTimeSeriesSourceChanges)
self.mSensors = []
self.addSensor(s)

Benjamin Jakimow
committed
def onTimeSeriesSourceChanges(self, timeSeriesDates:list):
"""
Reaction on changes in the time series data sources
:param timeSeriesDates: list
"""
sensors = set()
for tsd in timeSeriesDates:
assert isinstance(tsd, TimeSeriesDatum)
sensors.add(tsd.sensor())
for sensor in sensors:
self.updateSensor(sensor)
def addSensor(self, sensor:SensorInstrument):
"""
Adds a sensor
:param sensor: SensorInstrument
"""
assert isinstance(sensor, SensorInstrument)

Benjamin Jakimow
committed
i = self.rowCount()
self.beginInsertRows(QModelIndex(),i,i)
self.mSensors.append(sensor)
sensor.sigNameChanged.connect(lambda *args, sensor=sensor: self.updateSensor(sensor))
self.endInsertRows()

Benjamin Jakimow
committed
def updateSensor(self, sensor:SensorInstrument):
assert isinstance(sensor, SensorInstrument)

Benjamin Jakimow
committed
if sensor in self.mSensors:
tl = self.getIndexFromSensor(sensor)
br = self.createIndex(tl.row(), self.columnCount()-1)
self.dataChanged.emit(tl, br)

Benjamin Jakimow
committed
def removeSensor(self, sensor:SensorInstrument):
"""
Removes a SensorInstrument
:param sensor: SensorInstrument
"""
assert isinstance(sensor, SensorInstrument)
if sensor in self.mSensors:

Benjamin Jakimow
committed
i = self.mSensors.index(sensor)
self.beginRemoveRows(QModelIndex(), i, i)
self.mSensors.remove(sensor)
self.endRemoveRows()
def rowCount(self, parent = QModelIndex()):

Benjamin Jakimow
committed
return len(self.mSensors)
def removeRows(self, row, count , parent=QModelIndex()):
self.beginRemoveRows(parent, row, row+count-1)

Benjamin Jakimow
committed
toRemove = self.mSensors[row:row + count]
for tsd in toRemove:

Benjamin Jakimow
committed
self.mSensors.remove(tsd)
self.endRemoveRows()

Benjamin Jakimow
committed
def getIndexFromSensor(self, sensor)->QModelIndex:
return self.createIndex(self.mSensors.index(sensor), 0)

Benjamin Jakimow
committed
def getSensorFromIndex(self, index)->SensorInstrument:
if index.isValid():

Benjamin Jakimow
committed
return self.mSensors[index.row()]
return None
def columnCount(self, parent = QModelIndex()):

Benjamin Jakimow
committed
return len(self.mColumNames)
def data(self, index, role = Qt.DisplayRole):
if role is None or not index.isValid():
return None
value = None

Benjamin Jakimow
committed
columnName = self.mColumNames[index.column()]
sensor = self.getSensorFromIndex(index)
assert isinstance(sensor, SensorInstrument)

Benjamin Jakimow
committed
if role in [Qt.DisplayRole, Qt.EditRole]:
if columnName == self.mCN_Name:
value = sensor.name()

Benjamin Jakimow
committed
elif columnName == self.mCN_Band:
value = str(sensor.nb)

Benjamin Jakimow
committed
elif columnName == self.mCN_Images:
n = 0
for tsd in self.TS.tsds(sensor=sensor):
assert isinstance(tsd, TimeSeriesDatum)
n += len(tsd.sources())
value = n
elif columnName == self.mCN_Dates:
value = len(self.TS.tsds(sensor=sensor))
elif columnName == self.mCN_ID:
value = sensor.id()

Benjamin Jakimow
committed
elif columnName == self.mCN_WL:
value = 'undefined'
else:
value = ','.join([str(w) for w in sensor.wl])
if sensor.wlu is not None:
value += '[{}]'.format(sensor.wlu)
elif role == Qt.CheckStateRole:

Benjamin Jakimow
committed
if columnName == self.mCN_Name:

Benjamin Jakimow
committed
elif role == Qt.UserRole:
value = sensor

Benjamin Jakimow
committed
return value
def setData(self, index, value, role=None):
if role is None or not index.isValid():
return None

Benjamin Jakimow
committed
columnName = self.mColumNames[index.column()]
sensor = self.getSensorFromIndex(index)
assert isinstance(sensor, SensorInstrument)

Benjamin Jakimow
committed
b = False
if role == Qt.EditRole and columnName == self.mCN_Name:
if len(value) == 0: #do not accept empty strings

Benjamin Jakimow
committed
b = False
else:
sensor.setName(str(value))
b = True
#data changed will be emitted via signal from sensor in updateSensor

Benjamin Jakimow
committed
return b
def flags(self, index):
if index.isValid():

Benjamin Jakimow
committed
columnName = self.mColumNames[index.column()]
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable

Benjamin Jakimow
committed
if columnName in [self.mCN_Name]: #allow check state
flags = flags | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
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:

Benjamin Jakimow
committed
return self.mColumNames[col]
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
return col
return None
class SensorListModel(QAbstractListModel):
def __init__(self, TS, parent=None, *args):
super(SensorListModel, self).__init__()
assert isinstance(TS, TimeSeries)
self.TS = TS
self.TS.sigSensorAdded.connect(self.insertSensor)
self.TS.sigSensorRemoved.connect(self.removeSensor)
self.mSensors = []
self.sortColumnIndex = 0
self.sortOrder = Qt.AscendingOrder
253
254
255
256
257
258
259
260
261
262
263
264
265
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
self.insertSensor(s)
def insertSensor(self, sensor, i=None):
assert isinstance(sensor, SensorInstrument)
if i is None:
i = len(self.mSensors)
self.beginInsertRows(QModelIndex(), i, i)
self.mSensors.insert(i, sensor)
self.endInsertRows()
def removeSensor(self, sensor):
assert isinstance(sensor, SensorInstrument)
if sensor in self.mSensors:
i = self.mSensors.index(sensor)
self.beginRemoveRows(QModelIndex(), i, i)
self.mSensors.remove(sensor)
self.endRemoveRows()
def sort(self, col, order):
if self.rowCount() == 0:
return
self.layoutAboutToBeChanged.emit()
r = order != Qt.AscendingOrder
self.mSensors.sort(key = lambda s:s.name(), reverse=r)
self.layoutChanged.emit()
def rowCount(self, parent = QModelIndex()):
return len(self.mSensors)
def removeRows(self, row, count , parent=QModelIndex()):
self.beginRemoveRows(parent, row, row+count-1)
toRemove = self.mSensors[row:row + count]
for tsd in toRemove:
self.mSensors.remove(tsd)
self.endRemoveRows()
def sensor2idx(self, sensor):
assert isinstance(sensor, SensorInstrument)
return self.createIndex(self.mSensors.index(sensor), 0)
def idx2sensor(self, index):
assert isinstance(index, QModelIndex)
if index.isValid():
return self.mSensors[index.row()]
return None
def data(self, index, role = Qt.DisplayRole):
if role is None or not index.isValid():
return None
value = None
sensor = self.idx2sensor(index)
assert isinstance(sensor, SensorInstrument)
if role == Qt.DisplayRole:
value = sensor.name()
elif role == Qt.UserRole:
value = sensor
return value
def flags(self, index):
if index.isValid():
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