diff --git a/test/test_mapcanvas.py b/test/test_mapcanvas.py index c27642cc55a833c61078d1641af9c73e95e95371..cebeb5143ec0ac54681705d4cef605e2e7165dd4 100644 --- a/test/test_mapcanvas.py +++ b/test/test_mapcanvas.py @@ -21,7 +21,8 @@ from timeseriesviewer.utils import initQgisApplication from PyQt5.QtGui import * from PyQt5.QtCore import * -import unittest +import unittest, tempfile + from timeseriesviewer.mapcanvas import * QGIS_APP = initQgisApplication() @@ -46,7 +47,7 @@ class testclassDialogTest(unittest.TestCase): self.assertIsInstance(m.mLayerModel, MapCanvasLayerModel) - + m.saveAsImage() if __name__ == "__main__": diff --git a/test/test_utils.py b/test/test_utils.py index 01c4a909c114b200304ec5b67d2b3792b9897c50..cd7ede914fe9e0b1758adc219673307143c7dcff 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -48,7 +48,13 @@ class testclassUtilityTests(unittest.TestCase): self.assertIsInstance(center, SpatialPoint) self.assertEqual(ext.spatialCenter(), center) + def test_others(self): + p = 'This is a §$%& formed file path+§"^1' + + p2 = saveFilePath(p) + + s = "" if __name__ == "__main__": unittest.main() diff --git a/timeseriesviewer/main.py b/timeseriesviewer/main.py index de024009648d02644bd7c9be9dff482e7916e918..d399574ef98c6b6a757c506f1510df9226ba87e9 100644 --- a/timeseriesviewer/main.py +++ b/timeseriesviewer/main.py @@ -541,7 +541,7 @@ class TimeSeriesViewer(QgisInterface, QObject): filters = "CSV (*.csv *.txt);;" + \ "All files (*.*)" - path, filter = QFileDialog.getOpenFileName(caption='Load Time Series definition', directory=defDir, filters=filters) + path, filter = QFileDialog.getOpenFileName(caption='Load Time Series definition', directory=defDir, filter=filters) if path is not None and os.path.exists(path): s.setValue('file_ts_definition', path) M = self.ui.dockTimeSeries.tableView_TimeSeries.model() diff --git a/timeseriesviewer/mapcanvas.py b/timeseriesviewer/mapcanvas.py index ad05494e3cfb46686443aef01f53de0180eeead4..7767465f563245b705c361f2c6402383f588a6c9 100644 --- a/timeseriesviewer/mapcanvas.py +++ b/timeseriesviewer/mapcanvas.py @@ -912,7 +912,7 @@ class MapCanvas(QgsMapCanvas): else: path = 'mapcanvas' path = jp(lastDir, '{}.{}'.format(path, fileType.lower())) - path = QFileDialog.getSaveFileName(self, 'Save map as {}'.format(fileType), path) + path, _ = QFileDialog.getSaveFileName(self, 'Save map as {}'.format(fileType), path) if len(path) > 0: self.saveAsImage(path, None, fileType) SETTINGS.setValue('CANVAS_SAVE_IMG_DIR', os.path.dirname(path)) @@ -1126,5 +1126,7 @@ if __name__ == '__main__': c.setExtent(lyr1.extent()) c.setCrs(QgsCoordinateReferenceSystem('EPSG:32632')) c.setExtent(c.spatialExtentHint()) + + c.refresh() qgsApp.exec_() \ No newline at end of file diff --git a/timeseriesviewer/mapvisualization.py b/timeseriesviewer/mapvisualization.py index 47473ae815ac6d9235d43d7ddf1a4453e61359ba..8c9da339e5adfe3c0ca577c12b61cb6a47e5c2b8 100644 --- a/timeseriesviewer/mapvisualization.py +++ b/timeseriesviewer/mapvisualization.py @@ -111,8 +111,8 @@ class MapViewUI(QFrame, loadUI('mapviewdefinition.ui')): #l = self.renderSettingsLayout l = self.gbRasterRendering.layout() - l.removeWidget(sensorSettings.ui) - sensorSettings.ui.close() + l.removeWidget(sensorSettings) + sensorSettings.close() #self.resize(self.sizeHint()) @@ -2260,7 +2260,7 @@ class DateViewCollection(QObject): for DV in toRemove: self.mViews.remove(DV) - for mapCanvas in DV.mapCanvases.values(): + for mapCanvas in DV.mMapCanvases.values(): toRemove = mapCanvas.layers() mapCanvas.setLayers([]) toRemove = [l for l in toRemove if isinstance(l, QgsRasterLayer)] diff --git a/timeseriesviewer/profilevisualization.py b/timeseriesviewer/profilevisualization.py index 2416b522e6845332116c71a4cb3a9efeb70c4d5b..59c498a35bcee3b30280672fc644d0d84cc5e6e1 100644 --- a/timeseriesviewer/profilevisualization.py +++ b/timeseriesviewer/profilevisualization.py @@ -2221,7 +2221,9 @@ if __name__ == '__main__': STVis.createNewPlotStyle3D() STVis.ui.listWidget.setCurrentRow(1) - STVis.loadCoordinate(cpND) + STVis.loadCoordinate(cpND, backgroundProcess=False) + + STVis.tpCollection.mTemporalProfiles[0].setName('My Name') from example import exampleEvents #STVis.loadCoordinatesFromOgr(exampleEvents) diff --git a/timeseriesviewer/spectrallibraries.py b/timeseriesviewer/spectrallibraries.py index 611af5f30cc5df46e8659da970b74e532fe7b328..ea72ff5e5922edfc182170cb778339b230f60692 100644 --- a/timeseriesviewer/spectrallibraries.py +++ b/timeseriesviewer/spectrallibraries.py @@ -169,11 +169,24 @@ class SpectralLibraryTableView(QTableView): return [m.idx2profile(m.createIndex(r, 0)) for r in rows] def onSetColor(self): - c = QColorDialog.getColor() - if isinstance(c, QColor): - model = self.model() - for idx in self.selectedRowsIndexes(): - model.setData(model.createIndex(idx, 1), c, Qt.BackgroundRole) + model = self.model() + c0 = None + for r in self.selectedRowsIndexes(): + idx = model.createIndex(r, 1) + c0 = model.data(idx, Qt.BackgroundRole) + break + + if not isinstance(c0, QColor): + c0 = None + + c = QColorDialog(c0, self) + c.exec_() + + if c.result() == QDialog.Accepted: + c = c.currentColor() + if isinstance(c, QColor): + for r in self.selectedRowsIndexes(): + model.setData(model.createIndex(r, 1), c, Qt.BackgroundRole) def setCheckState(self, checkState): model = self.model() diff --git a/timeseriesviewer/temporalprofiles2d.py b/timeseriesviewer/temporalprofiles2d.py index 2820ba0df15fd088cf1418ae4e782d78ad6a4117..86a9b461d2b7b9e5f82185a6f650a83ead3465c5 100644 --- a/timeseriesviewer/temporalprofiles2d.py +++ b/timeseriesviewer/temporalprofiles2d.py @@ -1131,10 +1131,16 @@ class TemporalProfileCollection(QAbstractTableModel): self.mColumNames = [self.mcnName, self.mcnLoaded, self.mcnCoordinate] crs = QgsCoordinateReferenceSystem('EPSG:4862') - uri = 'Point?crs={}'.format(crs.authid()) + uri = 'Point?crs={}&field=id:integer&field=name:string(120)'.format(crs.authid()) + self.mLocations = QgsVectorLayer(uri, 'LOCATIONS', 'memory') + symbol = QgsFillSymbol.createSimple({'style': 'no', 'color': 'red', 'outline_color': 'black'}) + self.mLocations.renderer().setSymbol(symbol) self.TS = None - self.mLocations = QgsVectorLayer(uri, 'LOCATIONS', 'memory') + + + + self.mTemporalProfiles = [] self.mTPLookupSpatialPoint = {} self.mTPLookupID = {} @@ -1274,6 +1280,8 @@ class TemporalProfileCollection(QAbstractTableModel): self.prune(nMax=self.mMaxProfiles - l) self.beginInsertRows(QModelIndex(), i, i + l - 1) + + features = [] for temporalProfile in temporalProfiles: assert isinstance(temporalProfile, TemporalProfile) id = self.nextID @@ -1282,9 +1290,21 @@ class TemporalProfileCollection(QAbstractTableModel): self.mTemporalProfiles.insert(i, temporalProfile) self.mTPLookupID[id] = temporalProfile self.mTPLookupSpatialPoint[temporalProfile.mCoordinate] = temporalProfile + + f = QgsFeature(self.mLocations.fields()) + f.setFields(self.mLocations.fields()) + f.setAttribute('id', QVariant(id)) + f.setAttribute('name', QVariant(temporalProfile.name())) + f.setGeometry(QgsGeometry.fromPointXY(temporalProfile.coordinate())) + features.append(f) + + temporalProfile.sigDataChanged.connect(lambda: self.onUpdate(temporalProfile)) - temporalProfile.sigNameChanged.connect(lambda: self.onUpdate(temporalProfile)) + temporalProfile.sigNameChanged.connect(lambda: self.onUpdateName(temporalProfile)) i += 1 + self.mLocations.startEditing() + assert self.mLocations.dataProvider().addFeatures(features) + assert self.mLocations.commitChanges() self.endInsertRows() self.sigTemporalProfilesAdded.emit(temporalProfiles) @@ -1302,6 +1322,19 @@ class TemporalProfileCollection(QAbstractTableModel): else: return None + def temporalProfileFromFeature(self, feature): + + return None + + def temporalProfileToLocationFeature(self, tp:TemporalProfile): + + self.mLocations.selectByIds([tp.id()]) + for f in self.mLocations.selectedFeatures(): + assert isinstance(f, QgsFeature) + return f + + return None + def id(self, temporalProfile): """ Returns the id of an TemporalProfile @@ -1429,9 +1462,26 @@ class TemporalProfileCollection(QAbstractTableModel): if tp in self.mTemporalProfiles: idx0 = self.tp2idx(tp) - idx1 = self.createIndex(idx0.row(), self.rowCount()) + idx1 = self.createIndex(idx0.row(), self.columnCount()) self.dataChanged.emit(idx0, idx1, [Qt.DisplayRole]) + + + def onUpdateName(self, tp): + assert isinstance(tp, TemporalProfile) + + if tp in self.mTemporalProfiles: + idx0 = self.tp2idx(tp) + c = self.mColumNames.index(self.mcnName) + idx = self.createIndex(idx0.row(), c) + self.dataChanged.emit(idx, idx, [Qt.DisplayRole]) + + f = self.temporalProfileToLocationFeature(tp) + + if isinstance(f, QgsFeature): + f.setAttribute('name', tp.name()) + + def sort(self, col, order): if self.rowCount() == 0: return @@ -1540,7 +1590,7 @@ if __name__ == '__main__': qgsApp = utils.initQgisApplication() DEBUG = False - w = TemporalProfilePlotStyle3DWidget() + w = TemporalProfile2DPlotStyle() w.show() print(w.plotStyle()) diff --git a/timeseriesviewer/ui/profileviewdock.ui b/timeseriesviewer/ui/profileviewdock.ui index 21c9f24dedf2a7594d50ff941f6f2ea9c4743b30..8faeb074149713fa07d519421db5a7359e98a71a 100644 --- a/timeseriesviewer/ui/profileviewdock.ui +++ b/timeseriesviewer/ui/profileviewdock.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>885</width> - <height>331</height> + <height>442</height> </rect> </property> <property name="features"> diff --git a/timeseriesviewer/utils.py b/timeseriesviewer/utils.py index 9ee3699d8242ab7884fd05f69100672911d39740..49211d69de9b25593076ac18dfbbeddd35b846de 100644 --- a/timeseriesviewer/utils.py +++ b/timeseriesviewer/utils.py @@ -531,15 +531,13 @@ class SpatialExtent(QgsRectangle): -def saveFilePath(text): +def saveFilePath(text : str): """ Normalizes string, converts to lowercase, removes non-alpha characters, and converts spaces to hyphens. see https://stackoverflow.com/questions/295135/turn-a-string-into-a-valid-filename :return: path """ - import unicodedata - text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore') text = re.sub(r'[^\w\s.-]', '', text).strip().lower() text = re.sub(r'[-\s]+', '_', text) return re.sub(r'[ ]+]','',text)