Table of Contents

Class SeamAwareBoundsAccumulator

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

Accumulates the EPSG:3857 extent of a headless render while remaining aware of the ±180° antimeridian seam, so the auto-fit viewport frames a dataset on its true extent even when its geometry wraps the dateline.

public sealed class SeamAwareBoundsAccumulator
Inheritance
SeamAwareBoundsAccumulator
Inherited Members

Remarks

A naive min/max over projected world-X collapses for antimeridian- spanning data (e.g. the Alaska NWS S-411 product, ~175°E → ~225°E): one cluster near +179° and another near −179° make the X-span ≈ the full world width, so the fitted viewport becomes near-global and every feature draws sub-pixel (issue #413).

To detect the seam robustly the accumulator maintains a coarse longitude occupancy histogram (BinCount bins over [−180°, 180°)), tracking the exact observed [minX, maxX] per bin. On TryResolve(out double, out double, out double, out double) it locates the largest empty longitude arc (the emptiest gap): if that gap is an interior band — rather than the arc that already wraps the seam — the data straddles ±180°, so the western cluster is shifted by one Circumference to produce a contiguous world-X window whose maxX may exceed +½ circumference. The paired WorldToScreen wrap re-homes the shifted ops at draw time.

The seam logic only engages when the naive longitude span exceeds 180°; narrower extents (the overwhelming majority) take the fast path and behave exactly as the previous naive min/max fit. Genuinely wide / global datasets — whose emptiest gap is the seam-wrapping arc, not an interior band — also keep the naive extent, so the heuristic does not false-positive.

Constructors

SeamAwareBoundsAccumulator()

Creates an empty accumulator.

public SeamAwareBoundsAccumulator()

Fields

BinCount

Number of longitude occupancy bins (0.5° each).

public const int BinCount = 720

Field Value

int

Properties

HasGeometry

Whether any geometry has been accumulated.

public bool HasGeometry { get; }

Property Value

bool

Methods

Add(double, double)

Accumulates a single EPSG:3857 world coordinate (metres).

public void Add(double x, double y)

Parameters

x double

Easting in metres.

y double

Northing in metres.

AddLonLatBox(double, double, double, double)

Accumulates a WGS-84 lon/lat bounding box (degrees), projecting its corners to EPSG:3857 and marking every longitude bin it covers as occupied so a wide extent (e.g. a coverage grid) does not introduce a spurious interior gap. Boxes whose west exceeds east are treated as crossing the ±180° seam, as are boxes that run past +180° (a grid stored in 0°–360° longitudes) or before −180°.

public void AddLonLatBox(double west, double east, double south, double north)

Parameters

west double

Western longitude edge, degrees.

east double

Eastern longitude edge, degrees.

south double

Southern latitude edge, degrees.

north double

Northern latitude edge, degrees.

Remarks

The occupancy bins are 0.5° wide, but the X extent recorded in each bin is clipped to the box's own edges, so a sub-degree coverage resolves to its true extent rather than to the enclosing bin edges (issue #1097).

AddScene(VectorScene)

Accumulates every vertex of a resolved VectorScene — point and text anchors, polyline vertices, and area shell + hole rings.

public void AddScene(VectorScene scene)

Parameters

scene VectorScene

The lowered scene whose paint ops to bound.

TryResolve(out double, out double, out double, out double)

Resolves the accumulated geometry to a seam-aware EPSG:3857 window.

public bool TryResolve(out double minX, out double minY, out double maxX, out double maxY)

Parameters

minX double

Resolved minimum easting, metres.

minY double

Resolved minimum northing, metres.

maxX double

Resolved maximum easting, metres. May exceed +½ Circumference when the extent was shifted across the antimeridian; the paired WorldToScreen wrap re-homes ops into this window at draw time.

maxY double

Resolved maximum northing, metres.

Returns

bool

true when geometry was accumulated; otherwise false (all outputs zero).