Skip to content

Commit

Permalink
Merge pull request #694 from kartoza/timlinux/issue663
Browse files Browse the repository at this point in the history
Added option to pass workflow dir to workflows so we can run tests
  • Loading branch information
timlinux authored Dec 9, 2024
2 parents 16e45ee + 06fb0d6 commit fda4f22
Show file tree
Hide file tree
Showing 32 changed files with 816 additions and 113 deletions.
62 changes: 45 additions & 17 deletions geest/core/algorithms/area_iterator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@

class AreaIterator:
"""
An iterator to yield pairs of geometries from polygon and bbox layers
An iterator to yield sets of geometries from polygon, study_area_clip_polygons and bbox layers
found in a GeoPackage file, along with a progress percentage.
Attributes:
gpkg_path (str): The path to the GeoPackage file.
Precondition:
study_area_polygons (QgsVectorLayer): The vector layer containing polygons.
study_area_clip_polygons (QgsVectorLayer): The vector layer containing polygons expanded to
completely include the intersecting grid cells along the boundary.
study_area_bboxes (QgsVectorLayer): The vector layer containing bounding boxes.
There should be a one-to-one correspondence between the polygons and bounding boxes.
Expand All @@ -29,10 +31,11 @@ class AreaIterator:
gpkg_path = '/path/to/your/geopackage.gpkg'
area_iterator = AreaIterator(gpkg_path)
for polygon_geometry, bbox_geometry, progress_percent in area_iterator:
log_message(f"Polygon Geometry: {polygon_geometry.asWkt()}", 'Geest')
log_message(f"BBox Geometry: {bbox_geometry.asWkt()}", 'Geest')
log_message(f"Progress: {progress_percent:.2f}%", 'Geest')
for polygon_geometry, clip_geometry, bbox_geometry, progress_percent in area_iterator:
log_message(f"Polygon Geometry: {polygon_geometry.asWkt()}")
log_message(f"Clip Polygon Geometry: {clip_geometry.asWkt()}")
log_message(f"BBox Geometry: {bbox_geometry.asWkt()}")
log_message(f"Progress: {progress_percent:.2f}%")
```
"""

Expand All @@ -49,6 +52,11 @@ def __init__(self, gpkg_path: str) -> None:
self.polygon_layer: QgsVectorLayer = QgsVectorLayer(
f"{gpkg_path}|layername=study_area_polygons", "study_area_polygons", "ogr"
)
self.clip_polygon_layer: QgsVectorLayer = QgsVectorLayer(
f"{gpkg_path}|layername=study_area_clip_polygons",
"study_area_clip_polygons",
"ogr",
)
self.bbox_layer: QgsVectorLayer = QgsVectorLayer(
f"{gpkg_path}|layername=study_area_bboxes", "study_area_bboxes", "ogr"
)
Expand All @@ -57,17 +65,27 @@ def __init__(self, gpkg_path: str) -> None:
if not self.polygon_layer.isValid():
log_message(
"Error: 'study_area_polygons' layer failed to load from the GeoPackage",
"Geest",
tag="Geest",
level=Qgis.Critical,
)
raise ValueError(
"Failed to load 'study_area_polygons' layer from the GeoPackage."
)

if not self.clip_polygon_layer.isValid():
log_message(
"Error: 'study_area_clip_polygons' layer failed to load from the GeoPackage",
tag="Geest",
level=Qgis.Critical,
)
raise ValueError(
"Failed to load 'study_area_clip_polygons' layer from the GeoPackage."
)

