Newer
Older

benjamin.jakimow@geo.hu-berlin.de
committed
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 columnIndex(self, name):
return self.columNames.index(name)
def signaler(self, idxUL, idxLR):
if idxUL.isValid():
plotStyle = self.idx2plotStyle(idxUL)
cname = self.columNames[idxUL.column()]
if cname in [self.cnSensor,self.cnStyle]:
self.sigVisibilityChanged.emit(plotStyle)
if cname in [self.cnExpression]:
self.sigDataChanged.emit(plotStyle)
@staticmethod
def bandIndex2bandKey(i):
assert isinstance(i, int)
assert i >= 0
return 'b{}'.format(i+1)
@staticmethod
def bandKey2bandIndex(key):
match = PlotSettingsModel.regBandKeyExact.search(key)
assert match
idx = int(match.group()[1:])-1
return idx
def requiredBandsIndices(self, sensor):
"""
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, TemporalProfilePlotStyle)
expression = p.expression()
#remove leading & tailing "
bandKeys = PlotSettingsModel.regBandKey.findall(expression)
for bandIndex in [self.bandKey2bandIndex(key) for key in bandKeys]:
bandIndices.add(bandIndex)

benjamin.jakimow@geo.hu-berlin.de
committed
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, TemporalProfilePlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
for plotStyle in plotStyles:
assert isinstance(plotStyle, TemporalProfilePlotStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
self.beginInsertRows(QModelIndex(), i, i + len(plotStyles)-1)
for j, plotStyle in enumerate(plotStyles):
assert isinstance(plotStyle, TemporalProfilePlotStyle)
self.mPlotSettings.insert(i+j, plotStyle)
self.endInsertRows()
def removePlotStyles(self, plotStyles):
"""
Removes PlotStyle instances
:param plotStyles: TemporalProfilePlotStyle | [list-of-TemporalProfilePlotStyle]
"""
if isinstance(plotStyles, PlotStyle):
plotStyles = [plotStyles]
assert isinstance(plotStyles, list)
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()
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()
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
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
columnName = self.columNames[index.column()]
plotStyle = self.idx2plotStyle(index)
if isinstance(plotStyle, TemporalProfilePlotStyle):
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, TemporalProfilePlotStyle):
if role in [Qt.DisplayRole, Qt.EditRole]:
if columnName == self.cnExpression:
plotStyle.setExpression(value)
result = True
elif columnName == self.cnStyle:
if isinstance(value, PlotStyle):
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.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'):
return
#todo
assert isinstance(sensorPlotSettings, TemporalProfilePlotStyle)
#todo: avoid dumps
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, TemporalProfilePlotStyle):
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)
from timeseriesviewer import OPENGL_AVAILABLE, SETTINGS
#self.line.setVisible(False)
#self.listWidget.setVisible(False)
self.stackedWidget.setCurrentWidget(self.page2D)
if OPENGL_AVAILABLE:
l = self.page3D.layout()
l.removeWidget(self.labelDummy3D)
from pyqtgraph.opengl import GLViewWidget
l.addWidget(self.plotWidget3D)
else:
self.plotWidget3D = None
#pi = self.plotWidget2D.plotItem
#ax = DateAxis(orientation='bottom', showValues=True)
#pi.layout.addItem(ax, 3,2)
self.baseTitle = self.windowTitle()
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)
def date2num(d):
d2 = d.astype(datetime.datetime)
o = d2.toordinal()
#assert d == num2date(o)
return o
def num2date(n):
if n < 1:
n = 1
return np.datetime64('{:04}-{:02}-{:02}'.format(d.year,d.month,d.day), 'D')
class TemporalProfile(QObject):
_mNextID = 0
@staticmethod
def nextID():
n = TemporalProfile._mNextID
TemporalProfile._mNextID += 1
return n
def __init__(self, timeSeries, spatialPoint):
super(TemporalProfile, self).__init__()
assert isinstance(spatialPoint, SpatialPoint)
self.mUpdated = False
self.mName = '#{}'.format(self.mID)
self.mLoaded = self.mLoadedMax = 0
self.initMetadata()
self.updateLoadingStatus()
def initMetadata(self):
for tsd in self.mTimeSeries:
assert isinstance(tsd, TimeSeriesDatum)
meta = {'doy':tsd.doy,
'date':str(tsd.date)}
self.updateData(tsd, meta)
sigNameChanged = pyqtSignal(str)
def setName(self, name):
if name != self.mName:
self.mName = name
self.sigNameChanged.emit(self.mName)
def name(self):
return self.mName
def updateData(self, tsd, values):
assert isinstance(tsd, TimeSeriesDatum)
assert isinstance(values, dict)
if tsd not in self.mData.keys():
self.mData[tsd] = {}
self.mData[tsd].update(values)
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
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
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
self.updateLoadingStatus()
self.mUpdated = True
def qgsFieldFromKeyValue(self, key, value):
t = type(value)
if t in [int, float]:
fLen = 0
fPrec = 0
fComm = ''
fType = ''
f = QgsField(key, QVariant.Double, 'double', 40, 5)
else:
f = QgsField(key, QVariant.String, 'text', 40, 5)
return f
def dataFromExpression(self, sensor, expression, dateType='date'):
assert dateType in ['date','doy']
x = []
y = []
if not isinstance(expression, QgsExpression):
expression = QgsExpression(expression)
assert isinstance(expression, QgsExpression)
fields = QgsFields()
f = QgsFeature()
for i, tsd in enumerate(sorted([tsd for tsd in self.mData.keys() if tsd.sensor == sensor])):
assert isinstance(tsd, TimeSeriesDatum)
data = self.mData[tsd]
if i == 0:
#initialize the fields
for k in data.keys():
field = self.qgsFieldFromKeyValue(k, data[k])
fields.append(field)
f.setFields(fields)
for k, v in data.items():
f.setAttribute(k,v)
value = expression.evaluate(f)
if value is not None:
if dateType == 'date':
x.append(date2num(tsd.date))
elif dateType == 'doy':
x.append(tsd.doy)
y.append(value)
return np.asarray(x), np.asarray(y)
def data(self, tsd):
assert isinstance(tsd, TimeSeriesDatum)
if self.hasData(tsd):
return self.mData[tsd]
else:
return {}
def loadingStatus(self):
"""
Returns the loading status in terms of single pixel values.
nLoaded = sum of single band values
nLoadedMax = potential maximum of band values that might be loaded
:return: (nLoaded, nLoadedMax)
"""
return self.mLoaded, self.mLoadedMax
def updateLoadingStatus(self):
"""
Calculates and the loading status in terms of single pixel values.
nMax is the sum of all bands over each TimeSeriesDatum and Sensors
"""
self.mLoaded = self.mLoadedMax
for tsd in self.mTimeSeries:
assert isinstance(tsd, TimeSeriesDatum)
self.mLoadedMax += tsd.sensor.nb
if self.hasData(tsd):
self.mLoaded += len([k for k in self.mData[tsd].keys() if k.startswith('b')])
def hasData(self,tsd):
assert isinstance(tsd, TimeSeriesDatum)
return tsd in self.mData.keys()
def __repr__(self):
return 'TemporalProfile {}'.format(self.mCoordinate)
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(timeSeries, TimeSeries)
if not isinstance(ui, ProfileViewDockUI):
print('UI : {}'.format(ui))
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.TV.setSortingEnabled(False)
self.plot2D = ui.plotWidget2D
self.plot2D.plotItem.getViewBox().sigMoveToDate.connect(self.sigMoveToDate)
self.plot3D = ui.plotWidget3D
self.tpCollection = TemporalProfileCollection()
self.tpCollectionListModel = TemporalProfileCollectionListModel(self.tpCollection)
self.ui.tableViewTemporalProfiles.setModel(self.tpCollection)
self.ui.cbTemporalProfile3D.setModel(self.tpCollectionListModel)
#self.pxCollection.sigPixelAdded.connect(self.requestUpdate)
#self.pxCollection.sigPixelRemoved.connect(self.clear)
self.plotSettingsModel = None
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.updatePlot)
self.sigMoveToDate.connect(self.onMoveToDate)
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
self.initActions()
def createNewPlotStyle(self):
l = len(self.tpCollection)
if l > 0:
TP = self.tpCollection[0]
PS = TemporalProfilePlotStyle(TP)
sensors = self.TS.Sensors.keys()
if len(sensors) > 0:
PS.setSensor(sensors[0])
self.plotSettingsModel.insertPlotStyles([PS])
pdi = PS.createPlotItem(self.plot2D)
plotItem = self.plot2D.getPlotItem()
assert isinstance(plotItem, pg.PlotItem)
plotItem.addItem(pdi)
plotItem.update()
#plotItem.addDataItem(pdi)
plotItem.plot().sigPlotChanged.emit(plotItem)
self.updatePlot()
def initActions(self):
self.ui.btnAddView.setDefaultAction(self.ui.actionAddView)
self.ui.btnRemoveView.setDefaultAction(self.ui.actionRemoveView)
self.ui.btnRefresh2D.setDefaultAction(self.ui.actionRefresh)
self.ui.btnRefresh3D.setDefaultAction(self.ui.actionRefresh)
self.ui.actionRefresh.triggered.connect(self.updatePlot)
self.ui.actionAddView.triggered.connect(self.createNewPlotStyle)
#todo: self.ui.actionRemoveView.triggered.connect(self.plotSettingsModel.createPlotStyle)
def setTimeSeries(self, TS):
assert isinstance(TS, TimeSeries)
self.TS = TS
self.plotSettingsModel = PlotSettingsModel(self.tpCollection, self.plot2D, parent=self)
self.plotSettingsModel.sigVisibilityChanged.connect(self.setVisibility)
self.plotSettingsModel.sigDataChanged.connect(self.requestUpdate)
self.plotSettingsModel.rowsInserted.connect(self.onRowsInserted)
# self.plotSettingsModel.modelReset.connect(self.updatePersistantWidgets)
self.TV.setModel(self.plotSettingsModel)
self.delegate = PlotSettingsWidgetDelegate(self.TV, self.TS, self.tpCollectionListModel)
self.delegate.setItemDelegates(self.TV)
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)
if DEBUG:
print(t)
# QgsApplication.processEvents()
def requestUpdate(self, *args):
self.updateRequested = True
#next time
def updatePersistentWidgets(self):

benjamin.jakimow@geo.hu-berlin.de
committed
model = self.TV.model()
if isinstance(model, PlotSettingsModel):
colExpression = model.columnIndex(model.cnExpression)
colStyle = model.columnIndex(model.cnStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
for row in range(model.rowCount()):
idxExpr = model.createIndex(row, colExpression)
idxStyle = model.createIndex(row, colStyle)
#self.TV.openPersistentEditor(idxExpr)
#self.TV.openPersistentEditor(idxStyle)

benjamin.jakimow@geo.hu-berlin.de
committed
#self.TV.openPersistentEditor(model.createIndex(start, colStyle))
s = ""
def onRowsInserted(self, parent, start, end):
model = self.TV.model()
if isinstance(model, PlotSettingsModel):
colExpression = model.columnIndex(model.cnExpression)
colStyle = model.columnIndex(model.cnStyle)
while start <= end:
idxExpr = model.createIndex(start, colExpression)
idxStyle = model.createIndex(start, colStyle)
self.TV.openPersistentEditor(idxExpr)
self.TV.openPersistentEditor(idxStyle)
start += 1
#self.TV.openPersistentEditor(model.createIndex(start, colStyle))
s = ""
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):
"""
Loads a temporal profile for a single or multiple geometries.
:param spatialPoints: SpatialPoint | [list-of-SpatialPoints]
"""
if not isinstance(self.plotSettingsModel, PlotSettingsModel):
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 = []
LUT_bandIndices = dict()
# Define a which (new) bands need to be loaded for each sensor
for sensor in self.TS.Sensors:
LUT_bandIndices[sensor] = self.plotSettingsModel.requiredBandsIndices(sensor)
#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)
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)
existingBandKeys = [k for k in TP.data(tsd).keys() if PlotSettingsModel.regBandKeyExact.search(k)]
existingBandIndices = set([PlotSettingsModel.bandKey2bandIndex(k) for k in existingBandKeys])
need2load = requiredIndices.difference(existingBandIndices)
missingIndices = missingIndices.union(need2load)
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, TemporalProfilePlotStyle)
self.setVisibility2D(sensorPlotStyle)
def setVisibility2D(self, sensorPlotStyle):
self.plot2D.update()
if sensorView is None:
for sv in self.plotSettingsModel.items:
self.setData(sv)
else:
assert isinstance(sensorView, TemporalProfilePlotStyle)
self.setData2D(sensorView)
@QtCore.pyqtSlot()
def updatePlot(self):
if isinstance(self.plotSettingsModel, PlotSettingsModel):
if DEBUG:
pi = self.plot2D.getPlotItem()
piDataItems = pi.listDataItems()
locations = set()
for plotSetting in self.plotSettingsModel:
assert isinstance(plotSetting, TemporalProfilePlotStyle)
locations.add(plotSetting.temporalProfile().mCoordinate)
for pdi in plotSetting.mPlotItems:
assert isinstance(pdi, TemporalProfilePlotDataItem)
pdi.updateStyle()
pdi.updateData()
#2. load pixel data
self.loadCoordinate(list(locations))
# https://github.com/pyqtgraph/pyqtgraph/blob/5195d9dd6308caee87e043e859e7e553b9887453/examples/customPlot.py
return
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
# prepare QGIS environment
if sys.platform == 'darwin':
PATH_QGS = r'/Applications/QGIS.app/Contents/MacOS'
os.environ['GDAL_DATA'] = r'/usr/local/Cellar/gdal/1.11.3_1/share'
else:
# assume OSGeo4W startup
PATH_QGS = os.environ['QGIS_PREFIX_PATH']
assert os.path.exists(PATH_QGS)
qgsApp = QgsApplication([], True)
QApplication.addLibraryPath(r'/Applications/QGIS.app/Contents/PlugIns')
QApplication.addLibraryPath(r'/Applications/QGIS.app/Contents/PlugIns/qgis')
qgsApp.setPrefixPath(PATH_QGS, True)
qgsApp.initQgis()
gb = QGroupBox()
gb.setTitle('Sandbox')
PL = PixelLoader()
if False:
files = ['observationcloud/testdata/2014-07-26_LC82270652014207LGN00_BOA.bsq',
'observationcloud/testdata/2014-08-03_LE72270652014215CUB00_BOA.bsq'
]
else:
from timeseriesviewer.utils import file_search
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
searchDir = r'H:\LandsatData\Landsat_NovoProgresso'
files = file_search(searchDir, '*227065*band4.img', recursive=True)
#files = files[0:3]
lyr = QgsRasterLayer(files[0])
coord = lyr.extent().center()
crs = lyr.crs()
l = QVBoxLayout()
btnStart = QPushButton()
btnStop = QPushButton()
prog = QProgressBar()
tboxResults = QPlainTextEdit()
tboxResults.setMaximumHeight(300)
tboxThreads = QPlainTextEdit()
tboxThreads.setMaximumHeight(200)
label = QLabel()
label.setText('Progress')
def showProgress(n,m,md):
prog.setMinimum(0)
prog.setMaximum(m)
prog.setValue(n)
info = []
for k, v in md.items():
info.append('{} = {}'.format(k,str(v)))
tboxResults.setPlainText('\n'.join(info))
#tboxThreads.setPlainText(PL.threadInfo())
qgsApp.processEvents()
PL.sigPixelLoaded.connect(showProgress)
btnStart.setText('Start loading')
btnStart.clicked.connect(lambda : PL.startLoading(files, coord, crs))
btnStop.setText('Cancel')
btnStop.clicked.connect(lambda: PL.cancelLoading())
lh = QHBoxLayout()
lh.addWidget(btnStart)
lh.addWidget(btnStop)
l.addLayout(lh)
l.addWidget(prog)
l.addWidget(tboxThreads)
l.addWidget(tboxResults)
gb.setLayout(l)
gb.show()
#rs.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);')
#rs.handle.setStyleSheet('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);')
qgsApp.exec_()
qgsApp.exitQgis()
if __name__ == '__main__':
import site, sys
from timeseriesviewer import utils
qgsApp = utils.initQgisApplication()
for date in ['2012-01-01', '2017-12-23']:
dt1 = np.datetime64(date)
n = date2num(dt1)
dt2 = num2date(n)
assert dt1 == dt2
STVis = SpectralTemporalVisualization(ui)
STVis.setTimeSeries(TS)
import example.Images
from timeseriesviewer import file_search
files = file_search(os.path.dirname(example.Images.__file__), '*.tif')
TS.addFiles(files)
cp1 = SpatialPoint(ext.crs(),ext.center())
cp2 = SpatialPoint(ext.crs(), ext.center())
cp3 = SpatialPoint(ext.crs(), ext.center().x()+500, ext.center().y()+250)
STVis.loadCoordinate(cp1)
STVis.loadCoordinate(cp2)
STVis.loadCoordinate(cp3)
STVis.createNewPlotStyle()