diff --git a/imagechipviewsettings_widget.py b/imagechipviewsettings_widget.py index e967f1f52e469b54ecae96c5e8e289e2cc026fe1..2268686b5c46f1478b1d54f9a700f770735b6220 100644 --- a/imagechipviewsettings_widget.py +++ b/imagechipviewsettings_widget.py @@ -37,7 +37,7 @@ class ImageChipViewSettings(QGroupBox, FORM_CLASS): removeView = pyqtSignal() - def __init__(self, SC, parent=None): + def __init__(self, SensorConfiguration, parent=None): """Constructor.""" super(ImageChipViewSettings, self).__init__(parent) # Set up the user interface from Designer. @@ -47,17 +47,10 @@ class ImageChipViewSettings(QGroupBox, FORM_CLASS): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - import sensecarbon_tsv - # assert type(SC) is sensecarbon_tsv.SensorConfiguration - self.cb_useMask.stateChanged.connect(lambda: self.bt_color.setEnabled(self.cb_useMask.isChecked())) - self.bt_color.clicked.connect(lambda: self.ua_setMaskColor(None)) - self.cb_useMask.stateChanged.connect(self.ua_setMask) - self.maskcolor = QColor(255,255,255) - - self.SC = SC - self.SC.TS.datumAdded.connect(self._initBands) - func_removeView = lambda :self.removeView.emit() - self.SC.TS.closed.connect(func_removeView) + + self.SensorConfiguration = SensorConfiguration + self.setTitle(SensorConfiguration.sensor_name) + self.tb_range_r_min.setValidator(QDoubleValidator()) self.tb_range_g_min.setValidator(QDoubleValidator()) self.tb_range_b_min.setValidator(QDoubleValidator()) @@ -65,11 +58,7 @@ class ImageChipViewSettings(QGroupBox, FORM_CLASS): self.tb_range_g_max.setValidator(QDoubleValidator()) self.tb_range_b_max.setValidator(QDoubleValidator()) - #inform if remove button has been pressed - self.btn_removeView.clicked.connect(func_removeView) - - if len(self.SC.bandnames) > 0: - self._initBands(self.SC.bandnames) + self._initBands(self.SensorConfiguration.band_names) def ua_setMask(self, state): @@ -108,7 +97,7 @@ class ImageChipViewSettings(QGroupBox, FORM_CLASS): cb_G.addItem(bandname, i+1) cb_B.addItem(bandname, i+1) - if len(self.SC.bandnames) >= 3: + if len(self.SensorConfiguration.band_names) >= 3: cb_R.setCurrentIndex(2) cb_G.setCurrentIndex(1) cb_B.setCurrentIndex(0) @@ -118,7 +107,7 @@ class ImageChipViewSettings(QGroupBox, FORM_CLASS): assert len(bands) == 3 for b in bands: assert type(b) is int and b > 0 - assert b <= len(self.SC.bandnames), 'TimeSeries is not initializes/has no bands to show' + assert b <= len(self.SensorConfiguration.band_names), 'TimeSeries is not initializes/has no bands to show' self.cb_r.setCurrentIndex(bands[0]-1) self.cb_g.setCurrentIndex(bands[1]-1) self.cb_b.setCurrentIndex(bands[2]-1) diff --git a/imagechipviewsettings_widget_base.ui b/imagechipviewsettings_widget_base.ui index 2152c4173500b4e640f06f1a78b752f79229b582..005abf82c1164b43f860d84a160e6550f66c75c0 100644 --- a/imagechipviewsettings_widget_base.ui +++ b/imagechipviewsettings_widget_base.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>196</width> - <height>178</height> + <height>106</height> </rect> </property> <property name="sizePolicy"> @@ -20,7 +20,7 @@ <string>GroupBox</string> </property> <property name="title"> - <string>View#</string> + <string>Sensor</string> </property> <property name="flat"> <bool>false</bool> @@ -57,13 +57,6 @@ </property> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_g"> - <property name="text"> - <string>G</string> - </property> - </widget> - </item> <item row="5" column="1"> <widget class="QComboBox" name="cb_b"> <property name="sizePolicy"> @@ -80,14 +73,14 @@ </property> </widget> </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_b"> + <item row="4" column="0"> + <widget class="QLabel" name="label_g"> <property name="text"> - <string>B</string> + <string>G</string> </property> </widget> </item> - <item row="4" column="4"> + <item row="4" column="3"> <widget class="QLineEdit" name="tb_range_g_max"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> @@ -100,43 +93,22 @@ </property> </widget> </item> - <item row="0" column="4"> - <widget class="QLabel" name="label_max"> - <property name="text"> - <string>Max</string> - </property> - </widget> - </item> - <item row="5" column="3"> - <widget class="QLineEdit" name="tb_range_b_min"> - <property name="text"> - <string>0</string> - </property> - </widget> - </item> - <item row="0" column="3"> + <item row="0" column="2"> <widget class="QLabel" name="label_min"> <property name="text"> <string>Min</string> </property> </widget> </item> - <item row="3" column="3"> - <widget class="QLineEdit" name="tb_range_r_min"> - <property name="text"> - <string>0</string> - </property> - </widget> - </item> - <item row="4" column="3"> - <widget class="QLineEdit" name="tb_range_g_min"> + <item row="0" column="3"> + <widget class="QLabel" name="label_max"> <property name="text"> - <string>0</string> + <string>Max</string> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_band"> + <item row="3" column="3"> + <widget class="QLineEdit" name="tb_range_r_max"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -144,7 +116,7 @@ </sizepolicy> </property> <property name="text"> - <string>Band</string> + <string>5000</string> </property> </widget> </item> @@ -158,8 +130,15 @@ </property> </widget> </item> - <item row="5" column="4"> - <widget class="QLineEdit" name="tb_range_b_max"> + <item row="3" column="2"> + <widget class="QLineEdit" name="tb_range_r_min"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_band"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -167,12 +146,12 @@ </sizepolicy> </property> <property name="text"> - <string>5000</string> + <string>Band</string> </property> </widget> </item> - <item row="3" column="4"> - <widget class="QLineEdit" name="tb_range_r_max"> + <item row="5" column="3"> + <widget class="QLineEdit" name="tb_range_b_max"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -184,7 +163,7 @@ </property> </widget> </item> - <item row="4" column="5"> + <item row="4" column="4"> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -204,77 +183,24 @@ </property> </widget> </item> - <item row="8" column="1" colspan="4"> - <widget class="QPushButton" name="btn_removeView"> - <property name="text"> - <string>Remove view</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QCheckBox" name="cb_useMask"> - <property name="toolTip"> - <string>Draw masked pixels with specific mask color.</string> - </property> - <property name="text"> - <string>Mask</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="7" column="1"> - <widget class="QLabel" name="label_maskexpression"> - <property name="toolTip"> - <string>Boolean expression that returns False for masked pixels.</string> - </property> + <item row="4" column="2"> + <widget class="QLineEdit" name="tb_range_g_min"> <property name="text"> - <string>Expression</string> + <string>0</string> </property> </widget> </item> - <item row="7" column="3" colspan="2"> - <widget class="QLineEdit" name="tb_maskexpression"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Boolean expression that returns False for masked pixels.</string> - </property> + <item row="5" column="0"> + <widget class="QLabel" name="label_b"> <property name="text"> - <string>mask != 0</string> + <string>B</string> </property> </widget> </item> - <item row="6" column="3" colspan="2"> - <widget class="QPushButton" name="bt_color"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>23</height> - </size> - </property> - <property name="styleSheet"> - <string notr="true">background:rgb(255,255,255)</string> - </property> + <item row="5" column="2"> + <widget class="QLineEdit" name="tb_range_b_min"> <property name="text"> - <string>Mask color</string> - </property> - <property name="autoDefault"> - <bool>false</bool> - </property> - <property name="default"> - <bool>false</bool> - </property> - <property name="flat"> - <bool>false</bool> + <string>0</string> </property> </widget> </item> diff --git a/sensecarbon_tsv.py b/sensecarbon_tsv.py index 4076eb503928bc771dae2f6350d67216096b05f4..52c792c09d42e6e098a00795ed48017ce18dcc5c 100644 --- a/sensecarbon_tsv.py +++ b/sensecarbon_tsv.py @@ -21,8 +21,16 @@ ***************************************************************************/ """ +# Import the code for the dialog +import os, sys, re, fnmatch, collections, copy, traceback +from qgis.core import * +#os.environ['PATH'] += os.pathsep + r'C:\OSGeo4W64\bin' + +from osgeo import gdal, ogr, osr, gdal_array + + + try: - from qgis.core import * from qgis.gui import * import qgis import qgis_add_ins @@ -30,9 +38,6 @@ try: except: qgis_available = False -# Import the code for the dialog -import os, sys, re, fnmatch, collections, copy -from osgeo import gdal, ogr, osr, gdal_array import numpy as np import pickle @@ -61,8 +66,6 @@ DEBUG = True regLandsatSceneID = re.compile(r"L[EMCT][1234578]{1}[12]\d{12}[a-zA-Z]{3}\d{2}") - - def file_search(rootdir, wildcard, recursive=False, ignoreCase=False): assert rootdir is not None if not os.path.isdir(rootdir): @@ -218,45 +221,64 @@ class TimeSeriesItemModel(QAbstractItemModel): def columnCount(self, index=QModelIndex()): return 1 +LUT_SensorNames = {(6,30.,30.): 'L7 ETM+' \ + ,(7,30.,30.): 'L8 OLI' \ + ,(4,10.,10.): 'S2 MSI 10m' \ + ,(6,20.,20.): 'S2 MSI 20m' \ + ,(3,30.,30.): 'S2 MSI 60m' \ + ,(3,30.,30.): 'S2 MSI 60m' \ + } class SensorConfiguration(object): + """ + Describes a Sensor Configuration + """ def __init__(self,nb, px_size_x,px_size_y, band_names=None, wavelengths=None, sensor_name=None): assert nb >= 1 - assert px_size_x >= 0 - assert px_size_y >= 0 - self.TS = None self.nb = nb - self.px_size_x = float(px_size_x) - self.px_size_y = float(px_size_y) + self.px_size_x = float(abs(px_size_x)) + self.px_size_y = float(abs(px_size_y)) + + assert self.px_size_x > 0 + assert self.px_size_y > 0 if band_names is not None: assert len(band_names) == nb + else: + band_names = ['Band {}'.format(b+1) for b in range(nb)] + self.band_names = band_names if wavelengths is not None: assert len(wavelengths) == nb + self.wavelengths = wavelengths + if sensor_name is None: + id = (self.nb, self.px_size_x, self.px_size_y) + if id in LUT_SensorNames.keys(): + sensor_name = LUT_SensorNames[id] + else: + sensor_name = '{} b x {} m'.format(self.nb, self.px_size_x) + + print(sensor_name) self.sensor_name = sensor_name + self.hashvalue = hash(','.join(self.band_names)) + def __eq__(self, other): return self.nb == other.nb and self.px_size_x == other.px_size_x and self.px_size_y == other.px_size_y def __hash__(self): - return hash(self.__repr__()) + return self.hashvalue def __repr__(self): - info = [] - info.append('Spectral Configuration') - info.append(' bands:{}'.format(self.nb)) - info.append(' px x:{} y:{}'.format(self.px_size_x, self.px_size_y)) - info.append(' band names:{}'.format(self.band_names)) - return '\n'.join(info) + return self.sensor_name @@ -283,16 +305,12 @@ class TimeSeries(QObject): shape = None - SensorConfigurations = set() + SensorConfigurations = collections.OrderedDict() def __init__(self, imageFiles=None, maskFiles=None): QObject.__init__(self) self.Pool = None - #self.nb = None - #self.srs = None - #self.bandnames = list() - if imageFiles is not None: self.addFiles(imageFiles) @@ -456,20 +474,26 @@ class TimeSeries(QObject): print(pathImg) print('Add image {}...'.format(pathImg)) - TSD = TimeSeriesDatum(pathImg, pathMsk=pathMsk) + try: + TSD = TimeSeriesDatum(pathImg, pathMsk=pathMsk) - sensor = TSD.SensorConfiguration - if sensor not in self.SensorConfigurations: - sensor.TS = self - self.SensorConfigurations.add(sensor) - self.sensorAdded.emit(sensor) + sensor = SensorConfiguration(TSD.nb, TSD.gt[1], TSD.gt[5], TSD.bandnames, TSD.wavelength) + if sensor not in self.SensorConfigurations.keys(): + self.SensorConfigurations[sensor] = list() + self.SensorConfigurations[sensor].append(TSD) - self.data[TSD.getDate()] = TSD + self.data[TSD.getDate()] = TSD + + if not _quiet: + self._sortTimeSeriesData() + self.changed.emit() + self.datumAdded.emit() + except: + exc_type, exc_value, exc_traceback = sys.exc_info() + traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2) + six._print('Unable to add {}'.format(file), file=sys.stderr) + pass - if not _quiet: - self._sortTimeSeriesData() - self.changed.emit() - self.datumAdded.emit() def addFiles(self, files): @@ -479,10 +503,7 @@ class TimeSeries(QObject): self.progress.emit(0,0,l) for i, file in enumerate(files): - try: - self.addFile(file, _quiet=True) - except: - pass + self.addFile(file, _quiet=True) self.progress.emit(0,i+1,l) self._sortTimeSeriesData() @@ -580,13 +601,24 @@ class TimeSeriesDatum(object): self.nodata = refBand.GetNoDataValue() - bandnames = list() + self.bandnames = list() for b in range(self.nb): name = dsImg.GetRasterBand(b+1).GetDescription() if name is None or name == '': name = 'Band {}'.format(b+1) - bandnames.append(name) - self.SensorConfiguration = SensorConfiguration(self.nb, self.gt[1], self.gt[4], band_names=bandnames) + self.bandnames.append(name) + + self.wavelength = None + domains = dsImg.GetMetadataDomainList() + for domain in domains: + md = dsImg.GetMetadata_Dict(domain) + if 'wavelength' in md.keys(): + wl = md['wavelength'] + wl = re.split('[;,{}]', wl) + wl = [float(w) for w in wl] + assert len(wl) == self.nb + self.wavelength = wl + break if pathMsk: self.setMask(pathMsk) @@ -855,7 +887,27 @@ def Array2Image(d3d): return QImage(d3d.data, ns, nl, QImage.Format_RGB888) +class VerticalLabel(QLabel): + def __init__(self, text): + super(self.__class__, self).__init__() + self.text = text + + def paintEvent(self, event): + painter = QPainter(self) + painter.setPen(Qt.black) + painter.translate(20, 100) + painter.rotate(-90) + if self.text: + painter.drawText(0, 0, self.text) + painter.end() + def minimumSizeHint(self): + size = QLabel.minimumSizeHint(self) + return QSize(size.height(), size.width()) + + def sizeHint(self): + size = QLabel.sizeHint(self) + return QSize(size.height(), size.width()) class ImageChipBuffer(object): @@ -995,7 +1047,7 @@ class SenseCarbon_TSV: - self.VIEWS = list() + self.BAND_VIEWS = list() self.ImageChipBuffer = ImageChipBuffer() self.CHIPWIDGETS = collections.OrderedDict() @@ -1004,7 +1056,7 @@ class SenseCarbon_TSV: D.btn_showPxCoordinate.clicked.connect(lambda: self.ua_showPxCoordinate_start()) D.btn_selectByCoordinate.clicked.connect(self.ua_selectByCoordinate) D.btn_selectByRectangle.clicked.connect(self.ua_selectByRectangle) - D.btn_addBandView.clicked.connect(lambda :self.ua_addView()) + D.btn_addBandView.clicked.connect(lambda :self.ua_addBandView()) D.btn_addTSImages.clicked.connect(lambda :self.ua_addTSImages()) D.btn_addTSMasks.clicked.connect(lambda :self.ua_addTSMasks()) D.btn_removeTSD.clicked.connect(lambda : self.ua_removeTSD(None)) @@ -1031,7 +1083,9 @@ class SenseCarbon_TSV: self.PointMapTool.coordinateSelected.connect(self.ua_selectBy_Response) #self.RectangleMapTool.connect(self.ua_selectByRectangle_Done) - self.CPV = self.dlg.scrollAreaWidgetContents.layout() + self.ICP = self.dlg.scrollArea_imageChip_content.layout() + self.dlg.scrollArea_bandViews_content.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) + self.BVP = self.dlg.scrollArea_bandViews_content.layout() self.check_enabled() s = "" @@ -1114,10 +1168,10 @@ class SenseCarbon_TSV: def check_enabled(self): D = self.dlg hasTS = len(self.TS) > 0 or DEBUG - hasTSV = len(self.VIEWS) > 0 + hasTSV = len(self.BAND_VIEWS) > 0 hasQGIS = qgis_available - D.tabWidget_viewsettings.setEnabled(hasTS) + #D.tabWidget_viewsettings.setEnabled(hasTS) D.btn_showPxCoordinate.setEnabled(hasTS and hasTSV) D.btn_selectByCoordinate.setEnabled(hasQGIS) D.btn_selectByRectangle.setEnabled(hasQGIS) @@ -1248,7 +1302,7 @@ class SenseCarbon_TSV: def scrollToDate(self, date): QApplication.processEvents() - HBar = self.dlg.scrollArea.horizontalScrollBar() + HBar = self.dlg.scrollArea_imageChips.horizontalScrollBar() dates = list(self.CHIPWIDGETS.keys()) if len(dates) == 0: return @@ -1328,7 +1382,7 @@ class SenseCarbon_TSV: diff = set(dates_of_interest) diff = diff.symmetric_difference(self.CHIPWIDGETS.keys()) - self.clearLayoutWidgets(self.CPV) + self.clearLayoutWidgets(self.ICP) self.CHIPWIDGETS.clear() @@ -1342,22 +1396,22 @@ class SenseCarbon_TSV: TSD = self.TS.data[date] textLabel = QLabel('{}'.format(date.astype(str))) textLabel.setToolTip(str(TSD)) - self.CPV.addWidget(textLabel, 0, i) + self.ICP.addWidget(textLabel, 0, i) viewList = list() j = 1 - for view in self.VIEWS: + for view in self.BAND_VIEWS: imageLabel = QLabel() imageLabel.setFrameShape(QFrame.StyledPanel) imageLabel.setMinimumSize(size_x, size_y) imageLabel.setMaximumSize(size_x+1, size_y+1) imageLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) viewList.append(imageLabel) - self.CPV.addWidget(imageLabel,j, i) + self.ICP.addWidget(imageLabel, j, i) j += 1 textLabel = QLabel('{}'.format(date.astype(str))) textLabel.setToolTip(str(TSD)) - self.CPV.addWidget(textLabel, j, i) + self.ICP.addWidget(textLabel, j, i) self.CHIPWIDGETS[date] = viewList @@ -1374,7 +1428,7 @@ class SenseCarbon_TSV: missing_bands = set() for i, date in enumerate(dates_of_interest): required_bands = set() - for j, view in enumerate(self.VIEWS): + for j, view in enumerate(self.BAND_VIEWS): required_bands = required_bands.union(set(view.getBands())) missing = self.ImageChipBuffer.getMissingBands(date, required_bands) @@ -1405,7 +1459,7 @@ class SenseCarbon_TSV: if viewList: - for j, view in enumerate(self.VIEWS): + for j, view in enumerate(self.BAND_VIEWS): imageLabel = viewList[j] imageLabel.clear() @@ -1425,7 +1479,7 @@ class SenseCarbon_TSV: s = "" pass - self.CPV.layout().update() + self.ICP.layout().update() s = "" pass @@ -1449,9 +1503,10 @@ class SenseCarbon_TSV: self.TS.addFiles(files) M.endResetModel() - if len(self.VIEWS) == 0: - self.ua_addView([3,2,1]) - self.ua_addView([4,5,3]) + + if len(self.BAND_VIEWS) == 0: + self.ua_addBandView([3, 2, 1]) + self.ua_addBandView([4, 5, 3]) self.check_enabled() @@ -1472,31 +1527,38 @@ class SenseCarbon_TSV: self.check_enabled() - def setViewNames(self): - for i, w in enumerate(self.VIEWS): - w.setTitle('View {}'.format(i+1)) - self.check_enabled() - def ua_addView(self, bands = [3,2,1]): + + def ua_addBandView(self, band_recommendation = [3, 2, 1]): import imagechipviewsettings_widget - for sensor in self.TS.SensorConfigurations: + band_view_widgets = list() + + v_offset = len(self.BAND_VIEWS) + + + textLabel = VerticalLabel('View {}'.format(v_offset+1)) + textLabel.setToolTip('') + textLabel.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) + self.BVP.addWidget(textLabel, v_offset, 0) + + for h_offset, sensor in enumerate(self.TS.SensorConfigurations): w = imagechipviewsettings_widget.ImageChipViewSettings(sensor, parent=self.dlg) w.setMaximumSize(w.size()) #w.setMinimumSize(w.size()) w.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.MinimumExpanding) - w.setBands(bands) + w.setBands(band_recommendation) w.removeView.connect(lambda : self.ua_removeView(w)) - L = self.dlg.scrollArea_viewsWidget.layout() - L.addWidget(w) - self.dlg.scrollArea_views.show() - self.VIEWS.append(w) - self.setViewNames() + self.BVP.addWidget(w, v_offset, h_offset+1) + band_view_widgets.append(w) + self.check_enabled() + self.BAND_VIEWS.append(band_view_widgets) + def ua_removeTS(self): #remove views @@ -1518,7 +1580,7 @@ class SenseCarbon_TSV: def ua_removeView(self,w): - self.VIEWS.remove(w) + self.BAND_VIEWS.remove(w) L = self.dlg.scrollArea_viewsWidget.layout() L.removeWidget(w) w.deleteLater() diff --git a/sensecarbon_tsv_gui_base.ui b/sensecarbon_tsv_gui_base.ui index 0dd650e4cf2227fcfa1caebdb0f6cd0ebfa03c59..99a26ede2efcb21d0c1b94999c70fea38444c271 100644 --- a/sensecarbon_tsv_gui_base.ui +++ b/sensecarbon_tsv_gui_base.ui @@ -28,7 +28,7 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> - <widget class="QScrollArea" name="scrollArea"> + <widget class="QScrollArea" name="scrollArea_imageChips"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> @@ -47,7 +47,7 @@ <property name="widgetResizable"> <bool>false</bool> </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> + <widget class="QWidget" name="scrollArea_imageChip_content"> <property name="geometry"> <rect> <x>0</x> @@ -73,14 +73,14 @@ </layout> </widget> <widget class="QStatusBar" name="statusBar"/> - <widget class="QDockWidget" name="dockWidget_3"> + <widget class="QDockWidget" name="dockWidget_bottom"> <property name="windowTitle"> <string>Settings</string> </property> <attribute name="dockWidgetArea"> <number>8</number> </attribute> - <widget class="QWidget" name="dockWidgetContents_3"> + <widget class="QWidget" name="dockWidget_bottom_contents"> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QTabWidget" name="tabWidget"> @@ -88,7 +88,7 @@ <bool>true</bool> </property> <property name="currentIndex"> - <number>1</number> + <number>2</number> </property> <widget class="QWidget" name="tab_console"> <attribute name="title"> @@ -193,382 +193,13 @@ </item> </layout> </widget> - </widget> - </item> - </layout> - </widget> - </widget> - <widget class="QDockWidget" name="dockWidget_2"> - <attribute name="dockWidgetArea"> - <number>1</number> - </attribute> - <widget class="QWidget" name="dockWidgetContents_4"> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <widget class="QPushButton" name="btn_showPxCoordinate"> - <property name="toolTip"> - <string>Load the image chips for the entire time series. Requires specification of a time series and and spectral view.</string> - </property> - <property name="text"> - <string>Load image chips!</string> - </property> - </widget> - </item> - <item> - <widget class="QTabWidget" name="tabWidget_viewsettings"> - <property name="tabShape"> - <enum>QTabWidget::Triangular</enum> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <property name="elideMode"> - <enum>Qt::ElideNone</enum> - </property> - <property name="documentMode"> - <bool>false</bool> - </property> - <property name="movable"> - <bool>false</bool> - </property> - <widget class="QWidget" name="tab_spatial"> + <widget class="QWidget" name="tab_bandViews"> <attribute name="title"> - <string>Spatial</string> + <string>Band Views</string> </attribute> - <layout class="QVBoxLayout" name="verticalLayout_9"> + <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> - <widget class="QGroupBox" name="groupBox_spatialsubset"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="title"> - <string>Image subset</string> - </property> - <layout class="QFormLayout" name="formLayout_3"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="1"> - <widget class="QPushButton" name="btn_selectByCoordinate"> - <property name="toolTip"> - <string>Selects the center coordinate from QGIS.</string> - </property> - <property name="text"> - <string>Select center coordinate</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>x</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QDoubleSpinBox" name="spinBox_coordinate_x"> - <property name="decimals"> - <number>8</number> - </property> - <property name="minimum"> - <double>-999999999.000000000000000</double> - </property> - <property name="maximum"> - <double>999999999.000000000000000</double> - </property> - <property name="singleStep"> - <double>30.000000000000000</double> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>y</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QDoubleSpinBox" name="spinBox_coordinate_y"> - <property name="decimals"> - <number>8</number> - </property> - <property name="minimum"> - <double>-999999999.000000000000000</double> - </property> - <property name="maximum"> - <double>999999999.000000000000000</double> - </property> - <property name="singleStep"> - <double>30.000000000000000</double> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>size x</string> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>size y</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QPushButton" name="btn_selectByRectangle"> - <property name="toolTip"> - <string>Selects the image subset from QGIS.</string> - </property> - <property name="text"> - <string>Select subset by rectangle</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QDoubleSpinBox" name="doubleSpinBox_subset_size_x"> - <property name="suffix"> - <string>m</string> - </property> - <property name="minimum"> - <double>1.000000000000000</double> - </property> - <property name="maximum"> - <double>999999.000000000000000</double> - </property> - <property name="singleStep"> - <double>10.000000000000000</double> - </property> - <property name="value"> - <double>2000.000000000000000</double> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QDoubleSpinBox" name="doubleSpinBox_subset_size_y"> - <property name="suffix"> - <string>m</string> - </property> - <property name="minimum"> - <double>1.000000000000000</double> - </property> - <property name="maximum"> - <double>9999999.000000000000000</double> - </property> - <property name="singleStep"> - <double>10.000000000000000</double> - </property> - <property name="value"> - <double>2000.000000000000000</double> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer_4"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QGroupBox" name="groupBox_rendering"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="title"> - <string>Chip Rendering</string> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="6" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>First date</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QSpinBox" name="spinBox_ncpu"> - <property name="toolTip"> - <string>Number of CPUs used for parallel image chip calculation</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QSpinBox" name="spinBox_chipsize_max"> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Max. length of an image chip on screen.</string> - </property> - <property name="suffix"> - <string>px</string> - </property> - <property name="minimum"> - <number>20</number> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="singleStep"> - <number>10</number> - </property> - <property name="value"> - <number>200</number> - </property> - </widget> - </item> - <item row="6" column="1" colspan="2"> - <widget class="QComboBox" name="cb_centerdate"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>max. size </string> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>#cpu</string> - </property> - </widget> - </item> - <item row="4" column="2"> - <spacer name="horizontalSpacer_2"> - <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 row="0" column="0"> - <widget class="QRadioButton" name="rb_showEntireTS"> - <property name="text"> - <string>Entire Time Series</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QRadioButton" name="rb_showTimeWindow"> - <property name="toolTip"> - <string>Select </string> - </property> - <property name="text"> - <string>Time Window:</string> - </property> - </widget> - </item> - <item row="2" column="0" rowspan="2" colspan="3"> - <widget class="QFrame" name="frame_timewindow"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="minimumSize"> - <size> - <width>50</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_3"> - <item> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>before</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="sb_ndates_before"> - <property name="maximum"> - <number>9999</number> - </property> - <property name="value"> - <number>1</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>after</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="sb_ndates_after"> - <property name="maximum"> - <number>9999</number> - </property> - <property name="value"> - <number>1</number> - </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> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_spectral"> - <attribute name="title"> - <string>Spectral</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> + <layout class="QVBoxLayout" name="verticalLayout_8"> <item> <widget class="QPushButton" name="btn_addBandView"> <property name="maximumSize"> @@ -583,14 +214,27 @@ </widget> </item> <item> - <spacer name="horizontalSpacer"> + <widget class="QPushButton" name="bnt_removeBandView"> + <property name="maximumSize"> + <size> + <width>150</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> - <height>20</height> + <width>20</width> + <height>40</height> </size> </property> </spacer> @@ -598,9 +242,9 @@ </layout> </item> <item> - <widget class="QScrollArea" name="scrollArea_views"> + <widget class="QScrollArea" name="scrollArea_bandViews"> <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> + <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -614,13 +258,13 @@ <property name="widgetResizable"> <bool>true</bool> </property> - <widget class="QWidget" name="scrollArea_viewsWidget"> + <widget class="QWidget" name="scrollArea_bandViews_content"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>262</width> - <height>376</height> + <width>754</width> + <height>170</height> </rect> </property> <property name="sizePolicy"> @@ -629,14 +273,354 @@ <verstretch>0</verstretch> </sizepolicy> </property> - <layout class="QVBoxLayout" name="verticalLayout_4"/> + <layout class="QGridLayout" name="gridLayout_4"/> </widget> </widget> </item> </layout> + <zorder></zorder> + <zorder></zorder> + <zorder>scrollArea_bandViews</zorder> </widget> </widget> </item> + </layout> + </widget> + </widget> + <widget class="QDockWidget" name="dockWidget_left"> + <attribute name="dockWidgetArea"> + <number>1</number> + </attribute> + <widget class="QWidget" name="dockWidgetContents_4"> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QPushButton" name="btn_showPxCoordinate"> + <property name="toolTip"> + <string>Load the image chips for the entire time series. Requires specification of a time series and and spectral view.</string> + </property> + <property name="text"> + <string>Load image chips!</string> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_spatialsubset"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Image subset</string> + </property> + <layout class="QFormLayout" name="formLayout_3"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="0" column="1"> + <widget class="QPushButton" name="btn_selectByCoordinate"> + <property name="toolTip"> + <string>Selects the center coordinate from QGIS.</string> + </property> + <property name="text"> + <string>Select center coordinate</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>x</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDoubleSpinBox" name="spinBox_coordinate_x"> + <property name="decimals"> + <number>8</number> + </property> + <property name="minimum"> + <double>-999999999.000000000000000</double> + </property> + <property name="maximum"> + <double>999999999.000000000000000</double> + </property> + <property name="singleStep"> + <double>30.000000000000000</double> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>y</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QDoubleSpinBox" name="spinBox_coordinate_y"> + <property name="decimals"> + <number>8</number> + </property> + <property name="minimum"> + <double>-999999999.000000000000000</double> + </property> + <property name="maximum"> + <double>999999999.000000000000000</double> + </property> + <property name="singleStep"> + <double>30.000000000000000</double> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>size x</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>size y</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="btn_selectByRectangle"> + <property name="toolTip"> + <string>Selects the image subset from QGIS.</string> + </property> + <property name="text"> + <string>Select subset by rectangle</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QDoubleSpinBox" name="doubleSpinBox_subset_size_x"> + <property name="suffix"> + <string>m</string> + </property> + <property name="minimum"> + <double>1.000000000000000</double> + </property> + <property name="maximum"> + <double>999999.000000000000000</double> + </property> + <property name="singleStep"> + <double>10.000000000000000</double> + </property> + <property name="value"> + <double>2000.000000000000000</double> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QDoubleSpinBox" name="doubleSpinBox_subset_size_y"> + <property name="suffix"> + <string>m</string> + </property> + <property name="minimum"> + <double>1.000000000000000</double> + </property> + <property name="maximum"> + <double>9999999.000000000000000</double> + </property> + <property name="singleStep"> + <double>10.000000000000000</double> + </property> + <property name="value"> + <double>2000.000000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_rendering"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Chip Rendering</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="6" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>First date</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QSpinBox" name="spinBox_ncpu"> + <property name="toolTip"> + <string>Number of CPUs used for parallel image chip calculation</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QSpinBox" name="spinBox_chipsize_max"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Max. length of an image chip on screen.</string> + </property> + <property name="suffix"> + <string>px</string> + </property> + <property name="minimum"> + <number>20</number> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="singleStep"> + <number>10</number> + </property> + <property name="value"> + <number>200</number> + </property> + </widget> + </item> + <item row="6" column="1" colspan="2"> + <widget class="QComboBox" name="cb_centerdate"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>max. size </string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>#cpu</string> + </property> + </widget> + </item> + <item row="4" column="2"> + <spacer name="horizontalSpacer_2"> + <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 row="0" column="0"> + <widget class="QRadioButton" name="rb_showEntireTS"> + <property name="text"> + <string>Entire Time Series</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="rb_showTimeWindow"> + <property name="toolTip"> + <string>Select </string> + </property> + <property name="text"> + <string>Time Window:</string> + </property> + </widget> + </item> + <item row="2" column="0" rowspan="2" colspan="3"> + <widget class="QFrame" name="frame_timewindow"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>50</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_3"> + <item> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>before</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="sb_ndates_before"> + <property name="maximum"> + <number>9999</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>after</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="sb_ndates_after"> + <property name="maximum"> + <number>9999</number> + </property> + <property name="value"> + <number>1</number> + </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> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> <item> <widget class="QGroupBox" name="groupBox"> <property name="minimumSize"> @@ -659,6 +643,19 @@ </layout> </widget> </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> </widget>