Class SkiaDisplayListRenderer
A headless, direct-SkiaSharp renderer for the S-100 Part 9 vector intermediate representation produced by VectorSceneBuilder. Rasterises a VectorScene against a Viewport into a standalone SKBitmap — the vector analogue of SkiaCoverageRenderer, suitable for a tile-serving web API with no Mapsui / GUI dependency.
public sealed class SkiaDisplayListRenderer : IVectorSceneRenderer<SKCanvas>
- Inheritance
-
SkiaDisplayListRenderer
- Implements
- Inherited Members
Remarks
The renderer supplies the second half of the S-100 projection that the Mapsui backend delegates to its navigator: it projects the Viewport geographic bounds to EPSG:3857 and maps that rectangle linearly to pixels. Geometry is transformed world→screen, but stroke widths, symbol sizes, and text sizes are realised in display pixels per the IR unit contract (see PaintOp).
Scope. This renders point, line, solid-area, tiled pattern-area, and text ops. The renderer itself does not split geometry at the antimeridian or the Web-Mercator pole limits: VectorSceneBuilder already keeps rings within their own longitude frame, closes polar rings along the pole and clips to the latitude limit (issue #760).
Fields
PointCullMarginPx
Half-extent, in display pixels, by which the point/text cull rectangle is grown beyond the viewport so a symbol or label whose anchor sits just off-screen but whose body is partly visible is still drawn. Sized to comfortably exceed the largest compound symbol / point-anchored label. Exposed so callers that supply an explicit cull rectangle (e.g. the live overlay under a rotated viewport) inflate by the same margin.
public const float PointCullMarginPx = 256
Field Value
Properties
Background
Background colour cleared before painting. Defaults to transparent.
public RgbaColor Background { get; set; }
Property Value
EnableSeamWrap
Whether to apply the antimeridian seam-wrap in WorldToScreen
(wrapping each op's world-X into the viewport's shifted longitude window
when MaxLongitude > 180 or MinLongitude < −180).
Defaults to true so the headless single-viewport
auto-fit path (issue #413) can gather geometry across the ±180° seam.
The tiled subsystem sets this to false: it rasterises each tile from a narrow per-tile viewport over geometry that is already positioned in a continuous EPSG:3857 X frame (longitudes may exceed +180° without wrapping). Under a per-tile window whose bounds both lie east of +180°, the seam-wrap would teleport the far vertices of large polygons that extend west of the tile back across the world, smearing them across the tile. Disabling the wrap keeps continuous geometry continuous; off-tile vertices simply project outside the tile and are clipped.
public bool EnableSeamWrap { get; set; }
Property Value
HonorScaleVisibility
Whether to apply S-100 Part 9 §11.1 scale-visibility culling using the viewport's ScaleDenominator. Defaults to true (an explicit viewport carries a meaningful scale). Auto-fit / "render the whole dataset" callers set this to false, because the denominator synthesised from a fitted extent is not the dataset's compilation scale and would otherwise wrongly cull scale-ranged detail.
public bool HonorScaleVisibility { get; set; }
Property Value
KeepAreaSymbolsInView
Whether point symbols and text placed in the visible parts of a surface
(S-100 Part 9 AreaPlacement:VisibleParts, see
PlacementArea) move into the part of the surface in the
viewport when their anchor is outside it. Defaults to
true, for a viewport that is the whole display. A
caller that draws a display in pieces, such as tiles, sets it to
false, so each piece doesn't place its own copy.
public bool KeepAreaSymbolsInView { get; set; }
Property Value
Methods
Render(VectorScene, Viewport)
Renders the scene at the requested viewport, returning a new bitmap of WidthPixels × HeightPixels. The caller owns the returned bitmap.
public SKBitmap Render(VectorScene scene, Viewport viewport)
Parameters
sceneVectorSceneviewportViewport
Returns
RenderOnto(SKCanvas, VectorScene, Viewport)
Draws scene onto an existing canvas
using viewport's world→screen projection, without
allocating or clearing a backing bitmap and without flushing the canvas.
This lets a caller composite a display list directly onto a foreground
surface — e.g. the tiled subsystem's live screen-space symbol/text
overlay, which must be drawn at constant on-screen size (the tiled base
plane is rasterised at a discrete band resolution and then scaled, so any
op baked into it scales with zoom; ops drawn here against the live
viewport do not).
public void RenderOnto(SKCanvas canvas, VectorScene scene, Viewport viewport)
Parameters
canvasSKCanvasThe destination canvas. Not cleared or flushed.
sceneVectorSceneThe display list to draw.
viewportViewportThe live viewport whose projection places the ops.
RenderOnto(SKCanvas, VectorScene, Viewport, OverlayDrawOptions)
As RenderOnto(SKCanvas, VectorScene, Viewport, SKRect?), but
driven by options so the tiled subsystem's live label
plane can: suppress decluttered text
(SuppressedText), keep labels and
screen-relative symbols upright under a rotated viewport by
rotating each point and text anchor about the screen centre while
drawing glyphs unrotated
(AnchorRotationDegrees), and draw the
point and text passes separately
(DrawPoints /
DrawText). The defaults reproduce the
plain overlay behaviour (draw everything, no suppression, no rotation).
public void RenderOnto(SKCanvas canvas, VectorScene scene, Viewport viewport, OverlayDrawOptions options)
Parameters
canvasSKCanvasThe destination canvas. Not cleared or flushed.
sceneVectorSceneThe display list to draw.
viewportViewportThe live viewport whose projection places the ops.
optionsOverlayDrawOptionsOverlay draw controls; see OverlayDrawOptions.
RenderOnto(SKCanvas, VectorScene, Viewport, SKRect?)
As RenderOnto(SKCanvas, VectorScene, Viewport), but culls
point and point-anchored text ops whose projected anchor falls outside
pointCullBounds (in viewport pixel space) before any
per-op work — avoiding the cost of parsing a symbol SVG or measuring a
label that cannot be visible. When pointCullBounds is
null, the cull rectangle is the viewport inflated by
PointCullMarginPx. A caller that rotates the canvas (the
live overlay under a rotated viewport) must pass an explicit rectangle
expanded to the rotated viewport's bounding box, since this method draws
in pre-rotation pixel space.
public void RenderOnto(SKCanvas canvas, VectorScene scene, Viewport viewport, SKRect? pointCullBounds)
Parameters
canvasSKCanvasThe destination canvas. Not cleared or flushed.
sceneVectorSceneThe display list to draw.
viewportViewportThe live viewport whose projection places the ops.
pointCullBoundsSKRect?Pixel-space rectangle outside which point/text ops are skipped, or null to derive it from the viewport plus the symbol margin.