Skip to content

Commit ade11aa

Browse files
committed
fix: add boolean return for painter
1 parent 304b794 commit ade11aa

File tree

3 files changed

+177
-172
lines changed

3 files changed

+177
-172
lines changed

loopstructural/gui/map2loop_tools/basal_contacts_widget.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ def _run_extractor(self):
198198
log_level=2,
199199
)
200200
return True
201-
except Exception as err:
202-
if self._debug:
203-
self._debug.plugin.log(
204-
message=f"[map2loop] Basal contacts extraction failed: {err}",
205-
log_level=2,
206-
)
207-
raise err
208-
QMessageBox.critical(self, "Error", f"An error occurred: {err}")
201+
except Exception as err:
202+
if self._debug:
203+
self._debug.plugin.log(
204+
message=f"[map2loop] Basal contacts extraction failed: {err}",
205+
log_level=2,
206+
)
207+
raise err
208+
QMessageBox.critical(self, "Error", f"An error occurred: {err}")
209209
return False
210210

211211
def get_parameters(self):

loopstructural/gui/map2loop_tools/paint_stratigraphic_order_widget.py

Lines changed: 169 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -150,188 +150,194 @@ def _on_geology_layer_changed(self):
150150
break
151151

152152
def _run_painter(self):
153-
"""Run the paint stratigraphic order algorithm."""
153+
"""Run the paint stratigraphic order algorithm.
154+
155+
Returns
156+
-------
157+
bool
158+
True if operation completed without unhandled exceptions, False otherwise.
159+
"""
154160

