Table of Contents

Bringing S-57 ENCs into the S-100 pipeline

Why it matters

The world's operational ENC coverage is still overwhelmingly encoded as IHO S-57 (Edition 3.1) cells. EncDotNet.S100 lets you bring those legacy cells into the modern S-100 pipeline by translating them to S-101 on the fly — so an S-57 cell can be viewed, validated, rendered headlessly, and converted to a first-class S-101 dataset using the same tooling as native S-101 data.

S-57 is not a separate rendering path: every S-57 cell is translated to an S101Document by S57ToS101Translator and then flows through the S-101 portrayal, validation, and rendering machinery. This page covers the three things you can do with an S-57 cell — convert, view, and validate — plus the sibling-update behaviour and the known fidelity gaps.

Quick win

Convert a loose S-57 base cell to an S-101 dataset:

s100 s57 convert -o US5MA1BO.s101.000 US5MA1BO.000

The command prints a coverage summary and (if update files sit next to the base cell) folds them in first. The written .000 is a normal S-101 dataset (or an S-401 dataset for an inland ENC): inspect it with s100 info, validate it with s100 validate, or render it with s100 render.

Deep dive

Convert

s100 s57 convert -o <output> <source> translates an S-57 base cell to an ISO/IEC 8211 encoded S-101 dataset (S-100 Part 10a); an inland ENC cell is written as S-401 instead (see Inland ENCs). Translation semantics — feature-class mapping, attribute mapping, and allowed-value enforcement against the bundled Feature Catalogue — are owned by S57ToS101Translator; the command is a thin driver that also encodes the result with S101DocumentWriter.

Option Default Description
-o, --output <path> required Path of the S-101 or S-401 dataset file to write.
--target <target> auto Product to write: auto (S-401 for an inland ENC, S-101 otherwise), s101, or s401.
--report <path> off Write the full translation diagnostics as JSON.
--no-updates off Convert only the bare base cell (skip sibling updates).
--debug off Show a full stack trace on error.

After a successful convert the command names the product it wrote (for example as S-101 1.0.0) and prints a concise translation-coverage summary: how many feature records were read and emitted, sounding accounting, and the tallies of what did not translate (unmapped and rule-dropped object classes and attributes, Feature-Catalogue–rejected enumerated values, and features dropped for lack of geometry). Add --report <path> to capture the same information — broken down per object class, attribute, and value — as a machine-readable JSON document for corpus-wide auditing. The report also records the product written (product, productEdition) and the product the cell itself calls for (detectedProduct).

Tip

The counters come straight from S57TranslationDiagnostics, the same opt-in sink documented in the Datasets.S57 README. A high count under FC-rejected enum values usually signals a defective value remap rather than a genuine no-equivalent value.

Sibling update application

S-57 cells are distributed as a base cell (.000) plus a sequence of update cells (.001, .002, …) that must be applied in ascending order to bring the base up to date (S-57 Part 3, dataset updating). Both entry points apply them:

  • Exchange sets — S57DatasetProcessor folds each base cell's in-set sequential updates in via S57Document.ApplyChanges before translation.
  • Loose cells (s100 s57 convert) — sibling update files sitting next to the base cell on disk are auto-discovered (by cell name and numeric extension, in ascending order) and folded in the same way. Pass --no-updates to convert only the bare base cell.

Programmatically, use S57Dataset.Open(Stream, IReadOnlyList<Stream>) to apply updates yourself; S57Dataset.Open(string) reads a bare base cell only.

View

Drop an S-57 .000 cell (or a folder / exchange set of them) onto the viewer. The viewer detects S-57 by the ISO 8211 DSPM field, translates each cell to S-101, and portrays it through the S-101 portrayal catalogue — including the day/dusk/night palettes, display categories, and scale-band selection used for native S-101 cells.

S-57 has no minimum display scale, so the viewer stops drawing a cell once you zoom out past the larger of two values: its compilation scale (DSPM CSCL) or the largest SCAMIN on any of its features. Past that point only the cell's extent border is shown. Up to that point, SCAMIN thins individual features as usual. The compilation scale is the largest scale the cell is meant to be viewed at (S-52 §3.1.7), so it is not used as the cutoff by itself: that would hide cells like USACE inland charts, which are compiled at 1:5,000 but carry SCAMIN up to 1:300,000. Where cells overlap, the compilation scale still decides which one is finer: that cell draws on top and hides the coarser cell beneath it.

Inland ENCs

An S-57 inland ENC (IENC) — for example a USACE river chart — declares the inland ENC product specification in its DSID record (PRSP = 10, where a maritime ENC declares 1). Such a cell is still shown as an S-57 dataset, but it is translated into S-401 (IEHG inland ENC) instead of S-101 and portrayed with the bundled S-401 catalogues, so the viewer's ECDIS display controls switch to the S-401 viewing groups once the cell has loaded. A host that has no S-401 portrayal catalogue registered keeps translating inland cells into S-101.

