diff --git a/HISTORY.rst b/HISTORY.rst index 91cecee..9f03318 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,7 +4,7 @@ History 1.11 (unreleased) ----------------- -- Fixes/enhancements: #190 +- Fixes/enhancements: #190, #222, #224, #227, #228 1.10 (2024-04-12) diff --git a/threedi_schematisation_editor/custom_tools/__init__.py b/threedi_schematisation_editor/custom_tools/__init__.py index 2c5898f..7803ed0 100644 --- a/threedi_schematisation_editor/custom_tools/__init__.py +++ b/threedi_schematisation_editor/custom_tools/__init__.py @@ -200,7 +200,9 @@ class PointFeaturesImporter(AbstractFeaturesImporter): def new_structure_geometry(self, src_structure_feat): """Create new structure geometry based on the source structure feature.""" - src_geometry = src_structure_feat.geometry() + src_geometry = QgsGeometry(src_structure_feat.geometry()) + if src_geometry.isMultipart(): + src_geometry.convertToSingleType() src_point = src_geometry.asPoint() dst_point = src_point dst_geometry = QgsGeometry.fromPointXY(dst_point) @@ -289,6 +291,9 @@ def import_structures(self, context=None, selected_ids=None): create_connection_nodes, transformation, ) + new_structure_geom = new_structure_feat.geometry() + if find_point_nodes(new_structure_geom.asPoint(), self.structure_layer) is not None: + continue if new_nodes: self.update_attributes(dm.ConnectionNode, external_src_feat, *new_nodes) self.node_layer.addFeatures(new_nodes) @@ -296,15 +301,7 @@ def import_structures(self, context=None, selected_ids=None): self.update_attributes(self.structure_model_cls, external_src_feat, new_structure_feat) next_structure_id += 1 new_structures.append(new_structure_feat) - commit_errors = [] - success = self.node_layer.commitChanges() - if not success: - commit_errors += self.node_layer.commitErrors() self.structure_layer.addFeatures(new_structures) - success = self.structure_layer.commitChanges() - if not success: - commit_errors += self.structure_layer.commitErrors() - return success, commit_errors class LinearFeaturesImporter(AbstractFeaturesImporter): @@ -324,7 +321,9 @@ def setup_target_layers(self, structure_model_cls, structure_layer=None, node_la def new_structure_geometry(self, src_structure_feat): """Create new structure geometry based on the source structure feature.""" - src_geometry = src_structure_feat.geometry() + src_geometry = QgsGeometry(src_structure_feat.geometry()) + if src_geometry.isMultipart(): + src_geometry.convertToSingleType() src_polyline = src_geometry.asPolyline() dst_polyline = src_polyline if self.structure_model_cls == dm.Culvert else [src_polyline[0], src_polyline[-1]] dst_geometry = QgsGeometry.fromPolylineXY(dst_polyline) @@ -482,22 +481,11 @@ def import_structures(self, context=None, selected_ids=None): next_structure_id += 1 new_structures.append(new_structure_feat) external_source_structures.append(external_src_feat) - commit_errors = [] - success = self.node_layer.commitChanges() - if not success: - commit_errors += self.node_layer.commitErrors() if create_manholes: self.manhole_layer.startEditing() new_manholes = self.manholes_for_structures(external_source_structures, new_structures) self.manhole_layer.addFeatures(new_manholes) - success = self.manhole_layer.commitChanges() - if not success: - commit_errors += self.manhole_layer.commitErrors() self.structure_layer.addFeatures(new_structures) - success = self.structure_layer.commitChanges() - if not success: - commit_errors += self.structure_layer.commitErrors() - return success, commit_errors class CulvertsImporter(LinearFeaturesImporter): diff --git a/threedi_schematisation_editor/custom_widgets/__init__.py b/threedi_schematisation_editor/custom_widgets/__init__.py index dcb1986..2f806d8 100644 --- a/threedi_schematisation_editor/custom_widgets/__init__.py +++ b/threedi_schematisation_editor/custom_widgets/__init__.py @@ -585,12 +585,8 @@ def run_import_structures(self): structure_layer=structure_layer, node_layer=node_layer, ) - success, commit_errors = structures_importer.import_structures(selected_ids=selected_feat_ids) - if not success: - commit_errors_message = "\n".join(commit_errors) - self.uc.show_warn(f"Import failed due to the following errors:\n{commit_errors_message}") - else: - self.uc.show_info(f"Features successfully imported.", self) + structures_importer.import_structures(selected_ids=selected_feat_ids) + self.uc.show_info(f"Features successfully imported.", self) except Exception as e: self.uc.show_error(f"Import failed due to the following error:\n{e}", self) finally: diff --git a/threedi_schematisation_editor/processing/alghorithms_inflow.py b/threedi_schematisation_editor/processing/alghorithms_inflow.py index d527de2..b71c584 100644 --- a/threedi_schematisation_editor/processing/alghorithms_inflow.py +++ b/threedi_schematisation_editor/processing/alghorithms_inflow.py @@ -8,6 +8,7 @@ QgsProcessing, QgsProcessingAlgorithm, QgsProcessingException, + QgsProcessingParameterBoolean, QgsProcessingParameterEnum, QgsProcessingParameterNumber, QgsProcessingParameterVectorLayer, @@ -23,8 +24,10 @@ class LinkSurfacesWithNodes(QgsProcessingAlgorithm): """Link (impervious) surfaces to connection nodes.""" SURFACE_LAYER = "SURFACE_LAYER" + SELECTED_SURFACES = "SELECTED_SURFACES" SURFACE_MAP_LAYER = "SURFACE_MAP_LAYER" PIPE_LAYER = "PIPE_LAYER" + SELECTED_PIPES = "SELECTED_PIPES" NODE_LAYER = "NODE_LAYER" SEWERAGE_TYPES = "SEWERAGE_TYPES" STORMWATER_SEWER_PREFERENCE = "STORMWATER_SEWER_PREFERENCE" @@ -84,6 +87,12 @@ def initAlgorithm(self, config=None): defaultValue="Impervious Surface", ) ) + self.addParameter( + QgsProcessingParameterBoolean( + self.SELECTED_SURFACES, + self.tr("Selected (impervious) surfaces only"), + ) + ) self.addParameter( QgsProcessingParameterVectorLayer( self.SURFACE_MAP_LAYER, @@ -100,6 +109,12 @@ def initAlgorithm(self, config=None): defaultValue="Pipe", ) ) + self.addParameter( + QgsProcessingParameterBoolean( + self.SELECTED_PIPES, + self.tr("Selected pipes only"), + ) + ) self.addParameter( QgsProcessingParameterVectorLayer( self.NODE_LAYER, @@ -143,9 +158,11 @@ def processAlgorithm(self, parameters, context, feedback): surface_map_lyr = self.parameterAsLayer(parameters, self.SURFACE_MAP_LAYER, context) if surface_map_lyr is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.SURFACE_MAP_LAYER)) + selected_surfaces = self.parameterAsBool(parameters, self.SELECTED_SURFACES, context) pipe_lyr = self.parameterAsLayer(parameters, self.PIPE_LAYER, context) if pipe_lyr is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.PIPE_LAYER)) + selected_pipes = self.parameterAsBool(parameters, self.SELECTED_PIPES, context) node_lyr = self.parameterAsLayer(parameters, self.NODE_LAYER, context) if node_lyr is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.NODE_LAYER)) @@ -162,15 +179,16 @@ def processAlgorithm(self, parameters, context, feedback): if search_distance is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.SEARCH_DISTANCE)) surface_to_pipes_distances = {} + pipe_iterator = pipe_lyr.selectedFeatures() if selected_pipes else pipe_lyr.getFeatures() pipe_filter_request = QgsFeatureRequest( - [feat.id() for feat in pipe_lyr.getFeatures() if feat["sewerage_type"] in sewerage_types] + [feat.id() for feat in pipe_iterator if feat["sewerage_type"] in sewerage_types] ) pipe_features, pipe_index = spatial_index(pipe_lyr, pipe_filter_request) feedback.setProgress(0) - number_of_surfaces = surface_lyr.featureCount() + number_of_surfaces = surface_lyr.selectedFeatureCount() if selected_surfaces else surface_lyr.featureCount() number_of_steps = number_of_surfaces * 2 step = 1 - for surface_feat in surface_lyr.getFeatures(): + for surface_feat in surface_lyr.selectedFeatures() if selected_surfaces else surface_lyr.getFeatures(): if feedback.isCanceled(): return {} surface_fid = surface_feat.id() diff --git a/threedi_schematisation_editor/processing/algorithms_conversion.py b/threedi_schematisation_editor/processing/algorithms_conversion.py index 0a9733a..6c43d91 100644 --- a/threedi_schematisation_editor/processing/algorithms_conversion.py +++ b/threedi_schematisation_editor/processing/algorithms_conversion.py @@ -83,10 +83,7 @@ def processAlgorithm(self, parameters, context, feedback): with open(import_config_file) as import_config_json: import_config = json.loads(import_config_json.read()) culverts_importer = CulvertsImporter(source_layer, target_gpkg, import_config) - success, commit_errors = culverts_importer.import_structures(context=context) - if not success: - commit_errors_message = "\n".join(commit_errors) - feedback.reportError(commit_errors_message) + culverts_importer.import_structures(context=context) return {} def postProcessAlgorithm(self, context, feedback): @@ -158,10 +155,7 @@ def processAlgorithm(self, parameters, context, feedback): with open(import_config_file) as import_config_json: import_config = json.loads(import_config_json.read()) orifices_importer = OrificesImporter(source_layer, target_gpkg, import_config) - success, commit_errors = orifices_importer.import_structures(context=context) - if not success: - commit_errors_message = "\n".join(commit_errors) - feedback.reportError(commit_errors_message) + orifices_importer.import_structures(context=context) return {} def postProcessAlgorithm(self, context, feedback): @@ -233,10 +227,7 @@ def processAlgorithm(self, parameters, context, feedback): with open(import_config_file) as import_config_json: import_config = json.loads(import_config_json.read()) weirs_importer = WeirsImporter(source_layer, target_gpkg, import_config) - success, commit_errors = weirs_importer.import_structures(context=context) - if not success: - commit_errors_message = "\n".join(commit_errors) - feedback.reportError(commit_errors_message) + weirs_importer.import_structures(context=context) return {} def postProcessAlgorithm(self, context, feedback): @@ -308,10 +299,7 @@ def processAlgorithm(self, parameters, context, feedback): with open(import_config_file) as import_config_json: import_config = json.loads(import_config_json.read()) pipes_importer = PipesImporter(source_layer, target_gpkg, import_config) - success, commit_errors = pipes_importer.import_structures(context=context) - if not success: - commit_errors_message = "\n".join(commit_errors) - feedback.reportError(commit_errors_message) + pipes_importer.import_structures(context=context) return {} def postProcessAlgorithm(self, context, feedback): @@ -383,10 +371,7 @@ def processAlgorithm(self, parameters, context, feedback): with open(import_config_file) as import_config_json: import_config = json.loads(import_config_json.read()) manholes_importer = ManholesImporter(source_layer, target_gpkg, import_config) - success, commit_errors = manholes_importer.import_structures(context=context) - if not success: - commit_errors_message = "\n".join(commit_errors) - feedback.reportError(commit_errors_message) + manholes_importer.import_structures(context=context) return {} def postProcessAlgorithm(self, context, feedback):