Help us shape the future of Go! Take the 2026 Go Developer Survey

eooaoo

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 18 Imported by: 0

README

go-iucn-eoo-aoo

Version 0.2.0 — an auditable Go library, CLI and local API for IUCN-oriented EOO/AOO calculations with GDAL/PROJ.

The core transforms coordinates with airbusgeo/godal v0.0.18, computes metrics in equal-area projected coordinate systems, and records projection, grid, GDAL/PROJ versions and input provenance in every result. It never measures area in Web Mercator and never approximates kilometres with a fixed degrees conversion.

Two projection strategies are explicit in every result:

  • local-laea (default): a local Lambert Azimuthal Equal Area projection centred on the assessment distribution;
  • iucn-cea: World Cylindrical Equal Area (ESRI:54034), matching the projection documented by the IUCN EOO Calculator.

iucn-cea is a methodological compatibility mode, not IUCN certification and not an official reproduction of the ArcGIS tool. See docs/PROJECTIONS.md.

The Go module is:

github.com/lsbjordao/go-iucn-eoo-aoo

The executable is eoo-aoo.

Installation

Go library

Add the versioned module to your Go project:

go get github.com/lsbjordao/go-iucn-eoo-aoo@v0.2.0

Import the public package as eooaoo. API documentation and runnable examples are available on pkg.go.dev. Building applications that use the library requires Go 1.23+, GDAL 3.8+, PROJ, pkg-config, a C/C++ compiler, and CGO enabled.

Linux and macOS — prebuilt release

The normal installer downloads a precompiled, SHA-256-verified release. It does not install Go and does not compile the source code.

curl -fsSL https://raw.githubusercontent.com/lsbjordao/go-iucn-eoo-aoo/main/scripts/install.sh | sh

Or, from a cloned repository:

sh scripts/install.sh

The default destination is ~/.local/bin/eoo-aoo. Override it with:

PREFIX=/usr/local sh scripts/install.sh

Supported prebuilt Unix targets are:

  • Debian 13 amd64;
  • Ubuntu 24.04 amd64;
  • macOS Apple Silicon (arm64);
  • macOS Intel (amd64).

Linux uses the distribution GDAL/PROJ runtime packages. macOS uses Homebrew for the GDAL runtime. Neither path requires a Go toolchain.

Debian 13 package

Tagged releases also publish a native .deb:

sudo apt install ./eoo-aoo-debian13-amd64.deb

The package installs /usr/bin/eoo-aoo and declares its GDAL/PROJ runtime dependencies through Debian packaging.

Windows 10/11 x64 — prebuilt portable bundle

The Windows release is built natively with MSYS2 UCRT64 and ships with the GDAL/PROJ DLL dependency set and spatial resource data. End users do not need Go, GCC or MSYS2.

From PowerShell:

iwr https://raw.githubusercontent.com/lsbjordao/go-iucn-eoo-aoo/main/scripts/install.ps1 -OutFile $env:TEMP\install-eoo-aoo.ps1
powershell -ExecutionPolicy Bypass -File $env:TEMP\install-eoo-aoo.ps1

The installer downloads eoo-aoo-windows-amd64.zip, verifies its SHA-256 checksum, installs it under %LOCALAPPDATA%\Programs\eoo-aoo, and adds that directory to the user PATH.

The ZIP can also be downloaded from GitHub Releases and eoo-aoo.exe run directly from the extracted directory.

Build from source

Source compilation is a developer path rather than the default installation route:

git clone https://github.com/lsbjordao/go-iucn-eoo-aoo.git
cd go-iucn-eoo-aoo
sh scripts/install-from-source.sh

Building from source requires Go 1.23+, GDAL 3.8+, PROJ, pkg-config, and a C/C++ compiler because godal uses CGO. GDAL 3.8 is the floor because earlier versions (such as the 3.6 series in Debian 12) do not split antimeridian-crossing polygons into a MultiPolygon during RFC 7946 GeoJSON export, which produces display geometries that span the globe.

Container
docker compose up --build -d

The container is useful for reproducible server and pipeline deployments.

Input formats

CSV, JSON and GeoJSON are first-class input formats. TSV is also accepted.

The canonical tabular occurrence schema is deliberately small:

Field Type Required Meaning
id string no Record identifier preserved in provenance
taxon string recommended Taxon name or assessment-unit label; required by batch
lon number yes Longitude in degrees with the default EPSG:4326 input CRS
lat number yes Latitude in degrees with the default EPSG:4326 input CRS

For projected or other coordinate reference systems, custom coordinate columns can be supplied through --x-col and --y-col; numeric values are then interpreted according to --input-crs.

For interoperability with biodiversity datasets, decimalLongitude/decimalLatitude and scientificName are also recognized automatically in tabular CSV/JSON input. The canonical schema in this repository remains id,taxon,lon,lat.

CSV
id,taxon,lon,lat
demo-001,Mimosa demonstrativa,-43.2,-22.9
demo-002,Mimosa demonstrativa,-44.3,-21.5
demo-003,Mimosa demonstrativa,-42.9,-20.8
eoo-aoo calc --in occurrences.csv --out result.json
JSON

JSON input is an array of records using the same field names:

[
  {"id":"demo-001","taxon":"Mimosa demonstrativa","lon":-43.2,"lat":-22.9},
  {"id":"demo-002","taxon":"Mimosa demonstrativa","lon":-44.3,"lat":-21.5},
  {"id":"demo-003","taxon":"Mimosa demonstrativa","lon":-42.9,"lat":-20.8}
]
eoo-aoo calc --in occurrences.json --out result.json
GeoJSON

GeoJSON input is an RFC 7946 FeatureCollection containing Point geometries. The record identifier can be supplied as the Feature id, while taxon belongs in properties:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "demo-001",
      "properties": {"taxon": "Mimosa demonstrativa"},
      "geometry": {
        "type": "Point",
        "coordinates": [-43.2, -22.9]
      }
    },
    {
      "type": "Feature",
      "id": "demo-002",
      "properties": {"taxon": "Mimosa demonstrativa"},
      "geometry": {
        "type": "Point",
        "coordinates": [-44.3, -21.5]
      }
    }
  ]
}
eoo-aoo calc --in occurrences.geojson --out result.json

GeoJSON is always interpreted as WGS84 (EPSG:4326) as required by RFC 7946. Null geometries, LineStrings, Polygons, MultiPoints and other non-Point geometries are rejected. Altitude, when present as a third coordinate, is ignored.

Quick start

eoo-aoo calc --in examples/brazil.csv --out result.json \
  --gpkg result.gpkg --geojson-dir maps --html result.html --details

Equivalent JSON and GeoJSON examples:

eoo-aoo calc --in examples/occurrences.json --out result.json --html result.html

