EncDotNet.S100.Datasets.S104 0.26.0

dotnet add package EncDotNet.S100.Datasets.S104 --version 0.26.0
                    
NuGet\Install-Package EncDotNet.S100.Datasets.S104 -Version 0.26.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EncDotNet.S100.Datasets.S104" Version="0.26.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EncDotNet.S100.Datasets.S104" Version="0.26.0" />
                    
Directory.Packages.props
<PackageReference Include="EncDotNet.S100.Datasets.S104" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EncDotNet.S100.Datasets.S104 --version 0.26.0
                    
#r "nuget: EncDotNet.S100.Datasets.S104, 0.26.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EncDotNet.S100.Datasets.S104@0.26.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EncDotNet.S100.Datasets.S104&version=0.26.0
                    
Install as a Cake Addin
#tool nuget:?package=EncDotNet.S100.Datasets.S104&version=0.26.0
                    
Install as a Cake Tool

EncDotNet.S100.Datasets.S104

This package reads S-104 Water Level Information for Surface Navigation datasets from HDF5 files: water-level grids per time step, and time series at fixed stations. It also draws them, as station gauges and surface isolines, and validates them against the S-104 Edition 2.0.0 checklist. Reference it when you need the water levels directly, for example to sample a tide curve at a position. To open and render a dataset without wiring catalogues yourself, use the EncDotNet.S100 package instead.

Install

dotnet add package EncDotNet.S100.Datasets.S104
dotnet add package EncDotNet.S100.Hdf5.PureHdf

EncDotNet.S100.Hdf5.PureHdf provides the HDF5 reader the example uses.

Read a dataset

A file holds either a regular grid per time step or a series of values per station. ReadAny returns whichever the file contains:

using EncDotNet.S100.Datasets.S104;
using EncDotNet.S100.Hdf5.PureHdf;

using var file = PureHdfFile.Open("path/to/dataset.h5");

switch (S104DatasetReader.ReadAny(file))
{
    case S104DatasetData.GriddedCoverage gridded:
        foreach (WaterLevelCoverage step in gridded.Dataset.Coverages.Take(3))
            Console.WriteLine($"{step.TimePoint:u}: {step.Values.Length} cells");
        break;

    case S104DatasetData.StationSeries stations:
        foreach (WaterLevelStation station in stations.Dataset.Stations)
            Console.WriteLine($"{station.Identifier}: {station.NumberOfTimes} samples");
        break;
}

Each WaterLevelValue has a Height in metres relative to the dataset's vertical datum and a Trend: 1 (decreasing), 2 (increasing), 3 (steady) or 0 (unknown). Grid cells without data hold the fill value -9999. For more, see Reading product data.

Main types

  • S104Dataset: a gridded dataset, with its horizontal CRS, vertical datum, data coding format and one coverage per time step.
  • S104DatasetReader: reads data coding formats 2 (regular grid), 1 (time-major station series) and 8 (station-major station series).
    • For format 1, each Group_NNN/timePoint is the timestamp, including on uneven time axes. The time-major values are transposed into the same per-station model as format 8.
    • The reader targets the Edition 2.0.0 HDF5 layout and still reads datasets that declare older editions. Schema errors throw S100DatasetSchemaException.
    • The waterLevelTrend compound member accepts the signed and unsigned integer widths found in production data, including IC-ENC's Int16.
  • WaterLevelCoverage and WaterLevelValue: a grid at one time step and its values. WaterLevelCoverage.GroupPath is the HDF5 path of the coverage, such as /WaterLevel/WaterLevel.01. Validation findings use it as RelatedFeatureId.
  • S104StationSeriesDataset and WaterLevelStation: a station series and one station's heights and trends.
  • S104TimeSeriesSampler: samples a regular-grid (format 2) dataset at a geographic position across its time steps. It returns an S104TimeSeries: the nearest cell and an S104TimeSeriesPoint per step with height and trend, in time order and optionally limited to a from/to range. It finds the nearest cell in the coverage's geographic coordinates (EPSG:4326 in S-104 Ed 2.0.0) without reprojecting. Cells with the fill value report a null height. The MCP server's sample_coverage tool uses it for time windows.
  • S104CoverageSource: the ICoverageSource for the coverage pipeline.
  • S104PortrayalCatalogue: the SoundCharts portrayal of water level: the ink colours, isoline interval and label formats. See Portrayal.

