Class S101DatasetProcessor
IDatasetProcessor for IHO S-101 Electronic Navigational Chart
cells (S-100 Part 10a ISO 8211 encoding), portrayed through the S-101
Part 9A Lua portrayal catalogue. Also serves S-401 Inland ENC, which shares
the encoding and portrayal model, by constructing it with
spec: "S-401" so it resolves the S-401 catalogues.
public sealed class S101DatasetProcessor : IDatasetProcessor, IDepthAdjustableProcessor, IVectorPortrayalSource, IHeadlessImageRenderer, ILoadedDatasetProjection, IChartDepthCell, IDateDependentDatasetProcessor
- Inheritance
-
S101DatasetProcessor
- Implements
- Inherited Members
Remarks
Normally created through the S101 /
S401 registrations, or through
a DatasetPipelineFactory.CreateS101ProcessorWithUpdates overload to fold
a base cell's in-set sequential updates in before portrayal (the outcome is
reported by UpdateReport).
Renders are serialized per processor, and the unfiltered Lua rule output is cached by the inputs that change it, so a display-category, viewing-group or display-plane change only re-filters it. A host may inject a shared IPortrayalInstructionCache so a freshly opened processor for a previously portrayed cell can skip the Lua run; otherwise a per-processor in-memory cache is used.
Constructors
S101DatasetProcessor(IAssetSource, string, PortrayalCatalogueManager, ILuaEngine, FeatureCatalogueManager, IPortrayalInstructionCache?, IReadOnlyDictionary<string, string>?, string)
Initializes a new S101DatasetProcessor by reading
the ISO 8211 dataset relativePath from
source. Used by exchange-set bulk loading.
public S101DatasetProcessor(IAssetSource source, string relativePath, PortrayalCatalogueManager catalogueManager, ILuaEngine luaEngine, FeatureCatalogueManager featureCatalogueManager, IPortrayalInstructionCache? sharedInstructionCache = null, IReadOnlyDictionary<string, string>? supportFiles = null, string spec = "S-101")
Parameters
sourceIAssetSourcerelativePathstringcatalogueManagerPortrayalCatalogueManagerluaEngineILuaEnginefeatureCatalogueManagerFeatureCatalogueManagersharedInstructionCacheIPortrayalInstructionCachesupportFilesIReadOnlyDictionary<string, string>specstring
S101DatasetProcessor(IAssetSource, string, IReadOnlyList<string>, PortrayalCatalogueManager, ILuaEngine, FeatureCatalogueManager, IPortrayalInstructionCache?, IReadOnlyDictionary<string, string>?, string)
Initializes a new S101DatasetProcessor for a base cell at
baseRelativePath with the sequential update files at
updateRelativePaths applied (best-effort) before
portrayal. Used by exchange-set bulk loading to collapse a cell and its
in-set updates into a single up-to-date dataset; the apply outcome is
exposed via UpdateReport. S-101 / S-100 Part 10a.
public S101DatasetProcessor(IAssetSource source, string baseRelativePath, IReadOnlyList<string> updateRelativePaths, PortrayalCatalogueManager catalogueManager, ILuaEngine luaEngine, FeatureCatalogueManager featureCatalogueManager, IPortrayalInstructionCache? sharedInstructionCache = null, IReadOnlyDictionary<string, string>? supportFiles = null, string spec = "S-101")
Parameters
sourceIAssetSourcebaseRelativePathstringupdateRelativePathsIReadOnlyList<string>catalogueManagerPortrayalCatalogueManagerluaEngineILuaEnginefeatureCatalogueManagerFeatureCatalogueManagersharedInstructionCacheIPortrayalInstructionCachesupportFilesIReadOnlyDictionary<string, string>specstring
S101DatasetProcessor(string, PortrayalCatalogueManager, ILuaEngine, FeatureCatalogueManager, IPortrayalInstructionCache?, string)
Initializes a new S101DatasetProcessor by reading and
parsing the ISO 8211 cell at path. External text files
the cell references are resolved relative to the cell's folder,
including a sibling SUPPORT_FILES folder in an S-100 exchange-set
layout.
public S101DatasetProcessor(string path, PortrayalCatalogueManager catalogueManager, ILuaEngine luaEngine, FeatureCatalogueManager featureCatalogueManager, IPortrayalInstructionCache? sharedInstructionCache = null, string spec = "S-101")
Parameters
pathstringPath to the ISO 8211 cell file.
catalogueManagerPortrayalCatalogueManagerSupplies the portrayal catalogue for
spec.luaEngineILuaEngineLua engine that executes the portrayal catalogue's rules.
featureCatalogueManagerFeatureCatalogueManagerSupplies the feature catalogue used to decode feature and attribute names in feature info.
sharedInstructionCacheIPortrayalInstructionCacheOptional cross-processor cache of portrayal drawing instructions; null uses a per-processor in-memory cache.
specstringThe product whose catalogues portray the cell:
"S-101"(default) or"S-401"for inland ENC.
Exceptions
- ArgumentException
specis null or empty.
Properties
CellRankingScale
The cell's scale rank against overlapping cells (see
CellScaleRanking): the most permissive DataCoverage
minimum display scale, the same rank the display uses to hide a coarser
cell under a finer one. Smaller is finer; null when the
cell declares none.
public int? CellRankingScale { get; }
Property Value
- int?
Metadata
The lightweight, product-agnostic DatasetMetadata for this dataset — its declared specification and, where cheaply derivable, its geographic extent, horizontal CRS, display-scale window, and temporal coverage. Overriding processors derive it once from the already-parsed dataset (never a second parse) and cache it, so hosts can frame a viewport, register a layer, draw an out-of-scale indicator, or gate visibility without re-reading the dataset. The default implementation does not override this and instead returns a fresh, minimal value carrying only Spec on each access; processors that can supply an extent (and other facts) override it with the derive-once-and-cache behaviour above. See issue #467 / #460.
public DatasetMetadata Metadata { get; }
Property Value
Remarks
Derived once from the already-parsed S101Dataset (folding its spatial records into the extent); no second parse is incurred (issue #467, WS1).
PortrayalTimeIntervals
The distinct time intervals of the last portrayal's drawing instructions; empty when none is date-dependent or nothing has been portrayed yet.
public IReadOnlyList<PortrayalTimeInterval> PortrayalTimeIntervals { get; }
Property Value
SoundingDatum
The cell's vertical datum: the S-100 code its SoundingDatum
areas declare (the most common one when they declare several), or
null when the cell declares none.
public int? SoundingDatum { get; }
Property Value
- int?
Spec
The product specification (name + edition) this dataset declares
conformance to. Each per-spec processor returns a fixed name (e.g.
"S-101"); the edition portion is populated from the dataset itself
(HDF5 productSpecification attribute, GML application
namespace, S-101 ProductSpecificationEdition, etc.) when known,
otherwise defaults to SpecVersion default.
public SpecRef Spec { get; }
Property Value
UpdateReport
Outcome of applying sequential updates when this processor was constructed for a base cell plus in-set update files; otherwise null.
public S101UpdateReport? UpdateReport { get; }
Property Value
VersionAssessment
How the dataset's declared product specification edition
(Spec) relates to the version of the catalogue used to
process it, or null when no catalogue self-describes its
version (so no assessment can be made). Computed once at construction
— catalogue resolution is a one-shot per processor — and surfaced by
hosts (CLI info/render, viewer layer list) to warn on a
version mismatch per S-100 Edition 5.2.1 Part 2 §6.
public SpecVersionAssessment? VersionAssessment { get; }
Property Value
Methods
BuildVectorPortrayalAsync(RenderContext?, CancellationToken)
Builds an immutable, Mapsui-free snapshot of this dataset's vector portrayal for the supplied render context. Implementations run under the processor's render gate and snapshot all mutable portrayal state (palette, ECDIS display, asset pre-warm) so the result is safe to convert to Mapsui layers off the gate.
public Task<VectorPortrayalResult> BuildVectorPortrayalAsync(RenderContext? context = null, CancellationToken cancellationToken = default)
Parameters
contextRenderContextOptional render context (palette, scales, ECDIS, mariner).
cancellationTokenCancellationTokenCancellation token.
Returns
- Task<VectorPortrayalResult>
The Mapsui-free vector portrayal result.
CoversPoint(double, double)
Whether the cell's DataCoverage contains a WGS-84 point. A cell
that declares no coverage is treated as covering every point.
public bool CoversPoint(double latitude, double longitude)
Parameters
latitudedoubleLatitude in decimal degrees (WGS-84).
longitudedoubleLongitude in decimal degrees (WGS-84).
Returns
CreateLoadedData()
Allocates the LoadedDatasetData variant wrapping this processor's already-parsed model. Never re-reads the source bytes.
public LoadedDatasetData CreateLoadedData()
Returns
- LoadedDatasetData
The catalog payload wrapping the resident model (e.g. an
S125DatasetDataorS102CoverageData).
EnumerateFeatures()
Enumerates a lightweight summary of every feature exposed by this processor — used to seed the viewer's feature-search index without forcing a full GetFeatureInfo(string) call per feature.
public IEnumerable<FeatureSummary> EnumerateFeatures()
Returns
Remarks
Coverage products (S-102, S-104, S-111) and any processor that does not expose discrete features should leave this returning the default empty enumeration.
GetFeatureInfo(string)
Returns information about a feature identified by its reference string
(as stored in the rendered feature via the renderer's feature-ref key),
or null if the feature cannot be found.
public FeatureInfo? GetFeatureInfo(string featureRef)
Parameters
featureRefstring
Returns
Remarks
Real-world datasets occasionally contain features that share a
gml:id (a producer bug), so callers that already know the
feature's position within the dataset should prefer
GetFeatureInfoAt(int) for a collision-free lookup.
GetFeatureInfoAt(int)
Returns information about the feature at the given enumeration
ordinal — the same index reported via
Ordinal from
EnumerateFeatures(). Used by the search index so
duplicate gml:ids (a real producer bug) still route to
the correct feature.
public FeatureInfo? GetFeatureInfoAt(int ordinal)
Parameters
ordinalint
Returns
- FeatureInfo
Feature info, or
nullwhen the ordinal is out of range or this processor does not expose discrete features.
HitTestFeatures(double, double, double)
Hit-tests this dataset's vector features against a geographic point,
returning every feature whose geometry contains the point (area
features) or lies within radiusMeters of it (point /
curve features), in feature-enumeration order. The reusable geographic
complement to GetCoverageInfo(double, double, DateTime?): a caller resolves each hit
to full attributes via GetFeatureInfoAt(int) (or
GetFeatureInfo(string)) and ranks the results across datasets
itself — for example by a rendering paint stack, which the processor
contract deliberately knows nothing about.
public IReadOnlyList<FeatureGeometryHit> HitTestFeatures(double latitude, double longitude, double radiusMeters)
Parameters
latitudedoublePick latitude in WGS-84 degrees.
longitudedoublePick longitude in WGS-84 degrees.
radiusMetersdoubleSearch tolerance for point/curve features in metres; area features use exact containment and ignore it. Negative or non-finite values are treated as 0.
Returns
- IReadOnlyList<FeatureGeometryHit>
The matching features in enumeration order — each Ordinal aligns with GetFeatureInfoAt(int) — or an empty list. Vector processors override this; coverage / non-vector processors leave the default empty implementation and expose picks through GetCoverageInfo(double, double, DateTime?) instead.
RenderHeadlessAsync(int, int, RenderContext?, RgbaColor?, CancellationToken)
Renders this S-101 cell to a standalone SKBitmap through the headless, backend-agnostic Skia vector core (VectorSceneBuilder → SkiaDisplayListRenderer), bypassing Mapsui entirely. This is the vector analogue of the direct-Skia coverage renderer and the basis for a headless tile-serving API.
public Task<SKBitmap> RenderHeadlessAsync(int widthPixels, int heightPixels, RenderContext? context = null, RgbaColor? background = null, CancellationToken cancellationToken = default)
Parameters
widthPixelsintOutput bitmap width in pixels.
heightPixelsintOutput bitmap height in pixels.
contextRenderContextOptional render context (palette, symbol/text scale, ECDIS display, mariner settings).
backgroundRgbaColor?Optional background fill; defaults to opaque white.
cancellationTokenCancellationTokenCancellation token.
Returns
Remarks
Tiled-symbol pattern area-fills (e.g. shallow-water diamonds, quality-of-bathymetry overlays) are rasterised through RasterizePatternTile(string, AreaFill, double) and tiled across the polygon, anchored to a global world-space origin so adjacent polygons sharing a pattern align seamlessly. Unlike the Mapsui path, the headless renderer does not perform NetTopologySuite priority-clipping of overlapping patterns or land-occlusion, so patterns may visibly bleed across opaque overlay fills. Use BuildVectorPortrayalAsync(RenderContext?, CancellationToken) (the Mapsui path) for full pattern-fill fidelity. Unlike that path, this produces a single bitmap (no S-102 interleave split) and draw order follows the shared core's S-100 Part 9 ordering.
SampleNearestSounding(double, double)
Samples the nearest charted S-101 Sounding (per-point depth) to a
WGS-84 location for depth assimilation, or null when the dataset
contains no soundings. Delegates to
SampleNearest(S101Document, double, double) (S-101 multipoint spatial
records, S-100 Part 10a §10a-6).
public S101SoundingSample? SampleNearestSounding(double latitude, double longitude)
Parameters
latitudedoubleLatitude in decimal degrees (WGS-84).
longitudedoubleLongitude in decimal degrees (WGS-84).
Returns
- S101SoundingSample?
The nearest sounding sample, or
null.
SoundingDatumAt(double, double)
The vertical datum the cell's depths are relative to at a WGS-84 point:
the S-100 vertical datum code of the SoundingDatum area that
contains it, or null when none does. The route check
reads the same areas.
public int? SoundingDatumAt(double latitude, double longitude)
Parameters
latitudedoubleLatitude in decimal degrees (WGS-84).
longitudedoubleLongitude in decimal degrees (WGS-84).
Returns
Validate()
Runs the V-4 S-101 validation rule pack (Default) against the parsed document, returning the resulting ValidationReport.
public ValidationReport? Validate()
Returns
Remarks
Implements the processor integration shape defined by
docs/design/non-gml-validation.md §9.3: the document is
projected through the spec-vocabulary
S101DatasetView façade (design §3.1, option (b))
using the bundled FeatureCatalogueDecoder for
FC-conformance rules, then handed to the cached default rule
set. The report is cached on first call; subsequent calls
return the same instance (design §9.4).
When no S-101 Feature Catalogue is available the façade is
built without a decoder; rules requiring catalogue lookup
(S101-R-1.2, S101-R-4.1) degrade to no-ops per
design §8.1. Reader-level parse failures occur in the
constructor and never reach this method; the
S101-PROJ-PARSE rule is a documented placeholder for
future reader diagnostics (design §5.2 Stance A).