Newer
Older
p2.setAttribute('date', '{}'.format(tsd.mDate))
p2.setAttribute('doy', int(tsd.mDOY))
p2.setAttribute('sensor', tsd.mSensor.name())
profiles2.append(p2)
self.ui.dockSpectralLibrary.SLW.setCurrentSpectra(profiles2)
elif mapToolKey == MapTools.CursorLocation:
self.ui.dockCursorLocation.loadCursorLocation(spatialPoint, mapCanvas)
else:
s = ""
pass
def messageBar(self)->QgsMessageBar:
"""
Returns the QgsMessageBar that is used to show messages in the TimeSeriesViewer UI.
:return: QgsMessageBar
"""

Benjamin Jakimow
committed
return self.ui.mMapWidget.messageBar()
def loadTimeSeriesDefinition(self, path:str=None, n_max:int=None, runAsync=True):
"""
Loads a time series definition file
:param path:
:param n_max:
:return:
"""
if not (isinstance(path, str) and os.path.isfile(path)):
defFile = s.value('file_ts_definition')
defDir = None
if defFile is not None:
defDir = os.path.dirname(defFile)
filters = "CSV (*.csv *.txt);;" + \
"All files (*.*)"
path, filter = QFileDialog.getOpenFileName(caption='Load Time Series definition', directory=defDir, filter=filters)
if path is not None and os.path.exists(path):
self.clearTimeSeries()
progressDialog = self._createProgressDialog()
self.mTimeSeries.loadFromFile(path, n_max=n_max, progressDialog=progressDialog, runAsync=runAsync)

Benjamin Jakimow
committed
def createMapView(self, name:str=None)->MapView:

Benjamin Jakimow
committed
Creates a new MapView.
:return: MapView
return self.ui.dockMapViews.createMapView(name=name)
def mapViews(self)->typing.List[MapView]:
"""
Returns all MapViews
:return: [list-of-MapViews]
"""
return self.ui.dockMapViews[:]
def icon(self)->QIcon:
"""
Returns the EO Time Series Viewer icon
:return: QIcon
"""
import eotimeseriesviewer
return eotimeseriesviewer.icon()
def temporalProfiles(self)->list:
"""
Returns collected temporal profiles
:return: [list-of-TemporalProfiles]
"""
return self.spectralTemporalVis.temporalProfileLayer()[:]
def logMessage(self, message:str, tag:str, level):
"""
"""
if tag == LOG_MESSAGE_TAG and level in [Qgis.Critical, Qgis.Warning]:
self.messageBar().pushMessage(tag, message, level)
def onSensorAdded(self, sensor:SensorInstrument):
knownName = eotsvSettings.sensorName(sensor.id())
if isinstance(knownName, str) and len(knownName) > 0:
sensor.setName(knownName)
sensor.sigNameChanged.connect(lambda *args, s=sensor: self.onSensorNameChanged(sensor))
def onSensorNameChanged(self, sensor:SensorInstrument):
# save changed names to settings
from eotimeseriesviewer.settings import saveSensorName
if sensor in self.sensors():
saveSensorName(sensor)

benjamin.jakimow@geo.hu-berlin.de
committed
def onTimeSeriesChanged(self, *args):
if not self.mSpatialMapExtentInitialized:
if len(self.mTimeSeries) > 0:
if len(self.ui.dockMapViews) == 0:
self.ui.dockMapViews.createMapView()
extent = self.timeSeries().maxSpatialExtent()
if isinstance(extent, SpatialExtent):
self.ui.dockMapViews.setCrs(extent.crs())
self.ui.mMapWidget.setSpatialExtent(extent)
self.mSpatialMapExtentInitialized = True
else:
self.mSpatialMapExtentInitialized = False
print('Failed to calculate max. spatial extent of TimeSeries with length {}'.format(len(self.timeSeries())))
lastDate = self.ui.mMapWidget.currentDate()
if lastDate:
tsd = self.timeSeries().findDate(lastDate)
else:
tsd = self.timeSeries()[0]
self.setCurrentDate(tsd)

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

benjamin.jakimow@geo.hu-berlin.de
committed
if len(self.mTimeSeries) == 0:

benjamin.jakimow@geo.hu-berlin.de
committed
self.mSpatialMapExtentInitialized = False
def mapWidget(self)->MapWidget:
"""
Returns the MapWidget that contains all map canvases.
:return: MapWidget
"""

Benjamin Jakimow
committed
return self.ui.mMapWidget
def saveTimeSeriesDefinition(self):
defFile = s.value('FILE_TS_DEFINITION')
if defFile is not None:
defFile = os.path.dirname(defFile)
filters = "CSV (*.csv *.txt);;" + \
"All files (*.*)"
path, filter = QFileDialog.getSaveFileName(caption='Save Time Series definition', filter=filters, directory=defFile)
path = self.mTimeSeries.saveToFile(path)
if path is not None:
s.setValue('FILE_TS_DEFINITION', path)
def loadTimeSeriesStack(self):
from eotimeseriesviewer.stackedbandinput import StackedBandInputDialog
d = StackedBandInputDialog(parent=self.ui)
if d.exec_() == QDialog.Accepted:
self.addTimeSeriesImages(writtenFiles)
def loadExampleTimeSeries(self, n:int=None, loadAsync=True):

Benjamin Jakimow
committed
"""
Loads an example time series
:param n: int, max. number of images to load. Useful for developer test-cases
"""
import example.Images
exampleDataDir = os.path.dirname(example.__file__)
rasterFiles = list(file_search(exampleDataDir, '*.tif', recursive=True))
vectorFiles = list(file_search(exampleDataDir, re.compile(r'.*\.(gpkg|shp)$'), recursive=True))

