Skip to content
Snippets Groups Projects
sensorvisualization.py 11 KiB
Newer Older
  • Learn to ignore specific revisions
  • # -*- coding: utf-8 -*-
    """
    /***************************************************************************
    
                                  -------------------
            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.gui import *
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    from qgis.PyQt.QtCore import *
    from qgis.PyQt.QtGui import *
    from qgis.PyQt.QtWidgets import *
    
    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
    
            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 = ""
    
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
    class SensorTableModel(QAbstractTableModel):
        def __init__(self, TS, parent=None, *args):
    
            super(SensorTableModel, self).__init__()
            assert isinstance(TS, TimeSeries)
    
    
            # 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)
    
            self.TS.sigTimeSeriesDatesAdded.connect(self.onTimeSeriesSourceChanges)
            self.TS.sigTimeSeriesDatesRemoved.connect(self.onTimeSeriesSourceChanges)
            self.mSensors = []
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            for s in self.TS.sensors():
    
        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)
    
            i = self.rowCount()
            self.beginInsertRows(QModelIndex(),i,i)
            self.mSensors.append(sensor)
            sensor.sigNameChanged.connect(lambda *args, sensor=sensor: self.updateSensor(sensor))
            self.endInsertRows()
    
        def updateSensor(self, sensor:SensorInstrument):
    
            assert isinstance(sensor, SensorInstrument)
    
            if sensor in self.mSensors:
                tl = self.getIndexFromSensor(sensor)
                br = self.createIndex(tl.row(), self.columnCount()-1)
                self.dataChanged.emit(tl, br)
    
        def removeSensor(self, sensor:SensorInstrument):
            """
            Removes a SensorInstrument
            :param sensor: SensorInstrument
            """
            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 rowCount(self, parent = QModelIndex()):
    
    
    
        def removeRows(self, row, count , parent=QModelIndex()):
            self.beginRemoveRows(parent, row, row+count-1)
    
            toRemove = self.mSensors[row:row + count]
    
        def getIndexFromSensor(self, sensor)->QModelIndex:
            return self.createIndex(self.mSensors.index(sensor), 0)
    
        def getSensorFromIndex(self, index)->SensorInstrument:
    
            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.mColumNames[index.column()]
    
    
            sensor = self.getSensorFromIndex(index)
            assert isinstance(sensor, SensorInstrument)
    
    
            if role in [Qt.DisplayRole, Qt.EditRole]:
    
                if columnName == self.mCN_Name:
    
    
                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:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    if sensor.wl is None or sensor.wl.ndim == 0:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                        value = ','.join([str(w) for w in sensor.wl])
                        if sensor.wlu is not None:
                            value += '[{}]'.format(sensor.wlu)
    
    
            elif role == Qt.CheckStateRole:
    
            elif role == Qt.UserRole:
                value = sensor
    
            return value
    
        def setData(self, index, value, role=None):
            if role is None or not index.isValid():
                return None
    
    
            columnName = self.mColumNames[index.column()]
    
    
            sensor = self.getSensorFromIndex(index)
            assert isinstance(sensor, SensorInstrument)
    
            b = False
            if role == Qt.EditRole and columnName == self.mCN_Name:
    
                if len(value) == 0: #do not accept empty strings
    
                    b = False
                else:
                    sensor.setName(str(value))
                    b = True
    
            #data changed will be emitted via signal from sensor in updateSensor
    
    
        def flags(self, index):
            if index.isValid():
    
                columnName = self.mColumNames[index.column()]
    
                flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
    
                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:
    
            elif orientation == Qt.Vertical and role == Qt.DisplayRole:
                return col
            return None
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    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
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            for s in self.TS.sensors():
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                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