Commit 1a1bea22 authored by benjamin.jakimow@geo.hu-berlin.de's avatar benjamin.jakimow@geo.hu-berlin.de
Browse files

change RenderingDock

improved QGIS interaction
several UI issues and smaler bugs fixed
parent a39e9173
......@@ -8,15 +8,16 @@ logger = logging.getLogger(__file__)
#thanks user "funkwurm" in
#http://stackoverflow.com/questions/28020805/regex-validate-correct-iso8601-date-string-with-time
regISODate = re.compile(r'(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)')
regISODate2 = re.compile(r'([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?')
regISODate1 = re.compile(r'(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)')
regISODate3 = re.compile(r'([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?')
regISODate2 = re.compile(r'(19|20|21\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?')
#regISODate2 = re.compile(r'([12]\d{3}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?')
#https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s07.html
regYYYYMMDD = re.compile(r'(?P<year>[0-9]{4})(?P<hyphen>-?)(?P<month>1[0-2]|0[1-9])(?P=hyphen)(?P<day>3[01]|0[1-9]|[12][0-9])')
regYYYYMMDD = re.compile(r'(?P<year>(19|20)\d\d)(?P<hyphen>-?)(?P<month>1[0-2]|0[1-9])(?P=hyphen)(?P<day>3[01]|0[1-9]|[12][0-9])')
regMissingHypen = re.compile('^\d{8}')
regYYYYMM = re.compile(r'([0-9]{4})-(1[0-2]|0[1-9])')
regYYYYDOY = re.compile(r'(?P<year>[0-9]{4})-?(?P<day>36[0-6]|3[0-5][0-9]|[12][0-9]{2}|0[1-9][0-9]|00[1-9])')
regYYYYDOY = re.compile(r'(?P<year>(19|20)\d\d)-?(?P<day>36[0-6]|3[0-5][0-9]|[12][0-9]{2}|0[1-9][0-9]|00[1-9])')
def matchOrNone(regex, text):
match = regex.search(text)
......@@ -26,7 +27,7 @@ def matchOrNone(regex, text):
return None
def extractDateTimeGroup(text):
match = regISODate2.search(text)
match = regISODate1.search(text)
if match:
matchedText = match.group()
if regMissingHypen.search(matchedText):
......@@ -48,8 +49,10 @@ def extractDateTimeGroup(text):
return None
def datetime64FromYYYYMMDD(yyyymmdd):
return np.datetime64('{}-{}-{}'.format(yyyymmdd[0:4],yyyymmdd[4:6],yyyymmdd[6:8]))
if re.search('^\d{8}$', yyyymmdd):
#insert hyphens
yyyymmdd = '{}-{}-{}'.format(yyyymmdd[0:4],yyyymmdd[4:6],yyyymmdd[6:8])
return np.datetime64(yyyymmdd)
def datetime64FromYYYYDOY(yyyydoy):
return datetime64FromDOY(yyyydoy[0:4], yyyydoy[4:7])
......
......@@ -156,12 +156,16 @@ class QgisTsvBridge(QObject):
self.syncBlocked = False
from main import TimeSeriesViewerUI
from timeseriesviewer.ui.docks import RenderingDockUI
assert isinstance(self.ui, TimeSeriesViewerUI)
assert isinstance(self.ui.dockRendering, RenderingDockUI)
self.ui.dockRendering.sigQgisInteractionRequest.connect(self.onQgisInteractionRequest)
self.cbQgsVectorLayer = self.ui.dockRendering.cbQgsVectorLayer
self.gbQgsVectorLayer = self.ui.dockRendering.gbQgsVectorLayer
self.cbQgsVectorLayer.setEnabled(True)
self.gbQgsVectorLayer.setEnabled(True)
#self.cbQgsVectorLayer.setEnabled(True)
#self.gbQgsVectorLayer.setEnabled(True)
self.qgsMapCanvas = self.iface.mapCanvas()
assert isinstance(self.qgsMapCanvas, QgsMapCanvas)
......@@ -178,6 +182,47 @@ class QgisTsvBridge(QObject):
self.cbQgsVectorLayer.layerChanged.connect(self.onQgsVectorLayerChanged)
self.onQgsVectorLayerChanged(None)
def onQgisInteractionRequest(self, request):
assert isinstance(self.qgsMapCanvas, QgsMapCanvas)
extQgs = SpatialExtent.fromMapCanvas(self.qgsMapCanvas)
assert isinstance(self.TSV, TimeSeriesViewer)
extTsv = self.TSV.spatialTemporalVis.spatialExtent()
assert request in ['tsvCenter2qgsCenter',
'tsvExtent2qgsExtent',
'qgisCenter2tsvCenter',
'qgisExtent2tsvExtent']
if request == 'tsvCenter2qgsCenter':
center = SpatialPoint.fromSpatialExtent(extTsv)
center = center.toCrs(extQgs.crs())
if center:
self.qgsMapCanvas.setCenter(center)
self.qgsMapCanvas.refresh()
if request == 'qgisCenter2tsvCenter':
center = SpatialPoint.fromSpatialExtent(extQgs)
center = center.toCrs(extTsv.crs())
if center:
self.TSV.spatialTemporalVis.setSpatialCenter(center)
if request == 'tsvExtent2qgsExtent':
extent = extTsv.toCrs(extQgs.crs())
if extent:
self.qgsMapCanvas.setExtent(extent)
self.qgsMapCanvas.refresh()
if request == 'qgisExtent2tsvExtent':
extent = extQgs.toCrs(extTsv.crs())
if extent:
self.TSV.spatialTemporalVis.setSpatialExtent(extent)
def syncTsvWithQgs(self, *args):
if self.syncBlocked:
return
......@@ -340,8 +385,6 @@ class TimeSeriesViewerUI(QMainWindow,
#todo: move to QGS_TSV_Bridge
self.dockRendering.cbQgsVectorLayer.setFilters(QgsMapLayerProxyModel.VectorLayer)
#define subset-size behaviour
self.restoreSettings()
......@@ -357,8 +400,8 @@ class TimeSeriesViewerUI(QMainWindow,
from timeseriesviewer import QGIS_TSV_BRIDGE
from timeseriesviewer.main import QgisTsvBridge
b = isinstance(QGIS_TSV_BRIDGE, QgisTsvBridge)
self.dockRendering.gbSyncQgs.setEnabled(b)
self.dockRendering.gbQgsVectorLayer.setEnabled(b)
self.dockRendering.enableQgisSyncronization(b)
#self.dockRendering.gbQgsVectorLayer.setEnabled(b)
def _blockSignals(self, widgets, block=True):
states = dict()
......@@ -691,8 +734,14 @@ class TimeSeriesViewer:
def addTimeSeriesImages(self, files=None):
if files is None:
files = QFileDialog.getOpenFileNames()
s = QSettings('HU-Berlin','HUB TSV')
defDir = s.value('DIR_FILESEARCH')
files = QFileDialog.getOpenFileNames(directory=defDir)
if len(files) > 0 and os.path.exists(files[0]):
dn = os.path.dirname(files[0])
s.setValue('DIR_FILESEARCH', dn)
s = ""
#collect sublayers, if existing
......
......@@ -116,7 +116,7 @@ class SensorTableModel(QAbstractTableModel):
elif columnName == 'id':
value = sensor.id()
elif columnName == 'wl':
if sensor.wavelengths.ndim == 0:
if sensor.wavelengths is None or sensor.wavelengths.ndim == 0:
value = 'undefined'
else:
value = ','.join([str(w) for w in sensor.wavelengths]) +sensor.wavelengthUnits
......
......@@ -98,9 +98,12 @@ class SensorInstrument(QObject):
#find wavelength
wl, wlu = parseWavelengthFromDataSet(ds)
self.wavelengths = np.asarray(wl)
self.wavelengthUnits = wlu
if wl is None:
self.wavelengths = None
self.wavelengthUnits = None
else:
self.wavelengths = np.asarray(wl)
self.wavelengthUnits = wlu
self._id = '{}b{}m'.format(self.nb, self.px_size_x)
if wl is not None:
self._id += ';'.join([str(w) for w in self.wavelengths])+ wlu
......@@ -570,10 +573,10 @@ def parseWavelengthFromDataSet(ds):
wlu = None
#see http://www.harrisgeospatial.com/docs/ENVIHeaderFiles.html for supported wavelength units
regWLkey = re.compile('.*wavelength[_ ]*$')
regWLUkey = re.compile('.*wavelength[_ ]*units?$')
regNumeric = re.compile(r"([-+]?\d*\.\d+|[-+]?\d+)")
regWLU = re.compile('((micro|nano|centi)meters)|(um|nm|mm|cm|m|GHz|MHz)')
regWLkey = re.compile('.*wavelength[_ ]*$', re.I)
regWLUkey = re.compile('.*wavelength[_ ]*units?$', re.I)
regNumeric = re.compile(r"([-+]?\d*\.\d+|[-+]?\d+)", re.I)
regWLU = re.compile('((micro|nano|centi)meters)|(um|nm|mm|cm|m|GHz|MHz)', re.I)
for domain in ds.GetMetadataDomainList():
md = ds.GetMetadata_Dict(domain)
for key, value in md.items():
......@@ -585,7 +588,7 @@ def parseWavelengthFromDataSet(ds):
if wlu is None and regWLUkey.search(key):
match = regWLU.search(value)
if match:
wlu = match.group()
wlu = match.group().lower()
names = ['nanometers', 'micrometers', 'millimeters', 'centimeters', 'decimeters']
si = ['nm', 'um', 'mm', 'cm', 'dm']
if wlu in names:
......
......@@ -37,6 +37,7 @@ class RenderingDockUI(TsvDockWidgetBase, load('renderingdock.ui')):
sigCrsChanged = pyqtSignal(QgsCoordinateReferenceSystem)
sigMapSizeChanged = pyqtSignal(QSize)
sigQgisSyncStateChanged = pyqtSignal(QgisTsvBridge.SyncState)
sigQgisInteractionRequest = pyqtSignal(str)
def __init__(self, parent=None):
super(RenderingDockUI, self).__init__(parent)
......@@ -53,6 +54,11 @@ class RenderingDockUI(TsvDockWidgetBase, load('renderingdock.ui')):
self.btnCrs.crsChanged.connect(self.sigCrsChanged)
#default: disable QgsSync box
#todo: realt-time syncing?
self.frameRTSync.setVisible(False)
self.progressBar.setVisible(False)
self.enableQgisSyncronization(False)
self.mLastSyncState = self.qgsSyncState()
......@@ -60,8 +66,19 @@ class RenderingDockUI(TsvDockWidgetBase, load('renderingdock.ui')):
self.cbSyncQgsMapCenter.stateChanged.connect(self.onSyncStateChanged)
self.cbSyncQgsCRS.stateChanged.connect(self.onSyncStateChanged)
self.btnSetQGISCenter.clicked.connect(lambda : self.sigQgisInteractionRequest.emit('tsvCenter2qgsCenter'))
self.btnSetQGISExtent.clicked.connect(lambda: self.sigQgisInteractionRequest.emit('tsvExtent2qgsExtent'))
self.btnGetQGISCenter.clicked.connect(lambda: self.sigQgisInteractionRequest.emit('qgisCenter2tsvCenter'))
self.btnGetQGISExtent.clicked.connect(lambda: self.sigQgisInteractionRequest.emit('qgisExtent2tsvExtent'))
def enableQgisSyncronization(self, b):
self.gbSyncQgs.setEnabled(b)
if b:
self.gbSyncQgs.setTitle('QGIS')
else:
self.gbSyncQgs.setTitle('QGIS (not available)')
#self.gbQgsVectorLayer.setEnabled(b)
def onSyncStateChanged(self, *args):
......
......@@ -6,24 +6,36 @@
<rect>
<x>0</x>
<y>0</y>
<width>253</width>
<height>159</height>
<width>325</width>
<height>136</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="title">
<string/>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="horizontalSpacing">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="margin">
<property name="rightMargin">
<number>1</number>
</property>
<item row="0" column="0">
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QFrame" name="buttonList">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
......@@ -182,25 +194,30 @@
</layout>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="sensorList">
<property name="margin">
<number>1</number>
</property>
</layout>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item>
<widget class="QFrame" name="sensorList">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</spacer>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>267</width>
<height>50</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
<action name="actionRemoveMapView">
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<height>189</height>
<width>480</width>
<height>175</height>
</rect>
</property>
<property name="minimumSize">
......@@ -30,8 +30,8 @@
<item>
<widget class="QScrollArea" name="scrollAreaMapViews">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>1</horstretch>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
......@@ -51,7 +51,7 @@
<number>1</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
......@@ -67,8 +67,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<height>167</height>
<width>480</width>
<height>153</height>
</rect>
</property>
<property name="sizePolicy">
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>216</height>
<width>260</width>
<height>135</height>
</rect>
</property>
<property name="sizePolicy">
......@@ -47,10 +47,10 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
<number>2</number>
</property>
<property name="margin">
<number>6</number>
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
......@@ -155,17 +155,23 @@
<number>0</number>
</property>
<widget class="QWidget" name="pageMultiBand">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<pointsize>8</pointsize>
</font>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>6</number>
<number>2</number>
</property>
<property name="spacing">
<number>6</number>
<number>2</number>
</property>
<item row="1" column="1">
<widget class="QSlider" name="sliderRed">
......@@ -540,7 +546,7 @@
<widget class="QWidget" name="pageSingleBand">
<property name="font">
<font>
<pointsize>11</pointsize>
<pointsize>8</pointsize>
</font>
</property>
<layout class="QGridLayout" name="gridLayout">
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>206</width>
<height>386</height>
<width>327</width>
<height>359</height>
</rect>
</property>
<property name="windowTitle">
......@@ -235,124 +235,220 @@
</item>
<item>
<widget class="QGroupBox" name="gbSyncQgs">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>230</height>
</size>
</property>
<property name="title">
<string>Sync with QGIS Map on...</string>
<string>QGIS</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="cbSyncQgsMapCenter">
<layout class="QGridLayout" name="gridLayout_2" rowstretch="1,1,0,0" rowminimumheight="23,23,0,0">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="margin">
<number>6</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="1" column="2">
<widget class="QToolButton" name="btnGetQGISExtent">
<property name="toolTip">
<string>Take the spatial map extent from QGIS</string>
</property>
<property name="text">
<string>Center</string>
<string>Get Extent</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<item row="1" column="1">
<widget class="QToolButton" name="btnGetQGISCenter">
<property name="toolTip">
<string>Take the map center from QGIS</string>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="cbSyncQgsCRS">
<property name="text">
<string>CRS</string>
<string>Get Center</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="cbSyncQgsMapExtent">
<item row="0" column="2">
<widget class="QToolButton" name="btnSetQGISExtent">
<property name="toolTip">
<string>Try to set the QGIS map extent to the same spatial extent</string>
</property>
<property name="text">
<string>Exent</string>
<string>Set Extent</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="gbQgsVectorLayer">
<property name="title">
<string>Show Vector Layer</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="collapsed">
<bool>false</bool>
</property>
<property name="saveCheckedState">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_5">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="1">
<widget class="QgsMapLayerComboBox" name="cbQgsVectorLayer">
<item row="3" column="0" colspan="4">
<widget class="QFrame" name="frameRTSync">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="cbSyncQgsMapCenter">
<property name="text">
<string>Center</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbSyncQgsMapExtent">
<property name="text">
<string>Exent</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbSyncQgsCRS">
<property name="text">
<string>CRS</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>