Class DatasetPipelineFactory
Detects a dataset's product — each ProductRegistration claims its own files — and creates the appropriate IDatasetProcessor.
public sealed class DatasetPipelineFactory : IDatasetProcessorFactory
- Inheritance
-
DatasetPipelineFactory
- Implements
- Inherited Members
Constructors
DatasetPipelineFactory(PortrayalCatalogueManager, ILuaEngine, ICrsTransformFactory, FeatureCatalogueManager, IDisplayPlaneAuthorityProvider, IPortrayalInstructionCache?, ProductRegistry?)
Creates a new factory. The supplied
featureCatalogueManager is shared across every
processor this factory produces, so its FC parse cache survives
for the lifetime of the manager — not just the lifetime of the
factory. The supplied authorityProvider is
forwarded to every GML-based processor so they resolve the
default S-98 display plane through the host's DI container rather
than a static singleton.
public DatasetPipelineFactory(PortrayalCatalogueManager catalogueManager, ILuaEngine luaEngine, ICrsTransformFactory crsTransformFactory, FeatureCatalogueManager featureCatalogueManager, IDisplayPlaneAuthorityProvider authorityProvider, IPortrayalInstructionCache? sharedInstructionCache = null, ProductRegistry? productRegistry = null)
Parameters
catalogueManagerPortrayalCatalogueManagerPortrayal catalogue manager shared by every processor.
luaEngineILuaEngineLua engine for Part 9A portrayal.
crsTransformFactoryICrsTransformFactoryCRS transform factory for coverage products.
featureCatalogueManagerFeatureCatalogueManagerFeature catalogue manager (shared FC parse cache).
authorityProviderIDisplayPlaneAuthorityProviderDefault S-98 display-plane authority provider.
sharedInstructionCacheIPortrayalInstructionCacheOptional process-wide portrayal-instruction cache (e.g. a DiskPortrayalInstructionCache) shared by every S-101 processor this factory produces, so a fresh open of a previously-portrayed cell skips the multi-second MoonSharp Part 9A Lua run. When null each S-101 processor falls back to a bounded per-processor in-memory cache — the behaviour used by tools and tests.
productRegistryProductRegistryOptional set of products this factory can construct. When null the process-wide Default is used: every built-in product, plus any a host registered there. Supply a custom registry to enable only a subset of products (e.g. an S-101-only host) or to add a product of your own.
Methods
CreateProcessor(IAssetSource, string, string?, IReadOnlyDictionary<string, string>?)
Creates a processor for a dataset stored inside source
at relativePath. Used by exchange-set bulk loading
where dataset bytes may live inside a ZIP archive.
public IDatasetProcessor CreateProcessor(IAssetSource source, string relativePath, string? declaredProductSpec = null, IReadOnlyDictionary<string, string>? supportFiles = null)
Parameters
sourceIAssetSourceThe asset source (folder or ZIP) hosting the dataset.
relativePathstringPath to the dataset, relative to
source.declaredProductSpecstringProduct specification declared by the exchange-set catalogue (e.g. "S-101"). When non-null and recognized, content sniffing is skipped. When null or unrecognized, the dataset is content-sniffed as described on DetectProductSpecFromSourceAsync(IAssetSource, string, CancellationToken).
supportFilesIReadOnlyDictionary<string, string>Optional map of support-file name (case-insensitive) to source-relative path, from the exchange-set catalogue's
supportFileDiscoveryMetadata(S-100 Edition 5.2.1 Part 17). Lets S-101 resolvefileReferenceexternal text files via the catalogue.
Returns
CreateProcessor(string)
Creates a processor for the given dataset file. The processor can be called multiple times with different contexts.
public IDatasetProcessor CreateProcessor(string path)
Parameters
pathstring
Returns
CreateProcessorWithFilesystemUpdates(string)
Creates a processor for the base cell file at
baseFilePath, discovering and applying any sibling
sequential update files (….001, ….002, …) that live in the
same directory. This gives a single dropped .000 cell the same
up-to-date rendering as one loaded from an exchange set. S-57, S-101, and
S-401 cells (told apart by the ISO 8211 envelope in
DetectProductSpec(string)) all apply updates via their respective
*WithUpdates path; any other product, or a base cell with no
updates on disk, falls back to CreateProcessor(string).
S-57 Ed 3.1 App B.1 / S-100 Part 10a.
public IDatasetProcessor CreateProcessorWithFilesystemUpdates(string baseFilePath)
Parameters
baseFilePathstringPath to the base cell file (
….000).
Returns
CreateS101ProcessorWithUpdates(IAssetSource, string, IReadOnlyList<string>, IReadOnlyDictionary<string, string>?, string)
Creates an S-101 dataset processor for the base cell at
baseRelativePath with the in-set sequential update
files at updateRelativePaths applied (best-effort)
before portrayal. Used by exchange-set bulk loading to collapse a cell and
its updates into a single up-to-date dataset. S-101 / S-100 Part 10a.
public IDatasetProcessor CreateS101ProcessorWithUpdates(IAssetSource source, string baseRelativePath, IReadOnlyList<string> updateRelativePaths, IReadOnlyDictionary<string, string>? supportFiles = null, string spec = "S-101")
Parameters
sourceIAssetSourceThe asset source backing the exchange set.
baseRelativePathstringSource-relative path of the base cell (
….000).updateRelativePathsIReadOnlyList<string>Source-relative paths of the update files, in ascending update-number order.
supportFilesIReadOnlyDictionary<string, string>Optional map of support-file name to source-relative path, used to resolve file references the cell makes to its exchange set.
specstringThe product whose catalogues portray the cell:
"S-101"(default) or"S-401"for inland ENC, which shares the Part 10a encoding and the Part 9A Lua portrayal model.
Returns
CreateS101ProcessorWithUpdates(string, IReadOnlyList<string>, string)
Creates an S-101 dataset processor for the base cell file at
baseFilePath with the sibling sequential update files
at updateFilePaths applied (best-effort) before
portrayal. Used by command-line callers pointed at a loose base cell on
the local file system; the update files must live in the same directory
as the base cell. See S101FilesystemUpdateDiscovery for
locating the updates. S-101 / S-100 Part 10a.
public IDatasetProcessor CreateS101ProcessorWithUpdates(string baseFilePath, IReadOnlyList<string> updateFilePaths, string spec = "S-101")
Parameters
baseFilePathstringPath to the base cell file (
….000).updateFilePathsIReadOnlyList<string>Paths of the sibling update files, in ascending update-number order.
specstringThe product whose catalogues portray the cell:
"S-101"(default) or"S-401"for inland ENC.
Returns
CreateS57ProcessorWithUpdates(IAssetSource, string, IReadOnlyList<string>)
Creates an S-57 dataset processor for the base cell at
baseRelativePath with the in-set sequential update
files at updateRelativePaths applied before
translation. Used by exchange-set bulk loading to collapse an S-57 cell
and its updates into a single up-to-date dataset. The updates are folded
into the S-57 document before the S-57 → S-101 translation runs.
S-57 Part 3 (dataset updating).
public IDatasetProcessor CreateS57ProcessorWithUpdates(IAssetSource source, string baseRelativePath, IReadOnlyList<string> updateRelativePaths)
Parameters
sourceIAssetSourceThe asset source backing the exchange set.
baseRelativePathstringSource-relative path of the base cell (
….000).updateRelativePathsIReadOnlyList<string>Source-relative paths of the update files, in ascending update-number order.
Returns
DescribeUnrecognizedDataset(string)
Explains why DetectProductSpec(string) found no product for
path, as one sentence a host can show, using
Default. Returns null
when there is nothing more specific to say than "not recognised" (the
file isn't HDF5, or a product does claim it).
public static string? DescribeUnrecognizedDataset(string path)
Parameters
pathstringThe dataset file.
Returns
Remarks
Three HDF5 cases are told apart:
-
the root has no
productSpecificationattribute; - it names a product no registration reads, quoting the value;
-
a file named
.h5or.hdf5can't be read as HDF5: with no HDF5 signature it may be encrypted (S-100 Part 15), otherwise damaged.
DescribeUnrecognizedDataset(string, ProductRegistry)
Registry-aware DescribeUnrecognizedDataset(string): a value
naming a product registry lacks is reported as
unsupported.
public static string? DescribeUnrecognizedDataset(string path, ProductRegistry registry)
Parameters
pathstringThe dataset file.
registryProductRegistryThe products that can be detected.
Returns
DetectProductSpec(string)
Returns the product spec identifier for the given file, or null if
unrecognized, using Default (every built-in
product plus any a host registered there, so a .000 file is
disambiguated S-57 vs S-101). Hosts that build a factory from a subset
registry get subset-aware detection through the registry-aware overload
the factory uses internally.
public static string? DetectProductSpec(string path)
Parameters
pathstring
Returns
DetectProductSpec(string, ProductRegistry)
Registry-aware detection — the single implementation behind DetectProductSpec(string). Each registration claims its own files; there is no per-product chain here:
- The file's leading bytes are read once (DatasetHeader).
-
The encoding is taken from the extension (
.000ISO 8211,.h5/.hdf5HDF5,.gmlGML) or, when the extension is none of those, from the HDF5 signature in the leading bytes. The encoding's envelope is read once and offered to every registration's matcher for it (MatchIso8211, MatchHdf5, MatchGml). - A file no envelope matcher claimed is offered to every MatchBytes, whatever its extension — so a GRIB2 download with no useful extension is still recognised.
-
An unclaimed
.000file is"S-101", as it always has been; any other unclaimed file — including an HDF5 file whoseproductSpecificationno product declares — is unknown (null).
A registry without S-57 registered therefore never reports an S-57
dataset it has no registration to build, and the same holds for every
product. It does not otherwise guarantee the returned spec is buildable
(a registry lacking S-101 can still get "S-101" from the ISO 8211
fallback — construction then validates the spec against the registry and
throws if unregistered).
public static string? DetectProductSpec(string path, ProductRegistry registry)
Parameters
pathstringregistryProductRegistry
Returns
DetectProductSpecFromSource(IAssetSource, string)
Content-sniffs a dataset stored inside source to
determine its S-100 product specification. This synchronous wrapper
exists for synchronous processor creation; async callers should use
DetectProductSpecFromSourceAsync(IAssetSource, string, CancellationToken), which documents the
detection rules.
public static string? DetectProductSpecFromSource(IAssetSource source, string relativePath)
Parameters
sourceIAssetSourceThe asset source (folder or ZIP) hosting the dataset.
relativePathstringPath to the dataset, relative to
source.
Returns
- string
The canonical product-specification string, or
nullwhen not recognized.
DetectProductSpecFromSource(IAssetSource, string, ProductRegistry)
Registry-aware synchronous source detection, used by CreateProcessor(IAssetSource, string, string?, IReadOnlyDictionary<string, string>?) so the ISO 8211 and GML recognizers consult the factory's own product registry, as path-based detection does.
public static string? DetectProductSpecFromSource(IAssetSource source, string relativePath, ProductRegistry registry)
Parameters
sourceIAssetSourcerelativePathstringregistryProductRegistry
Returns
DetectProductSpecFromSourceAsync(IAssetSource, string, CancellationToken)
Asynchronously content-sniffs a dataset stored inside
source to determine its product specification,
applying the same rules as DetectProductSpec(string, ProductRegistry)
does for a file on disk — each registration claims its own files:
-
.000(ISO 8211): the dataset envelope is read and each product recognizes its own cells (S-57 by itsDSPMfield, S-101 and S-401 by their declaredPRSP); a readable cell that no product claims is treated as"S-101". -
.h5/.hdf5, or any other extension when the file starts with the HDF5 signature: each product's MatchHdf5 reads the root group (S-102, S-104 and S-111 by theirproductSpecification); an HDF5 file nobody claims is unknown. -
.gml/.xml: the GML root element and namespaces are matched against each product's MatchGml, reading only a bounded, BOM-aware prefix. This also covers catalogues that omit a machine-readableproductIdentifier, such as JCOMM S-411 exchange sets that declare only a human-readable product name. - Anything nobody has claimed yet: the leading bytes are offered to each product's MatchBytes.
Returns the canonical spec string (e.g. "S-411") understood by
CreateProcessor(IAssetSource, string, string?, IReadOnlyDictionary<string, string>?).
Uses Default.
public static Task<string?> DetectProductSpecFromSourceAsync(IAssetSource source, string relativePath, CancellationToken cancellationToken = default)
Parameters
sourceIAssetSourceThe asset source (folder or ZIP) hosting the dataset.
relativePathstringPath to the dataset, relative to
source.cancellationTokenCancellationTokenCancellation token for reading dataset bytes.
Returns
- Task<string>
The canonical product-specification string, or
nullwhen no product claims the file or the file cannot be read.
MapProductIdentifierToSpec(string?)
Normalizes an exchange-set product identifier (e.g. "S-101",
"S101", "s-101", or the long form
"INT.IHO.S-101.2.0.0") to the canonical spec strings used
by CreateProcessor(string)'s switch ("S-101", etc.).
Returns null when the identifier is null, blank, or unrecognized.
public static string? MapProductIdentifierToSpec(string? productIdentifier)
Parameters
productIdentifierstring
Returns
MapProductSpecificationToSpec(ProductSpecification?)
Resolves the canonical spec string ("S-101", etc.) for an
exchange-set ProductSpecification entry. Tries, in order,
the ProductIdentifier, the
Name, and finally the
Number (e.g. 101 → "S-101").
Many real-world S-100 catalogues (e.g. IC-ENC S-101 sets) populate only
name/number and omit productIdentifier; this overload
keeps such datasets from being reported as an unsupported product
specification. Returns null when none of the fields resolve.
public static string? MapProductSpecificationToSpec(ProductSpecification? productSpecification)
Parameters
productSpecificationProductSpecification