The inland object classes and attributes (codes 17000 and up, from the IEHG Inland ENC Feature Catalogue 2.4 — distance marks, notice marks, waterway gauges, inland bridges and shoreline constructions, and so on) are mapped to their S-401 counterparts, following the IEHG S-57 ENC to S-401 Conversion Guidance. Across 21 USACE cells every inland feature now translates.

Anchorage areas follow the guidance's S-401-specific rules (clauses 3.3, 3.4 and 3.85). These apply to both achare/catach and ACHARE/CATACH:

  • An anchorage area whose category is exactly 8 (small craft mooring area) becomes an S-401 MooringArea with categoryOfMooringArea 1.
  • Category 10 (anchorage for pushing-navigation vessels) becomes categoryOfAnchorage 16, on anchorage areas and anchor berths alike.

Clause 3.85's title lists "catach=1, 2, 3" for mooring areas. Those are the S-401 mooring-area codes; in S-57, categories 1–3 are unrestricted, deep-water and tanker anchorages. So they stay anchorage areas, as does a mixed list such as 7,8.

The unit of a waterway distance (hunits) becomes S-401's distanceUnitOfMeasurement; feet, which S-401 lacks, is dropped.

A time schedule (tisdge) becomes an S-401 TimeScheduleInGeneral information record. The lock, berth, gate or other feature it is linked to (through a C_ASSO or a feature pointer) references it. A feature with several schedules references them all, even though S-401 allows one such reference per feature. The summary's TimeScheduleInGeneral records row (and the report's timeSchedulesEmitted) counts them. S-401 bridges cannot carry a time schedule, so a schedule linked only to a bridge is dropped.

The usable length and width of a lock (horcll / horclw) become S-401's horizontal clearance length and width; a lock basin carries its width as its horizontal clearance.

A gate's VERCLR becomes its verticalClearanceOpen in S-401 (clause 3.55). S-101 has no such rule, so there the gate's VERCLR is dropped.

A bunker station's shore-power details (voltage, frequency, amperage, plug, connectors, allowed consumption) become S-401 power characteristics.

The fixed spans of an inland bridge arch, which IENC groups with a c_brga collection, are linked with S-401's bridge arch association. CATBRG 13 (bridge arch), an IENC extension of the maritime attribute, becomes bridgeConstruction 1 (arch) on the bridge itself (clauses 3.7 and 3.144).

A maximum permitted ship dimensions area (lg_sdm) carries its ship, assembly and cargo ranges in six paired attributes (lc_csi/lc_cse, lc_asi/lc_ase, lc_cci/lc_cce); all six convert (clause 3.82). lc_csi is the only one whose S-401 attribute declares no IENC alias, so its target comes from the clause instead.

The only inland codes that do not convert are NEWOBJ and the three attributes that define it (CLSDEF, CLSNAM, SYMINS): NEWOBJ has no fixed meaning, so S-401 has no equivalent. They are reported as rule-dropped.

Still to come:

  • s100 validate runs only the S-57 pre-translation pack for inland cells, because there is no S-401 rule pack.

s100 s57 convert writes an inland cell as an S-401 dataset, so its inland features survive the conversion. Across 21 USACE cells (72,726 feature records), the S-401 output has 72,479 features and the S-101 output 64,394. The product is chosen after sibling updates are folded in. To override it, pass --target:

s100 s57 convert -o U37IL005.s401.000 U37IL005.000
s100 s57 convert --target s101 -o U37IL005.s101.000 U37IL005.000

--target s101 restores the S-101 output and drops the inland features that have no S-101 equivalent. --target s401 also works on a maritime cell, but prints a warning because such a cell does not declare the inland product specification.

Progress is tracked in issue #608.

Validate

s100 validate runs the S-101 validation pack against the translated dataset, plus an S-57 pre-translation validation pack (S57PreTranslationRules) that inspects fields which do not survive translation. This catches problems both in the source encoding and in the translated S-101 result.

The translation itself passes the S-101 pack: across the 7,184-cell NOAA ENC corpus the only findings left are duplicate feature identifiers that are in NOAA's source cells. Findings that refer to a feature or geometry carry its location, so the viewer's validation overlay marks them on the map.

Known fidelity gaps

