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

Benjamin Jakimow
committed
EO Time Series Viewer
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

benjamin.jakimow@geo.hu-berlin.de
committed
File "D:\Programs\OSGeo4W\apps\Python27\lib\multiprocessing\managers.py", line
528, in start
self._address = reader.recv()
EOFError

benjamin.jakimow@geo.hu-berlin.de
committed
see https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing
see https://github.com/CleanCut/green/issues/103

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

benjamin.jakimow@geo.hu-berlin.de
committed
path = os.path.abspath(os.path.join(sys.exec_prefix, '../../bin/pythonw.exe'))
if os.path.exists(path):
multiprocessing.set_executable(path)
sys.argv = [ None ]
import qgis.utils
from qgis.core import *
from qgis.gui import *

benjamin.jakimow@geo.hu-berlin.de
committed
import qgis.utils
from eotimeseriesviewer.utils import *
from eotimeseriesviewer.timeseries import *
from eotimeseriesviewer.profilevisualization import SpectralTemporalVisualization
from eotimeseriesviewer import SpectralProfile, SpectralLibrary, SpectralLibraryPanel
from eotimeseriesviewer.externals.qps.maptools import MapTools, CursorLocationMapTool, QgsMapToolSelect, QgsMapToolSelectionHandler
from eotimeseriesviewer.externals.qps.cursorlocationvalue import CursorLocationInfoModel, CursorLocationInfoDock
import eotimeseriesviewer.labeling
EXTRA_SPECLIB_FIELDS = [
QgsField('date', QVariant.String, 'varchar'),
QgsField('doy', QVariant.Int, 'int'),
QgsField('sensor', QVariant.String, 'varchar')
]

benjamin.jakimow@geo.hu-berlin.de
committed
class TimeSeriesViewerUI(QMainWindow,
loadUI('timeseriesviewer.ui')):
def __init__(self, parent=None):
"""Constructor."""
super(TimeSeriesViewerUI, self).__init__(parent)
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
self.addActions(self.findChildren(QAction))
from eotimeseriesviewer import TITLE, icon, __version__
self.setWindowTitle('{} ({})'.format(TITLE, __version__))
self.setWindowIcon(icon())
if sys.platform == 'darwin':
self.menuBar().setNativeMenuBar(False)
# set button default actions -> this will show the action icons as well
# I don't know why this is not possible in the QDesigner when QToolButtons are
# placed outside a toolbar
area = None
def addDockWidget(dock):
"""
shortcut to add a created dock and return it
:param dock:
:return:
"""
self.addDockWidget(area, dock)
return dock
area = Qt.LeftDockWidgetArea
# self.dockRendering = addDockWidget(docks.RenderingDockUI(self))
from eotimeseriesviewer.labeling import LabelingDock
self.dockLabeling = addDockWidget(LabelingDock(self))
self.dockLabeling.setHidden(True)
from eotimeseriesviewer.sensorvisualization import SensorDockUI
self.dockSensors = addDockWidget(SensorDockUI(self))
from eotimeseriesviewer.mapvisualization import MapViewDock
self.dockMapViews = addDockWidget(MapViewDock(self))
self.dockCursorLocation = addDockWidget(CursorLocationInfoDock(self))
# self.tabifyDockWidget(self.dockMapViews, self.dockRendering)
self.tabifyDockWidget(self.dockSensors, self.dockCursorLocation)

benjamin.jakimow@geo.hu-berlin.de
committed
area = Qt.BottomDockWidgetArea
# from timeseriesviewer.mapvisualization import MapViewDockUI
# self.dockMapViews = addDockWidget(MapViewDockUI(self))
self.dockTimeSeries = addDockWidget(TimeSeriesDockUI(self))
from eotimeseriesviewer.profilevisualization import ProfileViewDockUI
self.dockProfiles = addDockWidget(ProfileViewDockUI(self))
from eotimeseriesviewer.labeling import LabelingDock
self.dockLabeling = addDockWidget(LabelingDock(self))
area = Qt.LeftDockWidgetArea
self.dockAdvancedDigitizingDockWidget = addDockWidget(QgsAdvancedDigitizingDockWidget(self.dockLabeling.canvas(), self))
self.dockAdvancedDigitizingDockWidget.setVisible(False)
self.tabifyDockWidget(self.dockSensors, self.dockAdvancedDigitizingDockWidget)
panel = SpectralLibraryPanel(None)
panel.setParent(self)
self.dockSpectralLibrary = addDockWidget(panel)
self.tabifyDockWidget(self.dockTimeSeries, self.dockSpectralLibrary)
#except Exception as ex:
# print('Unable to create SpectralLibrary panel', file=sys.stderr)
# print(ex, file=sys.stderr)
# self.dockSpectralLibrary = None