eoo-aoo calc --in examples/occurrences.geojson --out result.json --html result.html
Choose the projection strategy
# Regional geodetic default
eoo-aoo calc --in occurrences.csv \
  --projection local-laea --out local.json --html local.html

# World Cylindrical Equal Area used by the documented IUCN EOO Calculator method
eoo-aoo calc --in occurrences.csv \
  --projection iucn-cea --out iucn-cea.json --html iucn-cea.html
Compare both strategies
eoo-aoo compare --in occurrences.csv --out projection-comparison.json

The comparison runs the same records and grid configuration under both strategies and reports iucn-cea - local-laea differences for raw EOO, assessment EOO, AOO and occupied-cell count, including percentage differences when defined.

Audit and curate records

calc is strict and never drops records. audit reports suspect records line by line, including rows calc would reject, without excluding anything:

eoo-aoo audit --in gbif.csv --x-col decimalLongitude --y-col decimalLatitude --id-col ID \
  --source-flag-field issue --uncertainty-field coordinateUncertaintyInMeters \
  --context-fields locality,countryCode --out audit.json

Rules: INVALID_RECORD and INVALID_COORDINATE (errors); ZERO_ZERO_COORDINATE (exactly 0,0 in WGS84; a zero on one axis alone is never flagged); and, only when configured, COARSE_COORDINATE_PRECISION (--coarse-decimals), UNCERTAINTY_EXCEEDS_CELL_SIZE and SOURCE_QUALITY_FLAG. Source flags are kept verbatim; only documented GBIF issue codes are interpreted. calc also warns about (0,0) records but keeps them.

Exclusions need an explicit, versioned manifest (schema) bound to the exact input hash. Each decision selects a record by index plus its expected ID and/or coordinates and states a justification. curate verifies everything before writing a new derived file in the input format and a log with both hashes:

eoo-aoo curate --in occurrences.csv --manifest manifest.json \
  --derived curated.csv --out curation-log.json
EOO influence of hull vertices
eoo-aoo influence --in occurrences.csv --top-k 10 --out influence.json
eoo-aoo influence --in occurrences.csv --recompute-projection --out influence.json

Each hull-vertex coordinate group (all records at that coordinate) is removed in turn and the hull is rebuilt from all remaining points in the frozen analysis CRS of the original run. Groups are ranked by relative reduction of raw EOO. --recompute-projection adds, for comparison, the raw EOO with a newly chosen local-LAEA centre. The analysis is a sensitivity diagnostic: it never labels or excludes records.

Freeze a protocol for temporal series
eoo-aoo calc --in 2020.csv --out 2020.json --protocol-out protocol.json
eoo-aoo calc --in 2025.csv --out 2025.json --protocol protocol.json

The protocol (schema) records the full analysis CRS, centre, effective grid origin, cell size, orientation, boundary rule, hull and area methods and inclusion rules. Reproduction uses a fixed grid, so new records cannot move the centre or the origin. Conflicting flags fail before calculation; a different software, GDAL or PROJ version is reported in PROTOCOL_ENVIRONMENT_CHANGED.

Output

calc always returns a JSON calculation report, either to stdout or to the path supplied with --out. Additional GIS and interactive outputs can be requested independently.

An abridged result has this shape; numeric values below are illustrative:

{
  "schema_version": "1",
  "software_version": "0.2.0",
  "gdal_version": "...",
  "proj_version": "...",
  "taxon": "Mimosa demonstrativa",
  "input_sha256": "...",
  "geometry_sha256": "...",
  "protocol_sha256": "...",
  "input_records": 5,
  "unique_coordinates": 4,
  "duplicate_records": 1,
  "config": {
    "input_crs": "EPSG:4326",
    "projection_strategy": "local-laea",
    "cell_size_m": 2000,
    "grid_mode": "auto",
    "grid_steps": 10,
    "origin_m": [0, 0]
  },
  "projection": {
    "strategy": "local-laea",
    "reference": "...",
    "input_crs": "EPSG:4326",
    "analysis_proj": "...",
    "center_lon_lat": [-43.4, -21.8],
    "center_method": "spherical mean of sorted unique WGS84 coordinates",
    "max_angular_distance_deg": 1.5,
    "axis_order": "traditional GIS: longitude/easting, latitude/northing"
  },
  "eoo": {
    "raw_area_km2": 1234.56,
    "assessment_area_km2": 1234.56,
    "status": "ok",
    "adjusted_to_aoo": false,
    "method": "planar convex hull in the analysis CRS (...); GDAL planar polygon area in the analysis CRS",
    "geodesic_area_km2": 1236.02,
    "hull_wkt": "POLYGON ((...))"
  },
  "aoo": {
    "area_km2": 16,
    "occupied_cells": 4,
    "cell_size_m": 2000,
    "iucn_2km_scale": true,
    "grid_mode": "exact",
    "requested_grid_mode": "auto",
    "effective_grid_mode": "exact",
    "estimated_point_evaluations": 60,
    "search_guarantee": "translation_minimum",
    "origin_m": [412.3, 781.4],
    "candidate_origins": 25,
    "min_cells": 4,
    "max_cells": 5,
    "tested_min_cells": 4,
    "tested_max_cells": 5,
    "base_origin_cells": 5,
    "base_origin_area_km2": 20,
    "complete_translation_search": true,
    "orientation": "analysis CRS axes; no rotation search",
    "boundary_rule": "..."
  },
  "warnings": [
    "AUTO_CENTER: freeze center and grid origin for temporal comparisons",
    "POINT_BASED_ESTIMATE: records alone may underestimate occupancy; occurrence suitability and other Red List subcriteria require assessment"
  ]
}

The actual projection object also contains the full input and analysis WKT definitions. They are omitted from the example above only to keep the README readable.

Main JSON fields
Field Meaning
schema_version Version of the JSON result contract; 1 for the initial public release
software_version Version of go-iucn-eoo-aoo that produced the result
gdal_version, proj_version Native geospatial library versions loaded at runtime
taxon Assessment-unit label when present in the input
build Go version and, when the binary was built from a git checkout, the embedded VCS revision; never invented
input_sha256 SHA-256 of the ordered input records with their metadata, useful for reproducibility
geometry_sha256 SHA-256 of the sorted unique normalized WGS84 coordinates; unchanged by record order, duplicates or metadata
protocol_sha256 SHA-256 of the effective method and parameters (protocol without its environment)
wgs84_extent Longitude span (shortest arc, antimeridian-safe) and latitude span of the unique points
protocol Frozen analysis protocol for temporal reproduction; see --protocol-out
input_records Number of records received
unique_coordinates Number of distinct WGS84 coordinate pairs after normalization
duplicate_records Records sharing coordinates with another input record
config Effective configuration after defaults and user overrides are applied
projection Analysis projection strategy, CRS definitions, centre and axis metadata
eoo Extent of Occurrence result
aoo Area of Occupancy result
warnings Methodological or reproducibility warnings that should be reviewed
EOO fields
Field Meaning
raw_area_km2 Convex-hull area in the selected equal-area analysis plane; null when a non-degenerate hull cannot be constructed
assessment_area_km2 EOO value used by the result after the explicit rule that EOO must not be smaller than AOO
status ok, insufficient_unique_points, collinear, or numerically_degenerate
adjusted_to_aoo true when the assessment EOO was set to AOO because raw EOO was unavailable or smaller
method Hull construction and area measurement behind raw_area_km2
geodesic_area_km2 Diagnostic only: the same hull vertices joined by WGS84 geodesics; null when unavailable; never used for the assessment value
hull_wkt Exact convex hull in the analysis plane when a valid hull exists; omitted when no hull can be constructed