if not self.bbox_layer.isValid():
log_message(
"Error: 'study_area_bboxes' layer failed to load from the GeoPackage",
"Geest",
tag="Geest",
level=Qgis.Critical,
)
raise ValueError(
Expand All @@ -87,42 +105,52 @@ def __iter__(self) -> Iterator[Tuple[QgsGeometry, QgsGeometry, float]]:
along with a progress value representing the percentage of the iteration completed.
"""
try:
# Ensure both layers have the same CRS
# Ensure all layers have the same CRS
if self.polygon_layer.crs() != self.bbox_layer.crs():
log_message(
"Warning: CRS mismatch between polygon and bbox layers",
"Geest",
tag="Geest",
level=Qgis.Warning,
)
return

if self.polygon_layer.crs() != self.clip_polygon_layer.crs():
log_message(
"Warning: CRS mismatch between polygon and clip layers",
tag="Geest",
level=Qgis.Warning,
)
return

# Iterate over each polygon feature and calculate progress
for index, polygon_feature in enumerate(self.polygon_layer.getFeatures()):
polygon_id: int = polygon_feature.id()

# Request the corresponding bbox feature based on the polygon's ID
bbox_request: QgsFeatureRequest = QgsFeatureRequest().setFilterFid(
feature_request: QgsFeatureRequest = QgsFeatureRequest().setFilterFid(
polygon_id
)
bbox_feature = next(self.bbox_layer.getFeatures(bbox_request), None)
clip_feature = next(
self.clip_polygon_layer.getFeatures(feature_request), None
)
bbox_feature = next(self.bbox_layer.getFeatures(feature_request), None)

if bbox_feature:
if bbox_feature and clip_feature:
# Calculate the progress as the percentage of features processed
progress_percent: float = ((index + 1) / self.total_features) * 100

# Yield a tuple with polygon geometry, bbox geometry, and progress percentage
yield polygon_feature.geometry(), bbox_feature.geometry(), progress_percent
yield polygon_feature.geometry(), clip_feature.geometry(), bbox_feature.geometry(), progress_percent

else:
log_message(
f"Warning: No matching bbox found for polygon ID {polygon_id}",
"Geest",
f"Warning: No matching bbox or clip feature found for polygon ID {polygon_id}",
tag="Geest",
level=Qgis.Warning,
)

except Exception as e:
log_message(
f"Critical: Error during iteration - {str(e)}",
"Geest",
tag="Geest",
level=Qgis.Critical,
)
5 changes: 4 additions & 1 deletion geest/core/algorithms/point_and_paths_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ def process_areas(self, gpkg_path: str) -> None:
area_iterator = AreaIterator(gpkg_path)

# Iterate over areas and perform the analysis for each
for index, (current_area, current_bbox, progress) in enumerate(area_iterator):
for index, (current_area, clip_area, current_bbox, progress) in enumerate(
area_iterator
):
feedback.pushInfo(
f"Processing area {index+1} with progress {progress:.2f}%"
)
Expand Down Expand Up @@ -259,6 +261,7 @@ def _rasterize_grid(
"INPUT": grid_layer,
"FIELD": "value",
"EXTENT": bbox.boundingBox(),
"EXTRA": "-at", # All touched pixels
"OUTPUT": output_path,
}
processing.run("gdal:rasterize", params)
Expand Down
2 changes: 1 addition & 1 deletion geest/core/algorithms/raster_reclassification_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def reclassify(self):
temp_rasters = []

# Iterate over each area from the AreaIterator
for index, (current_area, current_bbox, progress) in enumerate(
for index, (current_area, clip_area, current_bbox, progress) in enumerate(
self.area_iterator
):
feedback.pushInfo(
Expand Down
5 changes: 4 additions & 1 deletion geest/core/algorithms/safety_polygon_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ def process_areas(self) -> None:
self.gpkg_path
) # Call the iterator from the other file

for index, (current_area, current_bbox, progress) in enumerate(area_iterator):
for index, (current_area, clip_area, current_bbox, progress) in enumerate(
area_iterator
):
feedback.pushInfo(
f"Processing area {index + 1} with progress {progress:.2f}%"
)
Expand Down Expand Up @@ -201,6 +203,7 @@ def _rasterize_safety(
"EXTENT": f"{bbox.xMinimum()},{bbox.xMaximum()},{bbox.yMinimum()},{bbox.yMaximum()}",
"NODATA": 255,
"DATA_TYPE": 0,
"EXTRA": "-at", # Assign all touched pixels
"OUTPUT": output_path,
}
processing.run("gdal:rasterize", params)
Expand Down
6 changes: 4 additions & 2 deletions geest/core/algorithms/single_point_buffer_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def process_areas(self) -> str:
feedback = QgsProcessingFeedback()
area_iterator = AreaIterator(self.gpkg_path)

for index, (current_area, current_bbox, progress) in enumerate(area_iterator):
for index, (current_area, clip_area, current_bbox, progress) in enumerate(
area_iterator
):
feedback.pushInfo(f"Processing area {index} with progress {progress:.2f}%")

# Step 1: Select features that intersect with the current area
Expand Down Expand Up @@ -294,7 +296,7 @@ def _rasterize(
"DATA_TYPE": 0,
"INIT": 1,
"INVERT": False,
"EXTRA": f"-a_srs {self.target_crs.authid()}",
"EXTRA": f"-a_srs {self.target_crs.authid()} -at", # Assign all touched pixels
"OUTPUT": output_path,
}

Expand Down
2 changes: 1 addition & 1 deletion geest/core/json_tree_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def getStatus(self):
if verbose_mode:
log_message(f"Error getting status: {e}", level=Qgis.Warning)
log_message(traceback.format_exc(), level=Qgis.Warning)
return "WRITE TOOL TIP"
return f"Status Failed - {e}"

def getFont(self):
"""Retrieve the appropriate font for the item based on its role."""
Expand Down
Loading

0 comments on commit fda4f22

Please sign in to comment.