2626from loopstructural .toolbelt .preferences import PlgSettingsStructure
2727from LoopStructural .utils .observer import Observable
2828
29+ from ..main .helpers import qgisAttributeIsNone
30+
2931
3032class AllSampler :
3133 """This is a simple sampler that just returns all the points, or all of the vertices
@@ -87,7 +89,7 @@ class GeologicalModelManager(Observable):
8789 It is responsible for updating the model with faults, stratigraphy, and other geological features.
8890 """
8991
90- def __init__ (self ):
92+ def __init__ (self , debug_manager = None ):
9193 """Initialize the geological model manager."""
9294 # Initialize Observable state
9395 super ().__init__ ()
@@ -104,6 +106,7 @@ def __init__(self):
104106 # internal flag to temporarily suppress notifications (used when
105107 # updates are performed in background threads)
106108 self ._suppress_notifications = False
109+ self ._debug_manager = debug_manager
107110
108111 @contextmanager
109112 def suspend_notifications (self ):
@@ -262,7 +265,7 @@ def update_contact_traces(
262265 self .stratigraphy .clear () # Clear existing stratigraphy
263266 unit_points = sampler (basal_contacts , self .dem_function , use_z_coordinate )
264267 if len (unit_points ) == 0 or unit_points .empty :
265- print ("No basal contacts found or empty GeoDataFrame." )
268+ self . _debug_manager . log ("No basal contacts found or empty GeoDataFrame." , log_level = 2 )
266269 return
267270 if unit_name_field is not None :
268271 unit_points ['unit_name' ] = unit_points [unit_name_field ].astype (str )
@@ -336,6 +339,12 @@ def update_foliation_features(self):
336339 """
337340 stratigraphic_column = {}
338341 for _i , group in enumerate (reversed (self .stratigraphic_column .get_groups ())):
342+ # check if the attribute is none, if its none we want so skip as it could be an
343+ # ambiguous attribute and cause multiple data assocaited with different features
344+ # to be applied the same value.
345+ if qgisAttributeIsNone (group ) is None :
346+ self ._debug_manager .log (f"Group { group .name } has no data, skipping." , log_level = 2 )
347+ continue
339348 val = 0
340349 data = []
341350 groupname = group .name
@@ -360,7 +369,9 @@ def update_foliation_features(self):
360369
361370 val += u .thickness
362371 if len (data ) == 0 :
363- print (f"No data found for group { groupname } , skipping." )
372+ self ._debug_manager .log (
373+ f"No data found for group { groupname } , skipping." , log_level = 2
374+ )
364375 continue
365376 data = pd .concat (data , ignore_index = True )
366377 foliation = self .model .create_and_add_foliation (
@@ -380,6 +391,20 @@ def update_foliation_features(self):
380391 def update_fault_features (self ):
381392 """Update the fault features in the geological model."""
382393 for fault_name , fault_data in self .faults .items ():
394+ if qgisAttributeIsNone (fault_name ):
395+ # check if the attribute is none, if its none we want so skip as it could be an
396+ # ambiguous attribute and cause multiple data assocaited with different features
397+ # to be applied the same value.
398+ # The DebugManager forwards to the toolbelt logger which is safe to
399+ # call from background threads. Call it directly and swallow any
400+ # exceptions to avoid causing freezes.
401+ try :
402+ dbg = getattr (self , '_debug_manager' , None )
403+ if dbg is not None and hasattr (dbg , 'log' ):
404+ dbg .log ('Skipping fault with no name.' , log_level = 2 )
405+ except Exception :
406+ pass
407+ continue
383408 if 'data' in fault_data and not fault_data ['data' ].empty :
384409 data = fault_data ['data' ].copy ()
385410 data ['feature_name' ] = fault_name
@@ -754,7 +779,9 @@ def export_feature_values_to_geodataframe(
754779 try :
755780 from shapely .geometry import Point as _Point
756781 except Exception :
757- print ("Shapely not available; geometry column will be omitted." )
782+ self ._debug_manager .log (
783+ "Shapely not available; geometry column will be omitted." , log_level = 2
784+ )
758785 _Point = None
759786
760787 pts = np .asarray (points )
0 commit comments