Skip to content

Commit 2c0fe3b

Browse files
committed
fix: applying some copilot changes
1 parent d901fe3 commit 2c0fe3b

6 files changed

Lines changed: 49 additions & 31 deletions

File tree

loopstructural/gui/data_conversion/configuration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""configuration helpers used by the data conversion UI."""
1+
"""Configuration helpers used by the data conversion UI."""
22

33
from __future__ import annotations
44

loopstructural/gui/data_conversion/data_conversion_widget.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from dataclasses import dataclass
88
from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple
99

10+
from LoopDataConverter import Datatype, InputData, LoopConverter, SurveyName
1011
from PyQt5.QtCore import Qt, QTimer
1112
from PyQt5.QtWidgets import (
1213
QComboBox,
@@ -25,7 +26,6 @@
2526

2627
from ...main.helpers import ColumnMatcher
2728
from ...main.vectorLayerWrapper import QgsLayerFromDataFrame, QgsLayerFromGeoDataFrame
28-
from LoopDataConverter import Datatype, InputData, LoopConverter, SurveyName
2929

3030
try:
3131
from geopandas import GeoDataFrame
@@ -34,7 +34,7 @@
3434

3535
try:
3636
from pandas import DataFrame
37-
except Exception: # pragma: no cover - pandas may be unavailable in tests
37+
except ImportException: # pragma: no cover - pandas may be unavailable in tests
3838
DataFrame = None
3939

4040

@@ -165,18 +165,27 @@ def _normalise_converters(converters: Optional[Iterable[Any]]) -> List[Converter
165165
)
166166
label = str(raw.get("label") or raw.get("name") or identifier)
167167
description = str(raw.get("description") or "")
168-
normalised.append(ConverterOption(identifier=identifier, label=label, description=description))
168+
normalised.append(
169+
ConverterOption(identifier=identifier, label=label, description=description)
170+
)
169171
continue
170172

171173
text = str(raw)
172174
normalised.append(ConverterOption(identifier=text, label=text, description=""))
173175
return normalised
174176

177+
175178
class AutomaticConversionWidget(QWidget):
176179
"""Widget showing the automatic conversion workflow."""
177180

178181
SUPPORTED_DATA_TYPES: Tuple[str, ...] = ("GEOLOGY", "STRUCTURE", "FAULT", "FOLD")
179-
OUTPUT_DATA_TYPES: Tuple[str, ...] = ("GEOLOGY", "STRUCTURE", "FAULT", "FOLD", "FAULT_ORIENTATION")
182+
OUTPUT_DATA_TYPES: Tuple[str, ...] = (
183+
"GEOLOGY",
184+
"STRUCTURE",
185+
"FAULT",
186+
"FOLD",
187+
"FAULT_ORIENTATION",
188+
)
180189
OUTPUT_GROUP_NAME = "Loop-Ready Data"
181190

182191
def __init__(
@@ -208,7 +217,9 @@ def __init__(
208217
self.summary_text.setMinimumHeight(80)
209218
layout.addWidget(self.summary_text)
210219

211-
source_description = QLabel("Select the layers that correspond to each dataset required by the converter.")
220+
source_description = QLabel(
221+
"Select the layers that correspond to each dataset required by the converter."
222+
)
212223
source_description.setWordWrap(True)
213224
layout.addWidget(source_description)
214225

@@ -221,6 +232,9 @@ def __init__(
221232
try:
222233
self.project.layersAdded.connect(self._guess_layers)
223234
except Exception:
235+
# Best-effort: if the project object does not provide a compatible
236+
# layersAdded signal (e.g., in certain QGIS versions or test stubs),
237+
# silently skip automatic layer guessing rather than failing the UI.
224238
pass
225239

226240
actions_widget = QWidget()
@@ -288,6 +302,8 @@ def _build_data_source_inputs(self) -> None:
288302
try:
289303
combo.setProject(self.project)
290304
except Exception:
305+
# Some QGIS/Qt environments may not support setProject or may raise here;
306+
# failure to bind the project is non-fatal, so we intentionally ignore
291307
pass
292308
combo.setFilters(self._layer_filter_for_data_type(data_type))
293309
combo.setAllowEmptyLayer(True)
@@ -327,9 +343,7 @@ def _guess_layers(self) -> None:
327343
if layer is not None:
328344
combo.setLayer(layer)
329345

330-
def _build_layer_candidate_map(
331-
self, combo: QgsMapLayerComboBox
332-
) -> Dict[str, QgsVectorLayer]:
346+
def _build_layer_candidate_map(self, combo: QgsMapLayerComboBox) -> Dict[str, QgsVectorLayer]:
333347
candidates: Dict[str, QgsVectorLayer] = {}
334348
for layer in self._layers_for_combo(combo):
335349
if not isinstance(layer, QgsVectorLayer) or not layer.isValid():
@@ -473,9 +487,7 @@ def _handle_run_conversion(self) -> bool:
473487
return False
474488

475489
if added_layers:
476-
message = (
477-
f"Conversion completed: {added_layers} layer(s) added to '{self.OUTPUT_GROUP_NAME}'."
478-
)
490+
message = f"Conversion completed: {added_layers} layer(s) added to '{self.OUTPUT_GROUP_NAME}'."
479491
elif result not in (None, True):
480492
message = f"Conversion completed: {result}"
481493
else:

loopstructural/gui/loop_widget.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,3 @@ def get_visualisation_widget(self):
7272
The visualisation widget.
7373
"""
7474
return self.visualisation_widget
75-

