Class S102DatasetRules
- Namespace
- EncDotNet.S100.Datasets.S102.Validation
- Assembly
- EncDotNet.S100.Datasets.S102.dll
The default ValidationRuleSet<TModel> of normative rules
for an S-102 S102Dataset. Rule identifiers follow the
convention S102-R-{clause} for normative rules and
S102-PROJ-{kind} for projection-diagnostic surrogates, traceable
back to S-102 (Edition 3.0.0) and S-100 Part 10c.
public static class S102DatasetRules
- Inheritance
-
S102DatasetRules
- Inherited Members
Remarks
This is the V-1 rule pack as defined in
docs/design/non-gml-validation.md §6.1. Rules read off the
strongly-typed S102Dataset produced by
S102DatasetReader; structural-schema failures the
reader cannot tolerate are thrown as
S100DatasetSchemaException at read
time and (per design §5.1) surfaced as S102-PROJ-SCHEMA
findings by the dataset processor's Validate() wrapper.
Tier-3 cross-dataset rules (e.g. tile coherency against a sibling chart) are out of scope; per-finding payload conventions follow design §4.3:
- per-coverage finding —
RelatedFeatureId = "{groupPath}" - per-cell finding —
RelatedFeatureId = "{groupPath}[row,col]"
Properties
CoverageExtentDoesNotWrap
S102-R-4.2 — Each coverage's far grid corner
(origin + (numPoints - 1) × spacing) is a plausible
position in the dataset's HorizontalCRS.
For a geographic CRS that means the extent does not wrap the
antimeridian (longitude end > 180) or cross the pole (latitude
end > 90) — antimeridian-spanning datasets are out of scope for
V-1; for a projected CRS it means the corner stays within the
projected bounds and reprojects to a valid WGS 84 position.
public static IValidationRule<S102Dataset> CoverageExtentDoesNotWrap { get; }
Property Value
Remarks
Spec reference: S-100 Part 10c §10.2.1.2; implements the
s102-bathymetry skill review-checklist item "tile
extent stays within range". See GridGeoreferencing.
When the rule fires, the finding carries a
BoundingBox approximating the
offending tile extent in WGS 84 (edges ordered only; values may
themselves be out of range) — for a projected grid only when it
can be reprojected.
CoverageOriginInWgs84Range
S102-R-4.1 — Each coverage's grid origin
(OriginLongitude,
OriginLatitude) is a plausible
position in the dataset's HorizontalCRS:
within [-90, 90] / [-180, 180] degrees for a geographic CRS, or
within the projected bounds (and reprojecting to a valid WGS 84
position) for a projected one.
public static IValidationRule<S102Dataset> CoverageOriginInWgs84Range { get; }
Property Value
Remarks
Spec reference: S-100 Part 10c §10.2.1.2 grid georeferencing;
S-102 Edition 3.0.0 permits projected CRSs (e.g. WGS 84 / UTM),
for which the gridOrigin* values are metres. See
GridGeoreferencing for the CRS-specific checks;
a CRS it cannot classify is not checked. Implements
s102-bathymetry skill review-checklist item
"georeferencing attributes within range".
CoverageValuesLengthMatchesShape
S102-R-1.1 — Every BathymetryCoverage's
Values array length equals
NumPointsLatitudinal ×
NumPointsLongitudinal.
public static IValidationRule<S102Dataset> CoverageValuesLengthMatchesShape { get; }
Property Value
Remarks
Spec reference: S-100 Part 10c §10.2.1.2 (gridded coverage
shape contract) and S-102 Edition 3.0.0 §12.6
(BathymetryCoverage). Implements the
s102-bathymetry skill review checklist item
"values array shape matches numPointsLat × numPointsLon".
Default
The canonical default rule set for S-102 bathymetry datasets.
public static ValidationRuleSet<S102Dataset> Default { get; }
Property Value
DepthValuesInPlausibleRange
S102-R-5.1 — Non-NODATA depth values across each
coverage lie within the plausible bathymetric range
[-50, 12 000] metres.
public static IValidationRule<S102Dataset> DepthValuesInPlausibleRange { get; }
Property Value
Remarks
Plausibility heuristic: continental shelves through the deepest trenches; catches common producer mistakes such as "depth recorded in centimetres" or "UTM-northing accidentally stored as depth". Per design §6.1, the rule emits one finding per coverage with the count of offending cells in the message — emitting one finding per cell on a broken tile would drown the report in cascade noise.
HorizontalCrsIsKnownEpsg
S102-R-3.1 — When HorizontalCRS
is set, it resolves to a known EPSG code.
public static IValidationRule<S102Dataset> HorizontalCrsIsKnownEpsg { get; }
Property Value
Remarks
Spec reference: S-102 Edition 3.0.0 §10.2 root attribute
horizontalCRS. Severity is Warning per design
§6.1 — an unknown EPSG code typically reflects a producer
mistake but does not render the dataset unusable; consumers
may still be able to resolve the CRS through extended
catalogues. See IsKnownEpsgCode(int) for the
recognised set.
IssueDateIsIso8601
S102-R-3.2 — When IssueDate is
set, it parses as an ISO 8601 date or date-time, in the basic
(20260902) or extended (2026-09-02) format.
public static IValidationRule<S102Dataset> IssueDateIsIso8601 { get; }
Property Value
Remarks
Spec reference: S-102 Edition 3.0.0 §10.2 root attribute
issueDate, which S-100 Part 10c writes in the ISO 8601
basic format YYYYMMDD. Implements the s102-bathymetry
skill review-checklist item "root metadata parse cleanly". See
IsDateOrDateTime(string?) for the accepted forms.
IssueTimeIsIso8601
S102-R-3.3 — When IssueTime is
set, it parses as an ISO 8601 time of day, in the basic
(105406Z, 105406+0000) or extended
(10:54:06Z) format.
public static IValidationRule<S102Dataset> IssueTimeIsIso8601 { get; }
Property Value
Remarks
Spec reference: S-102 Edition 3.0.0 §10.2 root attribute
issueTime, which S-100 Part 10c writes in the ISO 8601
basic format hhmmss with an optional zone designator. See
IsTimeOfDay(string?) for the accepted forms.
NoDataFillValueIsCanonical
S102-R-2.1 — The NODATA fill value in a coverage's depth
channel is exactly 1_000_000f. Any candidate-NODATA
pattern other than that sentinel (NaN,
NegativeInfinity,
PositiveInfinity) is flagged.
public static IValidationRule<S102Dataset> NoDataFillValueIsCanonical { get; }
Property Value
Remarks
Spec reference: S-100 Part 10c §11 NODATA convention, S-102
Edition 3.0.0 §10 (mandatory fill = 1_000_000f).
Implements s102-bathymetry skill review-checklist
pitfall "NODATA must be exactly 1_000_000f". Conservative
per design §6.1: only NaN / ±Infinity are flagged; finite
values (even implausibly large) are NOT treated as
candidate-NODATA because they are addressed by
DepthValuesInPlausibleRange (S102-R-5.1).
ProjectionSchemaSurrogate
S102-PROJ-SCHEMA — defensive projection-diagnostic
surrogate (design §5.1, §5.3).
public static IValidationRule<S102Dataset> ProjectionSchemaSurrogate { get; }
Property Value
Remarks
The rule body is intentionally a no-op: by the time the rule
pack runs the dataset is already constructed, so any
S100DatasetSchemaException
has already thrown out of the reader. The rule id is reserved
in this rule set so that S102DatasetProcessor.Validate()
can emit a single-finding report carrying the exception's
GroupPath, AttributeOrDataset, and
SpecReference under this same rule id when the
defensive try/catch around the rule-pack call fires.
Methods
Validate(S102Dataset, ValidationContext?)
Convenience wrapper around Run(TModel, ValidationContext?) using the Default rule set.
public static ValidationReport Validate(S102Dataset dataset, ValidationContext? context = null)
Parameters
datasetS102DatasetcontextValidationContext