Translation covers ~99% of feature instances across a 3,636-cell NOAA ENC corpus. The remaining gaps are bounded and documented; the ones most likely to surface in a coverage summary are:

  • Feature classes that become S-101 attributes or associations. TOPMAR (topmark) becomes an attribute on its parent structure rather than a standalone feature; C_ASSO associations and C_AGGR aggregations that are neither range systems nor bridge collections have no S-101 named-association home. MORFAC is split by primitive/CATMOR, an M_NSYS with an ORIENT value becomes a LocalDirectionOfBuoyage (S-65 Annex B § 12.2), and range-system C_AGGR collections are synthesised into RangeSystem features.
  • Bridges are decomposed into spans (S-65 Annex B §4.8.10). A BRIDGE carrying the clearance its span class needs (VERCLR for a fixed span, VERCCL for an opening one, i.e. CATBRG 2/3/4/5/7) becomes a Bridge plus a SpanFixed or SpanOpening. The two are linked by BridgeAggregation, and the span carries the clearances, their accuracies and VERDAT. S-57 can't say whether a bridge crosses navigable water, so a bridge without that clearance converts to a Bridge alone. An opening span with no VERCOP gets an unlimited open clearance. A point BRIDGE becomes a Landmark (categoryOfLandmark = bridge), and a C_AGGR of BRIDGE objects becomes a single Bridge with its spans and any PYLONS / PONTON as components. The collection's lights and signal stations are linked to that Bridge as theEquipment of a StructureEquipment association: IENC places bridge lights on the navigable span and the piers bounding it with no master object, and aggregates a bridge's vertical clearance indicators (sistaw, catsiw 16) and bridge-passage traffic signal stations (sistat, catsit 8) with it, so collection membership is the only link (IENC Encoding Guide 2.4.1, clauses N.1.1, I.3.3 and R.2.1). Other members, such as the fenders and notice marks IENC collects with a bridge, convert on their own. A collection that also holds a navigation line or track is a track grouping, not a bridge collection. The Bridge carries the collection's name; members' own, different names are kept as further featureNames that are not drawn (nameUsage 3 in S-401; none in S-101, which has no such value), since spans cannot carry a name. Members that don't join (twin or dual bridges, parts separated by gaps) give a multi-part Bridge: one curve or one surface per part, drawn and queried part by part. Only members that mix curves and surfaces convert one by one, as a Bridge each, with each light linked to the nearest of them. The summary's Bridge spans, Aggregated bridges, Bridge equipment linked and Bridge collections not joined rows (and the report's bridgeSpansEmitted / bridgeAggregationsEmitted / bridgeEquipmentLinked / bridgeCollectionsUnjoined) count them.
  • Vertical clearances are complexes. VERCLR, VERCCL, VERCOP and VERCSA become the verticalClearanceValue of verticalClearanceFixed, Closed, Open and Safe, with VERACC nested as their uncertainty (S-65 Annex B §2.2.4.3). This applies only on a feature class that binds the complex, for example CableOverhead, PipelineOverhead, Conveyor, Crane or Tunnel. Anywhere else the clearance is dropped and counted as rule-dropped.
  • Orientation. On NavigationLine, CurrentNonGravitational, TidalStreamFloodEbb and Crane, ORIENT becomes the orientation complex. Classes that bind orientationValue directly keep it flat.
  • Directional lights. A LIGHTS object with CATLIT 1 (directional function) or 16 (moiré effect) becomes LightSectored, and its ORIENT goes into lightSector → directionalCharacter (S-65 Annex B §12.8.6.1). CATLIT 16 also sets moireEffect. Without SECTR1/SECTR2 there is no sectorLimit, so the portrayal draws the direction line. In the NOAA base corpus this moves 34 lights from LightAllAround to LightSectored and carries ORIENT on 32 lights.
  • Attributes the S-101 class doesn't bind are dropped. An S-57 attribute is passed through only when the resolved S-101 (or S-401) class binds its target. The rest are counted as rule-dropped, which matches the conversion guidance's "will not be converted" exceptions (e.g. WATLEV on a dolphin, COLOUR on a seabed area). Across the NOAA base corpus the largest group is WATLEV: 14,591 instances, nearly all on dolphins.
  • Per-sector light emission. Co-located S-57 LIGHTS sector objects are merged into a single LightSectored feature carrying one sectorCharacteristics per arc; non-sector attributes come from the primary member.
  • zoneOfConfidence uncertainty complexes. Quantified zones (CATZOC A1–C) populate the nested horizontalPositionUncertainty / verticalUncertainty complexes from the IHO CATZOC accuracy table; ZOC D/U remain category-only.
  • Textual information. INFORM/TXTDSC/NINFOM/NTXTDS are emitted as a NauticalInformation information type bound by an AdditionalInformation association (the conversion-guidance "fuller path"), not as an inline information complex.
  • Bridge categories. CATBRG is split into bridgeConstruction, bridgeFunction, categoryOfOpeningBridge and openingBridge on the Bridge (S-65 Annex B § 4.8.10); the span type uses the same opening test. The IENC-only value 13 (bridge arch) becomes bridgeConstruction 1 (arch), per the IEHG conversion guidance; an arch is a fixed span.
  • Derived features get their own identifier. A BRIDGE span keeps the agency and FIDN of its BRIDGE but takes the next free FIDS, so FOIDs stay unique; the Bridge keeps the S-57 identifier. The summary's Derived feature identifiers row (derivedFeatureIdentifiersAssigned) counts them.
  • Meta objects with no S-101 equivalent (e.g. M_CSCL) are intentionally left unmapped.

See the Datasets.S57 README for the full mapping tables and the complete limitations list.

Troubleshooting

Important

S-57 and S-101 datasets share the .000 extension and the ISO 8211 envelope. The tooling disambiguates them by the presence of the S-57-only DSPM field. If a cell is misdetected, confirm it is a genuine S-57 base cell.

Next step