Skip to content
Snippets Groups Projects
timeseries.py 40.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            if len(addedDates) > 0:
                self.sigTimeSeriesDatesAdded.emit(addedDates)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            return len(self.mTSDs)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            return iter(self.mTSDs)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
        def __getitem__(self, slice):
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            return self.mTSDs[slice]
    
    
        def __delitem__(self, slice):
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            self.removeTSDs(slice)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
        def __contains__(self, item):
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            return item in self.mTSDs
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
        def __repr__(self):
            info = []
            info.append('TimeSeries:')
            l = len(self)
            info.append('  Scenes: {}'.format(l))
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            return '\n'.join(info)
    
    
    
    
    class TimeSeriesTableModel(QAbstractTableModel):
    
        def __init__(self, TS, parent=None, *args):
    
            super(TimeSeriesTableModel, self).__init__()
            assert isinstance(TS, TimeSeries)
    
            self.cnDate = 'Date'
            self.cnSensor = 'Sensor'
            self.cnNS = 'ns'
            self.cnNL = 'nl'
            self.cnNB = 'nb'
            self.cnCRS = 'CRS'
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            self.cnImage = 'Images'
    
            self.mColumnNames = [self.cnDate, self.cnSensor, \
                                self.cnNS, self.cnNL, self.cnNB, \
                                self.cnCRS, self.cnImage]
    
            self.TS = TS
            self.sensors = set()
            self.TS.sigTimeSeriesDatesRemoved.connect(self.removeTSDs)
            self.TS.sigTimeSeriesDatesAdded.connect(self.addTSDs)
    
    
            self.items = []
            self.sortColumnIndex = 0
            self.sortOrder = Qt.AscendingOrder
            self.addTSDs([tsd for tsd in self.TS])
    
        def removeTSDs(self, tsds):
            #self.TS.removeDates(tsds)
            for tsd in tsds:
                if tsd in self.TS:
                    #remove from TimeSeries first.
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    self.TS.removeTSDs([tsd])
    
                elif tsd in self.items:
                    idx = self.getIndexFromDate(tsd)
                    self.removeRows(idx.row(), 1)
    
            #self.sort(self.sortColumnIndex, self.sortOrder)
    
    
        def tsdChanged(self, tsd):
            idx = self.getIndexFromDate(tsd)
            self.dataChanged.emit(idx, idx)
    
    
        def sensorsChanged(self, sensor):
    
            i = self.mColumnNames.index(self.cnSensor)
    
            idx0 = self.createIndex(0, i)
            idx1 = self.createIndex(self.rowCount(), i)
            self.dataChanged.emit(idx0, idx1)
    
    
        def addTSDs(self, tsds):
    
    
            for tsd in tsds:
                assert isinstance(tsd, TimeSeriesDatum)
                row = bisect.bisect_left(self.items, tsd)
                self.beginInsertRows(QModelIndex(), row, row)
                self.items.insert(row, tsd)
                self.endInsertRows()
    
                #self.sort(self.sortColumnIndex, self.sortOrder)
    
    
            for tsd in tsds:
                assert isinstance(tsd, TimeSeriesDatum)
                tsd.sigVisibilityChanged.connect(lambda: self.tsdChanged(tsd))
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            for sensor in set([tsd.sensor() for tsd in tsds]):
    
                if sensor not in self.sensors:
                    self.sensors.add(sensor)
    
                    sensor.sigNameChanged.connect(self.sensorsChanged)
    
    
    
    
        def sort(self, col, order):
            if self.rowCount() == 0:
                return
    
            self.layoutAboutToBeChanged.emit()
    
            colName = self.mColumnNames[col]
    
            r = order != Qt.AscendingOrder
    
            if colName in ['date','ns','nl','sensor']:
                self.items.sort(key = lambda d:d.__dict__[colName], reverse=r)
    
            self.layoutChanged.emit()
            s = ""
    
    
        def rowCount(self, parent = QModelIndex()):
            return len(self.items)
    
    
        def removeRows(self, row, count , parent=QModelIndex()):
            self.beginRemoveRows(parent, row, row+count-1)
            toRemove = self.items[row:row+count]
            for tsd in toRemove:
                self.items.remove(tsd)
            self.endRemoveRows()
    
        def getIndexFromDate(self, tsd):
            return self.createIndex(self.items.index(tsd),0)
    
        def getDateFromIndex(self, index):
            if index.isValid():
                return self.items[index.row()]
            return None
    
        def getTimeSeriesDatumFromIndex(self, index):
            if index.isValid():
                i = index.row()
                if i >= 0 and i < len(self.items):
                    return self.items[i]
    
            return None
    
        def columnCount(self, parent = QModelIndex()):
    
            return len(self.mColumnNames)
    
    
        def data(self, index, role = Qt.DisplayRole):
            if role is None or not index.isValid():
                return None
    
            value = None
    
            columnName = self.mColumnNames[index.column()]
    
    
            TSD = self.getTimeSeriesDatumFromIndex(index)
    
            assert isinstance(TSD, TimeSeriesDatum)
    
            keys = list(TSD.__dict__.keys())
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
            tssList = TSD.sources()
    
    
            if role == Qt.DisplayRole or role == Qt.ToolTipRole:
    
                if columnName == self.cnImage:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    value = [os.path.basename(tss.uri()) for tss in tssList]
    
                elif columnName == self.cnSensor:
    
                    if role == Qt.ToolTipRole:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                        value = TSD.sensor().description()
    
                elif columnName == self.cnDate:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    value = '{}'.format(TSD.date())
    
                elif columnName == self.cnImage:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    value = '\n'.join(TSD.sourceUris())
    
                elif columnName == self.cnCRS:
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                    value = '\n'.join([tss.crs().description() for tss in tssList])
    
    
    
                elif columnName in keys:
                    value = TSD.__dict__[columnName]
                else:
                    s = ""
            elif role == Qt.CheckStateRole:
    
                if columnName == self.cnDate:
    
                    value = Qt.Checked if TSD.isVisible() else Qt.Unchecked
    
            elif role == Qt.BackgroundColorRole:
                value = None
            elif role == Qt.UserRole:
                value = TSD
    
            return value
    
        def setData(self, index, value, role=None):
            if role is None or not index.isValid():
                return None
    
            if role is Qt.UserRole:
    
                s = ""
    
    
            columnName = self.mColumnNames[index.column()]
    
    
            TSD = self.getTimeSeriesDatumFromIndex(index)
    
            if columnName == self.cnDate and role == Qt.CheckStateRole:
    
                TSD.setVisibility(value != Qt.Unchecked)
                return True
            else:
                return False
    
            return False
    
        def flags(self, index):
            if index.isValid():
    
                columnName = self.mColumnNames[index.column()]
    
                flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
    
                if columnName == self.cnDate: #allow check state
    
                    flags = flags | Qt.ItemIsUserCheckable
    
                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.mColumnNames[col]
    
            elif orientation == Qt.Vertical and role == Qt.DisplayRole:
                return col
            return None
    
    def getSpatialPropertiesFromDataset(ds):
        assert isinstance(ds, gdal.Dataset)
    
        nb = ds.RasterCount
        nl = ds.RasterYSize
        ns = ds.RasterXSize
        proj = ds.GetGeoTransform()
        px_x = float(abs(proj[1]))
        px_y = float(abs(proj[5]))
    
        crs = QgsCoordinateReferenceSystem(ds.GetProjection())
    
        return nb, nl, ns, crs, px_x, px_y
    
    
    
    
    
    
    
    
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    def extractWavelengths(ds):
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
        # see http://www.harrisgeospatial.com/docs/ENVIHeaderFiles.html for supported wavelength units
    
        regWLkey = re.compile('.*wavelength[_ ]*$', re.I)
        regWLUkey = re.compile('.*wavelength[_ ]*units?$', re.I)
        regNumeric = re.compile(r"([-+]?\d*\.\d+|[-+]?\d+)", re.I)
        regWLU = re.compile('((micro|nano|centi)meters)|(um|nm|mm|cm|m|GHz|MHz)', re.I)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
        if isinstance(ds, QgsRasterLayer):
            lyr = ds
            md = [l.split('=') for l in str(lyr.metadata()).splitlines() if 'wavelength' in l.lower()]
            #see http://www.harrisgeospatial.com/docs/ENVIHeaderFiles.html for supported wavelength units
            for kv in md:
                key, value = kv
                key = key.lower()
                if key == 'center wavelength':
                    tmp = re.findall(r'\d*\.\d+|\d+', value) #find floats
                    if len(tmp) == 0:
                        tmp = re.findall(r'\d+', value) #find integers
                    if len(tmp) == lyr.bandCount():
                        wl = [float(w) for w in tmp]
    
                if key == 'wavelength units':
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
                        wlu = match.group()
    
                    names = ['nanometers','micrometers','millimeters','centimeters','decimenters']
                    si   = ['nm','um','mm','cm','dm']
    
                    if wlu in names:
                        wlu = si[names.index(wlu)]
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
        elif isinstance(ds, gdal.Dataset):
    
            for domain in ds.GetMetadataDomainList():
                md = ds.GetMetadata_Dict(domain)
                for key, value in md.items():
                    if wl is None and regWLkey.search(key):
                        numbers = regNumeric.findall(value)
                        if len(numbers) == ds.RasterCount:
                            wl = [float(n) for n in numbers]
    
                    if wlu is None and regWLUkey.search(key):
                        match = regWLU.search(value)
                        if match:
                            wlu = match.group().lower()
                        names = ['nanometers', 'micrometers', 'millimeters', 'centimeters', 'decimeters']
                        si = ['nm', 'um', 'mm', 'cm', 'dm']
                        if wlu in names:
                            wlu = si[names.index(wlu)]
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
    if __name__ == '__main__':
    
        q  = QApplication([])
        p = QProgressBar()
        p.setRange(0,0)
    
    Benjamin Jakimow's avatar
    Benjamin Jakimow committed
    
    
        print(convertMetricUnit(100, 'cm', 'm'))
        print(convertMetricUnit(1, 'm', 'um'))