Changelog
Source:NEWS.md
obisindicators 0.6.1
-
Precomputed store articles: the figures now show on the pkgdown site (and in the
paper/gallery on GitHub). The vignettes that query anobis_h3store (scaling,taxon_children) rendered code-only (eval = FALSE) because the store is not available on GitHub Actions. They move tovignettes/articles/(pkgdown-only, excluded from the package build) as*.Rmd.origsources thatdata-raw/precompute_articles.Rknits locally against a store into committed*.Rmd+figures/; CI renders those as-is. The tile maps stay live.- The
paper/Quarto notebooks are folded into the articles, which now double as the manuscript’s figure notebooks:scaling(Tables 2, 5; Fig. 3),taxon_children(Table 3; Fig. 4), and new articleseov(Table 4; Figs. 1–2),decadal(Fig. 5) andplaces(Fig. 6). Each article saves its manuscript figure + CSV topaper/figures/(now committed) viapaper/_common.R;paper/README.mdis the figure gallery and index. - Site navigation: articles are grouped into “Shipped data” and “The obis_h3 store”. No changes to exported functions.
- The
-
Analysis-side helpers for the paper’s figures and case studies — the tile-SQL builders now have data-frame counterparts, so every figure in
paper/is a call to a tested, exported function rather than notebook code. No new indicator math: everything runs the SQL already pinned tocalc_indicators()/calc_spue(), or calls those references directly.- Store (
R/store.R):obis_store_connect()(read-only +LOAD h3),obis_store_stats()(tables, totals, cells by resolution — Table 2),obis_h3t_query()(run any tile SQL at a fixed resolution, keyed on the hex string),obis_cell_indicators()(n/sp/shannon/es per cell for any filter, readingidx_h3/idx_h3_eovwhen it can),obis_bench()+obis_bench_queries()(cold/warm timings of the four serving paths),h3_res_table(). - Scale (
R/scale.R):calc_scale_curves()andcalc_spue_scale()— occupied cells, records-per-cell quantiles, ES-eligible fraction, medians and reliability floors across H3 resolutions (Fig. 3). - Comparisons (
R/compare.R):calc_rank_vs_subtree()+obis_rank_presets()(records by DwC rank column vs AphiaID subtree — Table 3),calc_eov_totals()+compare_eov_totals()(per-EOV totals and before/after a taxonomy change — Table 4),calc_spue_cells(),h3_raster_to_cells()(aggregate an SDM raster to H3 by pixel centres or hexagon centroids) andcompare_spue_sdm()(Spearman + calibration bins, effort-gated — Fig. 4). - Periods (
R/temporal.R):calc_period_indicators()andcalc_period_change()(decadal ES50/richness per cell, change where both decades are reliable — Fig. 5). - Places (
R/place.R):place_cells()andcalc_place_indicators()(roll H3 cells up to sanctuary/EEZ polygons and compute indicators withcalc_indicators()— Fig. 6). - Visualize (
R/visualize.R):hex_sf()(cells → dateline-wrapped polygons),gmap_cells()(map a per-cell table with an optional reliability mask),plot_scale_curves(),plot_spue_sdm();gmap_indicator()gains abboxargument and drops the deprecatedaes_string(). - Tests:
tests/testthat/test-paper-helpers.Ron a new synthetic fixture (helper-paper.R: turtles + birds with DwC ranks and years, bakedidx_h3andidx_h3_eov) asserts exact values for every helper, including precomputed-vs-live agreement ofobis_cell_indicators(). -
paper/: Quarto notebooks, one per figure/table (store stats + benchmarks, rank vs subtree, gap-fill EOV totals, EOV maps, scale curves, SPUE vs SDM, decadal change, place roll-ups), driven byOBIS_H3_DUCKDB; pluspaper/build_demo_store.Rto build a regional demo store (Gulf of Mexico + Caribbean) from a local OBIS export and a WoRMS table. - Suggests:
terra(raster aggregation),patchwork(figure panels).
- Store (
obisindicators 0.5.0
-
Essential Ocean Variables (EOVs) — new
R/eov.Rmaps the GOOS/IOOS biology & ecosystems EOVs onto the H3 store. The IOOS Marine Life Data Network defines each EOV as a handful of root WoRMS AphiaIDs (33 seeds across 7 EOVs: fish, hardCorals, mangroves, marineMammals, seabirds, seagrasses, seaTurtles), which is exactly a multi-seed version of the existing subtree walk.-
obis_eov_seeds()/obis_eov_aphiaid()— the EOV definitions. -
obis_eov_sql()— tile SQL for an EOV, routing to a precomputed layer when it can and to the live AphiaID-subtree path when it must (year filters, several EOVs at once, or a store without the layer baked). -
obis_eov_bake()— addseov(membership) andidx_h3_eov(precomputed indicators, res 1-7) to a store; now also a step inbuild_obis_h3_duckdb(), skipped with a note whentaxonis absent. - New driver
data-raw/migrate_add_eov.R.
-
-
WoRMS gap-fill — new
R/taxon_gapfill.Rcloses a silent coverage hole. The bulk WoRMStaxon.txtdownload is not a complete cover of the AphiaIDs OBIS carries: on the 2026-07 global store 12,021 of 167,190 distinctocc_h3.aphiaidvalues (~7%, covering 8.3M of 121.9M records) were absent fromtaxon, so they were invisible to everyaphiaid/ EOV / SPUE query.-
obis_taxon_orphans()— report the gap. -
wm_aphia_records()— batched, parallel WoRMS REST lookups (AphiaRecordsByAphiaIDs, 50 ids/request), the per-id supplement to the bulk download. -
obis_taxon_fill_gaps()— fills orphans and iterates to transitive closure, because inserting an orphan whose ancestors are still missing leaves it disconnected from any seed above it. Warns and reportsclosed = FALSErather than implying a whole tree ifmax_roundsis hit. - New driver
data-raw/migrate_fill_taxon_gaps.R. - Adds
httr2to Suggests.
-
Two taxon-group presets in the h3-db app returned zero records (fixed in
MarineSensitivity/apps/h3-db, noted here because it motivated the EOV design): filtering the DwCclasscolumn cannot match when WoRMS files the name at another rank —class='Actinopterygii'(a Gigaclass; OBIS’s class isTeleostei, 44.2M records) andclass='Anthozoa'(a Subphylum; OBIS usesHexacorallia/Octocorallia) both matched nothing. AphiaID subtree walking is rank-agnostic and immune to this.Parity:
.h3t_idx_eov_sql()is a fifth copy of thecalc_indicators()ES(n) term and is pinned cell-for-cell by the newtests/testthat/test-eov-parity.R.
obisindicators 0.4.2
-
Vignette H3 tile maps now actually render (the
mapgl/MapLibre chunks that 0.4.1 still left as code-only):-
vignette("h3t")renders the interactive ES50 hexagon map;vignette("taxon_children")renders the Cetacea-records map and the SPUE map. These are client-side MapLibre widgets — tiles are fetched from the deployedh3tservice in the reader’s browser, so they need no store/S3 at build time. -
New Remote dependency: the maps require the h3t-antimeridian fix in
mapgl(renders H3 hexagons that cross the dateline), pinned viaRemotes: mapgl=bbest/mapgl@fix/h3t-antimeridian(walkerke/mapgl#211). Switch to upstreammapglonce that PR merges. - Fixed a latent bug in the
h3tmap example —interpolate(values=)now has the same length asstops=(a 3-stop viridis ramp), which previously would have errored had the chunk been evaluated. -
vignette("scaling")stays code-only: every chunk runs live benchmark queries against the deployed DuckDB store (no map widgets), which CI cannot reach.
-
obisindicators 0.4.1
-
Vignettes now render their evaluable R chunks on the pkgdown site instead of showing code-only:
-
vignette("h3")runs the full h3-grid →calc_indicators()→gmap_indicator()pipeline on shippedocc_1Mand renders the ES(50) map (only thedeckglinstall/demo stays code-only). -
vignette("taxon_children")now renders the generatedWITH RECURSIVEtile SQL and tile URLs fromobis_h3t_sql(aphiaid=)/obis_spue_sql()(pure builders, no store needed); only the DB-connection andmapglwidget chunks stay code-only. -
vignette("h3t")suppresses package-load messages so the evaluatedobis_h3t_sql()output is clean. - Chunks that genuinely require the deployed S3 / DuckDB store /
h3ttile service (vignette("scaling"), the build/deploy/map chunks) remain illustrative code, as they cannot run in CI.
-
obisindicators 0.4.0
-
Automatic per-tile spatial pruning via
hex_prune(supersedes 0.3.0’s client-side{{bbox}}placeholder). The tile bbox is fully determined by thez/x/ytile address, so the client no longer states it — theh3tserver derives each tile’s covering coarse H3 cells fromz/x/yand injects the prune itself:-
build_obis_h3_duckdb()now materializes a coarse H3-parent columnhex_prune = h3_cell_to_parent(cell_id, LEAST(res, H3T_PRUNE_RES))(res 3) onocc_h3andidx_h3and clusters both by(res, hex_prune, cell_id). This replaces the interimlat/lngclustering — pruning on the H3 index is 2D (tighter than a latitude band), needs no extra float columns, and the covering ids are canonical H3 (they match across the R build and the server with no version drift). Store schema change — rebuild, or migrate withdata-raw/migrate_add_spatial_cluster.R(dropslat/lng, addshex_prune). -
obis_h3t_sql()/obis_spue_sql()now emit plain per-resolution SELECTs — thebbox_placeholderargument is removed. The server (MarineSensitivity/server/h3t,CalCOFI/api-h3t-py) rewrites the query to addhex_prune IN (<covering cells>)to any scan of a table carrying that column; stores without it are untouched. - The math is unchanged and still pinned to
calc_indicators()/calc_spue();test-h3t-prune.Rasserts the prune is result-preserving (ahex_prune-pruned scan + the server’s outer centroid filter returns exactly the same cells and values as the unpruned scan).
-
obisindicators 0.3.0
-
Spatial (bbox) tile pruning (interim — the
{{bbox}}placeholder andlat/lngclustering here were replaced by thehex_pruneapproach in 0.4.0; kept for history). Liveocc_h3/idx_h3tile maps were pruned per tile instead of aggregating the whole globe for every tile:-
build_obis_h3_duckdb()materialized cell-centroidlat/lngcolumns onocc_h3andidx_h3and clustered both by(res, lat, lng). -
obis_h3t_sql()/obis_spue_sql()gained abbox_placeholderargument (default"{{bbox}}") that theh3tservice substituted per tile with alat/lngpredicate. - The math stayed pinned to
calc_indicators()/calc_spue(); the prune was asserted result-preserving.
-
obisindicators 0.2.0
- Added WoRMS taxonomy children resolution and an effort proxy (SPUE) so OBIS can be filtered by any WoRMS AphiaID at any rank from the local snapshot (see
vignette("taxon_children"),vignette("scaling")):-
obis_taxon_children()/obis_taxon_subtree_sql()recursively walk ataxontable (baked into the store;data-raw/build_taxon_parquet.R+data-raw/migrate_add_taxon.R) to return every descendant taxon. -
obis_h3t_sql(aphiaid=)serves arbitrary-rank children maps by filteringocc_h3.aphiaidto the resolved subtree via aWITH RECURSIVECTE. -
calc_spue()(R reference) +obis_spue_sql()compute the presence-only effort proxyrecords(target subtree) / records(effort subtree)per cell, pinned bytest-spue-parity.R.
-
- Added an H3 tiling (h3t) workflow to serve indicators as on-demand H3 hexagon map tiles (see
vignette("h3t")):-
build_obis_h3_duckdb()builds an authoritative DuckDB store from OBIS open-data parquet — a precomputed all-taxa indicator layer (idx_h3, res 1–7) plus a species-level store (occ_h3, tiers 3/5/7) for on-the-fly taxon/year-filtered queries. The ES50/Shannon/Simpson/richness math is the SQL translation ofcalc_indicators(), pinned by a new parity test. -
obis_h3t_sql()/obis_h3t_url()compose the validated read-onlySELECTand the base64-encoded tile URL for theh3tservice (MarineSensitivity/server/h3t) andmapgl::add_h3t_source(). - canonical SQL in
inst/sql/; server build driver indata-raw/build_obis_h3_duckdb.R.
-
obisindicators 0.0.2
- Renamed functions for consistency:
-
calc_es50()->calc_indicators() -
gmap_metric()->gmap_indicator()
-
- Fixed
gmap_indicator()to use default Robinson projection. - Updated vignettes with name changes and use of “indicators” over “metrics”.
- Supplemented documentation for
calc_indicators()with expected input and output columns to data frame. - Added documentation for
occ_fkandocc_1960stoocc_2010s - Made generation of occ_* datasets more reproducible with
set.seed()and sampled versions of dataset to minimize file size on Github indata-raw/occ.R.