From e3e45a1ce1ad901d0be65c2b6a70e387ec46d241 Mon Sep 17 00:00:00 2001 From: SebastienPeillet Date: Tue, 24 Oct 2023 16:02:13 +0200 Subject: [PATCH 1/5] fix link between boat and platform --- src/core/layers/plateform.py | 33 ++++++++++++++++++++++----------- src/core/session.py | 2 ++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/core/layers/plateform.py b/src/core/layers/plateform.py index d3100010..433ecf71 100644 --- a/src/core/layers/plateform.py +++ b/src/core/layers/plateform.py @@ -20,17 +20,6 @@ def _init(self, layer: QgsVectorLayer) -> None: self._init_widgets(layer) def _init_widgets(self, layer: QgsVectorLayer) -> None: - # shipName - idx = layer.fields().indexFromName("ship") - cfg = {} - cfg["map"] = [ - {"Thalassa": "Thalassa"}, - {"Europe": "Europe"}, - {"PourquoiPas": "PourquoiPas"}, - ] - setup = QgsEditorWidgetSetup("ValueMap", cfg) - layer.setEditorWidgetSetup(idx, setup) - # plateform idx = layer.fields().indexFromName("plateform") cfg = {} @@ -56,3 +45,25 @@ def _init_widgets(self, layer: QgsVectorLayer) -> None: } setup = QgsEditorWidgetSetup("Range", cfg) layer.setEditorWidgetSetup(idx, setup) + + def _link_boat(self, boatLayer: SammoLayer): + # shipName + idx = self.layer.fields().indexFromName("ship") + cfg = { + "AllowMulti": False, + "AllowNull": False, + "Description": '"ship"', + "FilterExpression": "", + "Key": "name", + "Layer": boatLayer.layer.id(), + "LayerName": boatLayer.name, + "LayerProviderName": "ogr", + "LayerSource": boatLayer.uri, + "NofColumns": 1, + "OrderByValue": False, + "UseCompleter": False, + "Value": "name", + } + setup = QgsEditorWidgetSetup("ValueRelation", cfg) + res = self.layer.setEditorWidgetSetup(idx, setup) + print(f"le res : {res}") \ No newline at end of file diff --git a/src/core/session.py b/src/core/session.py index 53c03c7f..83e6aaf3 100644 --- a/src/core/session.py +++ b/src/core/session.py @@ -203,6 +203,7 @@ def init(self, directory: str, load: bool = True) -> None: self._worldLayer.addToProject(project) self._plateformLayer.addToProject(project) self._boatLayer.addToProject(project) + self._plateformLayer._link_boat(self._boatLayer) self._surveyLayer.addToProject(project) self._transectLayer.addToProject(project) self._strateLayer.addToProject(project) @@ -247,6 +248,7 @@ def init(self, directory: str, load: bool = True) -> None: self._plateformLayer, ]: layer._init(layer.layer) + self._plateformLayer._link_boat(self._boatLayer) self.environmentLayer.actions().clearActions() self._environmentLayer.addSoundAction(self.environmentLayer) self._environmentLayer.addDuplicateAction(self.environmentLayer) From c60c795b61eb671c6471c694c49f72d6e25d06e7 Mon Sep 17 00:00:00 2001 From: SebastienPeillet Date: Mon, 6 Nov 2023 15:21:28 +0100 Subject: [PATCH 2/5] add survey management --- data/survey_type.csv | 10 +++++++++ src/core/database.py | 8 +++++++ src/core/layers/__init__.py | 1 + src/core/layers/plateform.py | 3 +-- src/core/layers/survey.py | 38 +++++++++++++++++++++------------- src/core/layers/survey_type.py | 23 ++++++++++++++++++++ src/core/session.py | 15 +++++++++++++- src/gui/settings.py | 10 ++++++++- src/gui/ui/settings.ui | 7 +++++++ 9 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 data/survey_type.csv create mode 100644 src/core/layers/survey_type.py diff --git a/data/survey_type.csv b/data/survey_type.csv new file mode 100644 index 00000000..8d57a9f8 --- /dev/null +++ b/data/survey_type.csv @@ -0,0 +1,10 @@ +name +PELGAS +PELACUS_springtime +IBTS +PELACUS_automn +CAMANOC +JUVENA +CGFS +EVHOE +MOOSE \ No newline at end of file diff --git a/src/core/database.py b/src/core/database.py index 7203189f..d63f265b 100644 --- a/src/core/database.py +++ b/src/core/database.py @@ -37,6 +37,7 @@ WORLD_TABLE = "world" BOAT_TABLE = "boat" SURVEY_TABLE = "survey" +SURVEY_TYPE_TABLE = "survey_type" TRANSECT_TABLE = "transect" STRATE_TABLE = "strate" PLATEFORM_TABLE = "plateform" @@ -95,6 +96,8 @@ def init(self, directory: str) -> bool: self._populateTable(BEHAVIOUR_SPECIES_TABLE, "behav.csv") self._createTable(self._fieldsBoat(), BOAT_TABLE) self._populateTable(BOAT_TABLE, "boat.csv") + self._createTable(self._fieldsSurveyType(), SURVEY_TYPE_TABLE) + self._populateTable(SURVEY_TYPE_TABLE, "survey_type.csv") self._createTable(self._fieldsSurvey(), SURVEY_TABLE) self._populateTable(SURVEY_TABLE, "survey.csv") self._createTable(self._fieldsTransect(), TRANSECT_TABLE) @@ -303,6 +306,11 @@ def _populateTable(self, layer_id: str, csv_name: str) -> None: lyr.addFeature(ft) lyr.commitChanges() + def _fieldsSurveyType(self) -> QgsFields: + fields = QgsFields() + fields.append(self._createFieldShortText("name")) + return fields + def _populateBoatTable(self) -> None: boatLyr = QgsVectorLayer(self.tableUri(BOAT_TABLE), "boat", "ogr") file = Path(__file__).parent.parent.parent / "data" / "boat.csv" diff --git a/src/core/layers/__init__.py b/src/core/layers/__init__.py index 7d4d7b12..db56cb79 100644 --- a/src/core/layers/__init__.py +++ b/src/core/layers/__init__.py @@ -15,4 +15,5 @@ from .sightings import SammoSightingsLayer from .plateform import SammoPlateformLayer from .behav import SammoBehaviourSpeciesLayer +from .survey_type import SammoSurveyTypeLayer from .environment import SammoEnvironmentLayer diff --git a/src/core/layers/plateform.py b/src/core/layers/plateform.py index 433ecf71..04c642b8 100644 --- a/src/core/layers/plateform.py +++ b/src/core/layers/plateform.py @@ -65,5 +65,4 @@ def _link_boat(self, boatLayer: SammoLayer): "Value": "name", } setup = QgsEditorWidgetSetup("ValueRelation", cfg) - res = self.layer.setEditorWidgetSetup(idx, setup) - print(f"le res : {res}") \ No newline at end of file + res = self.layer.setEditorWidgetSetup(idx, setup) \ No newline at end of file diff --git a/src/core/layers/survey.py b/src/core/layers/survey.py index 0d409406..bf894184 100644 --- a/src/core/layers/survey.py +++ b/src/core/layers/survey.py @@ -11,12 +11,19 @@ ) from .layer import SammoLayer from .boat import SammoBoatLayer +from .survey_type import SammoSurveyTypeLayer class SammoSurveyLayer(SammoLayer): - def __init__(self, db: SammoDataBase, boatLayer: SammoBoatLayer): + def __init__( + self, + db: SammoDataBase, + boatLayer: SammoBoatLayer, + surveyTypeLayer: SammoSurveyTypeLayer + ): super().__init__(db, SURVEY_TABLE, "Survey") self.boatLayer = boatLayer + self.surveyTypeLayer = surveyTypeLayer def _init(self, layer: QgsVectorLayer) -> None: self._init_widgets(layer) @@ -36,19 +43,22 @@ def _init_widgets(self, layer: QgsVectorLayer) -> None: # survey idx = layer.fields().indexFromName("survey") - cfg = {} - cfg["map"] = [ - {"PELGAS": "PELGAS"}, - {"PELACUS_springtime": "PELACUS_springtime"}, - {"IBTS": "IBTS"}, - {"PELACUS_automn": "PELACUS_automn"}, - {"CAMANOC": "CAMANOC"}, - {"JUVENA": "JUVENA"}, - {"CGFS": "CGFS"}, - {"EVHOE": "EVHOE"}, - {"MOOSE": "MOOSE"}, - ] - setup = QgsEditorWidgetSetup("ValueMap", cfg) + cfg = { + "AllowMulti": False, + "AllowNull": False, + "Description": '"survey"', + "FilterExpression": "", + "Key": "name", + "Layer": self.surveyTypeLayer.layer.id(), + "LayerName": self.surveyTypeLayer.name, + "LayerProviderName": "ogr", + "LayerSource": self.surveyTypeLayer.uri, + "NofColumns": 1, + "OrderByValue": False, + "UseCompleter": False, + "Value": "name", + } + setup = QgsEditorWidgetSetup("ValueRelation", cfg) layer.setEditorWidgetSetup(idx, setup) # shipName diff --git a/src/core/layers/survey_type.py b/src/core/layers/survey_type.py new file mode 100644 index 00000000..468d9e74 --- /dev/null +++ b/src/core/layers/survey_type.py @@ -0,0 +1,23 @@ +# coding: utf8 + +__contact__ = "info@hytech-imaging.fr" +__copyright__ = "Copyright (c) 2022 Hytech Imaging" + +from qgis.core import QgsEditorWidgetSetup, QgsVectorLayer + +from ..database import ( + SURVEY_TYPE_TABLE, + SammoDataBase, +) +from .layer import SammoLayer + + +class SammoSurveyTypeLayer(SammoLayer): + def __init__(self, db: SammoDataBase): + super().__init__(db, SURVEY_TYPE_TABLE, "Survey_type") + + def _init(self, layer: QgsVectorLayer) -> None: + self._init_widgets(layer) + + def _init_widgets(self, layer: QgsVectorLayer) -> None: + pass \ No newline at end of file diff --git a/src/core/session.py b/src/core/session.py index 83e6aaf3..da7012a0 100644 --- a/src/core/session.py +++ b/src/core/session.py @@ -46,6 +46,7 @@ SammoFollowersLayer, SammoObserversLayer, SammoSightingsLayer, + SammoSurveyTypeLayer, SammoEnvironmentLayer, SammoBehaviourSpeciesLayer, ) @@ -65,6 +66,7 @@ def __init__(self): self._sightingsLayer: SammoSightingsLayer = None self._environmentLayer: SammoEnvironmentLayer = None self._surveyLayer: SammoSurveyLayer = None + self._surveyTypeLayer: SammoSurveyLayer = None self._transectLayer: SammoTransectLayer = None self._strateLayer: SammoStrateLayer = None self._plateformLayer: SammoPlateformLayer = None @@ -132,6 +134,12 @@ def surveyLayer(self) -> QgsVectorLayer: return self._surveyLayer.layer return None + @property + def surveyTypeLayer(self) -> QgsVectorLayer: + if self._surveyLayer: + return self._surveyTypeLayer.layer + return None + @property def strateLayer(self) -> QgsVectorLayer: if self._strateLayer: @@ -161,6 +169,7 @@ def allLayers(self) -> List[QgsVectorLayer]: self.speciesLayer, self.sightingsLayer, self.surveyLayer, + self.surveyTypeLayer, self.strateLayer, self.boatLayer, self.plateformLayer, @@ -177,7 +186,10 @@ def init(self, directory: str, load: bool = True) -> None: # Administrator table self._plateformLayer = SammoPlateformLayer(self.db) self._boatLayer = SammoBoatLayer(self.db, self._plateformLayer) - self._surveyLayer = SammoSurveyLayer(self.db, self._boatLayer) + self._surveyTypeLayer = SammoSurveyTypeLayer(self.db) + self._surveyLayer = SammoSurveyLayer( + self.db, self._boatLayer, self._surveyTypeLayer + ) self._transectLayer = SammoTransectLayer(self.db) self._strateLayer = SammoStrateLayer(self.db) self._observersLayer = SammoObserversLayer(self.db) @@ -204,6 +216,7 @@ def init(self, directory: str, load: bool = True) -> None: self._plateformLayer.addToProject(project) self._boatLayer.addToProject(project) self._plateformLayer._link_boat(self._boatLayer) + self._surveyTypeLayer.addToProject(project) self._surveyLayer.addToProject(project) self._transectLayer.addToProject(project) self._strateLayer.addToProject(project) diff --git a/src/gui/settings.py b/src/gui/settings.py index ca488505..47bdb730 100644 --- a/src/gui/settings.py +++ b/src/gui/settings.py @@ -55,6 +55,7 @@ def __init__(self, session): self.session = session self.surveyButton.clicked.connect(self.surveyEdit) + self.surveyTypeButton.clicked.connect(self.surveyEdit) self.transectButton.clicked.connect(self.surveyEdit) self.strateButton.clicked.connect(self.surveyEdit) self.boatButton.clicked.connect(self.surveyEdit) @@ -64,6 +65,8 @@ def __init__(self, session): def surveyEdit(self): if self.sender() == self.surveyButton: vl = self.session.surveyLayer + if self.sender() == self.surveyTypeButton: + vl = self.session.surveyTypeLayer elif self.sender() == self.transectButton: vl = self.session.transectLayer elif self.sender() == self.strateButton: @@ -76,8 +79,13 @@ def surveyEdit(self): if not vl.featureCount(): feat = QgsVectorLayerUtils.createFeature(vl) vl.addFeature(feat) - if vl in [self.session.boatLayer, self.session.plateformLayer]: + if ( + vl in [ + self.session.surveyTypeLayer, + self.session.boatLayer, self.session.plateformLayer + ] + ): dlg = QDialog(self) dlg.setModal(True) dlg.setWindowTitle(vl.name()) diff --git a/src/gui/ui/settings.ui b/src/gui/ui/settings.ui index 4132bd4a..99c88e49 100644 --- a/src/gui/ui/settings.ui +++ b/src/gui/ui/settings.ui @@ -27,6 +27,13 @@ + + + + SurveyType + + + From 9112fef75ad16bcbffabbddfb6cb132dea39e83a Mon Sep 17 00:00:00 2001 From: SebastienPeillet Date: Wed, 15 Nov 2023 16:17:43 +0100 Subject: [PATCH 3/5] add standard plateform --- src/core/layers/plateform.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/layers/plateform.py b/src/core/layers/plateform.py index 04c642b8..0186afa6 100644 --- a/src/core/layers/plateform.py +++ b/src/core/layers/plateform.py @@ -24,8 +24,10 @@ def _init_widgets(self, layer: QgsVectorLayer) -> None: idx = layer.fields().indexFromName("plateform") cfg = {} cfg["map"] = [ + {"bridge": "bridge"}, {"bridge_inside": "bridge_inside"}, {"bridge_outside": "bridge_outside"}, + {"upper_bridge": "upper_bridge"}, {"upper_bridge_outside": "upper_bridge_outside"}, {"upper_bridge_inside": "upper_bridge_inside"}, {"deck": "deck"}, From 38eb8ae1d4d0c55fa102a9255f9436dd51d252d7 Mon Sep 17 00:00:00 2001 From: SebastienPeillet Date: Wed, 15 Nov 2023 16:19:06 +0100 Subject: [PATCH 4/5] styling --- src/core/layers/plateform.py | 2 +- src/core/layers/survey.py | 2 +- src/core/layers/survey_type.py | 4 ++-- src/gui/export.py | 2 +- src/gui/settings.py | 8 +++----- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/layers/plateform.py b/src/core/layers/plateform.py index 0186afa6..1a71aa99 100644 --- a/src/core/layers/plateform.py +++ b/src/core/layers/plateform.py @@ -67,4 +67,4 @@ def _link_boat(self, boatLayer: SammoLayer): "Value": "name", } setup = QgsEditorWidgetSetup("ValueRelation", cfg) - res = self.layer.setEditorWidgetSetup(idx, setup) \ No newline at end of file + self.layer.setEditorWidgetSetup(idx, setup) diff --git a/src/core/layers/survey.py b/src/core/layers/survey.py index bf894184..076e1dd2 100644 --- a/src/core/layers/survey.py +++ b/src/core/layers/survey.py @@ -19,7 +19,7 @@ def __init__( self, db: SammoDataBase, boatLayer: SammoBoatLayer, - surveyTypeLayer: SammoSurveyTypeLayer + surveyTypeLayer: SammoSurveyTypeLayer, ): super().__init__(db, SURVEY_TABLE, "Survey") self.boatLayer = boatLayer diff --git a/src/core/layers/survey_type.py b/src/core/layers/survey_type.py index 468d9e74..0117b8ab 100644 --- a/src/core/layers/survey_type.py +++ b/src/core/layers/survey_type.py @@ -3,7 +3,7 @@ __contact__ = "info@hytech-imaging.fr" __copyright__ = "Copyright (c) 2022 Hytech Imaging" -from qgis.core import QgsEditorWidgetSetup, QgsVectorLayer +from qgis.core import QgsVectorLayer from ..database import ( SURVEY_TYPE_TABLE, @@ -20,4 +20,4 @@ def _init(self, layer: QgsVectorLayer) -> None: self._init_widgets(layer) def _init_widgets(self, layer: QgsVectorLayer) -> None: - pass \ No newline at end of file + pass diff --git a/src/gui/export.py b/src/gui/export.py index 4c09ea0c..016c263d 100644 --- a/src/gui/export.py +++ b/src/gui/export.py @@ -293,7 +293,7 @@ def obsSpeLayerJoinInfo(self, layer: QgsVectorLayer) -> None: "name_fr", "group_fr", "family_fr", - "taxon_fr" + "taxon_fr", ] ) return speciesJoinInfo diff --git a/src/gui/settings.py b/src/gui/settings.py index 47bdb730..b2a8ecc0 100644 --- a/src/gui/settings.py +++ b/src/gui/settings.py @@ -79,13 +79,11 @@ def surveyEdit(self): if not vl.featureCount(): feat = QgsVectorLayerUtils.createFeature(vl) vl.addFeature(feat) - if ( - vl in [ + if vl in [ self.session.surveyTypeLayer, self.session.boatLayer, - self.session.plateformLayer - ] - ): + self.session.plateformLayer, + ]: dlg = QDialog(self) dlg.setModal(True) dlg.setWindowTitle(vl.name()) From 8eea27bdd00be8abf3f99f3faac7b476b361f706 Mon Sep 17 00:00:00 2001 From: SebastienPeillet Date: Thu, 16 Nov 2023 12:41:28 +0100 Subject: [PATCH 5/5] merge strate into transect and change transect into multi entity transect layer + import transect --- src/core/database.py | 35 ++++++++++----------- src/core/layers/__init__.py | 1 - src/core/layers/environment.py | 26 ++++++++++++++++ src/core/layers/strate.py | 44 -------------------------- src/core/layers/transect.py | 21 ++++++++++++- src/core/session.py | 54 +++++--------------------------- src/gui/export.py | 33 ++++++++++++++++---- src/gui/settings.py | 56 +++++++++++++++++++++++++++++++--- src/gui/ui/settings.ui | 40 ++++++++++++++++-------- 9 files changed, 175 insertions(+), 135 deletions(-) delete mode 100644 src/core/layers/strate.py diff --git a/src/core/database.py b/src/core/database.py index d63f265b..588db21b 100644 --- a/src/core/database.py +++ b/src/core/database.py @@ -14,6 +14,7 @@ QgsFeature, QgsProject, QgsWkbTypes, + QgsGeometry, QgsApplication, QgsFeatureSink, QgsVectorLayer, @@ -39,7 +40,6 @@ SURVEY_TABLE = "survey" SURVEY_TYPE_TABLE = "survey_type" TRANSECT_TABLE = "transect" -STRATE_TABLE = "strate" PLATEFORM_TABLE = "plateform" @@ -100,10 +100,10 @@ def init(self, directory: str) -> bool: self._populateTable(SURVEY_TYPE_TABLE, "survey_type.csv") self._createTable(self._fieldsSurvey(), SURVEY_TABLE) self._populateTable(SURVEY_TABLE, "survey.csv") - self._createTable(self._fieldsTransect(), TRANSECT_TABLE) - self._populateTable(TRANSECT_TABLE, "transect.csv") - self._createTable(self._fieldsStrate(), STRATE_TABLE) - self._populateTable(STRATE_TABLE, "strate.csv") + self._createTable( + self._fieldsTransect(), TRANSECT_TABLE, QgsWkbTypes.LineString + ) + self._populateTable(TRANSECT_TABLE, "transect.csv", ";") self._createTable(self._fieldsPlateform(), PLATEFORM_TABLE) self._populatePlateformTable() @@ -147,6 +147,7 @@ def _createFieldsForEnvironmentTable(self) -> QgsFields: fields.append(self._createFieldShortText("right")) fields.append(QgsField("dateTime", QVariant.DateTime)) fields.append(self._createFieldShortText("plateformId")) + fields.append(self._createFieldShortText("transectId")) fields.append(self._createFieldShortText("routeType")) fields.append(QgsField("speed", QVariant.Int)) fields.append(QgsField("courseAverage", QVariant.Int)) @@ -166,9 +167,6 @@ def _createFieldsForEnvironmentTable(self) -> QgsFields: fields.append(self._createFieldShortText("camera")) fields.append(QgsField("comment", QVariant.String, len=200)) fields.append(self._createFieldShortText("center")) - fields.append(self._createFieldShortText("transect")) - fields.append(self._createFieldShortText("strate")) - fields.append(self._createFieldShortText("length")) fields.append(self._createFieldShortText("status", len=5)) fields.append(self._createFieldShortText("soundFile", len=80)) @@ -284,20 +282,26 @@ def _fieldsBoat(self) -> QgsFields: fields.append(self._createFieldShortText("name")) return fields - def _populateTable(self, layer_id: str, csv_name: str) -> None: + def _populateTable( + self, layer_id: str, csv_name: str, delimiter="," + ) -> None: lyr = QgsVectorLayer(self.tableUri(layer_id), "no_matter", "ogr") file = Path(__file__).parent.parent.parent / "data" / csv_name lines = [] if file.exists(): with open(file.as_posix()) as f: lines = [ - {k: v for k, v in row.items()} for row in csv.DictReader(f) + {k: v for k, v in row.items()} + for row in csv.DictReader(f, delimiter=delimiter) ] lyr.startEditing() for attr in lines: ft = QgsFeature(lyr.fields()) for k, v in attr.items(): - if lyr.fields()[k].typeName() == "Integer": + if k == "wkt": + geom = QgsGeometry.fromWkt(v) + ft.setGeometry(geom) + elif lyr.fields()[k].typeName() == "Integer": ft[k] = int(v) elif lyr.fields()[k].typeName() == "Real": ft[k] = float(v) @@ -343,15 +347,8 @@ def _fieldsTransect(self) -> QgsFields: fields = QgsFields() fields.append(self._createFieldShortText("transect")) fields.append(self._createFieldShortText("strate")) - fields.append(QgsField("length", QVariant.Int)) - - return fields - - def _fieldsStrate(self) -> QgsFields: - fields = QgsFields() - fields.append(self._createFieldShortText("strate")) fields.append(self._createFieldShortText("subRegion")) - fields.append(self._createFieldShortText("region")) + fields.append(QgsField("length", QVariant.Int)) return fields diff --git a/src/core/layers/__init__.py b/src/core/layers/__init__.py index db56cb79..4a157368 100644 --- a/src/core/layers/__init__.py +++ b/src/core/layers/__init__.py @@ -7,7 +7,6 @@ from .boat import SammoBoatLayer from .world import SammoWorldLayer from .survey import SammoSurveyLayer -from .strate import SammoStrateLayer from .species import SammoSpeciesLayer from .transect import SammoTransectLayer from .followers import SammoFollowersLayer diff --git a/src/core/layers/environment.py b/src/core/layers/environment.py index 9c47133d..955d1528 100644 --- a/src/core/layers/environment.py +++ b/src/core/layers/environment.py @@ -19,6 +19,7 @@ ) from .layer import SammoLayer +from .transect import SammoTransectLayer from .plateform import SammoPlateformLayer from .observers import SammoObserversLayer @@ -29,6 +30,7 @@ def __init__( db: SammoDataBase, observersLayer: SammoObserversLayer, plateformLayer: SammoPlateformLayer, + transectLayer: SammoTransectLayer, ): super().__init__( db, @@ -39,6 +41,7 @@ def __init__( ) self.observersLayer = observersLayer self.plateformLayer = plateformLayer + self.transectLayer = transectLayer def _init(self, layer: QgsVectorLayer): self._init_symbology(layer) @@ -93,6 +96,29 @@ def _init_widgets(self, layer: QgsVectorLayer) -> None: layer.setEditFormConfig(form_config) layer.setFieldAlias(idx, "plateform") + # transect + idx = layer.fields().indexFromName("transectId") + cfg = { + "AllowMulti": False, + "AllowNull": True, + "Description": "transect", + "Key": "fid", + "Layer": self.transectLayer.layer.id(), + "LayerName": self.transectLayer.name, + "LayerProviderName": "ogr", + "LayerSource": self.transectLayer.uri, + "NofColumns": 1, + "OrderByValue": False, + "UseCompleter": False, + "Value": "transect", + } + setup = QgsEditorWidgetSetup("ValueRelation", cfg) + layer.setEditorWidgetSetup(idx, setup) + form_config = layer.editFormConfig() + form_config.setReadOnly(idx, False) + layer.setEditFormConfig(form_config) + layer.setFieldAlias(idx, "transect") + # route type idx = layer.fields().indexFromName("routeType") cfg = {} diff --git a/src/core/layers/strate.py b/src/core/layers/strate.py deleted file mode 100644 index 59d5ac2c..00000000 --- a/src/core/layers/strate.py +++ /dev/null @@ -1,44 +0,0 @@ -# coding: utf8 - -__contact__ = "info@hytech-imaging.fr" -__copyright__ = "Copyright (c) 2022 Hytech Imaging" - -from qgis.core import QgsEditorWidgetSetup, QgsVectorLayer -from ..database import ( - SammoDataBase, - STRATE_TABLE, -) - -from .layer import SammoLayer - - -class SammoStrateLayer(SammoLayer): - def __init__(self, db: SammoDataBase): - super().__init__(db, STRATE_TABLE, "Strate") - - def _init(self, layer: QgsVectorLayer) -> None: - self._init_widgets(layer) - - def _init_widgets(self, layer: QgsVectorLayer) -> None: - # subRegion - idx = layer.fields().indexFromName("subRegion") - cfg = {} - cfg["map"] = [ - {"MED": "MED"}, - {"ATL": "ATL"}, - {"MAN": "MAN"}, - ] - setup = QgsEditorWidgetSetup("ValueMap", cfg) - layer.setEditorWidgetSetup(idx, setup) - - # region - idx = layer.fields().indexFromName("region") - cfg = {} - cfg["map"] = [ - {"NEA": "NEA"}, - {"NSP": "NSP"}, - {"EA": "EA"}, - {"WC": "WC"}, - ] - setup = QgsEditorWidgetSetup("ValueMap", cfg) - layer.setEditorWidgetSetup(idx, setup) diff --git a/src/core/layers/transect.py b/src/core/layers/transect.py index e0f56e2b..04e0ddc0 100644 --- a/src/core/layers/transect.py +++ b/src/core/layers/transect.py @@ -3,7 +3,8 @@ __contact__ = "info@hytech-imaging.fr" __copyright__ = "Copyright (c) 2022 Hytech Imaging" -from qgis.core import QgsEditorWidgetSetup, QgsVectorLayer +from qgis.PyQt.QtGui import QColor +from qgis.core import QgsEditorWidgetSetup, QgsVectorLayer, QgsLineSymbol from ..database import ( SammoDataBase, TRANSECT_TABLE, @@ -17,8 +18,15 @@ def __init__(self, db: SammoDataBase): super().__init__(db, TRANSECT_TABLE, "Transect") def _init(self, layer: QgsVectorLayer) -> None: + self._init_symbology(layer) self._init_widgets(layer) + def _init_symbology(self, layer) -> None: + symbol = QgsLineSymbol.createSimple( + {"color": QColor("red"), "width": "1.5"} + ) + layer.renderer().setSymbol(symbol) + def _init_widgets(self, layer: QgsVectorLayer) -> None: # strate idx = layer.fields().indexFromName("strate") @@ -30,3 +38,14 @@ def _init_widgets(self, layer: QgsVectorLayer) -> None: ] setup = QgsEditorWidgetSetup("ValueMap", cfg) layer.setEditorWidgetSetup(idx, setup) + + # subRegion + idx = layer.fields().indexFromName("subRegion") + cfg = {} + cfg["map"] = [ + {"MED": "MED"}, + {"ATL": "ATL"}, + {"MAN": "MAN"}, + ] + setup = QgsEditorWidgetSetup("ValueMap", cfg) + layer.setEditorWidgetSetup(idx, setup) diff --git a/src/core/session.py b/src/core/session.py index da7012a0..925acf14 100644 --- a/src/core/session.py +++ b/src/core/session.py @@ -39,7 +39,6 @@ SammoBoatLayer, SammoWorldLayer, SammoSurveyLayer, - SammoStrateLayer, SammoSpeciesLayer, SammoTransectLayer, SammoPlateformLayer, @@ -68,7 +67,6 @@ def __init__(self): self._surveyLayer: SammoSurveyLayer = None self._surveyTypeLayer: SammoSurveyLayer = None self._transectLayer: SammoTransectLayer = None - self._strateLayer: SammoStrateLayer = None self._plateformLayer: SammoPlateformLayer = None self.lastGpsInfo: Dict[ str, @@ -140,12 +138,6 @@ def surveyTypeLayer(self) -> QgsVectorLayer: return self._surveyTypeLayer.layer return None - @property - def strateLayer(self) -> QgsVectorLayer: - if self._strateLayer: - return self._strateLayer.layer - return None - @property def plateformLayer(self) -> QgsVectorLayer: if self._plateformLayer: @@ -170,7 +162,6 @@ def allLayers(self) -> List[QgsVectorLayer]: self.sightingsLayer, self.surveyLayer, self.surveyTypeLayer, - self.strateLayer, self.boatLayer, self.plateformLayer, self.transectLayer, @@ -191,7 +182,6 @@ def init(self, directory: str, load: bool = True) -> None: self.db, self._boatLayer, self._surveyTypeLayer ) self._transectLayer = SammoTransectLayer(self.db) - self._strateLayer = SammoStrateLayer(self.db) self._observersLayer = SammoObserversLayer(self.db) self._behaviourSpeciesLayer = SammoBehaviourSpeciesLayer(self.db) self._speciesLayer = SammoSpeciesLayer(self.db) @@ -204,7 +194,10 @@ def init(self, directory: str, load: bool = True) -> None: self.db, self._observersLayer, self._speciesLayer ) self._environmentLayer = SammoEnvironmentLayer( - self.db, self._observersLayer, self._plateformLayer + self.db, + self._observersLayer, + self._plateformLayer, + self._transectLayer, ) # create database if necessary @@ -219,7 +212,6 @@ def init(self, directory: str, load: bool = True) -> None: self._surveyTypeLayer.addToProject(project) self._surveyLayer.addToProject(project) self._transectLayer.addToProject(project) - self._strateLayer.addToProject(project) self._gpsLayer.addToProject(project) self._behaviourSpeciesLayer.addToProject(project) self._speciesLayer.addToProject(project) @@ -256,8 +248,8 @@ def init(self, directory: str, load: bool = True) -> None: self._sightingsLayer, self._environmentLayer, self._surveyLayer, + self._surveyTypeLayer, self._transectLayer, - self._strateLayer, self._plateformLayer, ]: layer._init(layer.layer) @@ -314,33 +306,6 @@ def surveyValues(self, layer: QgsVectorLayer) -> tuple: session_value, ) - def transectValues(self, layer: QgsVectorLayer) -> tuple: - transect = ( - next(self.transectLayer.getFeatures()) - if self.transectLayer.featureCount() > 0 - else None - ) - print(transect, self.transectLayer.featureCount()) - if ( - not transect - or not transect["transect"] - or not transect["strate"] - or not transect["length"] - ): - iface.messageBar().pushWarning( - layer.name(), - "Administration table `transect` is not fulfilled," - f" all {layer.name().lower()} attributes cannot be filled", - ) - transect_value = "" - strate_value = "" - length_value = 0 - else: - transect_value = transect["transect"] - strate_value = transect["strate"] - length_value = transect["length"] - return transect_value, strate_value, length_value - def addEnvironmentFeature(self) -> QgsVectorLayer: layer = self.environmentLayer statusCode = StatusCode.display( @@ -355,7 +320,6 @@ def addEnvironmentFeature(self) -> QgsVectorLayer: ship_value, session_value, ) = self.surveyValues(layer) - transect_value, strate_value, length_value = self.transectValues(layer) # EffortGroup management effortGroup = max( @@ -384,9 +348,6 @@ def addEnvironmentFeature(self) -> QgsVectorLayer: session=session_value, computer=computer_value, shipName=ship_value, - transect=transect_value, - strate_value=strate_value, - length=length_value, ) return layer @@ -872,11 +833,12 @@ def merge( # copy content of static layers only if output is empty staticLayers = [ "speciesLayer", - "observersLayer", "surveyLayer", - "strateLayer", "transectLayer", "plateformLayer", + "observersLayer", + "surveyTypeLayer", + "behaviourSpeciesLayer", ] for layer in staticLayers: out = getattr(sessionOutput, layer) diff --git a/src/gui/export.py b/src/gui/export.py index 016c263d..a8982cdb 100644 --- a/src/gui/export.py +++ b/src/gui/export.py @@ -217,25 +217,36 @@ def export(self) -> None: layer.addJoin(self.obsSpeLayerJoinInfo(speciesJoinLayer)) elif layer.name() == self.session.environmentLayer.name(): - joinLayer = QgsVectorLayer( + obsJoinLayer = QgsVectorLayer( self.session.observersLayer.source(), self.session.observersLayer.name(), ) # keepped alive until export is done layer.addJoin( - self.environmentLayerJoinObserverInfo(joinLayer, "left") + self.environmentLayerJoinObserverInfo(obsJoinLayer, "left") ) layer.addJoin( - self.environmentLayerJoinObserverInfo(joinLayer, "rigth") + self.environmentLayerJoinObserverInfo( + obsJoinLayer, "rigth" + ) ) layer.addJoin( - self.environmentLayerJoinObserverInfo(joinLayer, "center") + self.environmentLayerJoinObserverInfo( + obsJoinLayer, "center" + ) ) - joinLayer = QgsVectorLayer( + plateformJoinLayer = QgsVectorLayer( self.session.plateformLayer.source(), self.session.plateformLayer.name(), ) layer.addJoin( - self.environmentLayerJoinPlateformInfo(joinLayer) + self.environmentLayerJoinPlateformInfo(plateformJoinLayer) + ) + transectJoinLayer = QgsVectorLayer( + self.session.transectLayer.source(), + self.session.transectLayer.name(), + ) + layer.addJoin( + self.environmentLayerJoinTransectInfo(transectJoinLayer) ) layer = self.addEndEffortFeature(layer) @@ -248,6 +259,7 @@ def export(self) -> None: not in [ "validated", "plateformId", + "transectId", "_effortLeg", "_effortGroup", "_focalId", @@ -320,6 +332,15 @@ def environmentLayerJoinPlateformInfo(self, layer: QgsVectorLayer) -> None: joinInfo.setJoinFieldNamesSubset(["plateform", "plateformHeight"]) return joinInfo + def environmentLayerJoinTransectInfo(self, layer: QgsVectorLayer) -> None: + joinInfo = QgsVectorLayerJoinInfo() + joinInfo.setJoinLayer(layer) + joinInfo.setJoinFieldName("fid") + joinInfo.setTargetFieldName("transectId") + joinInfo.setPrefix("") + joinInfo.setJoinFieldNamesSubset(["transect", "strate", "length"]) + return joinInfo + def addEndEffortFeature(self, layer: QgsVectorLayer) -> QgsVectorLayer: effortGroupValues = layer.uniqueValues( layer.fields().indexOf("_effortGroup") diff --git a/src/gui/settings.py b/src/gui/settings.py index b2a8ecc0..2d3cc387 100644 --- a/src/gui/settings.py +++ b/src/gui/settings.py @@ -7,12 +7,13 @@ from qgis.PyQt import uic from qgis.utils import iface -from qgis.PyQt.QtCore import QObject -from qgis.core import QgsVectorLayerUtils +from qgis.PyQt.QtCore import QObject, QDir +from qgis.core import QgsVectorLayerUtils, QgsVectorLayer, QgsFeature from qgis.PyQt.QtWidgets import ( QAction, QToolBar, QDialog, + QFileDialog, QVBoxLayout, QHBoxLayout, ) @@ -57,7 +58,7 @@ def __init__(self, session): self.surveyButton.clicked.connect(self.surveyEdit) self.surveyTypeButton.clicked.connect(self.surveyEdit) self.transectButton.clicked.connect(self.surveyEdit) - self.strateButton.clicked.connect(self.surveyEdit) + self.transectImportButton.clicked.connect(self.importTransect) self.boatButton.clicked.connect(self.surveyEdit) self.plateformButton.clicked.connect(self.surveyEdit) self.closeButton.clicked.connect(self.close) @@ -69,8 +70,6 @@ def surveyEdit(self): vl = self.session.surveyTypeLayer elif self.sender() == self.transectButton: vl = self.session.transectLayer - elif self.sender() == self.strateButton: - vl = self.session.strateLayer elif self.sender() == self.plateformButton: vl = self.session.plateformLayer elif self.sender() == self.boatButton: @@ -83,6 +82,7 @@ def surveyEdit(self): self.session.surveyTypeLayer, self.session.boatLayer, self.session.plateformLayer, + self.session.transectLayer, ]: dlg = QDialog(self) dlg.setModal(True) @@ -102,3 +102,49 @@ def surveyEdit(self): feat = next(vl.getFeatures()) iface.openFeatureForm(vl, feat) vl.commitChanges() + + def importTransect(self): + transect_path, _ = QFileDialog.getOpenFileName( + self, + "Select a ogr transect file", + QDir.currentPath(), + filter="OGR file (*.shp *.gpkg)", + options=QFileDialog.DontUseNativeDialog, + ) + if not transect_path: + return + lyr = QgsVectorLayer(transect_path, "importTransect", "ogr") + lyr.geometryType() + if lyr.geometryType() != 1: # not Linestring + iface.messageBar().pushWarning( + "Geometry Error", + "Imported transect layer is not a LineString layer, " + "please provide a LineString layer", + ) + return + elif lyr.crs().postgisSrid() != 4326: # not EPSG:4326: + iface.messageBar().pushWarning( + "CRS Error", "Convert the transect layer in EPSG:4326 first" + ) + return + + self.session.transectLayer.startEditing() + for importedFt in lyr.getFeatures(): + ft = QgsFeature(self.session.transectLayer.fields()) + ft.setGeometry(importedFt.geometry()) + for field in ft.fields(): + if field.name() == "fid": + continue + elif field.name() in lyr.fields().names(): + if field.type() is not lyr.fields()[field.name()].type(): + if field.typeName() == "Integer": + value = int(importedFt[field.name()]) + elif field.typeName() == "Real": + value = float(importedFt[field.name()]) + else: + value = importedFt[field.name()] + else: + value = importedFt[field.name()] + ft[field.name()] = value + self.session.transectLayer.addFeature(ft) + self.session.transectLayer.commitChanges() diff --git a/src/gui/ui/settings.ui b/src/gui/ui/settings.ui index 99c88e49..6486691c 100644 --- a/src/gui/ui/settings.ui +++ b/src/gui/ui/settings.ui @@ -7,7 +7,7 @@ 0 0 400 - 242 + 273 @@ -35,18 +35,32 @@ - - - Transect - - - - - - - Strate - - + + + + + Transect + + + + + + + + 40 + 16777215 + + + + + + + + ../../../images/plus.png../../../images/plus.png + + + +