diff --git a/m2l/processing/algorithms/__init__.py b/m2l/processing/algorithms/__init__.py index 08d76a0..a702bdf 100644 --- a/m2l/processing/algorithms/__init__.py +++ b/m2l/processing/algorithms/__init__.py @@ -1,4 +1,5 @@ from .extract_basal_contacts import BasalContactsAlgorithm +from .extract_contacts import ContactsAlgorithm from .sorter import StratigraphySorterAlgorithm from .user_defined_sorter import UserDefinedStratigraphyAlgorithm from .thickness_calculator import ThicknessCalculatorAlgorithm diff --git a/m2l/processing/algorithms/extract_basal_contacts.py b/m2l/processing/algorithms/extract_basal_contacts.py index 4d3ba5f..93e866d 100644 --- a/m2l/processing/algorithms/extract_basal_contacts.py +++ b/m2l/processing/algorithms/extract_basal_contacts.py @@ -43,7 +43,6 @@ class BasalContactsAlgorithm(QgsProcessingAlgorithm): INPUT_STRATI_COLUMN = 'STRATIGRAPHIC_COLUMN' INPUT_IGNORE_UNITS = 'IGNORE_UNITS' OUTPUT = "BASAL_CONTACTS" - ALL_CONTACTS = "ALL_CONTACTS" def name(self) -> str: """Return the algorithm name.""" @@ -127,13 +126,6 @@ def initAlgorithm(self, config: Optional[dict[str, Any]] = None) -> None: ) ) - self.addParameter( - QgsProcessingParameterFeatureSink( - "ALL_CONTACTS", - "All Contacts", - ) - ) - def processAlgorithm( self, parameters: dict[str, Any], @@ -178,7 +170,6 @@ def processAlgorithm( feedback.pushInfo("Extracting Basal Contacts...") contact_extractor = ContactExtractor(geology, faults) - all_contacts = contact_extractor.extract_all_contacts() basal_contacts = contact_extractor.extract_basal_contacts(strati_order) feedback.pushInfo("Exporting Basal Contacts Layer...") @@ -190,15 +181,7 @@ def processAlgorithm( output_key=self.OUTPUT, feedback=feedback, ) - contacts_layer = GeoDataFrameToQgsLayer( - self, - all_contacts, - parameters=parameters, - context=context, - output_key=self.ALL_CONTACTS, - feedback=feedback, - ) - return {self.OUTPUT: basal_contacts, self.ALL_CONTACTS: contacts_layer} + return {self.OUTPUT: basal_contacts} def createInstance(self) -> QgsProcessingAlgorithm: """Create a new instance of the algorithm.""" diff --git a/m2l/processing/algorithms/extract_contacts.py b/m2l/processing/algorithms/extract_contacts.py new file mode 100644 index 0000000..fe7d0bf --- /dev/null +++ b/m2l/processing/algorithms/extract_contacts.py @@ -0,0 +1,131 @@ +""" +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +""" +# Python imports +from typing import Any, Optional + +# QGIS imports +from qgis import processing +from qgis.core import ( + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingContext, + QgsProcessingException, + QgsProcessingFeedback, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsVectorLayer +) +# Internal imports +from ...main.vectorLayerWrapper import qgsLayerToGeoDataFrame, GeoDataFrameToQgsLayer +from map2loop.contact_extractor import ContactExtractor + +import logging +import traceback + +class ContactsAlgorithm(QgsProcessingAlgorithm): + """Processing algorithm to extract contacts.""" + + INPUT_GEOLOGY = 'GEOLOGY' + INPUT_FAULTS = 'FAULTS' + OUTPUT = "CONTACTS" + + def name(self) -> str: + """Return the algorithm name.""" + return "contacts" + + def displayName(self) -> str: + """Return the algorithm display name.""" + return "Extract Contacts" + + def group(self) -> str: + """Return the algorithm group name.""" + return "Contact Extractors" + + def groupId(self) -> str: + """Return the algorithm group ID.""" + return "Contact_Extractors" + + def initAlgorithm(self, config: Optional[dict[str, Any]] = None) -> None: + """Initialize the algorithm.""" + + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT_GEOLOGY, + "Geology polygons", + [QgsProcessing.TypeVectorPolygon], + optional=False + ) + ) + + self.addParameter( + QgsProcessingParameterField( + 'UNIT_NAME_FIELD', + 'Unit Name Field', + parentLayerParameterName=self.INPUT_GEOLOGY, + type=QgsProcessingParameterField.String, + defaultValue='unitname' + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT_FAULTS, + "Faults", + [QgsProcessing.TypeVectorLine], + optional=True + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink( + self.OUTPUT, + "Contacts", + ) + ) + + def processAlgorithm( + self, + parameters: dict[str, Any], + context: QgsProcessingContext, + feedback: QgsProcessingFeedback, + ) -> dict[str, Any]: + + feedback.pushInfo("Loading data...") + geology = self.parameterAsVectorLayer(parameters, self.INPUT_GEOLOGY, context) + faults = self.parameterAsVectorLayer(parameters, self.INPUT_FAULTS, context) + + unit_name_field = self.parameterAsString(parameters, 'UNIT_NAME_FIELD', context) + + geology = qgsLayerToGeoDataFrame(geology) + + faults = qgsLayerToGeoDataFrame(faults) if faults else None + if unit_name_field != 'UNITNAME' and unit_name_field in geology.columns: + geology = geology.rename(columns={unit_name_field: 'UNITNAME'}) + + contact_extractor = ContactExtractor(geology, faults) + all_contacts = contact_extractor.extract_all_contacts() + + feedback.pushInfo("Exporting Contacts Layer...") + contacts_layer = GeoDataFrameToQgsLayer( + self, + all_contacts, + parameters=parameters, + context=context, + output_key=self.OUTPUT, + feedback=feedback, + ) + return {self.OUTPUT: contacts_layer} + + def createInstance(self) -> QgsProcessingAlgorithm: + """Create a new instance of the algorithm.""" + return self.__class__() # ContactsAlgorithm() diff --git a/m2l/processing/provider.py b/m2l/processing/provider.py index 9616d9b..fb0881e 100644 --- a/m2l/processing/provider.py +++ b/m2l/processing/provider.py @@ -18,6 +18,7 @@ from .algorithms import ( BasalContactsAlgorithm, + ContactsAlgorithm, StratigraphySorterAlgorithm, UserDefinedStratigraphyAlgorithm, ThicknessCalculatorAlgorithm, @@ -35,6 +36,7 @@ class Map2LoopProvider(QgsProcessingProvider): def loadAlgorithms(self): """Loads all algorithms belonging to this provider.""" self.addAlgorithm(BasalContactsAlgorithm()) + self.addAlgorithm(ContactsAlgorithm()) self.addAlgorithm(StratigraphySorterAlgorithm()) self.addAlgorithm(UserDefinedStratigraphyAlgorithm()) self.addAlgorithm(ThicknessCalculatorAlgorithm())