Benjamin Jakimow
committed
self.tabifyDockWidget(self.dockTimeSeries, self.dockProfiles)

Benjamin Jakimow
committed
self.tabifyDockWidget(self.dockTimeSeries, self.dockLabeling)

benjamin.jakimow@geo.hu-berlin.de
committed
area = Qt.RightDockWidgetArea
from eotimeseriesviewer.systeminfo import SystemInfoDock

benjamin.jakimow@geo.hu-berlin.de
committed
self.dockSystemInfo = addDockWidget(SystemInfoDock(self))
self.dockSystemInfo.setVisible(False)
for dock in self.findChildren(QDockWidget):
if len(dock.actions()) > 0:
s = ""
self.menuPanels.addAction(dock.toggleViewAction())
self.mMapToolActions = [self.actionZoomPixelScale,
self.actionZoomFullExtent,
self.actionZoomIn,
self.actionZoomOut,
self.actionPan,
self.actionIdentify]
self.dockTimeSeries.raise_()
for a in self.mMapToolActions:
assert isinstance(a, QAction)
a.toggled.connect(self.onActionToggled)
def onActionToggled(self, b:bool):
action = QApplication.instance().sender()
assert isinstance(action, QAction)
otherActions = [a for a in self.mMapToolActions if a != action]
# enable / disable the other maptool actions
if b is True:
for a in otherActions:
assert isinstance(a, QAction)
a.setChecked(False)
else:
otherSelected = [a for a in otherActions if a.isChecked()]
if len(otherSelected) == 0:
action.setChecked(True)
b = self.actionIdentify.isChecked()
self.optionIdentifyCursorLocation.setEnabled(b)
self.optionIdentifySpectralProfile.setEnabled(b)
self.optionIdentifyTemporalProfile.setEnabled(b)
self.optionMoveCenter.setEnabled(b)
def _blockSignals(self, widgets, block=True):
states = dict()
if isinstance(widgets, dict):
for w, block in widgets.items():
states[w] = w.blockSignals(block)
else:
for w in widgets:
states[w] = w.blockSignals(block)
return states
sigSubsetSizeChanged = pyqtSignal(QSize)
def setSubsetSize(self, size, blockSignal=False):
old = self.subsetSize()
w = [self.spinBoxSubsetSizeX, self.spinBoxSubsetSizeY]
if blockSignal:
states = self._blockSignals(w, True)
self.spinBoxSubsetSizeX.setValue(size.width())
self.spinBoxSubsetSizeY.setValue(size.height())
self._setUpdateBehaviour()
if blockSignal:
self._blockSignals(states)
elif old != size:
self.sigSubsetSizeChanged(size)
def setProgress(self, value, valueMax=None, valueMin=0):
p = self.progressBar
if valueMin is not None and valueMin != self.progessBar.minimum():
p.setMinimum(valueMin)
if valueMax is not None and valueMax != self.progessBar.maximum():
p.setMaximum(valueMax)
self.progressBar.setValue(value)
Qgis.Info: 'INFO',
Qgis.Critical: 'INFO',
Qgis.Warning: 'WARNING',
Qgis.Success: 'SUCCESS',

benjamin.jakimow@geo.hu-berlin.de
committed
def showMessage(message, title, level):
v = QgsMessageViewer()
v.setTitle(title)
#print('DEBUG MSG: {}'.format(message))
v.setMessage(message, QgsMessageOutput.MessageHtml \
if message.startswith('<html>')
else QgsMessageOutput.MessageText)
v.showMessage(True)
class TimeSeriesViewer(QgisInterface, QObject):
_instance = None
@staticmethod
def instance():
"""
Returns the TimeSeriesViewer instance
:return:
"""
return TimeSeriesViewer._instance
sigCurrentLocationChanged = pyqtSignal([SpatialPoint],
[SpatialPoint, QgsMapCanvas])
sigCurrentSpectralProfilesChanged = pyqtSignal(list)
sigCurrentTemporalProfilesChanged = pyqtSignal(list)
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
# assert TimeSeriesViewer.instance() is None
QObject.__init__(self)
QgisInterface.__init__(self)
QApplication.processEvents()