With fewer than three unique coordinates, collinear points, or a numerically degenerate hull, raw_area_km2 is null. The software does not invent a replacement polygon: assessment_area_km2 uses AOO and a warning is emitted.

AOO fields
Field Meaning
area_km2 occupied_cells × cell_size_m², converted to km²
occupied_cells Number of occupied grid cells for the selected origin
cell_size_m Grid side length; default is 2,000 m
iucn_2km_scale Whether the 2 × 2 km IUCN reference scale is being used
requested_grid_mode Mode asked for after defaults: auto, exact, sampled or fixed
effective_grid_mode Mode actually used: exact, sampled or fixed (grid_mode repeats it for v1 clients)
fallback_reason Present when auto fell back to sampled search, e.g. EXACT_WORK_LIMIT (with exact_work_estimate)
estimated_point_evaluations Work of the executed search, in cell-count updates
grid_steps_effective Sampled offsets per axis; present only for sampled searches
search_guarantee translation_minimum (every translation, fixed orientation), tested_origins_minimum (sampled origins only) or fixed_origin
origin_m Selected grid origin in analysis-CRS metres
candidate_origins Number of candidate translations evaluated
tested_min_cells, tested_max_cells Occupancy range among evaluated origins: sensitivity to translation, not biological uncertainty (min_cells, max_cells repeat them)
base_origin_cells, base_origin_area_km2 Occupancy at the configured base origin, without any search
complete_translation_search Whether the translation search is exhaustive for the fixed grid orientation (v1 field)
orientation Records that the square grid follows the analysis CRS axes
boundary_rule Rule used when a point lies exactly on a grid-cell boundary

Grid translation is optimized; grid rotation is not. Two equal-area projections can therefore produce different AOO values because their axes orient the square grid differently.

--details

By default, calc omits the potentially large cells and points provenance arrays. Add --details to retain them:

eoo-aoo calc --in occurrences.csv --out result.json --details

Detailed results add:

  • cells: occupied AOO cell indices, unique-point counts and projected bounds;
  • points: normalized unique occurrence coordinates, projected coordinates, zero-based input indices and all original records sharing each coordinate.

The EOO hull WKT, when it exists, is part of both the default and detailed JSON result. --details specifically controls the large cell and point provenance arrays.

Spatial and interactive outputs

calc can create several outputs in one run:

eoo-aoo calc --in occurrences.csv --out result.json \
  --gpkg result.gpkg \
  --geojson-dir maps \
  --html result.html
Output Option Purpose
JSON --out result.json Authoritative metrics, configuration, versions, warnings and optional provenance
GeoPackage --gpkg result.gpkg Exact analysis-plane occurrence points, occupied AOO cells and EOO hull with the analysis CRS
GeoJSON directory --geojson-dir maps WGS84 display layers for occurrences, AOO and EOO
HTML --html result.html Interactive MapLibre report with embedded display GeoJSON and calculation metadata

The GeoPackage is preferred for authoritative GIS geometry. Exported GeoJSON and the HTML map are display products; do not recalculate authoritative areas from their rendered geometries or pixels.

compare output
eoo-aoo compare --in occurrences.csv --out projection-comparison.json

The comparison report contains:

  • local_laea: summary result using local LAEA;
  • iucn_cea: summary result using World Cylindrical Equal Area;
  • delta_iucn_cea_minus_local_laea: absolute and percentage differences in raw EOO, assessment EOO and AOO, plus occupied-cell difference;
  • warnings: structured caveats; GRID_SEARCH_COVERAGE_DIFFERS when the two AOO values come from searches with different guarantees, so the AOO delta mixes projection with search coverage, plus SAMPLED_GRID/FIXED_GRID per side;
  • note: interpretation warning about projection dependence.

The sign of every delta is iucn-cea - local-laea. The command reports sensitivity; it does not automatically choose one strategy as universally superior.

batch output
eoo-aoo batch --in examples/batch.csv --workers 4 --out batch.json

batch groups records by taxon and returns an array with one item per assessment unit. Each item contains taxon plus either a result or an error. Use --details if full per-taxon provenance is required.

Interfaces

Interface Purpose
Go library Calculate(ctx, points, config) for workers and pipelines
calc One assessment unit; rejects mixed taxa
compare Runs local-laea and iucn-cea on the same input
batch Splits input by taxon and processes groups concurrently
audit Line-by-line data-quality findings; never excludes records
curate Applies an explicit, hash-bound curation manifest and writes a derived input
influence Raw-EOO influence of each hull vertex under a frozen CRS
serve POST /v1/calculate and GET /healthz
GeoPackage Exact analysis-plane cells, occurrences and EOO hull
GeoJSON WGS84 input FeatureCollections and WGS84 display layers via GDAL RFC 7946
HTML Interactive MapLibre EOO/AOO/occurrence report

Additional examples:

# SIRGAS 2000 geographic coordinates
eoo-aoo calc --in occurrences.csv --input-crs EPSG:4674 --out result.json

# Projected input with custom coordinate columns
eoo-aoo calc --in utm.csv --x-col easting --y-col northing \
  --input-crs EPSG:31983 --out result.json

# Fixed projection centre and grid for a temporal series
eoo-aoo calc --in examples/brazil.csv \
  --config examples/fixed-brazil.json --out series.json

# Go library example
go run -buildvcs=false ./examples/library

examples/fixed-brazil.json is an example configuration, not a required CRS for Brazilian flora. Repeated temporal analyses should preserve projection strategy, centre when applicable, grid origin, resolution, inclusion rules and native GDAL/PROJ versions.

With a single unique coordinate (including duplicate records at that coordinate), auto, exact, and sampled center the occupied square on the projected point. For the default 2 km cell, its bounds extend 1,000 m in each axis direction from the point and AOO remains 4 km². The selected aoo.origin_m is the square's lower-left corner. fixed always preserves the configured origin.

