From 358a888990c9efea9df8cb0c97947eca839fda2e Mon Sep 17 00:00:00 2001
From: "benjamin.jakimow" <benjamin.jakimow@geo.hu-berlin.de>
Date: Tue, 29 May 2018 17:22:10 +0200
Subject: [PATCH] mapvisualization.py map canvases refresh immediately after
 changes of render styles added default spectrum for spectral libraries

---
 make/screenshots.py                      | 15 ++++-
 test/test_spectrallibraries.py           | 28 +++++++++-
 timeseriesviewer/main.py                 | 18 +++++-
 timeseriesviewer/mapvisualization.py     | 25 +++++++--
 timeseriesviewer/profilevisualization.py | 10 ++--
 timeseriesviewer/spectrallibraries.py    | 70 +++++++++++++++++++++++-
 6 files changed, 144 insertions(+), 22 deletions(-)

diff --git a/make/screenshots.py b/make/screenshots.py
index 168a72d1..fa8cd1b4 100644
--- a/make/screenshots.py
+++ b/make/screenshots.py
@@ -55,7 +55,7 @@ assert isinstance(mv1, MapView)
 assert isinstance(mv2, MapView)
 mv1.setTitle('True Color')
 mv2.setTitle('Short-Wave IR')
-
+TSV.spatialTemporalVis.adjustScrollArea()
 #set True Color Bands
 for sensor in [sensorLS, sensorRE]:
     rendering = mv1.sensorWidget(sensor)
@@ -86,6 +86,9 @@ renderer.setGreenBand(4)
 renderer.setBlueBand(3)
 rendering.setRasterRenderer(renderer)
 
+mv1.refreshMapView()
+mv2.refreshMapView()
+
 center = TSV.TS.getMaxSpatialExtent().spatialCenter()
 from timeseriesviewer.mapcanvas import MapTools
 
@@ -94,14 +97,21 @@ TSV.onShowProfile(center, mv1.mapCanvases()[0], MapTools.CursorLocation)
 
 TSV.ui.dockSpectralLibrary.setAddCurrentSpectraToSpeclibMode(True)
 
+
 #collect exemplary profiles
+
+import random
+n = len(mv1.mapCanvases())
+dx = random.sample(range(-500, 500, 30), n)
+dy = random.sample(range(-500, 500, 20), n)
 for i, mc in enumerate(mv1.mapCanvases()):
 
+
+    coordinate = SpatialPoint(center.crs(), center.x()+dx[i], center.y() + dy[i])
     TSV.onShowProfile(center, mc, MapTools.SpectralProfile)
     if i == 10:
         break
 
-
 ps2D_LS_NDVI = TSV.spectralTemporalVis.createNewPlotStyle2D()
 ps2D_RE_NDVI = TSV.spectralTemporalVis.createNewPlotStyle2D()
 
@@ -173,6 +183,7 @@ for dockWidget in TSV.ui.findChildren(QDockWidget):
 
     if name == 'spectralLibraryPanel':
         dockWidget.resize(QSize(800, 250))
+
         makePNG(dockWidget, name)
 
     if name == 'temporalProfilePanel':
diff --git a/test/test_spectrallibraries.py b/test/test_spectrallibraries.py
index f11f34f9..4c3a3705 100644
--- a/test/test_spectrallibraries.py
+++ b/test/test_spectrallibraries.py
@@ -322,7 +322,6 @@ class TestInit(unittest.TestCase):
         fieldName = 'newField'
         sp.setMetadata(fieldName, 'foo', addMissingFields=True)
         sl = SpectralLibrary()
-
         sl.startEditing()
         sl.addAttribute(createQgsField(fieldName, ''))
         sl.commitChanges()
@@ -331,17 +330,19 @@ class TestInit(unittest.TestCase):
         sl = SpectralLibrary()
         sl.addProfiles(sp)
 
-
         sl = SpectralLibrary()
         self.assertTrue(fieldName not in sl.fieldNames())
+        self.assertTrue(len(sl) == 0)
         sl.addProfiles(sp, addMissingFields=False)
         self.assertTrue(fieldName not in sl.fieldNames())
