@@ -125,7 +125,7 @@ def initAlgorithm(self, config: Optional[dict[str, Any]] = None) -> None:
125125 self .INPUT_GEOLOGY ,
126126 "Geology polygons" ,
127127 [QgsProcessing .TypeVectorPolygon ],
128- optional = True
128+ optional = False
129129 )
130130 )
131131
@@ -161,7 +161,7 @@ def initAlgorithm(self, config: Optional[dict[str, Any]] = None) -> None:
161161 optional = True
162162 )
163163 )
164-
164+
165165 self .addParameter (
166166 QgsProcessingParameterField (
167167 'GROUP_FIELD' ,
@@ -225,7 +225,7 @@ def initAlgorithm(self, config: Optional[dict[str, Any]] = None) -> None:
225225 "CONTACTS_LAYER" ,
226226 "Contacts Layer" ,
227227 [QgsProcessing .TypeVectorLine ],
228- optional = False ,
228+ optional = True ,
229229 )
230230 )
231231
@@ -256,9 +256,14 @@ def processAlgorithm(
256256
257257 algo_index : int = self .parameterAsEnum (parameters , self .SORTING_ALGORITHM , context )
258258 sorter_cls = list (SORTER_LIST .values ())[algo_index ]
259+ sorter_name = list (SORTER_LIST .keys ())[algo_index ]
260+ requires_contacts = sorter_cls in [SorterAlpha , SorterMaximiseContacts , SorterObservationProjections ]
259261 contacts_layer = self .parameterAsVectorLayer (parameters , self .CONTACTS_LAYER , context )
260262 in_layer = self .parameterAsVectorLayer (parameters , self .INPUT_GEOLOGY , context )
261263 output_file = self .parameterAsFileOutput (parameters , 'JSON_OUTPUT' , context )
264+
265+ if requires_contacts and not contacts_layer or not contacts_layer .isValid ():
266+ raise QgsProcessingException (f"{ sorter_name } requires a contacts layer" )
262267
263268 units_df , relationships_df , contacts_df = build_input_frames (in_layer ,contacts_layer , feedback ,parameters )
264269
@@ -384,26 +389,30 @@ def build_input_frames(layer: QgsVectorLayer,contacts_layer: QgsVectorLayer, fee
384389 if not group_field :
385390 raise QgsProcessingException ("Group Field is required" )
386391
392+ unique_units = {}
387393 units_records = []
388394 for f in layer .getFeatures ():
389- units_records .append (
390- dict (
391- layerId = f .id (),
392- name = f [unit_name_field ],
393- minAge = qvariantToFloat (f , min_age_field ),
394- maxAge = qvariantToFloat (f , max_age_field ),
395- group = f [group_field ],
395+ unit_name = f [unit_name_field ]
396+ if unit_name not in unique_units :
397+ unique_units [unit_name ] = len (unique_units )
398+ units_records .append (
399+ dict (
400+ layerId = len (units_records ),
401+ name = f [unit_name_field ],
402+ minAge = qvariantToFloat (f , min_age_field ),
403+ maxAge = qvariantToFloat (f , max_age_field ),
404+ group = f [group_field ],
405+ )
396406 )
397- )
398407 units_df = pd .DataFrame .from_records (units_records )
399408
400409 feedback .pushInfo (f"Units → { len (units_df )} records" )
401410 # map_data can be mocked if you only use Age-based sorter
402411
403412 if not contacts_layer or not contacts_layer .isValid ():
404413 raise QgsProcessingException ("No contacts layer provided" )
405-
406414 contacts_df = qgsLayerToGeoDataFrame (contacts_layer ) if contacts_layer else pd .DataFrame ()
415+
407416 if not contacts_df .empty :
408417 relationships_df = contacts_df .copy ()
409418 if 'length' in contacts_df .columns :
0 commit comments