Converts an H3 hexagonal effort grid (as produced by [aggregate_pds_effort()]) into contiguous fishing ground polygons by filtering cells that meet activity thresholds and dissolving their geometries. The result is ready for further spatial analysis.
Usage
derive_fishing_grounds(
h3_grid_df,
min_trips = 3L,
min_hours = NULL,
min_pings = NULL,
target_h3_res = NULL,
n_days = NULL
)Arguments
- h3_grid_df
Data frame with columns `h3_index`, `fishing_hours`, `unique_trips`, `n_active_days`, `first_active_date`, `last_active_date`, `avg_fidelity_sum`, `n_trips_for_fidelity` (as returned by [aggregate_pds_effort()]). A `year` column is accepted and collapsed by summation / min / max as appropriate.
- min_trips
Integer. Minimum number of unique trips per H3 cell required to retain the cell. Default is `3L`.
- min_hours
Numeric or `NULL`. Minimum accumulated fishing hours per cell. `NULL` (default) uses the median of `fishing_hours` across all cells.
- min_pings
Deprecated. Use `min_hours` instead. If supplied, a warning is emitted and the argument is ignored.
- target_h3_res
Integer (0-15) or `NULL`. If provided, effort is first rolled up to this coarser H3 resolution before thresholding. Must be lower than the resolution stored in `h3_grid_df`. `NULL` uses the grid as-is.
- n_days
Integer or `NULL`. Deprecated fallback for `n_total_days`. When `first_active_date` / `last_active_date` columns are present in `h3_grid_df` (grids produced by the current pipeline), `n_total_days` is inferred automatically and this argument is ignored.
Value
An `sf` POLYGON object in WGS84 (EPSG 4326) with columns:
- `ground_id`
Stable identifier, e.g. `"FG_1"`, ordered by descending area.
- `area_km2`
Area of each polygon in square kilometres.
- `fishing_hours`
Total accumulated fishing hours within the ground.
- `unique_trips`
Number of unique trips that fished within the ground.
- `n_active_days`
Sum of cell-level active days across all constituent H3 cells.
- `n_cells`
Number of H3 cells that make up the ground.
- `avg_fidelity`
Mean across cells of the average fraction of visiting trips' fishing time spent in each cell. Bounded [0, 1]. Higher values indicate stronger habitat preference (fidelity).
- `constancy`
Mean across cells of the fraction of study days each cell was fished. Bounded [0, 1]. Near 0 = sporadic; near 1 = daily.
- `avg_hours_per_day`
Mean across cells of fishing hours per calendar day (`fishing_hours / n_total_days`).
- `avg_visits_per_day`
Mean across cells of unique trips per calendar day (`unique_trips / n_total_days`).
- `hours_per_trip`
Mean across cells of fishing hours per trip (`fishing_hours / unique_trips`).
- `fishing_hours_per_km2`
Total fishing hours divided by ground area (effort density).
- `unique_trips_per_km2`
Total unique trips divided by ground area (visit density).
- `hours_per_day_per_km2`
`avg_hours_per_day` divided by ground area (effort-rate density).
Returns `NULL` with a warning if no cells survive the filters.
Details
The derivation proceeds in four steps:
1. **Optional rollup**: if `target_h3_res` is provided, all effort metrics are summed into parent H3 cells at the coarser resolution before applying thresholds. This lets you extract broad fishing grounds without reprocessing raw tracks. 2. **Threshold filtering**: cells are kept only when `unique_trips >= min_trips` and `fishing_hours >= min_hours`. When `min_hours` is `NULL` the median fishing-hours across all cells is used as the threshold. 3. **Per-cell normalisation**: after collapsing years, the study period length (`n_total_days`) is inferred from the stored date range (`first_active_date`, `last_active_date`). Per-day rates and constancy are computed at the cell level before polygon dissolution so that ground- level values are means of cell values (ecologically correct) rather than re-derived from ground totals. 4. **Polygon extraction**: filtered hexagons are converted to polygons via [create_spatial_grid()], dissolved into contiguous areas with `sf::st_union()`, split into individual polygons with `sf::st_cast("POLYGON")`, and annotated with a stable `ground_id` and `area_km2`.
If the input grid contains a `year` column (as produced by the default [aggregate_pds_effort()] schema), effort is collapsed across all years before thresholding.