+        self.assertTrue(len(sl) == 1)
 
 
         sl = SpectralLibrary()
         self.assertTrue(fieldName not in sl.fieldNames())
         sl.addProfiles(sp, addMissingFields=True)
         self.assertTrue(fieldName in sl.fieldNames())
+        self.assertTrue(len(sl) == 1)
         p = sl[0]
         self.assertIsInstance(p, SpectralProfile)
         self.assertEqual(p.metadata(fieldName), sp.metadata(fieldName))
@@ -383,10 +384,31 @@ class TestInit(unittest.TestCase):
         v.show()
 
     def test_speclibWidget(self):
+
+        speclib = self.createSpeclib()
+        p = SpectralLibraryWidget()
+        p.addSpeclib(speclib)
+        p.show()
+
+        self.assertEqual(p.speclib(), speclib)
+
         p = SpectralLibraryWidget()
-        p.addSpeclib(self.SPECLIB)
         p.show()
 
+        cs = [speclib[0], speclib[3], speclib[-1]]
+        p.setAddCurrentSpectraToSpeclibMode(False)
+        p.setCurrentSpectra(cs)
+        self.assertTrue(len(p.speclib()) == 0)
+        p.addCurrentSpectraToSpeclib()
+        self.assertTrue(len(p.speclib()) == len(cs))
+        self.assertEqual(p.speclib()[:], cs)
+
+        p.speclib().removeProfiles(p.speclib()[:])
+        self.assertTrue(len(p.speclib()) == 0)
+
+        p.setAddCurrentSpectraToSpeclibMode(True)
+        p.setCurrentSpectra(cs)
+        self.assertTrue(len(p.speclib()) == len(cs))
 
     def test_plotWidget(self):
 
diff --git a/timeseriesviewer/main.py b/timeseriesviewer/main.py
index d399574e..9cd17637 100644
--- a/timeseriesviewer/main.py
+++ b/timeseriesviewer/main.py
@@ -470,6 +470,18 @@ class TimeSeriesViewer(QgisInterface, QObject):
 
         D.dockSpectralLibrary.SLW.sigLoadFromMapRequest.connect(D.actionIdentifySpectralProfile.trigger)
 
+        from timeseriesviewer.spectrallibraries import createQgsField
+        newFields = QgsFields()
+        newFields.append(createQgsField('date', ''))
+        newFields.append(createQgsField('sensorname', ''))
+
+        D.dockSpectralLibrary.speclib().addMissingFields(newFields)
+        names = D.dockSpectralLibrary.speclib().fieldNames()
+        for name in ['sensorname', 'date']:
+            iFrom  = names.index(name)
+        D.dockSpectralLibrary.SLW.tableViewSpeclib.horizontalHeader().moveSection(iFrom, 1)
+
+        s = ""
 
     def initQGISConnection(self):
 
@@ -508,9 +520,9 @@ class TimeSeriesViewer(QgisInterface, QObject):
                 for p in profiles:
                     assert isinstance(p, SpectralProfile)
                     p.setName('Profile {} {}'.format(self.cntSpectralProfile, tsd.date))
-                    p.setMetadata(u'date', u'{}'.format(tsd.date))
-                    p.setMetadata(u'sensorname', u'{}'.format(tsd.sensor.name()))
-                    p.setMetadata(u'sensorid', u'{}'.format(tsd.sensor.id()))
+                    p.setMetadata(u'date', u'{}'.format(tsd.date), addMissingFields=True)
+                    p.setMetadata(u'sensorname', u'{}'.format(tsd.sensor.name()) , addMissingFields=True)
+                    p.setMetadata(u'sensorid', u'{}'.format(tsd.sensor.id()), addMissingFields=True)
 
             self.cntSpectralProfile += 1
             self.ui.dockSpectralLibrary.SLW.setCurrentSpectra(profiles)