The S104DatasetProcessor that renders, samples and validates a dataset is in EncDotNet.S100.Datasets.Pipelines.

Portrayal

S-104 Edition 2.0.0 has no portrayal. Clause 9 says the data is used to adjust depths in the ENC or bathymetry (S-98 Annex C), and the edition removed the earlier portrayal catalogue. The content/S104/pc/ folder in EncDotNet.S100.Specifications is empty.

Both renderings below are SoundCharts' own, not IHO symbology. S104PortrayalCatalogue describes them and S104DatasetProcessor builds them. Wherever a user meets them, they're labelled "SoundCharts portrayal: S-104 Ed 2.0.0 defines no symbology" (SpecConventions.S104Portrayal): in SoundCharts' Object information panel for a station or grid cell and its dataset inspector, on the Portrayal row of s100 info, and as portrayalNote in the MCP list_specs and describe_feature results. s100 render and render_to_image draw them unlabelled. They use one ink colour per palette, draw no colour fill over the ENC, and avoid magenta (mariner information), red and amber (danger) and blue and green (depth). Colour doesn't encode the trend or the height.

Palette Ink Square fill and value halo Isoline label halo
Day #0F5E73 #FFFFFF #F6FBFE
Dusk #9FD3DE #3B4650 #3B4650
Night #3E7C88 #0B0F14 #0B0F14

Night colours stay under luminance 0.2. S104PortrayalCatalogue.GetInk(PaletteType) returns a palette's colours.

Stations

Fixed-station series (data coding formats 1 and 8) are drawn as a gauge at each station, on the s104.stations sub-layer:

  • A 16 px rounded square. The mark inside shows waterLevelTrend at the selected time step: a chevron up for increasing, a chevron down for decreasing, a dash for steady and "?" for unknown. Steady means the change is under the dataset's waterLevelTrendThreshold.
  • The height at the selected step, to the right of the square, in metres above the dataset's vertical datum: sign always shown, two decimals, no unit, for example +1.42 or −0.12 (FormatStationValue). It's drawn at 1:100 000 and larger scales (StationLabelMaxScaleDenominator); at smaller scales only the square is drawn.
  • A station whose height at the step is the fill value (-9999) draws "—" in the square and no value.

The gauges are ordinary S-100 symbols (S104PortrayalCatalogue.GetSymbol, with colours from GetColorPalette) and text instructions, carried on a VectorCoverageSubLayer and drawn by the same renderer as S-101. So they follow the same rules as S-101 symbols and labels: the mariner's symbol and text scale, the label's scale minimum (SCAMIN), label decluttering (a label that overlaps a higher-priority one is dropped; symbols always draw), upright symbols and text on a rotated display, and picking. The value label uses the S-100 Part 9 font characteristics MonoSpaced and Bold, with a halo (TextInstruction.HaloColor).

Surface

A regular grid (data coding format 2) is drawn as dashed water-level isolines for the selected step, on the s104.isolines sub-layer, with no fill:

  • The interval is 0.5 m, or 0.25 m when the dataset's whole range (all steps, fill values excluded) is under 1 m (SelectIsolineInterval). It's chosen once per dataset, so the line density doesn't change while you scrub through time.
  • Each line is labelled with its level in metres, about every 250 px of line: one decimal (two for 0.25 m steps), "−" for negatives and no "+", for example 1.0, 0.5, 0 or −0.5 (FormatIsolineLabel).
  • Lines stop at fill-value nodes. A coarse grid is subdivided bilinearly before tracing (IsolineTracer) so the lines aren't angular.
  • Labels are drawn upright on a rotated display, scale with the mariner's text scale, and are dropped where they would overlap another isoline label.