Mode Behaviour
auto (default) Complete translation search when within the work budget; otherwise a 10 × 10 sampled search
exact Evaluates every coordinate-residue interval; minimum for the fixed CRS-axis orientation
sampled Lowest occupied-cell count among --grid-steps² origins; does not prove the global translation minimum
fixed Explicit origin, useful for temporal comparisons

Every mode reports effective_grid_mode and search_guarantee, and a fallback from auto is never hidden: it appears in fallback_reason, in the GRID_SEARCH_FALLBACK warning, on stderr and in the HTML report. Searches run as an event sweep: for each X interval, occupied-cell counts are updated incrementally as the Y origin crosses each point's residue, instead of rebuilding a full map per origin. The work limit is 25 million cell-count updates per calculation (about 1 s); about 2,800 well-spread points still fit an exact search. Grid translation is optimized; grid rotation is not. Because square-grid orientation follows the projected CRS axes, two equal-area projections can produce different AOO values. The compare command exposes that sensitivity rather than hiding it.

See docs/METHODOLOGY.md and docs/PROJECTIONS.md.

API

eoo-aoo serve --listen 127.0.0.1:8080 --workers 4

curl --fail-with-body http://127.0.0.1:8080/v1/calculate \
  -H 'Content-Type: application/json' --data-binary @examples/request.json

The API points member accepts the same JSON-array records or an RFC 7946 GeoJSON FeatureCollection. projection_strategy can be supplied in the API config object. An optional protocol member reproduces a frozen protocol exactly as calc --protocol does. When EOO_AOO_TOKEN is defined, calculations require Authorization: Bearer <token>. The default server listens only on loopback and is stateless.

The HTTP server is an implementation detail used by the CLI and lives under internal/server; it is not part of the public Go import API. The public library API is the root eooaoo package.

See docs/INTEGRATION.md for the integration contract.

Project layout

The root directory is the public Go package. The command and implementation-only packages are separated according to normal Go module conventions:

go-iucn-eoo-aoo/
├── audit.go         # AuditOccurrences: per-record data-quality findings
├── calculate.go
├── comparison.go
├── curation.go      # ApplyCuration: hash-bound exclusion manifests
├── export.go
├── geodesic.go      # diagnostic geodesic-edge hull area (PROJ geodesic)
├── grid.go          # AOO grid search (event sweep) and guarantees
├── html.go
├── hull.go          # convex hull with exact orientation predicate
├── influence.go     # AnalyzeEOOInfluence
├── projection.go
├── protocol.go      # AnalysisProtocol, geometry and protocol hashes
├── types.go
├── cmd/
│   └── eoo-aoo/
├── internal/
│   ├── input/
│   └── server/
├── examples/
├── docs/
├── schemas/
├── testdata/
└── scripts/

External Go programs import only the public root package:

import eooaoo "github.com/lsbjordao/go-iucn-eoo-aoo"

Packages below internal/ are intentionally unavailable to external modules.

Scientific scope

Scale and interpretation rules follow IUCN Red List guidance. This software is not certified by the IUCN and does not assign threat categories. Occurrence records still require biological curation for identification, origin, current presence, seasonality, precision and assessment period. Point-only AOO may underestimate actual occupancy.

local-laea is this project's regional geodetic implementation choice. iucn-cea uses the World Cylindrical Equal Area projection documented by the IUCN EOO Calculator materials. Equal-area projection does not eliminate projection dependence in hull shape or square-grid orientation; antimeridian distributions deserve particular inspection in a global cylindrical projection.

Release engineering

Tagged releases are built natively on Linux, macOS and Windows. Windows uses the MSYS2 UCRT64 environment and recursively identifies DLL dependencies before creating the portable ZIP. Every published asset is covered by SHA256SUMS, and the end-user installers verify that checksum before installation.

GitHub-hosted macOS release builds target both arm64 and Intel amd64. Windows currently targets x64. Linux prebuilt binaries currently target Debian 13 and Ubuntu 24.04 on amd64.

Validation

Validation includes go vet, race-enabled tests, antimeridian and polar cases, degenerate inputs, GIS exports, concurrency, projection-strategy comparison and independent geodesic checks. See docs/VALIDATION.md for the exact environment, evidence and limitations.

Provenance and license

MIT licensed. godal is Apache-2.0; GDAL/PROJ and bundled Windows runtime libraries retain their own licenses. See THIRD_PARTY.md.

Documentation

Overview

Package eooaoo computes auditable, point-based Extent of Occurrence (EOO) and Area of Occupancy (AOO) metrics using GDAL/PROJ.

Calculations normalize input coordinates to WGS84, preserve record provenance, project to an explicit equal-area analysis CRS, compute the convex-hull EOO, and evaluate occupied square-grid cells for AOO. The default AOO cell side is 2 km. Results record software, GDAL and PROJ versions, projection definitions, grid metadata, warnings and an input hash for reproducibility.

Two analysis strategies are available: ProjectionLocalLAEA, a local Lambert Azimuthal Equal Area projection centred on the distribution, and ProjectionIUCNCEA, a World Cylindrical Equal Area compatibility-oriented mode matching the projection documented by the IUCN EOO Calculator materials. ProjectionIUCNCEA does not imply IUCN certification.

The package computes spatial metrics only. It does not assign IUCN Red List categories and does not decide whether occurrence records are biologically suitable for an assessment.

Index

Examples

Constants

View Source
const (
	IssueInvalidRecord         = "INVALID_RECORD"
	IssueInvalidCoordinate     = "INVALID_COORDINATE"
	IssueZeroZero              = "ZERO_ZERO_COORDINATE"
	IssueCoarsePrecision       = "COARSE_COORDINATE_PRECISION"
	IssueUncertaintyExceedCell = "UNCERTAINTY_EXCEEDS_CELL_SIZE"
	IssueSourceQualityFlag     = "SOURCE_QUALITY_FLAG"
)

Audit issue codes. Codes are stable identifiers; messages may change.

View Source
const (
	GuaranteeTranslationMinimum   = "translation_minimum"
	GuaranteeTestedOriginsMinimum = "tested_origins_minimum"
	GuaranteeFixedOrigin          = "fixed_origin"

	// FallbackExactWorkLimit means auto mode estimated more work for the
	// complete translation search than gridWorkLimit allows.
	FallbackExactWorkLimit = "EXACT_WORK_LIMIT"
)

Grid search modes and guarantees reported in AOOResult.

View Source
const (
	ProtocolVersion       = "1"
	InclusionRulesVersion = "strict-v1: finite, in-domain coordinates; exact WGS84 equality merges records; lon 180 -> -180; lon 0 at the poles"
	HullMethod            = "planar convex hull in the analysis CRS (monotone chain, exact orientation predicate)"
	AreaMethod            = "GDAL planar polygon area in the analysis CRS"
	GridOrientation       = "fixed analysis CRS axes; no rotation"
	GridBoundaryRule      = "[left,right) x [bottom,top); no snapping"
)