diff --git a/timeseriesviewer/mapvisualization.py b/timeseriesviewer/mapvisualization.py
index 8c9da339..f46ba9ac 100644
--- a/timeseriesviewer/mapvisualization.py
+++ b/timeseriesviewer/mapvisualization.py
@@ -87,6 +87,7 @@ class MapViewUI(QFrame, loadUI('mapviewdefinition.ui')):
 
         #w = MapViewSensorSettings(sensor)
         w = MapViewRenderSettings(sensor)
+
         #sizePolicy = QSizePolicy(QSize)
         #w.ui.
         #l = self.renderSettingsLayout
@@ -1135,11 +1136,17 @@ class MapView(QObject):
     def title(self):
         return self.ui.tbName.text()
 
-    def refreshMapView(self, *args):
+    def refreshMapView(self, sensor=None):
+
+        if isinstance(sensor, SensorInstrument):
+            sensorSettings = [self.mSensorViews[sensor]]
+        else:
+            #update all sensors
+            sensorSettings = self.mSensorViews.values()
 
-        for renderSettings in self.mSensorViews.values():
-            assert isinstance(renderSettings, MapViewRenderSettings)
-            renderSettings.applyStyle()
+        for renderSetting in sensorSettings:
+            assert isinstance(renderSetting, MapViewRenderSettings)
+            renderSetting.applyStyle()
 
         #for mapCanvas in self.mapCanvases():
         #    assert isinstance(mapCanvas, MapCanvas)
@@ -1248,6 +1255,7 @@ class MapView(QObject):
 
             #w.showSensorName(False)
             w = self.ui.addSensor(sensor)
+            w.sigRendererChanged.connect(lambda s=sensor : self.refreshMapView(sensor=s))
             #w.sigSensorRendererChanged.connect(self.onSensorRenderingChanged)
             self.mSensorViews[sensor] = w
             s  =""