loopstructural/gui/map2loop_tools/thickness_calculator_widget.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Widget for thickness calculator."""
22

33
import os
4-
import pandas as pd
54

5+
import pandas as pd
66
from PyQt5.QtWidgets import QMessageBox, QWidget
77
from qgis.core import QgsMapLayerProxyModel
88
from qgis.PyQt import uic
@@ -151,7 +151,7 @@ def _guess_layers(self):
151151
if structure_layer_match:
152152
structure_layer = self.data_manager.find_layer_by_name(structure_layer_match)
153153
self.structureLayerComboBox.setLayer(structure_layer)
154-
154+
155155
# Attempt to find cross-sections layer
156156
cross_sections_layer_names = get_layer_names(self.crossSectionLayerComboBox)
157157
cross_sections_matcher = ColumnMatcher(cross_sections_layer_names)
@@ -221,14 +221,14 @@ def _on_calculator_type_changed(self):
221221
self.maxLineLengthSpinBox.setVisible(True)
222222
self.crossSectionLayerLabel.setVisible(False)
223223
self.crossSectionLayerComboBox.setVisible(False)
224-
225-
if calculator_type == "InterpolatedStructure":
224+
225+
elif calculator_type == "InterpolatedStructure":
226226
self.maxLineLengthLabel.setVisible(False)
227227
self.maxLineLengthSpinBox.setVisible(False)
228228
self.crossSectionLayerLabel.setVisible(False)
229229
self.crossSectionLayerComboBox.setVisible(False)
230-
231-
if calculator_type == "AlongSection":
230+
231+
elif calculator_type == "AlongSection":
232232
self.crossSectionLayerLabel.setVisible(True)
233233
self.crossSectionLayerComboBox.setVisible(True)
234234
self.maxLineLengthLabel.setVisible(False)
@@ -247,7 +247,7 @@ def _restore_selection(self):
247247
('basal_contacts_layer', self.basalContactsComboBox),
248248
('sampled_contacts_layer', self.sampledContactsComboBox),
249249
('structure_layer', self.structureLayerComboBox),
250-
("cross_sections_layer", self.crossSectionLayerComboBox)
250+
("cross_sections_layer", self.crossSectionLayerComboBox),
251251
):
252252
if layer_name := settings.get(key):
253253
layer = self.data_manager.find_layer_by_name(layer_name)
@@ -335,13 +335,12 @@ def _run_calculator(self):
335335
if not self.structureLayerComboBox.currentLayer():
336336
QMessageBox.warning(self, "Missing Input", "Please select a structure layer.")
337337
return False
338-
338+
339339
elif calculator_type == "AlongSection":
340340
if not self.crossSectionLayerComboBox.currentLayer():
341341
QMessageBox.warning(self, "Missing Input", "Please select a cross-sections layer.")
342342
return False
343343

344-
345344
# Prepare parameters
346345
params = self.get_parameters()
347346

loopstructural/main/m2l_api.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
SorterObservationProjections,
99
SorterUseNetworkX,
1010
)
11-
from map2loop.thickness_calculator import InterpolatedStructure, StructuralPoint, AlongSection
11+
from map2loop.thickness_calculator import AlongSection, InterpolatedStructure, StructuralPoint
1212
from osgeo import gdal
1313
from qgis.core import QgsVectorLayer
1414

@@ -457,7 +457,7 @@ def calculate_thickness(
457457
else basal_contacts_gdf
458458
)
459459
sampled_contacts_gdf = qgsLayerToGeoDataFrame(sampled_contacts)
460-
structure_gdf = qgsLayerToGeoDataFrame(structure)
460+
structure_gdf = qgsLayerToGeoDataFrame(structure)
461461
cross_sections_gdf = qgsLayerToGeoDataFrame(cross_sections)
462462

463463
# Log parameters via DebugManager if provided
@@ -475,7 +475,6 @@ def calculate_thickness(
475475
"sampled_contacts": sampled_contacts_gdf,
476476
"structure": structure_gdf,
477477
"cross_sections": cross_sections_gdf,
478-
479478
},
480479
)
481480

@@ -485,9 +484,7 @@ def calculate_thickness(
485484
'maxy': geology_gdf.total_bounds[3],
486485
'miny': geology_gdf.total_bounds[1],
487486
}
488-
489-
490-
487+
491488
# Rename unit name field if needed
492489
if unit_name_field and unit_name_field != 'UNITNAME':
493490
if unit_name_field in geology_gdf.columns:
@@ -535,8 +532,8 @@ def calculate_thickness(
535532
calculator = AlongSection(
536533
bounding_box=bounding_box,
537534
sections=cross_sections_gdf,
538-
)
539-
535+
)
536+
540537
if unit_name_field != 'UNITNAME' and unit_name_field in geology_gdf.columns:
541538
geology_gdf = geology_gdf.rename(columns={unit_name_field: 'UNITNAME'})
542539
units = geology_gdf.copy()

loopstructural/main/vectorLayerWrapper.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,18 @@ def _geometry_from_value(value):
599599
try:
600600
data = bytes(data)
601601
except Exception:
602+
# Best-effort conversion to bytes; if this fails, leave data as-is
603+
602604
pass
603605
try:
604606
return QgsGeometry.fromWkb(data)
605607
except Exception:
608+
# Best-effort conversion to bytes; if this fails, fall back to using the
609+
# original data and let the subsequent fromWkb call handle it.
610+
logger.debug(
611+
"Failed to convert WKB data to bytes in _geometry_from_value",
612+
exc_info=True,
613+
)
606614
continue
607615
# Shapely geometries expose wkb/wkt attributes
608616
wkb_data = getattr(value, "wkb", None)
@@ -661,6 +669,7 @@ def _crs_from_geodataframe_crs(crs_info) -> QgsCoordinateReferenceSystem:
661669
if epsg:
662670
return QgsCoordinateReferenceSystem.fromEpsgId(int(epsg))
663671
except Exception:
672+
logger.debug("Failed to convert EPSG code to QgsCoordinateReferenceSystem", exc_info=True)
664673
pass
665674
if isinstance(crs_info, str):
666675
try:
@@ -696,7 +705,9 @@ def QgsLayerFromGeoDataFrame(geodataframe, layer_name: str = "Converted Data"):
696705
for column in geodataframe.columns:
697706
if column == geometry_column:
698707
continue
699-
attribute_fields.append(QgsField(str(column), _qvariant_type_from_dtype(geodataframe[column].dtype)))
708+
attribute_fields.append(
709+
QgsField(str(column), _qvariant_type_from_dtype(geodataframe[column].dtype))
710+
)
700711
if attribute_fields:
701712
provider.addAttributes(attribute_fields)
702713
layer.updateFields()

0 commit comments

Comments
 (0)