Method identifiers recorded in results and protocols. Changing what a calculation does under one of these names requires a new identifier.

View Source
const (
	// ProjectionLocalLAEA selects a local Lambert Azimuthal Equal Area projection
	// centred on the assessment distribution.
	ProjectionLocalLAEA = "local-laea"
	// ProjectionIUCNCEA selects the World Cylindrical Equal Area strategy used for
	// methodological comparison with the projection documented by the IUCN EOO Calculator.
	ProjectionIUCNCEA = "iucn-cea"
)
View Source
const AuditRulesVersion = "1"

AuditRulesVersion identifies the rule set; change it whenever a rule changes.

View Source
const CurationManifestVersion = "1"

CurationManifestVersion is the manifest format accepted by ApplyCuration.

View Source
const MaxPoints = 100000

MaxPoints is the maximum number of occurrence records accepted by one calculation.

View Source
const Version = "0.2.0"

Version is the public software version reported in calculation results.

Variables

This section is empty.

Functions

func ApplyCuration added in v0.2.0

func ApplyCuration(points []Point, m CurationManifest) ([]Point, CurationLog, error)

ApplyCuration verifies every decision against points before applying any of them and returns a new slice; points is not modified. The input hash must match, each selector must identify its record unambiguously, and every exclusion needs a justification.

func ExportGeoJSON

func ExportGeoJSON(gpkg, dir string) error

ExportGeoJSON uses GDAL RFC7946 conversion (including antimeridian splitting). Splitting requires GDAL 3.8 or newer; earlier versions emit a single ring that spans the antimeridian instead of a MultiPolygon. Segmentization at 250 m is for display; authoritative areas are in the report and GeoPackage, never recomputed from the densified WGS84 display geometries.

func GDALVersion

func GDALVersion() string

GDALVersion identifies the loaded native GDAL library.

func InputHash added in v0.2.0

func InputHash(points []Point) (string, error)

InputHash returns the SHA-256 that Calculate records for these points.

func PROJVersion

func PROJVersion() string

PROJVersion identifies the loaded native coordinate transformation library.

func WriteGeoPackage

func WriteGeoPackage(path string, r Result) (err error)

WriteGeoPackage stores exact analysis-plane geometries with their CRS. It refuses to overwrite an existing destination.

func WriteMapHTML

func WriteMapHTML(path, geojsonDir string, r Result) error

WriteMapHTML creates a single HTML report with the GeoJSON data embedded in the document. MapLibre GL JS and the demonstration basemap are loaded from the network when the file is opened; occurrence/EOO/AOO data stay embedded.

Types

type AOOResult

type AOOResult struct {
	AreaKM2                   float64    `json:"area_km2"`
	OccupiedCells             int        `json:"occupied_cells"`
	CellSizeM                 float64    `json:"cell_size_m"`
	ReferenceScale            bool       `json:"iucn_2km_scale"`
	GridMode                  string     `json:"grid_mode"`
	RequestedGridMode         string     `json:"requested_grid_mode"`
	EffectiveGridMode         string     `json:"effective_grid_mode"`
	FallbackReason            string     `json:"fallback_reason,omitempty"`
	ExactWorkEstimate         int64      `json:"exact_work_estimate,omitempty"`
	EstimatedPointEvaluations int64      `json:"estimated_point_evaluations"`
	SampledSteps              *int       `json:"grid_steps_effective,omitempty"`
	SearchGuarantee           string     `json:"search_guarantee"`
	Origin                    [2]float64 `json:"origin_m"`
	Candidates                int        `json:"candidate_origins"`
	MinCells                  int        `json:"min_cells"`
	MaxCells                  int        `json:"max_cells"`
	TestedMinCells            int        `json:"tested_min_cells"`
	TestedMaxCells            int        `json:"tested_max_cells"`
	BaseOriginCells           int        `json:"base_origin_cells"`
	BaseOriginAreaKM2         float64    `json:"base_origin_area_km2"`
	CompleteTranslationSearch bool       `json:"complete_translation_search"`
	Orientation               string     `json:"orientation"`
	BoundaryRule              string     `json:"boundary_rule"`
}

AOOResult contains the occupied-cell result and the grid-search metadata used to obtain it for the fixed orientation of the analysis CRS axes.

SearchGuarantee states what the reported count is a minimum of: translation_minimum (every translation at fixed orientation, exact mode), tested_origins_minimum (only the sampled origins) or fixed_origin (no search). TestedMinCells/TestedMaxCells span the evaluated origins only; their range is sensitivity to grid translation, not biological uncertainty. GridMode, MinCells, MaxCells and CompleteTranslationSearch are retained for v1 clients.

type AnalysisProtocol added in v0.2.0

type AnalysisProtocol struct {
	ProtocolVersion    string              `json:"protocol_version"`
	InputCRS           string              `json:"input_crs"`
	ProjectionStrategy string              `json:"projection_strategy"`
	AnalysisPROJ       string              `json:"analysis_proj"`
	Center             *[2]float64         `json:"center_lon_lat,omitempty"`
	CellSizeM          float64             `json:"cell_size_m"`
	Origin             [2]float64          `json:"origin_m"`
	GridMode           string              `json:"grid_mode"`
	Orientation        string              `json:"orientation"`
	BoundaryRule       string              `json:"boundary_rule"`
	HullMethod         string              `json:"hull_method"`
	AreaMethod         string              `json:"area_method"`
	InclusionRules     string              `json:"inclusion_rules_version"`
	Environment        ProtocolEnvironment `json:"environment"`
}

AnalysisProtocol freezes every effective parameter needed to reproduce a calculation on a changed record set: full analysis CRS definition, projection centre, cell size, grid origin and orientation, boundary rule, hull and area methods, and the record-inclusion rules. Reproduction always uses a fixed grid, so added records cannot move the centre or the origin.

func (AnalysisProtocol) SHA256 added in v0.2.0

func (p AnalysisProtocol) SHA256() string

SHA256 hashes the canonical JSON serialization of the protocol without its Environment, so the hash identifies method and effective parameters only.

type AuditConfig added in v0.2.0