s100 render draws the same stations and isolines.

Visibility and clipping to water

SoundCharts loads a gridded surface hidden; you can show it from the layer controls. Station gauges are shown by default. S104DatasetProcessor.IsGriddedSurface tells the two apart.

When the surface is shown with an S-101 ENC, the S-98 interoperability rule R-101-104-B (S98DefaultRules.R_101_104_B_ClipSurfaceToWater) attaches the ENC's LandArea geometry to the isoline sub-layer (IsolineCoverageSubLayer.LandAreaMask). The isolines are then clipped to water at output-pixel resolution, in the viewer and in headless renders, so they never cross land however coarse the grid is. The surface is layered like S-102 bathymetry, under the ENC's line work.

Validation

The bundled rule pack, EncDotNet.S100.Datasets.S104.Validation.S104DatasetRules.Default, checks an S104Dataset against the S-104 Edition 2.0.0 checklist and returns a ValidationReport. S104DatasetProcessor.Validate() runs it for you. To run it directly:

using EncDotNet.S100.Datasets.S104.Validation;

var report = S104DatasetRules.Default.Run(dataset);
foreach (var finding in report.Findings)
    Console.WriteLine($"{finding.RuleId} {finding.Severity}: {finding.Message}");
Rule ID Severity Checks
S104-R-1.1 Error Each coverage's Values.Length equals NumPointsLatitudinal × NumPointsLongitudinal.
S104-R-1.2 Error DataCodingFormat is a supported gridded format: 2 or 3.
S104-R-2.1 Warning Coverages are in strictly increasing TimePoint order. One finding at the first violation.
S104-R-2.2 Warning The intervals between TimePoints are within ±10% of the median interval. Skipped when there are fewer than three coverages.
S104-R-3.1 Warning MethodWaterLevelProduct is set when there's more than one coverage.
S104-R-4.1 Warning Water levels other than the fill value are within [-15, 15] m. There's one finding per coverage with values outside the range. -9999, NaN and ±Infinity are skipped.
S104-R-4.2 Error Each coverage's origin and far corner (origin + (numPoints - 1) × spacing) are valid in HorizontalCRS: within WGS 84 ranges and not crossing the antimeridian when geographic; within UTM bounds, and reprojectable to WGS 84, when projected.
S104-PROJ-SCHEMA Error The HDF5 dataset failed schema parsing inside Validate().
S104-PROJ-UNSUPPORTED Error The reader raised S100DatasetNotSupportedException inside Validate().
S104-STATION-SHAPE Error A station's timestamps, heights, trends and declared sample count disagree.
S104-STATION-TIME Error A station's explicit timestamps aren't strictly increasing.
S104-STATION-TREND Error A station has a trend code outside 0–3.

S104DatasetProcessor checks station series itself with the S104-STATION-* rules, because the rule pack works on gridded S104Datasets. The S-111 rule pack reuses the time-axis checks in S104-R-2.1 and S104-R-2.2.

For the validation API and your own rules, see Custom catalogues and validation.

See also

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on EncDotNet.S100.Datasets.S104:

Package Downloads
EncDotNet.S100.Datasets.Pipelines

Per-spec IDatasetProcessor implementations, the DatasetPipelineFactory (file -> processor detection), the headless image-render capability, the S-98 interoperability authority, and the validation runner for IHO S-100 product datasets. Consumed by the EncDotNet.S100 convenience package, the viewer, and the s100 CLI.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.26.0 52 10/24/2026
0.25.1 115 10/12/2026
0.25.0 117 10/12/2026
0.24.0 140 10/4/2026
0.23.0 144 9/17/2026
0.22.0 205 7/19/2026
0.21.0 181 7/10/2026
0.20.0 209 6/29/2026
0.19.0 192 6/27/2026
0.18.0 205 6/17/2026
0.17.1 198 6/16/2026
0.17.0 199 6/15/2026
0.16.0 194 6/8/2026