Table of Contents

Class PolylineStore

Namespace
LansMap.Core.Vector

Colored line collection drawn at constant screen-pixel width, stored as mercator segments for the GPU line layer.

public sealed class PolylineStore
Inheritance
object
PolylineStore

Fields

DashDutyRatio

Fraction of one dash period spent drawn, the rest gap. Must match LANSMAP_DASH_DUTY in PolylineSegment.shader.

public const float DashDutyRatio = 0.5

Field Value

float

DashFadeFullPeriodPx

Screen px per period at or above which a ground-locked dash draws at full contrast. Must match LANSMAP_DASH_FADE_FULL_PX in PolylineSegment.shader.

public const float DashFadeFullPeriodPx = 4

Field Value

float

DashFadeSolidPeriodPx

Screen px per period at or below which a ground-locked dash draws as a solid line at DashDutyRatio alpha. Must match LANSMAP_DASH_FADE_SOLID_PX in PolylineSegment.shader.

public const float DashFadeSolidPeriodPx = 2

Field Value

float

FreeRangeSearchWindow

Newest free-range entries searched by a reservation before falling back to a fresh append.

public const int FreeRangeSearchWindow = 32

Field Value

int

InitialSegmentCapacity

Starting segment-list capacity for a new store.

public const int InitialSegmentCapacity = 1024

Field Value

int

Properties

CompactionsRun

Times the store has compacted wasted slots; diagnostic.

public int CompactionsRun { get; }

Property Value

int

Dirty

True when segments changed since the last ClearDirty().

public bool Dirty { get; }

Property Value

bool

LineCount

Number of lines currently stored (removed ones excluded).

public int LineCount { get; }

Property Value

int

MaxAltitudeMercator

Tallest finite endpoint altitude this store has ever carried, in normalized mercator, for altitude-aware re-anchor.

public double MaxAltitudeMercator { get; }

Property Value

double

Remarks

A running maximum: it never decreases, even after the tallest line is removed. Non-finite values are ignored so one bad endpoint cannot poison the rest.

SegmentCount

Number of segment slots, including collapsed removed ones and unused ring-line slots.

public int SegmentCount { get; }

Property Value

int

Segments

Live segment list the GPU line layer uploads.

public IReadOnlyList<PolylineStore.Segment> Segments { get; }

Property Value

IReadOnlyList<PolylineStore.Segment>

Methods

AddEmptyPolyline(int, float, uint, float)

Reserves a polyline with no vertices yet; invisible until SetPolylinePoints(int, IReadOnlyList<LatLon>) writes at least two.

public int AddEmptyPolyline(int maxPoints, float widthPx, uint colorRgba, float dashPeriodPx)

Parameters

maxPoints int

Maximum vertices this line will ever hold in one call without reallocating; at least 2.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

dashPeriodPx float

Dash plus gap length in screen px; 0 draws solid.

Returns

int

Line id of the reserved polyline.

Remarks

Ids are never recycled - nextId is a plain int - so a caller that rents and returns a line every frame instead of keeping one long-lived id wraps it in about 99 hours at 60 Hz for 100 lines. Reserve once, call SetPolylinePoints(int, IReadOnlyList<LatLon>) every frame instead.

Exceptions

ArgumentException

maxPoints is less than 2.

AddPolyline(IReadOnlyList<LatLon>, float, uint)

Adds a ground-level polyline (all altitudes zero).

public int AddPolyline(IReadOnlyList<LatLon> points, float widthPx, uint colorRgba)

Parameters

points IReadOnlyList<LatLon>

Vertices in degrees WGS84; at least two.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

Returns

int

Line id of the stored polyline.

Exceptions

ArgumentException

Fewer than two points.

AddPolyline(IReadOnlyList<LatLon>, float, uint, float)

Adds a ground-level polyline (all altitudes zero), optionally dashed.

public int AddPolyline(IReadOnlyList<LatLon> points, float widthPx, uint colorRgba, float dashPeriodPx)

Parameters

points IReadOnlyList<LatLon>

Vertices in degrees WGS84; at least two.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

dashPeriodPx float

Dash plus gap length in screen px; 0 draws solid.

Returns

int

Line id of the stored polyline.

Exceptions

ArgumentException

Fewer than two points.

AddPolyline3D(IReadOnlyList<LatLon>, IReadOnlyList<double>, float, uint)