type AuditConfig struct {
	InputCRS string `json:"input_crs,omitempty"`
	// CellSizeM is the AOO cell side compared against coordinate uncertainty.
	// Zero selects 2000.
	CellSizeM float64 `json:"cell_size_m,omitempty"`
	// CoarseDecimals enables COARSE_COORDINATE_PRECISION for records whose
	// input X and Y are both whole multiples of 10^-CoarseDecimals input-CRS
	// units. Nil disables the rule.
	CoarseDecimals *int `json:"coarse_decimals,omitempty"`
	// UncertaintyField names the record property holding coordinate
	// uncertainty in metres. Empty disables UNCERTAINTY_EXCEEDS_CELL_SIZE.
	UncertaintyField string `json:"uncertainty_field,omitempty"`
	// SourceFlagField names the record property holding source quality flags,
	// separated by commas or semicolons. Empty disables SOURCE_QUALITY_FLAG.
	SourceFlagField string `json:"source_flag_field,omitempty"`
	// ContextFields are record properties copied verbatim into every finding's
	// evidence (e.g. locality), so a reviewer sees them next to the finding.
	ContextFields []string `json:"context_fields,omitempty"`
}

AuditConfig enables and parameterizes the optional rules. Every threshold is explicit: nothing is inferred from field names unless a field is named here.

type AuditIssue added in v0.2.0

type AuditIssue struct {
	Code       string         `json:"code"`
	Severity   string         `json:"severity"`
	InputIndex *int           `json:"input_index"`
	SourceRow  *int           `json:"source_row,omitempty"`
	RecordID   string         `json:"record_id,omitempty"`
	Evidence   map[string]any `json:"evidence"`
	Message    string         `json:"message"`
}

AuditIssue is one finding about one record. It never states a biological conclusion and never removes the record.

type AuditRecord added in v0.2.0

type AuditRecord struct {
	Point
	// SourceRow is the 1-based CSV line number including the header, or 0.
	SourceRow  int
	ParseError string
}

AuditRecord is one input record as read by a permissive parser. ParseError is set when the record could not be turned into numeric coordinates (the strict calc parser would reject it); X/Y are then meaningless.

type AuditReport added in v0.2.0

type AuditReport struct {
	SchemaVersion   string      `json:"schema_version"`
	RulesVersion    string      `json:"rules_version"`
	SoftwareVersion string      `json:"software_version"`
	Config          AuditConfig `json:"config"`
	InputCRS        string      `json:"input_crs"`
	// InputSHA256 matches Result.InputSHA256 for the same records; it is null
	// when some record has no numeric coordinates and so cannot be hashed the
	// same way.
	InputSHA256           *string        `json:"input_sha256"`
	SourceSHA256          string         `json:"source_sha256,omitempty"`
	InputRecords          int            `json:"input_records"`
	InvalidRecords        int            `json:"invalid_records"`
	RecordsWithIssues     int            `json:"records_with_issues"`
	ValidUniqueCoords     int            `json:"valid_unique_coordinates"`
	DuplicateRecordIDs    int            `json:"duplicate_record_ids"`
	UncertaintyUnknown    *int           `json:"uncertainty_unknown,omitempty"`
	CountsByCode          map[string]int `json:"counts_by_code"`
	CountsBySeverity      map[string]int `json:"counts_by_severity"`
	CalculationCompatible bool           `json:"calculation_compatible"`
	Issues                []AuditIssue   `json:"issues"`
	Note                  string         `json:"note"`
}

AuditReport summarizes data-quality findings without running a grid search or changing which records a calculation uses.

func AuditOccurrences added in v0.2.0

func AuditOccurrences(ctx context.Context, records []AuditRecord, cfg AuditConfig) (AuditReport, error)

AuditOccurrences diagnoses records one by one. It reuses Calculate's domain checks and CRS transformation but never runs the grid search and never changes the record set: suspect records are reported, not removed.

type BuildInfo added in v0.2.0

type BuildInfo struct {
	GoVersion     string `json:"go_version"`
	ModuleVersion string `json:"module_version,omitempty"`
	VCSRevision   string `json:"vcs_revision,omitempty"`
	VCSTime       string `json:"vcs_time,omitempty"`
	VCSModified   *bool  `json:"vcs_modified,omitempty"`
}

BuildInfo identifies the compiled code. Fields are only filled from metadata the Go toolchain embedded; a local build without VCS stamping reports no revision rather than an invented one.

func Build added in v0.2.0

func Build() *BuildInfo

Build returns the embedded build metadata, or nil when unavailable.

type Cell

type Cell struct {
	Column       int64      `json:"column"`
	Row          int64      `json:"row"`
	UniquePoints int        `json:"unique_points"`
	Bounds       [4]float64 `json:"bounds_m"`
}

Cell describes one occupied AOO cell in analysis-CRS metres.

type ComparisonWarning added in v0.2.0

type ComparisonWarning struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

ComparisonWarning is a structured caveat about what a delta can mean.

type Config

type Config struct {
	InputCRS string `json:"input_crs,omitempty"`
	// ProjectionStrategy is local-laea (default) or iucn-cea.
	ProjectionStrategy string `json:"projection_strategy,omitempty"`
	// Center is [longitude, latitude] in WGS84. Nil selects a spherical mean.
	// It is only valid with local-laea.
	Center    *[2]float64 `json:"center,omitempty"`
	CellSizeM float64     `json:"cell_size_m,omitempty"`
	// GridMode is auto, exact, sampled, or fixed. Orientation is never rotated.
	GridMode  string     `json:"grid_mode,omitempty"`
	GridSteps int        `json:"grid_steps,omitempty"`
	Origin    [2]float64 `json:"origin_m"`
	// ExtentWarningDeg triggers PROJECTION_SENSITIVE_EXTENT when the longitude
	// or latitude span of the unique points exceeds it. Zero selects 20 degrees,
	// a provisional value pending calibration on more taxa.
	ExtentWarningDeg float64 `json:"extent_warning_deg,omitempty"`
}

Config controls coordinate interpretation, analysis projection and AOO grid search. Zero values select the documented defaults: EPSG:4326 input, local-laea, 2,000 m cells, auto grid search and 10 sampled steps when fallback is needed.

func ApplyProtocol added in v0.2.0

func ApplyProtocol(c Config, p AnalysisProtocol) (Config, error)

ApplyProtocol returns the fixed-grid Config that reproduces p. Fields already set in c must agree with the protocol; any disagreement, or a protocol whose methods differ from this software's, is an error raised before calculation.

type CurationDecision added in v0.2.0

type CurationDecision struct {
	InputIndex    int      `json:"input_index"`
	RecordID      *string  `json:"record_id,omitempty"`
	Lon           *float64 `json:"lon,omitempty"`
	Lat           *float64 `json:"lat,omitempty"`
	Action        string   `json:"action"`
	Justification string   `json:"justification"`
}

CurationDecision selects one record by zero-based input index and states what the curator expects to find there, so a manifest written for one file cannot silently apply to another. At least one of RecordID or Lon/Lat is required; every field given must match exactly.

type CurationLog added in v0.2.0