Benjamin Jakimow
committed
self.mMapLayerStore = QgsMapLayerStore()
import eotimeseriesviewer.utils
eotimeseriesviewer.utils.MAP_LAYER_STORES.insert(0, self.mapLayerStore())

Benjamin Jakimow
committed
self.ui = TimeSeriesViewerUI()
assert isinstance(qgis.utils.iface, QgisInterface)

Benjamin Jakimow
committed
# init empty time series
self.mTimeSeries = TimeSeries()

Benjamin Jakimow
committed
self.mTimeSeries.setDateTimePrecision(DateTimePrecision.Day)

benjamin.jakimow@geo.hu-berlin.de
committed
self.mSpatialMapExtentInitialized = False
self.mTimeSeries.sigTimeSeriesDatesAdded.connect(self.onTimeSeriesChanged)
# init other GUI components
# self.ICP = D.scrollAreaSubsetContent.layout()
# D.scrollAreaMapViews.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
# self.BVP = self.ui.scrollAreaMapViews.layout()
# D.dockNavigation.connectTimeSeries(self.TS)
self.ui.dockTimeSeries.setTimeSeries(self.mTimeSeries)
self.ui.dockSensors.setTimeSeries(self.mTimeSeries)
self.spectralTemporalVis = SpectralTemporalVisualization(self.mTimeSeries, self.ui.dockProfiles)

benjamin.jakimow@geo.hu-berlin.de
committed
self.spectralTemporalVis.pixelLoader.sigLoadingFinished.connect(
lambda dt: self.ui.dockSystemInfo.addTimeDelta('Pixel Profile', dt))
assert isinstance(self, TimeSeriesViewer)
from eotimeseriesviewer.mapvisualization import SpatialTemporalVisualization
self.spatialTemporalVis = SpatialTemporalVisualization(self)
# self.spatialTemporalVis.sigLoadingStarted.connect(self.ui.dockRendering.addStartedWork)
# self.spatialTemporalVis.sigLoadingFinished.connect(self.ui.dockRendering.addFinishedWork)
# self.spatialTemporalVis.sigShowProfiles.connect(self.spectralTemporalVis.loadCoordinate)

Benjamin Jakimow
committed
self.spatialTemporalVis.sigShowProfiles.connect(self.onShowProfile)

Benjamin Jakimow
committed
self.ui.dockMapViews.sigCrsChanged.connect(self.spatialTemporalVis.setCrs)
self.ui.dockMapViews.sigMapSizeChanged.connect(self.spatialTemporalVis.setMapSize)
self.ui.dockMapViews.sigMapCanvasColorChanged.connect(self.spatialTemporalVis.setMapBackgroundColor)

