Table of Contents

Class PatternPriorityClipper

Namespace
EncDotNet.S100.Rendering.Scene
Assembly
EncDotNet.S100.Rendering.Scene.dll

Backend-neutral priority-clipping of S-100 Part 9 §11.3 tiled pattern area fills. Given the pattern areas grouped by (pattern reference, drawing priority) and the opaque non-patterned colour fills, this computes the visible portion of each pattern group by subtracting every higher-priority pattern area and every opaque colour fill (e.g. land) from it, so that a lower-priority pattern does not show through a higher-priority pattern zone and no pattern bleeds over an opaque area.

public static class PatternPriorityClipper
Inheritance
PatternPriorityClipper
Inherited Members

Remarks

This is the single, shared implementation used by both render paths: the Mapsui feature path (MapsuiDisplayListRenderer) invokes it directly, and the VectorScene IR path (VectorSceneBuilder, consumed by the headless Skia backend and the Mapsui TiledScene subsystem) applies it when lowering pattern ops. Both therefore clip identically.

All geometry is expressed in EPSG:3857 (Web-Mercator) metres, matching the PaintOp unit contract. The algorithm uses NetTopologySuite NetTopologySuite.Operation.OverlayNG.OverlayNGRobust (OverlayNG) for full-precision, robust overlay and generalizes dense areas via NetTopologySuite.Simplify.TopologyPreservingSimplifier (gated by MinPointsToSimplify) to keep the overlay cost bounded on very dense coverage cells. The clip geometry is palette-independent, so results are cacheable keyed on the palette-independent portrayal key.

Fields

MinPointsToSimplify

Minimum vertex count at which SimplifyForClip(Geometry) generalizes a geometry before the clip overlay. Below this, the NetTopologySuite Difference/Union cost is already small (profiling: a ~2,600-vertex pattern area clips in ~50 ms) and the simplifier's own fixed setup cost would be net overhead. The cost the optimization targets is super-linear and only becomes significant for very dense areas (profiling: a ~64,000-vertex M_QUAL coverage area took ~7.7 s), so gating on vertex count applies the generalization only where it provides a clear net win and leaves the common case (small/moderate areas) byte-identical to no generalization at all.

public const int MinPointsToSimplify = 2000

Field Value

int

SimplifyToleranceMetres

Tolerance, in EPSG:3857 (Web Mercator) metres, used to generalize pattern and exclusion geometries before clipping. Web Mercator inflates distances by 1/cos(latitude), so this projected tolerance is conservative (smaller in ground metres) away from the equator. The clipped boundary only bounds a tiled raster pattern fill, so this generalization is not visually significant.

public const double SimplifyToleranceMetres = 1

Field Value

double

Methods

Clip(IReadOnlyList<PatternGroup>, IReadOnlyList<Polygon>)

Clips each pattern group against all higher-priority pattern areas and the supplied non-patterned colour fills.

public static IReadOnlyList<PatternPriorityClipper.ClippedPattern> Clip(IReadOnlyList<PatternPriorityClipper.PatternGroup> entries, IReadOnlyList<Polygon> nonPatternedColorFills)

Parameters

entries IReadOnlyList<PatternPriorityClipper.PatternGroup>

The pattern groups, pre-sorted ascending by priority. The returned list is in the same order as this input.

nonPatternedColorFills IReadOnlyList<Polygon>

Non-patterned colour-fill polygons (e.g. land) that should occlude every pattern fill. The clipper treats each polygon as a full occluder; the caller is responsible for supplying only fills that are actually opaque. May be empty.

Returns

IReadOnlyList<PatternPriorityClipper.ClippedPattern>

The clipped geometry for each input group, in input order. A group whose area is fully occluded yields an empty geometry.

Remarks

The overlay favours robustness: when an individual Difference or Union fails (a NetTopologySuite.Geometries.TopologyException or ArgumentException on degenerate input, or the AggregateException that NetTopologySuite.Operation.OverlayNG.OverlayNGRobust throws when all of its fallback strategies fail), the algorithm falls back to the unclipped geometry for that step rather than failing the whole clip. This keeps a pattern visible (un-clipped) in preference to dropping it, matching the historical Mapsui behaviour.

Every overlay result is reduced to its polygonal components before it is used again or returned. OverlayNG's snapping fallback can collapse a sliver of an areal result to a line, yielding a mixed-dimension NetTopologySuite.Geometries.GeometryCollection that a following overlay rejects.

ExtractPolygonal(Geometry)

Reduces an arbitrary geometry to its polygonal components, returning a NetTopologySuite.Geometries.Polygon or NetTopologySuite.Geometries.MultiPolygon (or null when no polygonal component exists). This guards the pattern-clip overlays against the mixed-dimension NetTopologySuite.Geometries.GeometryCollection that topology-preserving simplification can emit, which OverlayNG rejects.

public static Geometry? ExtractPolygonal(Geometry geometry)

Parameters

geometry Geometry

The geometry to reduce; may be any dimension.

Returns

Geometry

The polygonal-only geometry, or null when the input contains no polygon.

RemoveDuplicateComponents(Geometry)

Drops exact duplicate components (equal vertex sequences) from a collection, keeping the first of each. A duplicate adds nothing to a fill or clip area, and NetTopologySuite.Simplify.TopologyPreservingSimplifier keys rings by value, so it throws on a repeated ring. NOAA ENCs give such areas in 14 of 7,184 cells, among them pattern areas of over 80,000 vertices that would otherwise skip simplification.

public static Geometry RemoveDuplicateComponents(Geometry geometry)

Parameters

geometry Geometry

The geometry to deduplicate.

Returns

Geometry

geometry itself when it has no duplicates or isn't a collection; otherwise a new collection of the distinct components.

SimplifyForClip(Geometry)

Generalizes a polygonal geometry for use as a clip subject/mask, preserving topological validity so the result is safe for subsequent NetTopologySuite overlay operations. Geometries below MinPointsToSimplify vertices are returned unchanged (the overlay is already inexpensive at that size). Exact duplicate components are dropped first (see RemoveDuplicateComponents(Geometry)). Returns the original geometry if simplification fails or degenerates to empty.

public static Geometry SimplifyForClip(Geometry geometry)

Parameters

geometry Geometry

The geometry to generalize.

Returns

Geometry

The generalized (or original) geometry.