Adds a polyline with optional per-vertex altitude.

public int AddPolyline3D(IReadOnlyList<LatLon> points, IReadOnlyList<double> altitudesMeters, float widthPx, uint colorRgba)

Parameters

points IReadOnlyList<LatLon>

Vertices in degrees WGS84; at least two.

altitudesMeters IReadOnlyList<double>

Null for a ground line; otherwise one altitude in meters WGS84 per vertex, converted to mercator at that latitude.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

Returns

int

Line id of the stored polyline.

Exceptions

ArgumentException

Fewer than two points, or altitudesMeters is non-null and its count does not match points.

AddPolyline3D(IReadOnlyList<LatLon>, IReadOnlyList<double>, float, uint, float)

Adds a polyline with optional per-vertex altitude, optionally dashed.

public int AddPolyline3D(IReadOnlyList<LatLon> points, IReadOnlyList<double> altitudesMeters, float widthPx, uint colorRgba, float dashPeriodPx)

Parameters

points IReadOnlyList<LatLon>

Vertices in degrees WGS84; at least two.

altitudesMeters IReadOnlyList<double>

Null for a ground line; otherwise one altitude in meters WGS84 per vertex, converted to mercator at that latitude.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

dashPeriodPx float

Dash plus gap length in screen px; 0 draws solid.

Returns

int

Line id of the stored polyline.

Exceptions

ArgumentException

Fewer than two points, or altitudesMeters is non-null and its count does not match points.

AddRingLine(MercatorPoint, float, MercatorPoint, float, int, float, uint)

Reserves a fixed-capacity trail line and writes its first segment, for in-place append without reallocating.

public int AddRingLine(MercatorPoint first, float firstAltMerc, MercatorPoint second, float secondAltMerc, int maxPoints, float widthPx, uint colorRgba)

Parameters

first MercatorPoint

First vertex in normalized mercator.

firstAltMerc float

First altitude in normalized mercator.

second MercatorPoint

Second vertex in normalized mercator; chain-unwrapped against first.

secondAltMerc float

Second altitude in normalized mercator.

maxPoints int

Maximum vertices the trail will hold; at least 2. Capacity is maxPoints minus 1 segments.

widthPx float

Stroke width in screen px.

colorRgba uint

Stroke color as packed RGBA.

Returns

int

Line id of the ring line.

Exceptions

ArgumentException

maxPoints is less than 2.

AppendRingPoint(int, MercatorPoint, float)

Appends one vertex to a ring line, overwriting the oldest once the trail is full. Writes at most three segment slots, all within the line's own reservation.

public void AppendRingPoint(int id, MercatorPoint point, float altMerc)

Parameters

id int

Ring-line id from AddRingLine(MercatorPoint, float, MercatorPoint, float, int, float, uint).

point MercatorPoint

New vertex in normalized mercator; chain-unwrapped against the last sample, not against slot order.

altMerc float

New altitude in normalized mercator.

Exceptions

ArgumentException

id is not a ring line.

ClearDirty()

Clears Dirty after the GPU line layer has uploaded.

public void ClearDirty()

RemovePolyline(int)

Collapses a line's segments (width 0) and frees its slot range for reuse. Unknown ids are ignored. Compacts when more than half the slots are waste. Works for both ordinary polylines and ring lines.

public void RemovePolyline(int id)

Parameters

id int

Line id from a successful add.

SetLineColor(int, uint)

Recolors every segment currently stored for a line, including a ring line's already-written history. Unknown ids are ignored.

public void SetLineColor(int id, uint colorRgba)

Parameters

id int

Line id from a successful add.

colorRgba uint

New stroke color as packed RGBA.

SetLineCornerRadiusRatio(int, float)

Sets the corner radius of every join and cap of a line as a fraction of half its width. Unknown ids are ignored.

public void SetLineCornerRadiusRatio(int id, float cornerRadiusRatio)

Parameters

id int

Line id from a successful add.

cornerRadiusRatio float

0 draws sharp mitered joins (clipped flat past a 120 degree turn) and butt caps; 1, the default, draws fully round joins and caps; values between round the miter tip and the cap corners by that fraction of the half width.

Exceptions

ArgumentException

cornerRadiusRatio is outside 0..1 or not finite.

SetLineDashPeriod(int, float)

