diff --git a/gnavs/gnavs.py b/gnavs/gnavs.py index 997c50c..f148d03 100644 --- a/gnavs/gnavs.py +++ b/gnavs/gnavs.py @@ -25,6 +25,8 @@ from qgis.PyQt.QtGui import QIcon from qgis.PyQt.QtWidgets import QAction +from qgis.core import QgsMessageLog + # Initialize Qt resources from file resources.py #from .resources import * from . import resources @@ -53,10 +55,16 @@ def __init__(self, iface): # initialize locale locale = QSettings().value('locale/userLocale')[0:2] + + # due to error message when installation from QGIS-Repo + loc = locale + if loc != 'de': + loc = 'en' + locale_path = os.path.join( self.plugin_dir, 'i18n', - 'gnavs_{}.qm'.format(locale)) + 'gnavs_{}.qm'.format(loc)) if os.path.exists(locale_path): self.translator = QTranslator() diff --git a/gnavs/gui/gnavs_dockwidget.py b/gnavs/gui/gnavs_dockwidget.py index 77d7066..ae79410 100644 --- a/gnavs/gui/gnavs_dockwidget.py +++ b/gnavs/gui/gnavs_dockwidget.py @@ -33,6 +33,7 @@ from .setup.settings import Settings from ..utils.utils import Utils from .recording.toggle_buttons import ToggleButtons +from qgis.core import QgsMessageLog FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'gnavs_dockwidget_base.ui')) @@ -74,6 +75,9 @@ def __init__(self, interface, parent=None): self.toHome() self.toggleButtonsChanged('navigation') + filePath = Utils.getSettingsDirectory() # Create the settings directory if it does not exist + QgsMessageLog.logMessage(filePath, 'gnavs') + def addToMap(self): """Add the recorded points to the map""" diff --git a/gnavs/gui/gnavs_dockwidget_base.ui b/gnavs/gui/gnavs_dockwidget_base.ui index 872a4e6..c5644f1 100644 --- a/gnavs/gui/gnavs_dockwidget_base.ui +++ b/gnavs/gui/gnavs_dockwidget_base.ui @@ -45,7 +45,7 @@ 0 - + 0 @@ -98,7 +98,7 @@ border-bottom: 0px solid #888; 0 0 654 - 514 + 518 @@ -153,21 +153,23 @@ border-bottom: 0px solid #888; 5 - - - false - - - - 75 - true - - - - PointingHandCursor - - - QPushButton{ + + + + + false + + + + 75 + true + + + + PointingHandCursor + + + QPushButton{ border: 2px solid #888; color: #888; padding: 5px; @@ -181,11 +183,13 @@ QPushButton:enabled{ background-color: green; color: #fff; } - - - ADD TO MAP - - + + + ADD TO MAP + + + + diff --git a/gnavs/gui/measurement/aggregation.py b/gnavs/gui/measurement/aggregation.py index 19c0b18..d4efa96 100644 --- a/gnavs/gui/measurement/aggregation.py +++ b/gnavs/gui/measurement/aggregation.py @@ -40,7 +40,7 @@ def emitData(self): self.getTextFields() self.lfbAddToMapBtn.setEnabled(False) - Utils.addPointToLayer('GNAVS - Aggregated', self.aggregatedValues, self.gpsInfos) + Utils.addPointToLayer('GNAVS-Aggregated', self.aggregatedValues, self.gpsInfos) self.reset() def updateAggregatedValues(self, gpsInfos): diff --git a/gnavs/gui/measurement/precision.py b/gnavs/gui/measurement/precision.py new file mode 100644 index 0000000..277b327 --- /dev/null +++ b/gnavs/gui/measurement/precision.py @@ -0,0 +1,69 @@ + +import os +import json +import statistics +import time + + +from qgis.PyQt import QtWidgets, uic +from qgis.PyQt.QtWidgets import QDialog +from PyQt5 import QtCore + +from qgis.core import QgsMessageLog + +from ..recording.indicator import Indicator +from ...utils.utils import Utils + + +UI_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'precision.ui')) + +class PrecisionNote(QtWidgets.QWidget, UI_CLASS): + """ + PrecisionNote class. + Shows a dialog with a note about the precision of the measurement. + """ + + addToMap = QtCore.pyqtSignal(object, list) + + def __init__(self, interface): + """Constructor.""" + + _translate = QtCore.QCoreApplication.translate + + QDialog.__init__(self, interface.mainWindow()) + self.setupUi(self) + + self.indicator = Indicator(interface, 25, 25) + self.lfbPrecition.insertWidget(0, self.indicator) + + self.lfbShowPrecitionBad.hide() + self.lfbShowPrecitionGood.hide() + + + self.lfbShowPrecitionBad.setText(_translate("Form", "qualityNoteBad")) + #self.lfbShowPrecitionGoodsetText(self._translate("Form", "qualityNoteGood")) + + self.hide() + + def hideGroup(self): + """Hides the group""" + QgsMessageLog.logMessage('Hide precision note', 'gnavs') + + self.hide() + + def updateIndicator(self, gpsInfo): + """Updates the color indicator""" + + self.indicator.setColor(gpsInfo) + + def update(self, gpsInfos): + self.show() + """Updates the note indicator""" + showNote = self.indicator.getAggregatedNote(gpsInfos) + + if showNote: + self.lfbShowPrecitionBad.show() + #self.lfbShowPrecitionGood.hide() + else: + self.lfbShowPrecitionBad.hide() + #self.lfbShowPrecitionGood.show() \ No newline at end of file diff --git a/gnavs/gui/measurement/precision.ui b/gnavs/gui/measurement/precision.ui new file mode 100644 index 0000000..16ec1e3 --- /dev/null +++ b/gnavs/gui/measurement/precision.ui @@ -0,0 +1,109 @@ + + + Form + + + + 0 + 0 + 850 + 206 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Precision + + + + 4 + + + 20 + + + 4 + + + 4 + + + + + 0 + + + + + + 0 + 0 + + + + color:#f00; + + + Die Qualitätsparameter sind so schlecht, dass auf eine Messung verzichtet oder durch die Einmessung von mindestens drei Hilfspunkten mit Azimut und Distanz für eine anschließende Fehlerberrechnung und -ausgleichsrechnung erfolgen sollte. + + + true + + + + + + + + 0 + 0 + + + + Qualität ist ausreichend! + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + + + diff --git a/gnavs/gui/navigate/selection.py b/gnavs/gui/navigate/selection.py index 9b1215c..274dc5b 100644 --- a/gnavs/gui/navigate/selection.py +++ b/gnavs/gui/navigate/selection.py @@ -59,7 +59,7 @@ def updateToC(self): self.layerSelectionChanged() - def updateCoordinates(self, gpsInfo): + def updateCoordinates(self, gpsInfo, trackingState = 'navigation'): """Update the GPS coordinates and list of targets selected by the user""" if gpsInfo is None or gpsInfo.latitude is None or gpsInfo.longitude is None: @@ -73,7 +73,10 @@ def updateCoordinates(self, gpsInfo): Utils.clearLayer('lfb-tmp-position', 'point') Utils.drawPosition('lfb-tmp-position', position) - self.updateSelectionTargets() + if trackingState == 'navigation': + self.updateSelectionTargets() + else: + Utils.clearLayer('lfb-tmp-distance', 'linestring') def createTargetList(self): """Create a list of targets selected by the user""" @@ -117,22 +120,46 @@ def removeAllTargets(self): def updateSelectionTargets(self): """Update the list of targets selected by the user""" - self.removeAllTargets() + #self.removeAllTargets() Utils.clearLayer('lfb-tmp-distance', 'linestring') - if self.targets is not None and len(self.targets) > 0: - for targetElement in self.targets: + newTargets = self.targets + for i in reversed(range(self.lfbSelectedTargets.count())): # existing Targets + exists = None + target = self.lfbSelectedTargets.itemAt(i).widget() + + for targetElement in newTargets: # new Targets + if target.getId() == targetElement['id']: + exists = target + target.updateValues(targetElement) + newTargets.remove(targetElement) + Utils.drawDistance('lfb-tmp-distance',targetElement['startPoint'], targetElement['endPoint']) + break + + if exists is None: + # remove it from the layout list + self.lfbSelectedTargets.removeWidget(target) + # remove it from the gui + target.setParent(None) + else: + Utils.drawDistance('lfb-tmp-distance',targetElement['startPoint'], targetElement['endPoint']) + + + if newTargets is not None and len(newTargets) > 0: + + for targetElement in newTargets: + target = Target(self.interface, targetElement, self.onlyOne) self.lfbSelectedTargets.addWidget(target) Utils.drawDistance('lfb-tmp-distance',targetElement['startPoint'], targetElement['endPoint']) - else: - for element in self.selectedFeatures: - target = Target(self.interface, { - 'id': element['feature'].id(), - 'feature': element['feature'], - 'layer': element['layer'], - }, self.onlyOne) - self.lfbSelectedTargets.addWidget(target) + #else: + # for element in self.selectedFeatures: + # target = Target(self.interface, { + # 'id': element['feature'].id(), + # 'feature': element['feature'], + # 'layer': element['layer'], + # }, self.onlyOne) + # self.lfbSelectedTargets.addWidget(target) def updateSelectionLabel(self): diff --git a/gnavs/gui/navigate/target.py b/gnavs/gui/navigate/target.py index e55e7e9..a633c00 100644 --- a/gnavs/gui/navigate/target.py +++ b/gnavs/gui/navigate/target.py @@ -8,6 +8,8 @@ from ...utils.utils import Utils +from qgis.core import QgsMessageLog + UI_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'target.ui')) @@ -29,13 +31,18 @@ def __init__(self, interface, targetElement=None, onlyOne=False): self.lfbTargetRemoveBtn.clicked.connect(self.removeTargetSelection) self.lfbTargetFokusBtn.clicked.connect(self.fokusToTarget) - self.updateValues() + self.updateValues(self.targetElement) self.updateAttributeTableView() if onlyOne: self.lfbAttributeTableWidget.hide() self.lfbTargetEdit_2.hide() + def getId(self): + """Get the id of the target""" + + return self.targetElement['id'] + def removeTargetSelection(self): """Deselect target""" Utils.deselectFeature(self.targetElement['layer'], self.targetElement['feature']) @@ -80,19 +87,19 @@ def updateAttributeTableView(self): item.setTextAlignment(QtCore.Qt.AlignCenter) self.lfbAttributeTableWidget.setItem(0 , i, item) - def updateValues(self): + def updateValues(self, targetElement): """Update the distance and bearing values""" - if 'distance' in self.targetElement: + if 'distance' in targetElement: #self.lfbTargetDetailsWidget.show() - if self.targetElement['distance'] > 1000: - self.lfbDistanceEdit.setText(str(round(self.targetElement['distance']/1000, 2))) + if targetElement['distance'] > 1000: + self.lfbDistanceEdit.setText(str(round(targetElement['distance']/1000, 2))) self.lfbDistanceUnit.setText("km") - elif self.targetElement['distance'] > 1: - self.lfbDistanceEdit.setText(str(round(self.targetElement['distance'], 0))) + elif targetElement['distance'] > 1: + self.lfbDistanceEdit.setText(str(round(targetElement['distance'], 0))) self.lfbDistanceUnit.setText("m") else: - self.lfbDistanceEdit.setText(str(round(self.targetElement['distance']*100, 0))) + self.lfbDistanceEdit.setText(str(round(targetElement['distance']*100, 0))) self.lfbDistanceUnit.setText("cm") else: #self.lfbTargetDetailsWidget.hide() @@ -107,10 +114,10 @@ def updateValues(self): self.lfbBearingUnit.setText("gon") else: self.lfbBearingUnit.setText("rad") - if 'bearing' in self.targetElement: + if 'bearing' in targetElement: degUnit = Utils.getSetting('degUnit', 'deg') - rad = self.targetElement['bearing'] + rad = targetElement['bearing'] deg = math.degrees(rad) deg = deg % 360 diff --git a/gnavs/gui/navigate/target.ui b/gnavs/gui/navigate/target.ui index fb5d316..0aad9cf 100644 --- a/gnavs/gui/navigate/target.ui +++ b/gnavs/gui/navigate/target.ui @@ -130,7 +130,7 @@ background-color:#ddd; - 0 + 10 10 @@ -143,6 +143,9 @@ background-color:#ddd; + + 0 + 0 @@ -224,6 +227,9 @@ background-color:#ddd; + + 0 + 0 @@ -317,6 +323,9 @@ background-color:#ddd; 8 + + PointingHandCursor + background-color: transparent; color: red; @@ -355,6 +364,9 @@ border: none; PointingHandCursor + + false + QPushButton{ border: 2px solid #333; diff --git a/gnavs/gui/recording/indicator.py b/gnavs/gui/recording/indicator.py index 3c4d68a..badfeca 100644 --- a/gnavs/gui/recording/indicator.py +++ b/gnavs/gui/recording/indicator.py @@ -30,6 +30,12 @@ def __init__(self, interface, width=100, height=100): self.lfbIndicatorFrame.setFixedSize(width, height) + self.lfbHelpBtn.clicked.connect(self.getHelp) + + + def getHelp(self): + QgsMessageLog.logMessage('Help', 'gnavs') + def stop(self, size): """Sets the size of the widget""" @@ -41,8 +47,22 @@ def setColor(self, gpsInfo): self.lfbIndicatorFrame.setStyleSheet("background-color: " + color + ";") + return color + + def getAggregatedNote(self, gpsInfos): + """Show a note about the aggregated precision of the measurement""" + + longitudeStDev = gpsInfos['longitudeStDev'] + latitudeStDev = gpsInfos['latitudeStDev'] + + + if gpsInfos is None or gpsInfos['pdop'] is None or gpsInfos['satellitesUsed'] is None: + return True + elif gpsInfos['pdop'] > 6 or gpsInfos['satellitesUsed'] < 6 or longitudeStDev > 0.00002 or latitudeStDev > 0.00002: + return True - pass + return False + def getColor(self, gpsInfo): """Returns the color of the indicator""" @@ -52,7 +72,7 @@ def getColor(self, gpsInfo): return 'green' elif str(gpsInfo.qualityIndicator) == 'GpsQualityIndicator.FloatRTK' and gpsInfo.pdop < 6 and gpsInfo.satellitesUsed >= 6: return 'yellow' - elif str(gpsInfo.qualityIndicator) == 'GpsQualityIndicator.GPS' and gpsInfo.pdop < 6 and gpsInfo.satellitesUsed >= 6: + elif str(gpsInfo.qualityIndicator) == 'GpsQualityIndicator.GPS' and gpsInfo.pdop < 10 and gpsInfo.satellitesUsed >= 6: return 'orange' else: return 'red' \ No newline at end of file diff --git a/gnavs/gui/recording/indicator.ui b/gnavs/gui/recording/indicator.ui index 243c13b..3c04b3d 100644 --- a/gnavs/gui/recording/indicator.ui +++ b/gnavs/gui/recording/indicator.ui @@ -6,10 +6,13 @@ 0 0 - 662 - 457 + 381 + 263 + + PointingHandCursor + Form @@ -37,6 +40,25 @@ QFrame::Raised + + + + + + 0 + 0 + + + + width: 100%; +background: none; + + + + + + + diff --git a/gnavs/gui/recording/recording.py b/gnavs/gui/recording/recording.py index 8e1a52c..34c8a18 100644 --- a/gnavs/gui/recording/recording.py +++ b/gnavs/gui/recording/recording.py @@ -85,6 +85,8 @@ def __init__(self, interface, aggregate=True): self.lfbValidIndicator.hide() self.lfbValidIndicator.setStyleSheet("background-color: gray; border-radius: 5px;") + + self.lfbRecordingPercent.setRange(0, 100) self.lfbRecordingPercent.setContentsMargins(0,0,0,0) self.lfbRecordingPercent.setValue(0) @@ -315,13 +317,14 @@ def cancelConnection(self, reset=True): if reset: self.setMeasurementsCount() - self.getProgress() except Exception as e: pass + self.getProgress() + def connection_succeed(self, connection, closeConnection=False): """Connection succeed to the GPS device""" @@ -436,8 +439,11 @@ def getProgress(self): val = round(len(self.measures) / int(meassurementSetting) * 100) + self.lfbRecordingPercent.setValue(val) - self.lfbRecordingPercent.show() + + if self.recordingStyle != 'navigation': + self.lfbRecordingPercent.show() return val @@ -456,6 +462,7 @@ def setMeasurementsCount(self): self.lfbGPSCountSeperator.show() self.lfbGPSCount.show() self.label_2.show() + self.lfbRecordingPercent.show() def createGPSObject(self, GPSInfo): """Create a GPS object and emit values""" @@ -475,11 +482,15 @@ def createGPSObject(self, GPSInfo): self.setMeasurementsCount() + + self.currentPositionChanged.emit(GPSInfo) + + if self.recordingStyle == 'navigation': + return self.aggregatedValuesChanged.emit(self.measures) - self.currentPositionChanged.emit(GPSInfo) val = self.getProgress() - if val >= 100: + if val >= 100 and self.recordingStyle != 'navigation': self.cancelConnection(False) \ No newline at end of file diff --git a/gnavs/gui/setup/settings.py b/gnavs/gui/setup/settings.py index 0e9488e..32a4336 100644 --- a/gnavs/gui/setup/settings.py +++ b/gnavs/gui/setup/settings.py @@ -31,7 +31,7 @@ def __init__(self, interface): self.connectionTimer.setSingleShot(True) - directory = Utils.getLayerDirectory('GNAVS - Aggregated') + directory = Utils.getLayerDirectory('GNAVS-Aggregated') self.lfbFileSelectionFileWidget.setFilePath(directory) self.lfbFileSelectionFileWidget.fileChanged.connect(self.directoryEntered) @@ -147,7 +147,7 @@ def directoryEntered(self, directory): directory = directory + '.gpkg' self.lfbFileSelectionFileWidget.setFilePath(directory) - Utils.saveLayerAsFile('GNAVS - Aggregated') + Utils.saveLayerAsFile('GNAVS-Aggregated') def aggregationChanged(self, item): """Save the aggregation type""" diff --git a/gnavs/gui/setup/setup.py b/gnavs/gui/setup/setup.py index 8776d28..43f8518 100644 --- a/gnavs/gui/setup/setup.py +++ b/gnavs/gui/setup/setup.py @@ -12,6 +12,10 @@ from ..measurement.aggregation import Aggregation from ..recording.focus import Focus +from qgis.core import QgsMessageLog + +from ..measurement.precision import PrecisionNote + from ..recording.indicator import Indicator @@ -38,6 +42,8 @@ def __init__(self, interface): self.rec = self.addRecording() self.followBtn = self.addFocus() + + self.precisionNote = self.addPrecisionNote() self.measurement = self.addMeasurement() self.selection = self.addNavigation() @@ -54,6 +60,7 @@ def __del__(self): def stopTracking(self): """Stop the GPS tracking""" self.rec.cancelConnection(True) + #def stateChanged(self, state): # self.state = state @@ -75,8 +82,11 @@ def coordinatesChanged(self, gpsInfo): #self.indicator.setColor(gpsInfo) - if self.toggleState == 'navigation' and self.selection is not None: - self.selection.updateCoordinates(gpsInfo) + #if self.toggleState == 'navigation' and self.selection is not None: + self.selection.updateCoordinates(gpsInfo, self.toggleState) + + if self.toggleState == 'point': + self.precisionNote.updateIndicator(gpsInfo) def aggregatedValuesChanged(self, gpsInfos): """Update the aggregated values""" @@ -84,7 +94,8 @@ def aggregatedValuesChanged(self, gpsInfos): self.measurementCountChanged.emit(len(gpsInfos)) if self.toggleState == 'point' and len(gpsInfos) > 0: - self.measurement.updateAggregatedValues(gpsInfos) + aggregated = self.measurement.updateAggregatedValues(gpsInfos) + self.precisionNote.update(aggregated) def toggleButtonsChanged(self, toggleButtons): """Toggle between the navigation and point-recording view""" @@ -99,9 +110,11 @@ def updateView(self): if self.toggleState == 'navigation': self.selection.show() self.measurement.hide() + self.precisionNote.hide() else: self.selection.hide() self.measurement.show() + self.precisionNote.show() # self.rec.toggleButtonsChanged(self.toggleState) - Deprecated @@ -110,6 +123,7 @@ def recordingStateChanged(self, state): if state == False: self.selection.stopRecording() + self.precisionNote.hideGroup() #self.indicator.stop() def addRecording(self): @@ -124,6 +138,13 @@ def addRecording(self): self.lfbSetup.addWidget(rec) return rec + def addPrecisionNote(self): + """Add the precision note view""" + + precisionNote = PrecisionNote(self.interface) + self.lfbSetup.addWidget(precisionNote) + return precisionNote + def addFocus(self): """Add the center map view""" diff --git a/gnavs/i18n/gnavs_de.ts b/gnavs/i18n/gnavs_de.ts index 6c6a046..1a9f941 100644 --- a/gnavs/i18n/gnavs_de.ts +++ b/gnavs/i18n/gnavs_de.ts @@ -75,5 +75,10 @@ BEENDEN STOP + + + qualityNoteBad + Die Qualitätsparameter sind so schlecht, dass auf eine Messung verzichtet oder durch die Einmessung von mindestens drei Hilfspunkten mit Azimut und Distanz für eine anschließende Fehlerberrechnung und -ausgleichsrechnung erfolgen sollte. + \ No newline at end of file diff --git a/gnavs/i18n/gnavs_en.ts b/gnavs/i18n/gnavs_en.ts index f50dd27..d866675 100644 --- a/gnavs/i18n/gnavs_en.ts +++ b/gnavs/i18n/gnavs_en.ts @@ -130,5 +130,10 @@ BEENDEN STOP + + + qualityNoteBad + The quality parameters are so poor that a measurement should be omitted or should be made by measuring at least three auxiliary points with azimuth and distance for a subsequent error calculation and compensation. + \ No newline at end of file diff --git a/gnavs/metadata.txt b/gnavs/metadata.txt index c65af54..4c8a466 100644 --- a/gnavs/metadata.txt +++ b/gnavs/metadata.txt @@ -6,7 +6,7 @@ name=GNAVS qgisMinimumVersion=3.0 description=GNSS Navigate and Save -version=1.0.4 +version=1.0.5 author=Torsten Wiebke (Concept), Gerrit Balindt (Development) email=support@gruenecho.de diff --git a/gnavs/utils/utils.py b/gnavs/utils/utils.py index b95c451..ee8318b 100644 --- a/gnavs/utils/utils.py +++ b/gnavs/utils/utils.py @@ -452,7 +452,7 @@ def getLayerById(layerName): layers = QgsProject.instance().mapLayers().values() - layerId1 = re.sub('[^a-zA-Z0-9 \n\.]', '', layerName) + layerId1 = re.sub(r'[^a-zA-Z0-9 \n\.]', '', layerName) layerId2 = layerName.replace('-', '_') for layer in layers: @@ -469,7 +469,9 @@ def addPointToLayer(layerName, aggregatedValues, gpsInfos): fields = Utils.getGPSInfoFields() if layer is None: - layer = Utils.getPrivateLayers(layerName, 'point', False, False, fields) + layerId1 = re.sub(r'[^a-zA-Z0-9 \n\.]', '', layerName).lower() + layer = Utils.getPrivateLayers(layerId1, 'point', False, False, fields) + layer.setName(layerName) if layer is None: return diff --git a/plugins.xml b/plugins.xml index 3eed638..bc885c0 100644 --- a/plugins.xml +++ b/plugins.xml @@ -1,14 +1,14 @@ - + - 1.0.4 + 1.0.5 3.22 https://github.com/b-lack/qgis-gnavs-plugin gnavs.zip gnavs/icon.png Torsten Wiebke (Concept), Gerrit Balindt (Development) - https://github.com/b-lack/qgis-gnavs-plugin/releases/download/v1.0.4/gnavs.zip + https://github.com/b-lack/qgis-gnavs-plugin/releases/download/v1.0.5/gnavs.zip Grünecho 2023-07-30 2023-08-30