type CurationLog struct {
	SchemaVersion   string           `json:"schema_version"`
	SoftwareVersion string           `json:"software_version"`
	ManifestSHA256  string           `json:"manifest_sha256"`
	InputSHA256     string           `json:"input_sha256"`
	OutputSHA256    string           `json:"output_sha256"`
	InputRecords    int              `json:"input_records"`
	OutputRecords   int              `json:"output_records"`
	Excluded        []ExcludedRecord `json:"excluded"`
	Note            string           `json:"note"`
}

CurationLog links the original and derived record sets.

type CurationManifest added in v0.2.0

type CurationManifest struct {
	ManifestVersion string             `json:"manifest_version"`
	InputSHA256     string             `json:"input_sha256"`
	Description     string             `json:"description,omitempty"`
	Curator         string             `json:"curator,omitempty"`
	Decisions       []CurationDecision `json:"decisions"`
}

CurationManifest is a versioned, reviewable list of explicit exclusions for one exact input, identified by the same hash Calculate records.

type EOOInfluence added in v0.2.0

type EOOInfluence struct {
	SchemaVersion       string           `json:"schema_version"`
	SoftwareVersion     string           `json:"software_version"`
	InputSHA256         string           `json:"input_sha256"`
	GeometrySHA256      string           `json:"geometry_sha256"`
	ProtocolSHA256      string           `json:"protocol_sha256"`
	Projection          Projection       `json:"projection"`
	CRSPolicy           string           `json:"crs_policy"`
	OriginalRawEOOKM2   *float64         `json:"original_raw_eoo_km2"`
	OriginalStatus      string           `json:"original_eoo_status"`
	Status              string           `json:"status"`
	HullVertexGroups    int              `json:"hull_vertex_groups"`
	EvaluatedGroups     int              `json:"evaluated_groups"`
	RankingComplete     bool             `json:"ranking_complete"`
	Groups              []InfluenceGroup `json:"groups"`
	RecomputeProjection bool             `json:"recompute_projection"`
	Note                string           `json:"note"`
}

EOOInfluence reports how much raw EOO depends on each hull vertex. It is a sensitivity diagnostic: it never classifies a record as an error and never excludes records. The AOO floor is not applied to any value here.

func AnalyzeEOOInfluence added in v0.2.0

func AnalyzeEOOInfluence(ctx context.Context, points []Point, config Config, ic InfluenceConfig) (EOOInfluence, error)

AnalyzeEOOInfluence computes the original hull, freezes its complete analysis CRS and removes each hull-vertex coordinate group in turn, rebuilding the hull from all remaining points (interior points may become vertices). Groups are ordered by relative reduction, largest first; groups whose removal leaves no valid hull come first because they have no numeric delta. Remaining ties are broken by longitude then latitude.

type EOOResult

type EOOResult struct {
	RawAreaKM2        *float64 `json:"raw_area_km2"`
	AssessmentAreaKM2 float64  `json:"assessment_area_km2"`
	Status            string   `json:"status"`
	AdjustedToAOO     bool     `json:"adjusted_to_aoo"`
	Method            string   `json:"method"`
	GeodesicAreaKM2   *float64 `json:"geodesic_area_km2"`
	HullWKT           string   `json:"hull_wkt,omitempty"`
}

EOOResult contains raw convex-hull EOO and the assessment value after the explicit rule that assessment EOO must not be smaller than AOO.

Method names the hull construction and area measurement behind RawAreaKM2. GeodesicAreaKM2 is a diagnostic: the same hull vertices, transformed back to WGS84 and joined by ellipsoidal geodesics. It is a different polygon from the planar hull and is never used for the assessment value.

type ExcludedRecord added in v0.2.0

type ExcludedRecord struct {
	InputIndex    int     `json:"input_index"`
	RecordID      string  `json:"record_id,omitempty"`
	Lon           float64 `json:"lon"`
	Lat           float64 `json:"lat"`
	Justification string  `json:"justification"`
	Record        Point   `json:"record"`
}

ExcludedRecord documents one record removed by a manifest decision.

type Extent added in v0.2.0

type Extent struct {
	LonSpanDeg float64 `json:"lon_span_deg"`
	LatSpanDeg float64 `json:"lat_span_deg"`
}

Extent is the angular extent of the unique WGS84 points. The longitude span is the shortest arc covering every point, so it is correct across ±180.

type InfluenceConfig added in v0.2.0

type InfluenceConfig struct {
	// MaxCandidates limits how many hull-vertex groups are evaluated, in
	// longitude/latitude order. Zero selects 1000. When more vertices exist
	// the report is partial and its ranking is not global.
	MaxCandidates int `json:"max_candidates,omitempty"`
	// TopK limits how many evaluated groups are listed. Zero lists all.
	TopK int `json:"top_k,omitempty"`
	// RecomputeProjection additionally recalculates raw EOO for each removal
	// with a freshly chosen automatic local-laea centre, to separate geometric
	// influence from the effect of moving the projection centre.
	RecomputeProjection bool `json:"recompute_projection,omitempty"`
}

InfluenceConfig bounds an EOO influence analysis.

type InfluenceGroup added in v0.2.0

type InfluenceGroup struct {
	Longitude    float64  `json:"lon"`
	Latitude     float64  `json:"lat"`
	X            float64  `json:"x_m"`
	Y            float64  `json:"y_m"`
	InputIndices []int    `json:"input_indices"`
	RecordIDs    []string `json:"record_ids"`
	// RawEOOWithoutKM2 is the raw hull area of all remaining points in the
	// frozen analysis CRS; null when the remaining hull is degenerate.
	RawEOOWithoutKM2 *float64 `json:"raw_eoo_without_km2"`
	StatusWithout    string   `json:"eoo_status_without"`
	// ReductionKM2 is original raw EOO minus RawEOOWithoutKM2.
	ReductionKM2            *float64 `json:"reduction_km2"`
	RelativeReductionPct    *float64 `json:"relative_reduction_percent"`
	RecomputedRawEOOKM2     *float64 `json:"recomputed_projection_raw_eoo_km2,omitempty"`
	RecomputedStatus        string   `json:"recomputed_projection_status,omitempty"`
	RecomputedProjectionErr string   `json:"recomputed_projection_error,omitempty"`
}

InfluenceGroup is one unique coordinate that is a vertex of the original hull, removed as a geometric unit together with every record at it.

type Point

type Point struct {
	X          float64        `json:"lon"`
	Y          float64        `json:"lat"`
	ID         string         `json:"id,omitempty"`
	Taxon      string         `json:"taxon,omitempty"`
	Properties map[string]any `json:"properties,omitempty"`
}

Point is one occurrence record. X/Y use traditional GIS axis order: longitude/easting and latitude/northing. JSON uses the canonical public field names lon/lat. Properties are retained for provenance; records at identical coordinates are merged only geometrically, never discarded.

type Projection