155-
geology_layer = self.geologyLayerComboBox.currentLayer()
156-
unit_name_field = self.unitNameFieldComboBox.currentField()
157-
stratigraphic_order = self.data_manager.stratigraphic_order = (
158-
self.data_manager.get_stratigraphic_unit_names() if self.data_manager else []
159-
)
160-
paint_stratigraphic_order(
161-
geology_layer, stratigraphic_order, unit_name_field, debug_manager=self._debug
162-
)
163-
164-
# If requested, duplicate layer and apply style using selected colour ramp
165161
try:
166-
duplicate = (
167-
getattr(self, 'duplicateLayerCheckBox', None)
168-
and self.duplicateLayerCheckBox.isChecked()
162+
geology_layer = self.geologyLayerComboBox.currentLayer()
163+
unit_name_field = self.unitNameFieldComboBox.currentField()
164+
stratigraphic_order = self.data_manager.stratigraphic_order = (
165+
self.data_manager.get_stratigraphic_unit_names() if self.data_manager else []
166+
)
167+
paint_stratigraphic_order(
168+
geology_layer, stratigraphic_order, unit_name_field, debug_manager=self._debug
169169
)
170-
except Exception:
171-
duplicate = False
172170

173-
if duplicate:
174-
# Get chosen ramp name
171+
# If requested, duplicate layer and apply style using selected colour ramp
175172
try:
176-
ramp_name = self.colorRampComboBox.currentText()
173+
duplicate = (
174+
getattr(self, 'duplicateLayerCheckBox', None)
175+
and self.duplicateLayerCheckBox.isChecked()
176+
)
177177
except Exception:
178-
ramp_name = None
178+
duplicate = False
179+
180+
if duplicate:
181+
# Get chosen ramp name
182+
try:
183+
ramp_name = self.colorRampComboBox.currentText()
184+
except Exception:
185+
ramp_name = None
186+
187+
# Step 1: create a memory copy of the geology layer and copy attributes/geometry
188+
try:
189+
from PyQt5.QtCore import QVariant
190+
from qgis.core import (
191+
QgsFeature,
192+
QgsField,
193+
QgsGraduatedSymbolRenderer,
194+
QgsProject,
195+
QgsRendererRange,
196+
QgsStyle,
197+
QgsSymbol,
198+
QgsVectorLayer,
199+
QgsWkbTypes,
200+
)
179201

180-
# Step 1: create a memory copy of the geology layer and copy attributes/geometry
181-
try:
182-
from PyQt5.QtCore import QVariant
183-
from qgis.core import (
184-
QgsFeature,
185-
QgsField,
186-
QgsGraduatedSymbolRenderer,
187-
QgsProject,
188-
QgsRendererRange,
189-
QgsStyle,
190-
QgsSymbol,
191-
QgsVectorLayer,
192-
QgsWkbTypes,
193-
)
202+
geom_type = QgsWkbTypes.displayString(geology_layer.wkbType())
203+
crs_auth = (
204+
geology_layer.crs().authid() if hasattr(geology_layer, 'crs') else None
205+
)
206+
uri = f"{geom_type}?crs={crs_auth}" if crs_auth else f"{geom_type}"
207+
mem_layer = QgsVectorLayer(uri, f"{geology_layer.name()}_strat", "memory")
194208

195-
geom_type = QgsWkbTypes.displayString(geology_layer.wkbType())
196-
crs_auth = geology_layer.crs().authid() if hasattr(geology_layer, 'crs') else None
197-
uri = f"{geom_type}?crs={crs_auth}" if crs_auth else f"{geom_type}"
198-
mem_layer = QgsVectorLayer(uri, f"{geology_layer.name()}_strat", "memory")
199-
200-
mem_dp = mem_layer.dataProvider()
201-
mem_dp.addAttributes(list(geology_layer.fields()))
202-
mem_layer.updateFields()
203-
204-
# copy each feature and its attributes explicitly
205-
src_field_names = [f.name() for f in geology_layer.fields()]
206-
new_feats = []
207-
for src_feat in geology_layer.getFeatures():
208-
nf = QgsFeature()
209-
nf.setGeometry(src_feat.geometry())
210-
nf.setFields(mem_layer.fields())
211-
attrs = []
212-
for f in mem_layer.fields():
213-
fname = f.name()
214-
if fname in src_field_names:
215-
try:
216-
attrs.append(src_feat[fname])
217-
except Exception:
218-
attrs.append(None)
219-
else:
220-
attrs.append(None)
221-
nf.setAttributes(attrs)
222-
new_feats.append(nf)
223-
mem_dp.addFeatures(new_feats)
224-
mem_layer.updateExtents()
225-
QgsProject.instance().addMapLayer(mem_layer)
226-
except Exception as e:
227-
QMessageBox.warning(self, 'Duplicate Layer', f'Failed to create copy: {e}')
228-
return
229-
230-
# Step 2: ensure 'strat_order' exists on memory layer and populate numeric values by matching geometries
231-
field_name = 'strat_order'
232-
try:
233-
if field_name not in [f.name() for f in mem_layer.fields()]:
234-
mem_layer.startEditing()
235-
mem_dp.addAttributes([QgsField(field_name, QVariant.Int)])
209+
mem_dp = mem_layer.dataProvider()
210+
mem_dp.addAttributes(list(geology_layer.fields()))
236211
mem_layer.updateFields()
237-
mem_layer.commitChanges()
238-
239-
# build mapping from geometry WKB -> numeric strat value from original layer
240-
geom_to_val = {}
241-
for of in geology_layer.getFeatures():
242-
try:
243-
raw = of[field_name]
244-
except Exception:
245-
raw = None
246-
if raw is None:
247-
continue
248-
try:
249-
val = int(raw)
250-
except Exception:
212+
213+
# copy each feature and its attributes explicitly
214+
src_field_names = [f.name() for f in geology_layer.fields()]
215+
new_feats = []
216+
for src_feat in geology_layer.getFeatures():
217+
nf = QgsFeature()
218+
nf.setGeometry(src_feat.geometry())
219+
nf.setFields(mem_layer.fields())
220+
attrs = []
221+
for f in mem_layer.fields():
222+
fname = f.name()
223+
if fname in src_field_names:
224+
try:
225+
attrs.append(src_feat[fname])
226+
except Exception:
227+
attrs.append(None)
228+
else:
229+
attrs.append(None)
230+
nf.setAttributes(attrs)
231+
new_feats.append(nf)
232+
mem_dp.addFeatures(new_feats)
233+
mem_layer.updateExtents()
234+
QgsProject.instance().addMapLayer(mem_layer)
235+
except Exception as e:
236+
QMessageBox.warning(self, 'Duplicate Layer', f'Failed to create copy: {e}')
237+
return False
238+
239+
# Step 2: ensure 'strat_order' exists on memory layer and populate numeric values by matching geometries
240+
field_name = 'strat_order'
241+
try:
242+
if field_name not in [f.name() for f in mem_layer.fields()]:
243+
mem_layer.startEditing()
244+
mem_dp.addAttributes([QgsField(field_name, QVariant.Int)])
245+
mem_layer.updateFields()
246+
mem_layer.commitChanges()
247+
248+
# build mapping from geometry WKB -> numeric strat value from original layer
249+
geom_to_val = {}
250+
for of in geology_layer.getFeatures():
251251
try:
252-
val = int(float(raw))
252+
raw = of[field_name]
253253
except Exception:
254+
raw = None
255+
if raw is None:
254256
continue
255-
try:
256-
geom_to_val[of.geometry().asWkb()] = val
257-
except Exception:
258-
# fallback to WKT if asWkb unavailable
259257
try:
260-
geom_to_val[of.geometry().asWkt()] = val
258+
val = int(raw)
261259
except Exception:
262-
continue
263-
264-
if geom_to_val:
265-
mem_layer.startEditing()
266-
strat_idx = mem_layer.fields().indexFromName(field_name)
267-
for mf in mem_layer.getFeatures():
260+
try:
261+
val = int(float(raw))
262+
except Exception:
263+
continue
268264
try:
269-
key = mf.geometry().asWkb()
265+
geom_to_val[of.geometry().asWkb()] = val
270266
except Exception:
271267
try:
272-
key = mf.geometry().asWkt()
268+
geom_to_val[of.geometry().asWkt()] = val
273269
except Exception:
274-
key = None
275-
if key is None:
276-
continue
277-
val = geom_to_val.get(key, None)
278-
if val is not None:
279-
mem_layer.changeAttributeValue(mf.id(), strat_idx, int(val))
280-
mem_layer.commitChanges()
281-
except Exception:
282-
# continue; styling will fallback if numeric data missing
283-
pass
270+
continue
284271

285-
# Step 3: build graduated renderer using explicit ranges per unique strat value
286-
try:
287-
vals = set()
288-
for f in mem_layer.getFeatures():
289-
try:
290-
v = f[field_name]
291-
except Exception:
292-
v = None
293-
if v is None:
294-
continue
295-
try:
296-
vals.add(float(v))
297-
except Exception:
298-
continue
299-
unique_vals = sorted(vals)
300-
301-
if not unique_vals:
302-
QMessageBox.information(
303-
self,
304-
'Styling',
305-
"No 'strat_order' values found on duplicated layer; leaving default styling.",
306-
)
307-
else:
308-
from qgis.core import QgsRendererRange
309-
310-
ramp = QgsStyle().defaultStyle().colorRamp(ramp_name) if ramp_name else None
311-
ranges = []
312-
n = len(unique_vals)
313-
for i, v in enumerate(unique_vals):
314-
lower = v - 0.5
315-
upper = v + 0.5
316-
symbol = QgsSymbol.defaultSymbol(mem_layer.geometryType())
317-
if ramp:
272+
if geom_to_val:
273+
mem_layer.startEditing()
274+
strat_idx = mem_layer.fields().indexFromName(field_name)
275+
for mf in mem_layer.getFeatures():
318276
try:
319-
color = ramp.color(i / (n - 1) if n > 1 else 0)
320-
symbol.setColor(color)
277+
key = mf.geometry().asWkb()
321278
except Exception:
322-
pass
323-
label = str(int(v)) if float(v).is_integer() else str(v)
324-
ranges.append(QgsRendererRange(lower, upper, symbol, label))
325-
renderer = QgsGraduatedSymbolRenderer(field_name, ranges)
326-
mem_layer.setRenderer(renderer)
327-
mem_layer.triggerRepaint()
328-
except Exception as e:
329-
QMessageBox.warning(
330-
self, 'Duplicate Layer', f'Failed to apply graduated styling: {e}'
331-
)
279+
try:
280+
key = mf.geometry().asWkt()
281+
except Exception:
282+
key = None
283+
if key is None:
284+
continue
285+
val = geom_to_val.get(key, None)
286+
if val is not None:
287+
mem_layer.changeAttributeValue(mf.id(), strat_idx, int(val))
288+
mem_layer.commitChanges()
289+
except Exception:
290+
# continue; styling will fallback if numeric data missing
291+
pass
292+
293+
# Step 3: build graduated renderer using explicit ranges per unique strat value
294+
try:
295+
vals = set()
296+
for f in mem_layer.getFeatures():
297+
try:
298+
v = f[field_name]
299+
except Exception:
300+
v = None
301+
if v is None:
302+
continue
303+
try:
304+
vals.add(float(v))
305+
except Exception:
306+
continue
307+
unique_vals = sorted(vals)
308+
309+
if not unique_vals:
310+
QMessageBox.information(
311+
self,
312+
'Styling',
313+
"No 'strat_order' values found on duplicated layer; leaving default styling.",
314+
)
315+
else:
316+
ramp = QgsStyle().defaultStyle().colorRamp(ramp_name) if ramp_name else None
317+
ranges = []
318+
n = len(unique_vals)
319+
for i, v in enumerate(unique_vals):
320+
lower = v - 0.5
321+
upper = v + 0.5
322+
symbol = QgsSymbol.defaultSymbol(mem_layer.geometryType())
323+
if ramp:
324+
try:
325+
color = ramp.color(i / (n - 1) if n > 1 else 0)
326+
symbol.setColor(color)
327+
except Exception:
328+
pass
329+
label = str(int(v)) if float(v).is_integer() else str(v)
330+
ranges.append(QgsRendererRange(lower, upper, symbol, label))
331+
renderer = QgsGraduatedSymbolRenderer(field_name, ranges)
332+
mem_layer.setRenderer(renderer)
333+
mem_layer.triggerRepaint()
334+
except Exception as e:
335+
QMessageBox.warning(
336+
self, 'Duplicate Layer', f'Failed to apply graduated styling: {e}'
337+
)
338+
339+
except Exception as e:
340+
QMessageBox.warning(self, 'Paint Stratigraphic Order', f'Operation failed: {e}')
341+
return False
332342

333-
# QMessageBox.information(
334-
# self,
335-
# "Paint Stratigraphic Order",
336-
# "Stratigraphic order has been painted onto the geology layer.",
337-
# )
343+
return True

loopstructural/processing/provider.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
from .algorithms import (
1818
BasalContactsAlgorithm,
19-
PaintStratigraphicOrderAlgorithm,
2019
SamplerAlgorithm,
2120
StratigraphySorterAlgorithm,
2221
ThicknessCalculatorAlgorithm,

0 commit comments

Comments
 (0)