Benjamin Jakimow
committed
if isinstance(n, bool) or not isinstance(n, int):

Benjamin Jakimow
committed
n = min(n, len(rasterFiles))

Benjamin Jakimow
committed
n = max(1, n)
self.addTimeSeriesImages(rasterFiles[0:n], loadAsync=loadAsync)
if len(vectorFiles) > 0:
self.addVectorData(vectorFiles)
for lyr in QgsProject.instance().mapLayers().values():
if isinstance(lyr, QgsVectorLayer) and lyr.source() in vectorFiles:
renderer = lyr.renderer()
if lyr.geometryType() == QgsWkbTypes.PolygonGeometry and isinstance(renderer, QgsSingleSymbolRenderer):
renderer = renderer.clone()
symbol = renderer.symbol()
if isinstance(symbol, QgsFillSymbol):
symbol.setOpacity(0.25)
lyr.setRenderer(renderer)
s = ""
def timeSeries(self)->TimeSeries:
"""
Returns the TimeSeries instance.
:return: TimeSeries
"""
return self.mTimeSeries
# noinspection PyMethodMayBeStatic
def tr(self, message):
"""Get the translation for a string using Qt translation API.
We implement this ourselves since we do not inherit QObject.
:param message: String for translation.
:type message: str, QString
:returns: Translated version of message.
:rtype: QString
"""
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass

benjamin.jakimow@geo.hu-berlin.de
committed
return QCoreApplication.translate('HUBTSV', message)
"""Removes the plugin menu item and icon """
self.iface.removeToolBarIcon(self.action)
def clearLayoutWidgets(self, L):
if L is not None:
while L.count():
w = L.takeAt(0)
if w.widget():
w.widget().deleteLater()

Benjamin Jakimow
committed
QApplication.processEvents()
def addVectorData(self, files=None)->list:
"""
Adds vector data
:param files: vector layer sources
:return: [list-of-QgsVectorLayers]
"""
vectorLayers = []
defDir = s.value('DIR_FILESEARCH')

Benjamin Jakimow
committed
filters = QgsProviderRegistry.instance().fileVectorFilters()
files, filter = QFileDialog.getOpenFileNames(directory=defDir, filter=filters)

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

Benjamin Jakimow
committed
if len(files) > 0 and os.path.exists(files[0]):
dn = os.path.dirname(files[0])
s.setValue('DIR_FILESEARCH', dn)
if files:
from eotimeseriesviewer.mapvisualization import MapView

Benjamin Jakimow
committed
from .externals.qps.layerproperties import subLayers

Benjamin Jakimow
committed
for f in files:
vectorLayers.extend(subLayers(QgsVectorLayer(f)))
if len(vectorLayers) > 0:
QgsProject.instance().addMapLayers(vectorLayers)
for mapView in self.mapViews():
assert isinstance(mapView, MapView)
for l in vectorLayers:
mapView.addLayer(l)

Benjamin Jakimow
committed
def addTimeSeriesImages(self, files: list, loadAsync=True):
"""
Adds images to the time series
:param files:
"""

Benjamin Jakimow
committed
if files is None:
s = settings()
filters = QgsProviderRegistry.instance().fileRasterFilters()
files, filter = QFileDialog.getOpenFileNames(directory=defDir, filter=filters)
if len(files) > 0 and os.path.exists(files[0]):
dn = os.path.dirname(files[0])
progressDialog = self._createProgressDialog()
progressDialog.setRange(0, len(files))
progressDialog.setLabelText('Start loading {} images....'.format(len(files)))
self.mTimeSeries.addSources(files, progressDialog=progressDialog, runAsync=loadAsync)
self.mTimeSeries.beginResetModel()
self.mTimeSeries.clear()
self.mTimeSeries.endResetModel()
class SaveAllMapsDialog(QDialog, loadUI('saveallmapsdialog.ui')):
def __init__(self, parent=None):
super(SaveAllMapsDialog, self).__init__(parent)
self.setupUi(self)
self.setWindowTitle('Save Maps')
assert isinstance(self.fileWidget, QgsFileWidget)
assert isinstance(self.cbFileType, QComboBox)
self.fileWidget.setStorageMode(QgsFileWidget.GetDirectory)
formats = [('Portable Network Graphics (*.png)', 'PNG'),
('Joint Photographic Experts Group (*.jpg)', 'JPG'),
('Windows Bitmap (*.bmp)', 'BMP'),
('Portable Bitmap (*.pbm)', 'PBM'),
('Portable Graymap (*.pgm)', 'PGM'),
('Portable Pixmap (*.ppm)', 'PPM'),
('X11 Bitmap (*.xbm)', 'XBM'),
('X11 Pixmap (*.xpm)', 'XPM'),
]
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
for t in formats:
self.cbFileType.addItem(t[0], userData=t[1])
self.fileWidget.fileChanged.connect(self.validate)
self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(lambda : self.setResult(QDialog.Accepted))
self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(lambda : self.setResult(QDialog.Rejected))
self.validate()
def validate(self, *args):
b = os.path.isdir(self.directory())
self.buttonBox.button(QDialogButtonBox.Save).setEnabled(b)
def setDirectory(self, path:str):
assert os.path.isdir(path)
self.fileWidget.setFilePath(path)
def directory(self)->str:
"""
Returns the selected directory
:return: str
"""
return self.fileWidget.filePath()
def fileType(self)->str:
"""
Returns the selected file type
:return:
"""
return self.cbFileType.currentData(Qt.UserRole)
def disconnect_signal(signal):
while True:
try:
signal.disconnect()
except TypeError:
break