type Projection struct {
	Strategy              string     `json:"strategy"`
	Reference             string     `json:"reference"`
	InputCRS              string     `json:"input_crs"`
	InputWKT              string     `json:"input_wkt"`
	AnalysisPROJ          string     `json:"analysis_proj"`
	AnalysisWKT           string     `json:"analysis_wkt"`
	Center                [2]float64 `json:"center_lon_lat"`
	CenterMethod          string     `json:"center_method"`
	MaxAngularDistanceDeg float64    `json:"max_angular_distance_deg"`
	AxisOrder             string     `json:"axis_order"`
}

Projection records the effective input and analysis CRS definitions and the information needed to reproduce the projection choice.

type ProjectionComparison

type ProjectionComparison struct {
	SchemaVersion   string              `json:"schema_version"`
	SoftwareVersion string              `json:"software_version"`
	InputSHA256     string              `json:"input_sha256"`
	LocalLAEA       Result              `json:"local_laea"`
	IUCNCEA         Result              `json:"iucn_cea"`
	Delta           ProjectionDelta     `json:"delta_iucn_cea_minus_local_laea"`
	Warnings        []ComparisonWarning `json:"warnings"`
	Note            string              `json:"note"`
}

ProjectionComparison contains summary results for both supported projection strategies plus their signed differences. It exposes projection sensitivity; it does not select a universally preferred strategy. Warnings flag when the two AOO values were not obtained with the same search coverage, in which case the AOO delta mixes projection with grid-search effects.

func CompareProjections

func CompareProjections(ctx context.Context, points []Point, config Config) (ProjectionComparison, error)

CompareProjections runs the same normalized records and grid configuration through the local LAEA and IUCN-compatible World Cylindrical Equal Area strategies. The delta is always iucn-cea minus local-laea.

type ProjectionDelta

type ProjectionDelta struct {
	EOORawKM2            *float64 `json:"eoo_raw_km2"`
	EOORawPercent        *float64 `json:"eoo_raw_percent"`
	EOOAssessmentKM2     float64  `json:"eoo_assessment_km2"`
	EOOAssessmentPercent *float64 `json:"eoo_assessment_percent"`
	AOOKM2               float64  `json:"aoo_km2"`
	AOOPercent           *float64 `json:"aoo_percent"`
	AOOOccupiedCells     int      `json:"aoo_occupied_cells"`
}

ProjectionDelta reports iucn-cea minus local-laea differences for the same normalized records and grid configuration. Percentage fields are nil when a baseline is zero or the corresponding raw EOO is unavailable.

type ProtocolEnvironment added in v0.2.0

type ProtocolEnvironment struct {
	SoftwareVersion string `json:"software_version"`
	GDALVersion     string `json:"gdal_version"`
	PROJVersion     string `json:"proj_version"`
}

ProtocolEnvironment records the native stack that produced a result. It is reported but excluded from the protocol hash: a protocol fixes method and parameters, while bit-identical output across native versions is not promised.

type Result

type Result struct {
	SchemaVersion     string     `json:"schema_version"`
	SoftwareVersion   string     `json:"software_version"`
	GDALVersion       string     `json:"gdal_version"`
	PROJVersion       string     `json:"proj_version"`
	Taxon             string     `json:"taxon,omitempty"`
	Build             *BuildInfo `json:"build,omitempty"`
	InputSHA256       string     `json:"input_sha256"`
	GeometrySHA256    string     `json:"geometry_sha256"`
	ProtocolSHA256    string     `json:"protocol_sha256"`
	InputRecords      int        `json:"input_records"`
	UniqueCoordinates int        `json:"unique_coordinates"`
	DuplicateRecords  int        `json:"duplicate_records"`
	Config            Config     `json:"config"`
	Projection        Projection `json:"projection"`
	Extent            Extent     `json:"wgs84_extent"`
	EOO               EOOResult  `json:"eoo"`
	AOO               AOOResult  `json:"aoo"`
	Warnings          []string   `json:"warnings"`
	// Protocol freezes the effective parameters for temporal reproduction.
	Protocol *AnalysisProtocol `json:"protocol,omitempty"`
	Cells    []Cell            `json:"cells,omitempty"`
	Points   []UsedPoint       `json:"points,omitempty"`
}

Result is the reproducible calculation record returned by Calculate. InputSHA256 hashes the ordered records with their metadata; GeometrySHA256 hashes only the sorted unique normalized coordinates; ProtocolSHA256 hashes the effective method and parameters (see AnalysisProtocol). Cells and Points are omitted by Summary and by default CLI/API responses.

func Calculate

func Calculate(ctx context.Context, points []Point, config Config) (Result, error)

Calculate accepts exactly one assessment unit (taxon). Context cancellation is checked between transforms and inside the grid search. All input is strict: no silent dropping, imputing missing coordinates to zero, or auto-swapping axes.

Example
package main

import (
	"context"
	"fmt"

	eooaoo "github.com/lsbjordao/go-iucn-eoo-aoo"
)

func main() {
	points := []eooaoo.Point{
		{X: -43.2, Y: -22.9, ID: "demo-001", Taxon: "Mimosa demonstrativa"},
	}

	result, err := eooaoo.Calculate(context.Background(), points, eooaoo.Config{})
	if err != nil {
		panic(err)
	}

	fmt.Println(result.AOO.AreaKM2)
	fmt.Println(result.EOO.RawAreaKM2 == nil)
}
Output:
4
true

func CalculateWithProtocol added in v0.2.0

func CalculateWithProtocol(ctx context.Context, points []Point, p AnalysisProtocol, c Config) (Result, error)

CalculateWithProtocol reproduces a frozen protocol on a (possibly changed) record set. Differences in software, GDAL or PROJ versions are reported as a warning, not hidden; identical output across native versions is not promised.

func (Result) Summary

func (r Result) Summary() Result

Summary returns a copy with the potentially large cell and point provenance arrays removed. It does not mutate the receiver.

type UsedPoint

type UsedPoint struct {
	Longitude float64 `json:"lon"`
	Latitude  float64 `json:"lat"`
	X         float64 `json:"x_m"`
	Y         float64 `json:"y_m"`
	// InputIndices are zero-based positions in the input slice.
	InputIndices []int   `json:"input_indices"`
	Records      []Point `json:"records"`
}

UsedPoint is one unique normalized WGS84 coordinate together with its analysis-plane coordinate and complete source-record provenance.

Directories

Path Synopsis
cmd
eoo-aoo command
examples
library command
internal
input
Package input reads strict coordinate tables and WGS84 point GeoJSON.
Package input reads strict coordinate tables and WGS84 point GeoJSON.
server
Package server exposes a bounded, stateless HTTP interface for local stacks.
Package server exposes a bounded, stateless HTTP interface for local stacks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL