Commit 3b83fdce authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

refactoring


timeseries.py: fixed CRS error in sensor mockup datasets
mapvisualization.py:  if existent MapView.currentLayer() returns a none-mockup SensorProxyLayer instance from a visible map canvas

Signed-off-by: Benjamin Jakimow's avatarBenjamin Jakimow <benjamin.jakimow@geo.hu-berlin.de>
parent 38b1380a
......@@ -116,6 +116,7 @@ def initResources():
initQtResources(pathlib.Path(__file__).parent)
def initEditorWidgets():
"""
Initialises QgsEditorWidgets
......
This diff is collapsed.
......@@ -874,7 +874,8 @@ class MapCanvas(QgsMapCanvas):
viewPortMapLayers = [l for l in self.layers() if isinstance(l, QgsMapLayer)]
viewPortRasterLayers = [l for l in viewPortMapLayers if isinstance(l, QgsRasterLayer) and SpatialExtent.fromLayer(l).toCrs(self.crs()).contains(pointGeo)]
viewPortRasterLayers = [l for l in viewPortMapLayers if isinstance(l, QgsRasterLayer) and
SpatialExtent.fromLayer(l).toCrs(self.crs()).contains(pointGeo)]
viewPortSensorLayers = [l for l in viewPortRasterLayers if isinstance(l, SensorProxyLayer)]
viewPortVectorLayers = [l for l in viewPortMapLayers if isinstance(l, QgsVectorLayer)]
......@@ -935,13 +936,16 @@ class MapCanvas(QgsMapCanvas):
if isinstance(refSensorLayer, SensorProxyLayer):
m = menu.addMenu('Raster stretch...')
action = m.addAction('Linear')
action.triggered.connect(lambda *args, lyr=refSensorLayer: self.stretchToExtent(self.spatialExtent(), 'linear_minmax', layer=lyr, p=0.0))
action.triggered.connect(lambda *args, lyr=refSensorLayer:
self.stretchToExtent(self.spatialExtent(), 'linear_minmax', layer=lyr, p=0.0))
action = m.addAction('Linear 5%')
action.triggered.connect(lambda *args, lyr=refSensorLayer: self.stretchToExtent(self.spatialExtent(), 'linear_minmax', layer=lyr, p=0.05))
action.triggered.connect(lambda *args, lyr=refSensorLayer:
self.stretchToExtent(self.spatialExtent(), 'linear_minmax', layer=lyr, p=0.05))
action = m.addAction('Gaussian')
action.triggered.connect(lambda *args, lyr=refSensorLayer: self.stretchToExtent(self.spatialExtent(), 'gaussian', layer=lyr, n=3))
action.triggered.connect(lambda *args, lyr=refSensorLayer:
self.stretchToExtent(self.spatialExtent(), 'gaussian', layer=lyr, n=3))
menu.addSeparator()
......@@ -967,7 +971,6 @@ class MapCanvas(QgsMapCanvas):
visibleLayers = viewPortRasterLayers + viewPortVectorLayers
for mapLayer in visibleLayers:
#sub = m.addMenu(mapLayer.name())
if isinstance(mapLayer, SensorProxyLayer):
name = os.path.basename(mapLayer.source())
else:
......
......@@ -141,7 +141,7 @@ class MapView(QFrame):
self.mDummyCanvas.setVisible(False)
self.mLayerTree = QgsLayerTree()
self.mLayerTreeMapCanvasBridget = QgsLayerTreeMapCanvasBridge(self.mLayerTree, self.mDummyCanvas)
self.mLayerTreeMapCanvasBridge = QgsLayerTreeMapCanvasBridge(self.mLayerTree, self.mDummyCanvas)
# self.mLayerTreeModel = QgsLayerTreeModel(self.mLayerTree)
self.mLayerTreeModel = MapViewLayerTreeModel(self.mLayerTree)
......@@ -255,8 +255,7 @@ class MapView(QFrame):
if layer not in self.mSensorLayerList:
for c in self.mapCanvases():
c.setCurrentLayer(layer)
else:
s = ""
return True
def addSpectralProfileLayer(self):
"""Adds the EOTSV Spectral Profile Layer"""
......@@ -456,6 +455,10 @@ class MapView(QFrame):
mapCanvas.setStyleSheet(styleOff)
def currentMapCanvas(self) -> MapCanvas:
"""
Returns the MapCanvas that was clicked / used last
:return: MapCanvas
"""
if not isinstance(self.mMapWidget, MapWidget):
return None
canvases = sorted(self.mMapWidget.mapViewCanvases(self),
......@@ -467,10 +470,20 @@ class MapView(QFrame):
def currentLayer(self) -> QgsMapLayer:
"""
Returns the current map layer, i.e. that selected in the map layer tree view
:return:
Returns the current map layer, i.e. that selected in the map layer tree view.
If this is a proxy layer, the MapView will try to return a "real" layer from a MapCanvas
:return: QgsMapLayer
"""
return self.mLayerTreeView.currentLayer()
cl = self.mLayerTreeView.currentLayer()
if isinstance(cl, SensorProxyLayer):
sensor = cl.sensor()
for c in [c for c in self.mapCanvases() if c.tsd().sensor() == sensor]:
for l in c.layers():
if isinstance(l, SensorProxyLayer):
return l
return cl
def crosshairStyle(self) -> CrosshairStyle:
"""
......@@ -670,17 +683,24 @@ class MapViewLayerTreeViewMenuProvider(QgsLayerTreeViewMenuProvider):
view = self.layerTreeView()
currentGroup = view.currentGroupNode()
currentLayer = view.currentLayer()
currentCanvas = self.mapView().currentMapCanvas()
isSensorGroup = isinstance(currentGroup, QgsLayerTreeGroup) and currentGroup.customProperty(
KEY_SENSOR_GROUP) in [True, 'true']
isSensorLayer = isinstance(currentLayer, SensorProxyLayer)
mv = self.mapView().mapWidget()
mv: MapView = self.mapView()
mw: MapWidget = mv.mapWidget()
mw.setCurrentMapView(mv)
if isSensorLayer:
# the current layer is an "empty" proxy layer. use one from a visible map canvas instead
pass
from eotimeseriesviewer.main import EOTimeSeriesViewer
eotsv = EOTimeSeriesViewer.instance()
if not isinstance(eotsv, EOTimeSeriesViewer):
return
menu = QMenu(view)
assert isinstance(mv, MapWidget)
assert isinstance(mw, MapWidget)
if isinstance(currentLayer, QgsMapLayer):
# zoom to layer
menu.addAction(eotsv.actionZoomToLayer())
......
......@@ -20,18 +20,15 @@
"""
# noinspection PyPep8Naming
import sys, os
from qgis.core import *
from qgis.gui import *
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.timeseries import TimeSeries, SensorInstrument, TimeSeriesDate
from eotimeseriesviewer.utils import loadUi
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from qgis.gui import QgsDockWidget
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.timeseries import TimeSeries, SensorInstrument, TimeSeriesDate, TimeSeriesSource
from eotimeseriesviewer.utils import loadUi
class SensorDockUI(QgsDockWidget):
def __init__(self, parent=None):
super(SensorDockUI, self).__init__(parent)
......@@ -52,7 +49,6 @@ class SensorDockUI(QgsDockWidget):
s = ""
class SensorTableModel(QAbstractTableModel):
def __init__(self, timeSeries: TimeSeries, parent=None, *args):
......@@ -80,7 +76,7 @@ class SensorTableModel(QAbstractTableModel):
for s in self.TS.sensors():
self.addSensor(s)
def onTimeSeriesSourceChanges(self, timeSeriesDates:list):
def onTimeSeriesSourceChanges(self, timeSeriesDates: list):
"""
Reaction on changes in the time series data sources
:param timeSeriesDates: list
......@@ -93,45 +89,42 @@ class SensorTableModel(QAbstractTableModel):
for sensor in sensors:
self.updateSensor(sensor)
def addSensor(self, sensor:SensorInstrument):
def addSensor(self, sensor: SensorInstrument):
"""
Adds a sensor
:param sensor: SensorInstrument
"""
assert isinstance(sensor, SensorInstrument)
i = self.rowCount()
self.beginInsertRows(QModelIndex(),i,i)
self.beginInsertRows(QModelIndex(), i, i)
self.mSensors.append(sensor)
sensor.sigNameChanged.connect(lambda *args, sensor=sensor: self.updateSensor(sensor))
sensor.sigNameChanged.connect(lambda *args, s=sensor: self.updateSensor(s))
self.endInsertRows()
def updateSensor(self, sensor:SensorInstrument):
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)
br = self.createIndex(tl.row(), self.columnCount() - 1)
self.dataChanged.emit(tl, br)
def removeSensor(self, sensor:SensorInstrument):
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 rowCount(self, parent=QModelIndex()):
return len(self.mSensors)
def removeRows(self, row, count , parent=QModelIndex()):
self.beginRemoveRows(parent, row, row+count-1)
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)
......@@ -145,10 +138,10 @@ class SensorTableModel(QAbstractTableModel):
return self.mSensors[index.row()]
return None
def columnCount(self, parent = QModelIndex()):
def columnCount(self, parent=QModelIndex()):
return len(self.mColumNames)
def data(self, index, role = Qt.DisplayRole):
def data(self, index, role=Qt.DisplayRole):
if role is None or not index.isValid():
return None
......@@ -206,27 +199,27 @@ class SensorTableModel(QAbstractTableModel):
assert isinstance(sensor, SensorInstrument)
b = False
if role == Qt.EditRole and columnName == self.mCN_Name:
if len(value) == 0: #do not accept empty strings
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
# data changed will be emitted via signal from sensor in updateSensor
return b
def index(self, row:int , col: int, parent: QModelIndex=None):
def index(self, row: int, col: int, parent: QModelIndex = None):
return self.createIndex(row, col, self.mSensors[row])
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
if columnName in [self.mCN_Name]: # allow check state
flags = flags | Qt.ItemIsUserCheckable | Qt.ItemIsEditable
return flags
#return item.qt_flags(index.column())
# return item.qt_flags(index.column())
return None
def headerData(self, col, orientation, role):
......@@ -238,6 +231,7 @@ class SensorTableModel(QAbstractTableModel):
return col + 1
return None
class SensorListModel(QAbstractListModel):
def __init__(self, timeSeries: TimeSeries, parent=None, *args):
......@@ -276,16 +270,14 @@ class SensorListModel(QAbstractListModel):
self.layoutAboutToBeChanged.emit()
r = order != Qt.AscendingOrder
self.mSensors.sort(key = lambda s:s.name(), reverse=r)
self.mSensors.sort(key=lambda s: s.name(), reverse=r)
self.layoutChanged.emit()
def rowCount(self, parent = QModelIndex()):
def rowCount(self, parent=QModelIndex()):
return len(self.mSensors)
def removeRows(self, row, count , parent=QModelIndex()):
self.beginRemoveRows(parent, row, row+count-1)
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)
......@@ -301,7 +293,7 @@ class SensorListModel(QAbstractListModel):
return self.mSensors[index.row()]
return None
def data(self, index, role = Qt.DisplayRole):
def data(self, index, role=Qt.DisplayRole):
if role is None or not index.isValid():
return None
......@@ -315,12 +307,11 @@ class SensorListModel(QAbstractListModel):
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 item.qt_flags(index.column())
return None
def headerData(self, col, orientation, role):
......@@ -330,4 +321,4 @@ class SensorListModel(QAbstractListModel):
return self.columnames[col]
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
return col
return None
\ No newline at end of file
return None
......@@ -37,18 +37,20 @@ from eotimeseriesviewer.utils import file_search
from osgeo import ogr, osr, gdal, gdal_array
import qgis.testing
import example
from eotimeseriesviewer import DIR_EXAMPLES, DIR_QGIS_RESOURCES, DIR_UI
from eotimeseriesviewer import DIR_EXAMPLES, DIR_QGIS_RESOURCES, DIR_UI, DIR_REPO
from eotimeseriesviewer.timeseries import TimeSeries
from eotimeseriesviewer.externals.qps.resources import findQGISResourceFiles
from eotimeseriesviewer.externals.qps.testing import *
from eotimeseriesviewer.externals.qps.resources import initQtResources
class EOTSVTestCase(TestCase):
@classmethod
def setUpClass(cls):
if DIR_QGIS_RESOURCES.is_dir():
initQtResources(DIR_QGIS_RESOURCES)
initQtResources(DIR_REPO / 'eotimeseriesviewer' / 'externals')
eotsv_resources = DIR_UI / 'eotsv_resources_rc.py'
assert eotsv_resources.is_file(), \
'eotsv_resources_rc.py not compiled. run python scripts/compile_resourcefiles.py first.'
......@@ -73,6 +75,7 @@ class EOTSVTestCase(TestCase):
print('Close blocking {} "{}"'.format(w.__class__.__name__, w.windowTitle()))
w.close()
def testRasterFiles() -> list:
return list(file_search(os.path.dirname(example.__file__), '*.tif', recursive=True))
......@@ -85,6 +88,7 @@ def createTimeSeries(self) -> TimeSeries:
self.assertTrue(len(TS) > 0)
return TS
class TestObjects(eotimeseriesviewer.externals.qps.testing.TestObjects):
"""
Creates objects to be used for testing. It is preferred to generate objects in-memory.
......
This diff is collapsed.
......@@ -9,7 +9,6 @@ from eotimeseriesviewer.externals.qps.resources import compileResourceFiles
from eotimeseriesviewer.utils import file_search
def compileEOTSVResourceFiles():
dir1 = os.path.join(DIR_REPO, 'eotimeseriesviewer')
......
......@@ -37,7 +37,6 @@ from eotimeseriesviewer.tests import TestObjects, EOTSVTestCase
from eotimeseriesviewer.main import *
class TestMain(EOTSVTestCase):
def tearDown(self):
eotsv = EOTimeSeriesViewer.instance()
if isinstance(eotsv, EOTimeSeriesViewer):
......@@ -100,8 +99,6 @@ class TestMain(EOTSVTestCase):
self.showGui(edit)
def test_TimeSeriesViewer(self):
from eotimeseriesviewer.main import EOTimeSeriesViewer
TSV = EOTimeSeriesViewer()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment