Planar solid line casing
When a matching SDK reports commonPlanarLayerComposition:true, the shared Mercator view with zero pitch/roll and no terrain/extrusion combines media, backgrounds, labels, heat and supported static line/fill effects in complete layer order. This capability supersedes earlier media-combination exclusions only within that shared planar scope. Custom line animation, tilted/globe/terrain views and other unsupported material combinations retain their respective limits. Reordering and compatible diff preserve identities, caches, pending requests and fade clocks; material, geometry and texture budgets are validated before publication. See planar layer composition.
The shared planar solid-line paint property line-gap-width defaults to 0 and requires a finite nonnegative CSS-pixel number. Capability: commonLineGapSolid. Positive gap values define the inner gap width; the total outer width is gap+2×line-width, with line-width thickness on each side. Gap 0 retains previous solid-line width; line-width 0 leaves no visible casing or end caps.
The inner region is transparent and reveals the map or lower layers. In this example, red should show through the blue casing's gap. The gap does not paint over the lower layer. Overlapping triangles at corners or self-crossings within one feature must not repeatedly blend translucent casing colors.
import { map } from 'sqsmap';
map.setStyle(null);
await map.sqs.flush();
map.setProjection({type:'mercator'});
map.jumpTo({center:[116.4,39.9],zoom:13,pitch:0});
await map.sqs.flush();
map.addSource('underlay',{type:'geojson',data:{type:'Feature',properties:{},
geometry:{type:'Polygon',coordinates:[[[116.35,39.85],[116.45,39.85],
[116.45,39.95],[116.35,39.95],[116.35,39.85]]]}}});
map.addLayer({id:'underlay',type:'fill',source:'underlay',paint:{'fill-color':'#ff0000'}});
map.addSource('route',{type:'geojson',data:{type:'Feature',id:1,
properties:{gap:12},geometry:{type:'LineString',coordinates:[[116.38,39.9],[116.42,39.9]]}}});
map.addLayer({id:'route',type:'line',source:'route',paint:{
'line-color':'#0000ff','line-width':4,
'line-gap-width':['coalesce',['feature-state','gap'],['get','gap']]
}});
await map.sqs.flush({render:true});
map.setFeatureState({source:'route',id:1},{gap:8});
await map.sqs.flush({render:true});
Numeric, property, paint feature-state, global-state, type/lexical/lazy and continuous-zoom expressions are supported. For example ['interpolate',['linear'],['zoom'],10,12,11,24] changes the gap at fractional zoom. Set the paint property to null to remove it. Existing solid caps/joins, closed lines, polygon rings/holes and supported offset/translate combinations preserve original IDs, properties, filtering and sorting. Zero-gap and positive-gap features in one layer retain their interleaved sort order.
Project budgets retain the 24 CSS-pixel line-width limit and allow gap up to 128. The private outer mesh width can reach 176 without widening the existing public line-width interface. Inner and outer meshes share one million worst-case generated vertices; actual combined cap/join/offset/translate extrusion is limited to 2048 CSS pixels. Expression depth 32, nodes 1024, steps 8192 and the combined two-million candidate-node estimate remain. Render-target allocation is checked using a conservative 64 bytes per physical pixel and 512 MiB budget, including MSAA attachments and aligned readback buffers. Only nonzero gaps introduce the additional target constraint; physical dimensions include DPR. Exceeding a budget reports RESOURCE_LIMIT rather than silently truncating or ignoring it.
Actual nonzero gaps do not yet combine with dash, gradient, animation, pitch/3D, globe or media. Zero retains previous paths. Invalid types, negative/nonfinite values, unsupported combinations and budgets retain the previous source, state, camera, display, resource queues and identities. Unselected future branches remain lazy.
queryRenderedFeatures retains conservative geometric hits: an unpainted inner gap may still hit the original line, so it is not per-pixel picking. Queries use the complete casing envelope with actual offset/translate and preserve source/feature IDs. Even without translation, MVT planning includes unknown neighboring gap/width/offset/join bounds rather than only cached samples, retaining the full-map 64-tile budget and candidate transactions.
The shared script and complete HTML cover lower-layer visibility, blue casings, interleaved green zero-gap features, zero width and equal translucent corner/straight-segment pixels. Core72599dba passes five CPU checks, one final serial actual GPU case and the same34-check script with real pixels on Linux, browser main thread and Worker. The previous36-check translation script passes all three paths. See SDK acceptance for matching version and archive SHA. Devices, external platforms, mobile/iOS, formal release and deployment remain separate.
Semantics follow the official MapLibre gap specification, with an independently implemented SqsMap engine.