@@ -1318,6 +1326,7 @@ class MapViewRenderSettings(QgsCollapsibleGroupBox, loadUI('mapviewrendersetting
     LUT_RENDERER[QgsSingleBandGrayRenderer]=SingleBandGrayRendererWidget
     LUT_RENDERER[QgsPalettedRasterRenderer] = PalettedRendererWidget
 
+    sigRendererChanged = pyqtSignal()
     def __init__(self, sensor, parent=None):
         """Constructor."""
         super(MapViewRenderSettings, self).__init__(parent)
@@ -1724,6 +1733,7 @@ class DatumView(QObject):
         mapCanvas.setObjectName('MapCanvas {} {}'.format(mapView.title(), self.TSD.date))
         mapCanvas.blockSignals(True)
         mapCanvas.setMapView(mapView)
+
         mapCanvas.setTSD(self.TSD)
         self.registerMapCanvas(mapView, mapCanvas)
 
@@ -1771,7 +1781,7 @@ class DatumView(QObject):
         assert isinstance(mapCanvas, MapCanvas)
         assert isinstance(mapView, MapView)
         self.mMapCanvases[mapView] = mapCanvas
-
+        mapCanvas.setVisible(mapView.isVisible())
 
 
         #mapView.sigTitleChanged.connect(lambda title : mapCanvas.setSaveFileName('{}_{}'.format(self.TSD.date, title)))
@@ -2543,6 +2553,8 @@ class MapViewCollectionDock(QgsDockWidget, loadUI('mapviewdock.ui')):
         if isinstance(nextShown, MapView):
             self.setCurrentMapView(nextShown)
 
+        for mapView in mapViews:
+            self.sigMapViewAdded.emit(mapView)
 
     def updateButtons(self, *args):
         b = len(self.mMapViews) > 0
@@ -2566,7 +2578,7 @@ class MapViewCollectionDock(QgsDockWidget, loadUI('mapviewdock.ui')):
 
         mapView.sigShowProfiles.connect(self.sigShowProfiles)
         self.mMapViews.addMapView(mapView)
-        self.sigMapViewAdded.emit(mapView)
+        #self.sigMapViewAdded.emit(mapView)
         return mapView
 
 
@@ -2698,6 +2710,7 @@ if __name__ == '__main__':
     else:
 
         w = MapViewRenderSettings(TS.sensors()[0])
+
         w.show()
         w.setRasterRenderer(w.rasterRenderer())
         #renderer2 = w.rasterRenderer()
diff --git a/timeseriesviewer/profilevisualization.py b/timeseriesviewer/profilevisualization.py
index 59c498a3..5b720344 100644
--- a/timeseriesviewer/profilevisualization.py
+++ b/timeseriesviewer/profilevisualization.py
@@ -1389,7 +1389,7 @@ class SpectralTemporalVisualization(QObject):
             for plotStyle in plotStyles:
                 assert isinstance(plotStyle, PlotStyle)
                 for pi in plotStyle.mPlotItems:
-                    self.plot2D.getPlotItem().removeItem(pi)
+                    self.plot2D.plotItem().removeItem(pi)
 
         def on3DPlotStyleRemoved(plotStyles):
             toRemove = []
@@ -1526,7 +1526,7 @@ class SpectralTemporalVisualization(QObject):
         assert isinstance(pdi, TemporalProfilePlotDataItem)
         pdi.sigClicked.connect(self.onProfileClicked2D)
         pdi.sigPointsClicked.connect(self.onPointsClicked2D)
-        self.plot2D.getPlotItem().addItem(pdi)
+        self.plot2D.plotItem.addItem(pdi)
         #self.plot2D.getPlotItem().addItem(pg.PlotDataItem(x=[1, 2, 3], y=[1, 2, 3]))
         #plotItem.addDataItem(pdi)
         #plotItem.plot().sigPlotChanged.emit(plotItem)
@@ -1952,11 +1952,11 @@ class SpectralTemporalVisualization(QObject):
                 plotSetting.temporalProfile().resetUpdatedFlag()
 
 
-        for i in self.plot2D.getPlotItem().dataItems:
+        for i in self.plot2D.plotItem.dataItems:
             i.updateItems()
 
 
-        notInit = [0, 1] == self.plot2D.getPlotItem().getAxis('bottom').range
+        notInit = [0, 1] == self.plot2D.plotItem.getAxis('bottom').range
         if notInit:
             x0 = x1 = None
             for plotSetting in self.plotSettingsModel2D:
@@ -1973,7 +1973,7 @@ class SpectralTemporalVisualization(QObject):
                         x1 = max(pdi.xData.max(), x1)
 
             if x0 is not None:
-                self.plot2D.getPlotItem().setXRange(x0, x1)
+                self.plot2D.plotItem().setXRange(x0, x1)
                 #self.plot2D.xAxisInitialized = True
 
     @QtCore.pyqtSlot()
diff --git a/timeseriesviewer/spectrallibraries.py b/timeseriesviewer/spectrallibraries.py
index ca7f5955..00e5049e 100644
--- a/timeseriesviewer/spectrallibraries.py
+++ b/timeseriesviewer/spectrallibraries.py
@@ -49,6 +49,13 @@ HIDDEN_ATTRIBUTE_PREFIX = '__serialized__'
 CURRENT_SPECTRUM_STYLE = PlotStyle()
 CURRENT_SPECTRUM_STYLE.linePen.setStyle(Qt.SolidLine)
 CURRENT_SPECTRUM_STYLE.linePen.setColor(Qt.green)
+
+
+DEFAULT_SPECTRUM_STYLE = PlotStyle()
+DEFAULT_SPECTRUM_STYLE.linePen.setStyle(Qt.SolidLine)
+DEFAULT_SPECTRUM_STYLE.linePen.setColor(Qt.white)
+
+
 #CURRENT_SPECTRUM_STYLE.linePen
 #pdi.setPen(fn.mkPen(QColor('green'), width=3))
 def gdalDataset(pathOrDataset, eAccess=gdal.GA_ReadOnly):
@@ -741,7 +748,7 @@ class SpectralProfile(QgsFeature):
 
         self.setXUnit(xUnit)
         self.setYUnit(yUnit)
-        self.setStyle(PlotStyle())
+        self.setStyle(DEFAULT_SPECTRUM_STYLE)
 
 
     def fieldNames(self):
@@ -894,6 +901,21 @@ class SpectralProfile(QgsFeature):
     def yUnit(self):
         return self.metadata('y_unit', None)
 
+    def copyFieldSubset(self, fields):
+
+        sp = SpectralProfile(fields=fields)
+
+        fieldsInCommon = [field for field in sp.fields() if field in self.fields()]
+
+        sp.setGeometry(self.geometry())
+        sp.setId(self.id())
+
+        for field in fieldsInCommon:
+            assert isinstance(field, QgsField)
+            i = sp.fieldNameIndex(field.name())
+            sp.setAttribute(i, self.attribute(field.name()))
+        return sp
+
     def clone(self):
 
         sp = SpectralProfile(fields=self.fields())
@@ -1612,6 +1634,13 @@ class SpectralLibraryPanel(QgsDockWidget):
         self.SLW = SpectralLibraryWidget(self)
         self.setWidget(self.SLW)
 
+
+    def speclib(self):
+        return self.SLW.speclib()
+
+    def setCurrentSpectra(self, listOfSpectra):
+        self.SLW.setCurrentSpectra(listOfSpectra)
+
     def setAddCurrentSpectraToSpeclibMode(self, b: bool):
         self.SLW.setAddCurrentSpectraToSpeclibMode(b)
 
@@ -1756,7 +1785,11 @@ class SpectralLibrary(QgsVectorLayer):
 
         b = self.isEditable()
         self.startEditing()
-        self.addFeatures(profiles)
+
+        if not addMissingFields:
+            profiles = [p.copyFieldSubset(self.fields()) for p in profiles]
+
+        assert self.addFeatures(profiles)
         saveEdits(self, leaveEditable=b)
 
     def removeProfiles(self, profiles):
@@ -2195,6 +2228,37 @@ class SpectralLibraryPlotWidget(PlotWidget):
         #if self.mModel.rowCount() > 0:
         #    self.onRowsInserted(self.mModel.index(0,0), 0, self.mModel.rowCount())
 
+    def onMouseMoved2D(self, evt):
+        pos = evt[0]  ## using signal proxy turns original arguments into a tuple
+
+        plotItem = self.getPlotItem()
+        if plotItem.sceneBoundingRect().contains(pos):
+            vb = plotItem.vb
+            assert isinstance(vb, DateTimeViewBox)
+            mousePoint = vb.mapSceneToView(pos)
+            x = mousePoint.x()
+            if x >= 0:
+                y = mousePoint.y()
+                date = num2date(x)
+                doy = dateDOY(date)
+                plotItem.vb.updateCurrentDate(num2date(x, dt64=True))
+                self.mInfoLabelCursor.setText('DN {:0.2f}\nDate {}\nDOY {}'.format(
+                                              mousePoint.y(), date, doy),
+                                              color=self.mInfoColor)
+
+                s = self.size()
+                pos = QPointF(s.width(), 0)
+                self.mInfoLabelCursor.setVisible(vb.mActionShowCursorValues.isChecked())
+                self.mInfoLabelCursor.setPos(pos)
+
+                b = vb.mActionShowCrosshair.isChecked()
+                self.mCrosshairLineH.setVisible(b)
+                self.mCrosshairLineV.setVisible(b)
+                self.mCrosshairLineH.pen.setColor(self.mInfoColor)
+                self.mCrosshairLineV.pen.setColor(self.mInfoColor)
+                self.mCrosshairLineV.setPos(mousePoint.x())
+                self.mCrosshairLineH.setPos(mousePoint.y())
+
 
     def speclib(self):
         if not isinstance(self.mModel, SpectralLibraryTableModel):
@@ -2598,7 +2662,7 @@ class SpectralLibraryWidget(QFrame, loadUI('spectrallibrarywidget.ui')):
 
         self.mCurrentSpectra.clear()
         self.mCurrentSpectra.extend(listOfSpectra)
-        if self.actionSaveCurrentProfiles.isChecked() and len(self.mCurrentSpectra) > 0:
+        if self.actionAddCurrentProfilesAutomatically.isChecked() and len(self.mCurrentSpectra) > 0:
             self.addCurrentSpectraToSpeclib()
             #this will change the speclib and add each new profile automatically to the plot
         else:
-- 
GitLab