Commit fa24d506 authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

MapVisualization refactoring and code review I:


simplified MapViews and lazy rendering
Signed-off-by: Benjamin Jakimow's avatarbenjamin.jakimow <benjamin.jakimow@geo.hu-berlin.de>
parent ac2f0da1
......@@ -78,9 +78,6 @@ except Exception as ex:
import eotimeseriesviewer.externals.qps.utils
eotimeseriesviewer.externals.qps.utils.UI_DIRECTORIES.append(DIR_UI)
# import QPS modules
from eotimeseriesviewer.externals.qps.crosshair.crosshair import CrosshairStyle, CrosshairWidget, CrosshairMapCanvasItem, CrosshairDialog, getCrosshairStyle
......@@ -90,6 +87,7 @@ from eotimeseriesviewer.externals.qps.models import Option, OptionListModel, Tre
from eotimeseriesviewer.externals.qps.speclib.spectrallibraries import SpectralLibrary, SpectralProfile, SpectralLibraryPanel
from eotimeseriesviewer.externals.qps.maptools import *
from eotimeseriesviewer.externals.qps.utils import *
eotimeseriesviewer.externals.qps.utils.UI_DIRECTORIES.append(DIR_UI)
def messageLog(msg, level=None):
"""
......
......@@ -7,12 +7,13 @@ from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from osgeo import gdal
from eotimeseriesviewer.externals.qps.layerproperties import *
from eotimeseriesviewer.utils import loadUI, qgisInstance
from qps.classification.classificationscheme \
from eotimeseriesviewer.externals.qps.classification.classificationscheme \
import ClassificationSchemeWidget, ClassificationScheme, ClassInfo, ClassificationSchemeComboBox
from eotimeseriesviewer.timeseries import TimeSeriesDatum
from qps.layerproperties import *
#the QgsProject(s) and QgsMapLayerStore(s) to search for QgsVectorLayers
MAP_LAYER_STORES = [QgsProject.instance()]
......@@ -482,6 +483,8 @@ class LabelAttributeTypeWidgetDelegate(QStyledItemDelegate):
model.setData(index, w.currentData(Qt.UserRole), Qt.EditRole)
class LabelingDock(QgsDockWidget, loadUI('labelingdock.ui')):
def __init__(self, parent=None):
super(LabelingDock, self).__init__(parent)
......
......@@ -100,8 +100,8 @@ class TimeSeriesViewerUI(QMainWindow,
from eotimeseriesviewer.sensorvisualization import SensorDockUI
self.dockSensors = addDockWidget(SensorDockUI(self))
from eotimeseriesviewer.mapvisualization import MapViewCollectionDock
self.dockMapViews = addDockWidget(MapViewCollectionDock(self))
from eotimeseriesviewer.mapvisualization import MapViewDock
self.dockMapViews = addDockWidget(MapViewDock(self))
from qps.cursorlocationvalue import CursorLocationInfoDock
self.dockCursorLocation = addDockWidget(CursorLocationInfoDock(self))
......
This diff is collapsed.
This diff is collapsed.
......@@ -27,8 +27,9 @@ from qgis.gui import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
import qps.testing
from qps.utils import file_search
import eotimeseriesviewer.externals.qps.testing
import eotimeseriesviewer.externals.qps
from eotimeseriesviewer.utils import file_search
from osgeo import ogr, osr, gdal, gdal_array
import example
from eotimeseriesviewer import DIR_EXAMPLES
......@@ -44,11 +45,11 @@ def initQgisApplication(*args, **kwds)->QgsApplication:
return QgsApplication.instance()
else:
app = qps.testing.initQgisApplication(*args, **kwds)
import eotimeseriesviewer.externals.qps.testing
app = eotimeseriesviewer.externals.qps.testing.initQgisApplication(*args, **kwds)
import eotimeseriesviewer
eotimeseriesviewer.initEditorWidgets()
eotimeseriesviewer.initAll()
return app
def testRasterFiles()->list:
......@@ -63,7 +64,7 @@ def createTimeSeries(self) -> TimeSeries:
self.assertTrue(len(TS) > 0)
return TS
class TestObjects(qps.testing.TestObjects):
class TestObjects(eotimeseriesviewer.externals.qps.testing.TestObjects):
"""
Creates objects to be used for testing. It is preferred to generate objects in-memory.
"""
......
......@@ -145,7 +145,6 @@ def sensorIDtoProperties(idString:str)->tuple:
return nb, px_size_x, px_size_y, dt, wl, wlu
class SensorInstrument(QObject):
"""
Describes a Sensor Configuration
......@@ -153,13 +152,13 @@ class SensorInstrument(QObject):
SensorNameSettingsPrefix = 'SensorName.'
sigNameChanged = pyqtSignal(str)
LUT_Wavelengths = dict({'B':480,
'G':570,
'R':660,
'nIR':850,
'swIR':1650,
'swIR1':1650,
'swIR2':2150
LUT_Wavelengths = dict({'B': 480,
'G': 570,
'R': 660,
'nIR': 850,
'swIR': 1650,
'swIR1': 1650,
'swIR2': 2150
})
def __init__(self, sid:str, sensor_name:str=None, band_names:list = None):
......@@ -193,21 +192,29 @@ class SensorInstrument(QObject):
import uuid
path = '/vsimem/mockupImage.{}.bsq'.format(uuid.uuid4())
self.mMockupDS = TestObjects.inMemoryImage(path=path, nb=self.nb, eType=self.dataType, ns=2, nl=2)
self.mMockupLayer = QgsRasterLayer(self.mMockupDS.GetFileList()[0])
def mockupLayer(self)->QgsRasterLayer:
#create an in-memory data set
return self.mMockupLayer
def proxyLayer(self)->QgsRasterLayer:
"""
Creates an "empty" layer that can be used as proxy for band names, data types and render styles
:return: QgsRasterLayer
"""
lyr = SensorProxyLayer(self.mMockupDS.GetFileList()[0], name=self.name(), sensor=self)
lyr.nameChanged.connect(lambda l=lyr: self.setName(l.name()))
lyr.setCustomProperty('eotsv/sensorid', self.id())
self.sigNameChanged.connect(lyr.setName)
return lyr
def id(self)->str:
"""
Returns the Sensor id
:return: str
"""
return self.mId
def _sensorSettingsKey(self):
return SensorInstrument.SensorNameSettingsPrefix+self.mId
def setName(self, name:str):
def setName(self, name: str):
"""
Sets the sensor/product name
:param name: str
......@@ -255,6 +262,20 @@ class SensorInstrument(QObject):
return '\n'.join(info)
class SensorProxyLayer(QgsRasterLayer):
def __init__(self, *args, sensor:SensorInstrument, **kwds):
super(SensorProxyLayer, self).__init__(*args, **kwds)
self.mSensor = sensor
def sensor(self)->SensorInstrument:
"""
Returns the SensorInstrument this layer relates to
:return: SensorInstrument
"""
return self.mSensor
def verifyInputImage(datasource):
"""
Checks if an image source can be uses as TimeSeriesDatum, i.e. if it can be read by gdal.Open() and
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Frame</class>
<widget class="QFrame" name="Frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>312</width>
<height>269</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>257</width>
<height>28</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QToolButton" name="btnToggleMapViewVisibility">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Toggle map view visibility</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/mapviewHidden.svg</normaloff>:/timeseriesviewer/icons/mapviewHidden.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="popupMode">
<enum>QToolButton::DelayedPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnToggleCrosshair">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Show/hide crosshair</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/crosshair.svg</normaloff>:/timeseriesviewer/icons/crosshair.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="tbName">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>Map View Title</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QgsLayerTreeView" name="mLayerTreeView">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>261</width>
<height>211</height>
</rect>
</property>
</widget>
<action name="actionToggleMapViewHidden">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/mapviewHidden.svg</normaloff>:/timeseriesviewer/icons/mapviewHidden.svg</iconset>
</property>
<property name="text">
<string>Hide Map View</string>
</property>
<property name="toolTip">
<string>Hide this map view</string>
</property>
</action>
<action name="actionToggleCrosshairVisibility">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/crosshair.svg</normaloff>:/timeseriesviewer/icons/crosshair.svg</iconset>
</property>
<property name="text">
<string>Show/hide Crosshair</string>
</property>
<property name="toolTip">
<string>Show/hide a crosshair</string>
</property>
</action>
<action name="actionSetCrosshairStyle">
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/symbology.svg</normaloff>:/timeseriesviewer/icons/symbology.svg</iconset>
</property>
<property name="text">
<string>Set crosshair style</string>
</property>
</action>
<action name="actionToggleVectorVisibility">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/mIconPolygonLayer.svg</normaloff>
<normalon>:/timeseriesviewer/icons/mIconPolygonLayer.svg</normalon>:/timeseriesviewer/icons/mIconPolygonLayer.svg</iconset>
</property>
<property name="text">
<string>Toogle vector overlay visibility</string>
</property>
<property name="toolTip">
<string>Toogle the visibility of the overlayed vector file</string>
</property>
</action>
<action name="actionToggleRasterVisibility">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>toggleRasterVisibility</string>
</property>
</action>
<action name="actionSetVectorStyle">
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/symbology.svg</normaloff>:/timeseriesviewer/icons/symbology.svg</iconset>
</property>
<property name="text">
<string>Set Vector Style</string>
</property>
<property name="toolTip">
<string>Sets the style of the selected vector layer.</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>QgsLayerTreeView</class>
<extends>QTreeView</extends>
<header>qgis.gui</header>
</customwidget>
</customwidgets>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mapViewPanel</class>
<widget class="QDockWidget" name="mapViewPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>505</width>
<height>335</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>194</width>
<height>335</height>
</size>
</property>
<property name="windowTitle">
<string>Maps &amp;&amp; Map Views</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="btnRemoveMapView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/mActionRemoveMapView.svg</normaloff>:/timeseriesviewer/icons/mActionRemoveMapView.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnAddMapView">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/timeseriesviewer/icons/mActionAddMapView.svg</normaloff>:/timeseriesviewer/icons/mActionAddMapView.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="btnHighlightMapView">
<property name="text">
<string>?</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QToolBox" name="toolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QToolBox::tab {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
border-radius: 5px;
color: black;
}
QToolBox::tab:selected { /* italicize selected tabs */
/*font: italic;*/
color: blue;
}</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="pageMapProperties">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>501</width>
<height>254</height>
</rect>
</property>
<attribute name="label">
<string>Map Properties</string>
</attribute>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>spinBoxMapSizeY</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinBoxMapSizeX">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>