EncDotNet.S100.Core
0.25.1
dotnet add package EncDotNet.S100.Core --version 0.25.1
NuGet\Install-Package EncDotNet.S100.Core -Version 0.25.1
<PackageReference Include="EncDotNet.S100.Core" Version="0.25.1" />
<PackageVersion Include="EncDotNet.S100.Core" Version="0.25.1" />
<PackageReference Include="EncDotNet.S100.Core" />
paket add EncDotNet.S100.Core --version 0.25.1
#r "nuget: EncDotNet.S100.Core, 0.25.1"
#:package EncDotNet.S100.Core@0.25.1
#addin nuget:?package=EncDotNet.S100.Core&version=0.25.1
#tool nuget:?package=EncDotNet.S100.Core&version=0.25.1
EncDotNet.S100.Core
EncDotNet.S100.Core holds the abstractions and pipeline framework that the
other EncDotNet.S100 packages share: asset sources, HDF5 and Lua interfaces,
the coverage and vector portrayal pipelines, the validation framework, dataset
metadata, spec-version checks and dynamic feature sources. Reference it
directly when you write a product reader, an HDF5 or Lua backend, a validation
rule pack or a rendering host. If you only want to open and render datasets,
use the EncDotNet.S100 facade, which brings
this package in.
Install
dotnet add package EncDotNet.S100.Core
Example: read a file from a folder or ZIP
Readers get their files through IAssetSource, so the same code reads from a
folder or a ZIP archive:
using EncDotNet.S100.Core;
using IAssetSource source = FileSystemAssetSource.Create("path/to/exchange-set");
// or: using IAssetSource source = ZipAssetSource.Create("path/to/exchange-set.zip");
await using Stream catalogue = await source.OpenAsync("CATALOG.XML");
Main entry points
Asset sources
IAssetSource (namespace EncDotNet.S100.Core) reads files by relative path.
FileSystemAssetSource reads from a folder, ZipAssetSource from a ZIP
archive, and CachingAssetSource caches reads from another source.
HDF5
IHdf5File and IHdf5Group (namespace EncDotNet.S100.Hdf5) read HDF5 data
without binding to a specific HDF5 library.
EncDotNet.S100.Hdf5.PureHdf
implements them.
HDF5 readers throw two exception types:
S100DatasetSchemaException: a required attribute or group is missing or malformed.S100DatasetNotSupportedException: the file uses an optional part of the specification that the reader doesn't implement yet.
Both carry the product, file, group path and specification reference, and a
WithFile(...) helper that processors use to attach the source file name.
S100DatasetSchemaException also carries an optional AdditionalContext, set
with WithAdditionalContext(...) and kept across WithFile(...). Readers use
it to add an explanation, such as a note that the dataset declares an
unexpected product-specification edition.
Hdf5RequiredAttributeExtensions provides ReadRequiredDoubleAttribute,
ReadRequiredInt64Attribute and ReadRequiredStringAttribute. They turn a
backend's "missing attribute" failure into these typed exceptions.
Lua scripting
ILuaEngine and ILuaContext (namespace EncDotNet.S100.Scripting) run
sandboxed Lua portrayal scripts. S100LuaHost is the host API the scripts
call.
EncDotNet.S100.Scripting.MoonSharp
implements the engine.
Coverage pipeline
ICoverageSource, ICoverageRenderer<T> and CoveragePipeline (namespace
EncDotNet.S100.Pipelines.Coverage) render gridded data, with
GridGeoreferencer, CoverageColorScheme and StyledCoverageLayer.
ICoveragePortrayalCatalogue.ResolveColorSchemereturnsCoverageColorScheme?. Catalogues that only emit symbols, such as S-111's arrow-only portrayal, returnnull. The coverage renderers throw if you pass them a layer with anullscheme.CoveragePipeline.ProcessAsynctakes an optionalViewport. When you pass one, it usesGridRegion.FromViewportto sample only the cells inside the viewport, at the viewport's ground resolution. It clamps the subset to the intersection of the viewport and the grid extent, and picks a stride so the ground resolution isn't finer than the cell size. Without a viewport it samples the full grid.- For a grid in a CRS other than EPSG:4326, also pass
wgs84ToNative, anICrsTransformfrom WGS 84 to the grid's CRS. - The georeferencer on the resulting
StyledCoverageLayeris built from the sampled subset'sGridMetadata: its origin is adjusted for the subset and its spacing scaled by the stride. A sampled subset is drawn at its true location. - Viewport sampling happens when the pipeline builds the layer.
ICoverageSourcecan also serve an overview pyramid (S-100 Part 10c):AvailableOverviewLevelslists the levels andSelectOverviewLevelpicks one.CoveragePyramidandCoveragePyramidBuilder(namespaceEncDotNet.S100.Pipelines.Coverage.Pyramid) build one in memory.
Vector pipeline
IVectorSource, IVectorPortrayalCatalogue and VectorPipeline (namespace
EncDotNet.S100.Pipelines.Vector) run vector portrayal. The output is the
DrawingInstruction hierarchy (AreaInstruction, LineInstruction,
PointInstruction, TextInstruction), modelled on the S-100 Part 9 display
list.
- Rule execution is pluggable behind
IVectorRuleExecutor. There are two implementations:Pipelines.Vector.Xslt.XsltRuleExecutor(S-100 Part 9 §9.4) gets the FeatureXML, selects rules, runs the XSLT transformation and assembles the display list.Pipelines.Vector.Lua.LuaRuleExecutor(S-100 Part 9A) is one product-independent executor. Products supply their own parts throughILuaDataProviderandILuaDataProviderFactory(the host bridge),LuaContextParameterBinding(mariner settings to context parameters),IFeatureAnchorProviderandIDrawingInstructionTransform. S-101 and S-131 share the executor this way.
VectorPipelineruns the built-in XSLT executor, appends the output of an optional injected Lua executor, then filters by viewing group and display plane and sorts by priority. It contains no XSLT-specific code.DrawingInstructionParserparses Lua-emitted drawing instructions.Part9DisplayListReaderparses the Part 9 display-list XML produced by the XSLT pipelines (S-124, S-129, S-421) into the sameDrawingInstructionhierarchy that S-101's Lua pipeline emits, so one renderer handles both.
Portrayal-instruction caching
IPortrayalInstructionCache (namespace
EncDotNet.S100.Pipelines.Vector.Caching) caches the DrawingInstruction list
that the vector pipeline produces. When you reopen a dataset you've portrayed
before, a cache hit skips the portrayal run, which for S-101 is a Lua run
taking several seconds.
GetOrCompute(key, factory)returns the cached list or computes it.InMemoryPortrayalInstructionCacheis a bounded LRU cache that holds list references.DiskPortrayalInstructionCachewrites each list to a.dlistfile withDrawingInstructionSerializer. Writes go to a temporary file and are then moved into place, and an LRU byte cap bounds the cache. A corrupt file or aFormatVersionmismatch counts as a miss, so a stale or partial file never breaks a render.- You supply a key that captures every portrayal input.
S101DatasetProcessorhashes the dataset bytes, the feature and portrayal catalogue content (including overrides and Lua rules) and the engine assembly versions. - The cache stores the pipeline's final output, so a hit returns exactly the list a fresh run would produce.
Dataset metadata
DatasetMetadata (namespace EncDotNet.S100.Core) is what every dataset
reader returns from its ReadMetadata path: the facts a host can get without a
full parse and portrayal.
- It has
Spec(SpecRef),Extent(BoundingBox?),HorizontalCrsEpsg(int?),DisplayScale(DisplayScaleRange?) andTimeCoverage(TimeCoverage?). - Only
Specis always set. Anulloptional value means it isn't available cheaply; load the dataset fully to get it. - A host can use it to load a folder of datasets with no catalogue in phases: read every dataset's metadata, frame the viewport from the union of their extents, and load each dataset fully when it comes into view.
Gml.GmlDatasetMetadata.Create(specName, declaredEdition, features)folds feature geometry into an extent for the GML products.
The EncDotNet.S100.Core.Metadata namespace caches metadata between sessions:
DatasetMetadataSerializerwrites aDatasetMetadatato a small versioned binary blob. A corrupt blob or aFormatVersionmismatch counts as a miss.IDatasetMetadataCacheandDiskDatasetMetadataCachestore one.dmetafile per dataset, keyed by the source file's last-write time and length. Any mismatch, or an unwritable or corrupt entry, is a miss and never breaks loading. Writes are atomic and an LRU byte cap bounds the cache, as for the portrayal-instruction cache.
Validation
The EncDotNet.S100.Validation namespace has the product-independent types
for checking normative clauses against the typed data models:
IValidationRule<TModel>is one rule.ValidationRuleSet<TModel>runs a set of rules, collects every finding, and catches exceptions from individual rules.ValidationFindinghas the rule id, severity, message, an optionalGeoPositionorBoundingBox, and a related feature id.ValidationSeverityandValidationReport.ValidationContextcarriesReferenceTimeand an optionalIServiceProviderfor rules that look across datasets.ValidationRuleBuilderbuilds rules fluently:RuleFor<T>("rule-id").Check(predicate, message).Build(), or.Yield(producer)for rules that return several findings.
Each product's rule pack lives in the Validation/ folder of its
EncDotNet.S100.Datasets.Sxxx project.
- S-101, S-102, S-104, S-111, S-122, S-124, S-125, S-127, S-128, S-129, S-131, S-201, S-411 and S-421 ship a rule pack. S-57 delegates to the S-101 pack.
- S-401 (IEHG Inland ENC) is read and portrayed but has no rule pack. The S-101
pack checks S-101 clauses and doesn't run against inland data, so
Validate()reports that no rules are available. - Rule packs for vector products read from a façade that follows the
specification, not from the raw reader types. For S-101 that's
S101DatasetView,S101FeatureViewandS101AttributeView. Rule code then doesn't change if a typed data model replaces the reader types later. - Coverage records have a
GroupPath(BathymetryCoverage.GroupPathin S-102,WaterLevelCoverage.GroupPathin S-104). Rule packs use it as theValidationFinding.RelatedFeatureIdfor each coverage.
Custom catalogues and validation shows how to run the bundled rules and write your own.
Spec-version assessment
SpecRef, CatalogueRef and SpecVersion identify product specifications
and catalogues. SpecCompatibility.Classify(declared, implemented) compares
two editions (S-100 Edition 5.2.1 Part 2 §6).
SpecVersionAssessment compares a dataset's declared product-specification
edition with the editions the application supports.
- It doesn't compare against the feature or portrayal catalogue version. A catalogue declares only its own version, not the product-specification edition it targets, so that comparison would give false warnings.
IsWarningistrueonly when the application supports an older edition on the same major version, or no edition on the declared major version.BuildMessage()returns the note to show the user.Gml.GmlDatasetIdentification.ReadDeclaredEdition(root)reads the declared edition from a GML dataset'sDatasetIdentificationInformation/productEdition(S-100 GML 5.0 or the legacy 1.0 profile).
Shared types
IPortrayalCatalogue,ICrsTransform,ICrsTransformFactory,Viewport,BoundingBox,RgbaColorandColorPalette(namespaceEncDotNet.S100.Pipelines).MarinerSettings: the S-100 Part 9 §4.2 mariner selections, including the four depth contours and S-101 portrayal options such asFourShades,SimplifiedSymbols,RadarOverlayandNationalLanguage.DepthUnitandDepthFormatting: culture-invariant conversion, formatting and parsing of depths in metres, feet, fathoms, and fathoms and feet.EncDotNet.S100.Crs.ProjNetimplementsICrsTransformFactory.
Data-coverage geometry
DataModel.CoverageArea is the data-coverage footprint of a vector cell, in
EPSG:4326 latitude and longitude (S-100 Part 10b §6.2). It has an
ExteriorRing and optional InteriorRings (holes with no coverage). The S-101
and S-57 processors build it from DataCoverage surfaces with
categoryOfCoverage = 1. A host uses it to hide a coarser cell where a finer,
overlapping cell in the display band has coverage.
Dynamic feature sources
The EncDotNet.S100.DynamicSources namespace describes features that change
over time and are pushed to the host, such as own ship, AIS targets, route
previews and sensor overlays. They're drawn alongside static datasets. The
types don't depend on any graphics library.
IDynamicFeatureSourceprovides a snapshot of features and aChangedevent.DynamicFeatureuses the same geometry vocabulary as the static vector pipeline: theGeometryTypeenum and(Latitude, Longitude)tuples.DynamicMotionadds motion to a moving point feature.DynamicVesselGeometryadds vessel dimensions: length, beam, and the CCRP and GPS-antenna offsets (IEC 62388). It matches the AIS type 5dimA/dimB/dimC/dimDfields.DynamicSourceMetadatacarriesDisplayNameandRendererKey.EncDotNet.S100.Renderers.Mapsuiuses the key to find the renderer.DynamicFeaturesChangedandDynamicSourceChangeKinddescribe a change.DynamicFeatureTracker<TInbound>helps adapters that age features out, such as AIS sleep and lost timers or stale-sensor styling.
Dynamic feature sources explains the design.
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
NuGet packages (25)
Showing the top 5 NuGet packages that depend on EncDotNet.S100.Core:
| Package | Downloads |
|---|---|
|
EncDotNet.S100.Portrayals
Libraries for manipulating S-100 based nautical charts. |
|
|
EncDotNet.S100.Features
Libraries for manipulating S-100 based nautical charts. |
|
|
EncDotNet.S100.Datasets.S101
Libraries for manipulating S-100 based nautical charts. |
|
|
EncDotNet.S100.Renderers.Skia
Headless SkiaSharp rasteriser for the IHO S-100 portrayal pipeline. Renders the backend-neutral scene IR from EncDotNet.S100.Rendering.Scene (VectorScene / PaintOp) to an image with no GUI or map framework: SkiaDisplayListRenderer.RenderOnto, HeadlessVectorRenderer, CoverageHeadlessRenderer, and the multi-layer HeadlessCompositeRenderer. Lets a consumer embed just the renderer + IR without the EncDotNet.S100 facade or Mapsui. |
|
|
EncDotNet.S100.ExchangeSets
Libraries for manipulating S-100 based nautical charts. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.25.1 | 0 | 10/12/2026 |
| 0.25.0 | 0 | 10/12/2026 |
| 0.24.0 | 527 | 10/4/2026 |
| 0.23.0 | 542 | 9/17/2026 |
| 0.22.0 | 648 | 7/19/2026 |
| 0.21.0 | 654 | 7/10/2026 |
| 0.20.0 | 641 | 6/29/2026 |
| 0.19.0 | 645 | 6/27/2026 |
| 0.18.0 | 625 | 6/17/2026 |
| 0.17.1 | 617 | 6/16/2026 |
| 0.17.0 | 604 | 6/15/2026 |
| 0.16.0 | 617 | 6/8/2026 |
| 0.15.0 | 318 | 6/6/2026 |
| 0.14.0 | 314 | 6/6/2026 |
| 0.13.0 | 305 | 6/3/2026 |
| 0.12.0 | 311 | 5/29/2026 |
| 0.11.0 | 311 | 5/19/2026 |
| 0.10.0 | 306 | 5/16/2026 |
| 0.9.0 | 309 | 5/15/2026 |
| 0.8.0 | 311 | 5/13/2026 |