Skip to contents

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.

See also

[aggregate_pds_effort()], [rollup_h3_resolution()], [create_spatial_grid()], [plot_effort_map()]