Table of Contents

EncDotNet.S100.Datasets.S102

Reader and coverage portrayal pipeline for S-102 Bathymetric Surface datasets.

Overview

This library reads S-102 datasets from HDF5 files and provides coverage data (depth and uncertainty grids) for the portrayal pipeline. Key types include:

  • S102Dataset — root model containing horizontal CRS, vertical datum, and bathymetric coverages.
  • S102DatasetReader — reads an S-102 dataset from an IHdf5File. The horizontal CRS is resolved from the Edition 3.0.0 horizontalCRS root attribute, falling back to the Edition 2.1 horizontalDatumValue attribute when the former is absent, so both editions georeference correctly. The verticalDatum root attribute (S-102 Ed 3.0.0 §12.3) is surfaced as S102Dataset.VerticalDatum (an S-100 register code) and resolved to a label by S102CoverageSource via EncDotNet.S100.DataModel.VerticalDatums. ReadMetadata(file) is the phased-loading "peek" path (issue #460): it returns a DatasetMetadata (declared spec, grid extent, and HorizontalCrsEpsg for correct UTM reprojection) computed from the grid georeferencing attributes alone, without reading any depth / uncertainty values arrays.
  • S102CoverageSource — ICoverageSource adapter for the coverage pipeline. Its overview pyramid and residual viewport-stride sampling both min-pool depth and max-pool uncertainty. Every source cell belongs to an output block, and residual blocks are balanced across the sampled footprint so their regular-grid georeferencing remains exact. Overview levels stop before either axis would require a partial 2×2 edge pool. Small-scale sampling therefore cannot skip a narrow shoal that falls between stride lattice points. Coverage read spans report s100.coverage.reducer=min.
  • S102PortrayalCatalogue — coverage portrayal catalogue for depth shading.
  • BathymetryCoverage, BathymetryValue — bathymetric data models. BathymetryCoverage.GroupPath carries the HDF5 instance path (e.g. /BathymetryCoverage/BathymetryCoverage.01) and is used by the validation rule pack as the per-coverage RelatedFeatureId.

Portrayal

Portrayal is PC-driven: S102PortrayalCatalogue executes the bundled BathymetryCoverage.lua rule (S-102 Edition 3.0.0, Annex B) through an ILuaEngine and resolves the emitted CoverageColor tokens (DEPDW, DEPMD, DEPMS, DEPVS, DEPIT, NODTA) against the bundled ColorProfiles/colorProfile.xml. The Day, Dusk, and Night palettes are all loaded; SwitchPalette selects the active mood.

The four S-102 context parameters flow in via MarinerSettings:

  • FourShades — toggle between two-band (DEPVS / DEPDW split at SafetyContour) and four-band (DEPVS / DEPMS / DEPMD / DEPDW split at ShallowContour / SafetyContour / DeepContour) shading.
  • SafetyContour, ShallowContour, DeepContour — depth boundaries in metres.

Invariants (ShallowContour ≤ SafetyContour ≤ DeepContour) are clamped (with a diagnostic) rather than throwing — the viewer settings panel surface area means transient out-of-order slider values must not crash the render pipeline.

Cells whose depth equals S102CoverageSource.FillValue (1,000,000f) are painted with the active palette's NODTA colour via CoverageColorScheme.NoDataColor by default. Set S102PortrayalCatalogue.RenderNoDataFill = false to leave NODATA cells transparent instead — the correct behaviour when S-102 is overlaid on another layer (e.g. an S-101 ENC in the viewer), so the un-surveyed remainder of the rectangular coverage extent does not obscure the chart beneath.

Validation

A bundled rule pack (EncDotNet.S100.Datasets.S102.Validation.S102DatasetRules.Default) evaluates a typed S102Dataset against the S-102 Edition 3.0.0 checklist and emits a ValidationReport of findings. The pack is invoked automatically by S102DatasetProcessor.Validate() and is also runnable directly:

var report = S102DatasetRules.Default.Run(dataset);
foreach (var finding in report.Findings)
    Console.WriteLine($"{finding.RuleId} {finding.Severity}: {finding.Message}");
Rule id Severity Checks
S102-R-1.1 Error Each coverage's Values.Length equals NumPointsLatitudinal × NumPointsLongitudinal.
S102-R-2.1 Error NODATA fill in Depth/Uncertainty is exactly 1_000_000f; flags NaN / ±Infinity as illegal sentinel substitutes.
S102-R-3.1 Warning HorizontalCRS, when set, is a recognised EPSG code (4326, 4269, or WGS-84 UTM band).
S102-R-3.2 Warning IssueDate, when set, parses as an ISO 8601 date or date-time, basic (20260902) or extended (2026-09-02).
S102-R-3.3 Warning IssueTime, when set, parses as an ISO 8601 time of day, basic (105406+0000) or extended (10:54:06Z).
S102-R-4.1 Error Each coverage's origin is valid in HorizontalCRS: lat ∈ [-90, 90] / lon ∈ [-180, 180] when geographic; UTM easting/northing bounds (and reprojects to WGS 84) when projected.
S102-R-4.2 Error Each coverage's far corner is valid in HorizontalCRS the same way; a geographic extent must not wrap the antimeridian.
S102-R-5.1 Warning Non-NODATA depth values fall within [-50, 12 000] m (one finding per offending coverage).
S102-PROJ-SCHEMA Error Defensive surrogate: emitted when the underlying HDF5 dataset fails schema-level parsing inside Validate().

Installation

dotnet add package EncDotNet.S100.Datasets.S102