Benjamin Jakimow
committed
self.spatialTemporalVis.sigCRSChanged.connect(self.ui.dockMapViews.setCrs)
self.spatialTemporalVis.sigMapSizeChanged.connect(self.ui.dockMapViews.setMapSize)
self.spectralTemporalVis.sigMoveToTSD.connect(self.showTimeSeriesDatum)
self.spectralTemporalVis.ui.actionLoadProfileRequest.triggered.connect(self.ui.actionIdentifyTemporalProfile.trigger)
tstv = self.ui.dockTimeSeries.tableView_TimeSeries
assert isinstance(tstv, TimeSeriesTableView)
tstv.sigMoveToDateRequest.connect(self.showTimeSeriesDatum)
# init map tools
self.mMapTools = []
self.mCurrentMapLocation = None
self.mCurrentMapSpectraLoading = 'TOP'
def initMapToolAction(action, key):
assert isinstance(action, QAction)
assert isinstance(key, str)
assert key in MapTools.mapToolKeys()
action.triggered.connect(lambda: self.setMapTool(key))
action.setProperty('eotsv/maptoolkey', key)
initMapToolAction(self.ui.actionPan, MapTools.Pan)
initMapToolAction(self.ui.actionZoomIn, MapTools.ZoomIn)
initMapToolAction(self.ui.actionZoomOut, MapTools.ZoomOut)
initMapToolAction(self.ui.actionZoomPixelScale, MapTools.ZoomPixelScale)
initMapToolAction(self.ui.actionZoomFullExtent, MapTools.ZoomFull)
initMapToolAction(self.ui.actionIdentify, MapTools.CursorLocation)
initMapToolAction(self.ui.actionSelectFeatures, MapTools.SelectFeature)
assert isinstance(self.ui.actionSelectFeatures, QAction)
self.ui.optionSelectFeaturesRectangle.triggered.connect(self.onSelectFeatureOptionTriggered)
self.ui.optionSelectFeaturesPolygon.triggered.connect(self.onSelectFeatureOptionTriggered)
self.ui.optionSelectFeaturesFreehand.triggered.connect(self.onSelectFeatureOptionTriggered)
self.ui.optionSelectFeaturesRadius.triggered.connect(self.onSelectFeatureOptionTriggered)
m = QMenu()
m.addAction(self.ui.optionSelectFeaturesRectangle)
m.addAction(self.ui.optionSelectFeaturesPolygon)
m.addAction(self.ui.optionSelectFeaturesFreehand)
m.addAction(self.ui.optionSelectFeaturesRadius)
self.ui.actionSelectFeatures.setMenu(m)
# create edit toolbar
tb = self.ui.toolBarEditing
assert isinstance(tb, QToolBar)
tb.addAction(self.ui.dockLabeling.actionToggleEditing())
tb.addAction(self.ui.dockLabeling.actionSaveEdits())
tb.addAction(self.ui.dockLabeling.actionAddFeature())
self.ui.dockLabeling.sigMapExtentRequested.connect(self.setSpatialExtent)
self.ui.dockLabeling.sigMapCenterRequested.connect(self.setSpatialCenter)
initMapToolAction(self.ui.dockLabeling.actionAddFeature(), MapTools.AddFeature)
self.ui.dockLabeling.sigVectorLayerChanged.connect(lambda : self.spatialTemporalVis.setCurrentLayer(self.ui.dockLabeling.currentVectorSource()))
#initMapToolAction(self.ui.dockLabeling., MapTools.AddFeature)
# set default map tool
self.ui.dockCursorLocation.sigLocationRequest.connect(self.ui.actionIdentifyCursorLocationValues.trigger)
self.ui.dockCursorLocation.mLocationInfoModel.setNodeExpansion(CursorLocationInfoModel.ALWAYS_EXPAND)
#D.actionIdentifyMapLayers.triggered.connect(lambda: self.spatialTemporalVis.activateMapTool('identifyMapLayers'))
self.ui.actionAddMapView.triggered.connect(self.spatialTemporalVis.MVC.createMapView)
self.ui.actionAddTSD.triggered.connect(lambda : self.addTimeSeriesImages(None))
self.ui.actionAddVectorData.triggered.connect(lambda : self.addVectorData())
self.ui.actionRemoveTSD.triggered.connect(lambda: self.mTimeSeries.removeTSDs(self.ui.dockTimeSeries.selectedTimeSeriesDates()))
self.ui.actionRefresh.triggered.connect(self.spatialTemporalVis.refresh)
self.ui.actionLoadTS.triggered.connect(self.loadTimeSeriesDefinition)
self.ui.actionClearTS.triggered.connect(self.clearTimeSeries)
self.ui.actionSaveTS.triggered.connect(self.saveTimeSeriesDefinition)
self.ui.actionAddTSExample.triggered.connect(self.loadExampleTimeSeries)
self.ui.actionLoadTimeSeriesStack.triggered.connect(self.loadTimeSeriesStack)
self.ui.actionShowCrosshair.toggled.connect(self.spatialTemporalVis.setCrosshairVisibility)

benjamin.jakimow@geo.hu-berlin.de
committed
from eotimeseriesviewer.widgets import AboutDialogUI
self.ui.actionAbout.triggered.connect(lambda: AboutDialogUI(self.ui).exec_())
self.ui.actionSettings.triggered.connect(self.onShowSettingsDialog)
from eotimeseriesviewer import DOCUMENTATION, SpectralLibrary, SpectralLibraryPanel, SpectralLibraryWidget
self.ui.actionShowOnlineHelp.triggered.connect(lambda: webbrowser.open(DOCUMENTATION))
Loading
Loading full blame...