Sets the dash period of every live segment of a line; 0 draws it solid. Unknown ids are ignored.

public void SetLineDashPeriod(int id, float dashPeriodPx)

Parameters

id int

Line id from a successful add.

dashPeriodPx float

New dash plus gap length in screen px; 0 draws solid.

SetLineDashPeriodMercator(int, float)

Sets a ground-locked dash period on every live segment of a line, in normalized mercator; 0 draws it solid. Unknown ids are ignored.

public void SetLineDashPeriodMercator(int id, float dashPeriodMercator)

Parameters

id int

Line id from a successful add.

dashPeriodMercator float

New dash plus gap length in normalized mercator, the same ground length at every zoom; 0 draws solid. Replaces any screen-px period.

Exceptions

ArgumentException

dashPeriodMercator is negative or not finite.

SetLineDashPitchInvariant(int, bool)

Sets whether a line's screen-px dash pattern ignores pitch. Unknown ids are ignored.

public void SetLineDashPitchInvariant(int id, bool pitchInvariant)

Parameters

id int

Line id from a successful add.

pitchInvariant bool

True scales the dash from each segment's own on-screen length, so a dash is the same screen length near and far under pitch, and the pattern may step slightly at a vertex. False, the default, scales every segment by the view centre's scale, so the pattern is continuous at every vertex and foreshortens toward the horizon. No effect at pitch 0, on a ground-locked or solid line, on a flat line, or on a tabletop draw.

SetLineFlat(int, bool)

Sets whether a line lies flat in the ground plane. Unknown ids are ignored.

public void SetLineFlat(int id, bool flat)

Parameters

id int

Line id from a successful add.

flat bool

True lays the ribbon in the ground plane: its width is WidthPx at the view centre's ground scale and foreshortens with the map under pitch, the same way a flat bulk marker does. False, the default, faces the ribbon to the screen at a constant pixel width. Identical at pitch 0. No effect on a tabletop draw.

SetLineWidth(int, float)

Sets the stroke width of every live segment of a line; 0 hides it. Unknown ids are ignored.

public void SetLineWidth(int id, float widthPx)

Parameters

id int

Line id from a successful add.

widthPx float

New stroke width in screen px.

SetPolylinePoints(int, IReadOnlyList<LatLon>)

Rewrites every vertex of an existing ground polyline in place.

public void SetPolylinePoints(int id, IReadOnlyList<LatLon> points)

Parameters

id int

Line id from AddPolyline(IReadOnlyList<LatLon>, float, uint) or AddEmptyPolyline(int, float, uint, float).

points IReadOnlyList<LatLon>

New vertices in degrees WGS84. Fewer than two hides the line (a state the line carries, not an error) while keeping its reservation.

Exceptions

ArgumentException

id is a ring line or unknown.

SetPolylinePoints3D(int, IReadOnlyList<LatLon>, IReadOnlyList<double>)

Rewrites every vertex of an existing polyline in place, with one altitude per vertex.

public void SetPolylinePoints3D(int id, IReadOnlyList<LatLon> points, IReadOnlyList<double> altitudesMeters)

Parameters

id int

Line id from AddPolyline3D(IReadOnlyList<LatLon>, IReadOnlyList<double>, float, uint) or AddEmptyPolyline(int, float, uint, float).

points IReadOnlyList<LatLon>

New vertices in degrees WGS84. Fewer than two hides the line (a state the line carries, not an error) while keeping its reservation.

altitudesMeters IReadOnlyList<double>

Null for a ground line; otherwise one altitude in meters WGS84 per vertex.

Remarks

When the new point count needs no more segments than the line's current reservation, every write lands in place: no List growth, no dictionary insert. A count that needs more segments reallocates a new range at max(needed, 2x old) and keeps the same id - the old range joins the free list instead of leaking. A caller whose peak count is known up front avoids the allocating path entirely by reserving with AddEmptyPolyline(int, float, uint, float) once.

Exceptions

ArgumentException

id is a ring line or unknown, or altitudesMeters is non-null and its count does not match points.

TryGetLine(int, out PolylineInfo)

Reads a line's current settings and vertex count; false when the id is not live.

public bool TryGetLine(int id, out PolylineInfo info)

Parameters

id int

Line id from a successful add.

info PolylineInfo

The line's settings, or default when not live.

Returns

bool