A matching development SDK with commonLineSymbols also supports shared planar line symbols, including true per-glyph curved geometry, target ownership, joint icon/text groups and shared budgets. Earlier point-only scope and pending line-symbol notes below are superseded for this bounded subset. Complex shaping, tilted/globe/terrain placement and complete road stitching remain pending.
Icons and text in one layer
Common symbol layers support both icon-image and text-field. Images and fonts retain separate atlases. Components at one point test collisions together and do not collide with their own sibling. Queries return one logical feature and can hit either displayed component.
// Register marker with addImage; points contains a name property.
map.addLayer({ id: 'places', type: 'symbol', source: 'points',
layout: { 'icon-image': 'marker', 'text-field': ['get', 'name'],
'text-size': 18, 'text-offset': [2, 0] },
paint: { 'text-color': '#2563eb' }
});
await map.sqs.flush({ render: true });
Each component uses its own icon/text allow-overlap, ignore-placement and padding options. All effective components are tested before inserting collision boxes; by default, if any required component is blocked, the pair is withheld. Set icon-optional: true to retain fitting text when its icon is blocked, or text-optional: true to retain a fitting icon when its text is blocked. Both default to false; a blocked component itself remains hidden. Transparent components, empty text and missing images do not participate; remaining components may display independently. Existing ordering, MultiPoint, property editing, missing-image events and identities are retained.
Icon/text opacity controls components independently. Text offsets remain in em; rotation/anchors are independent. Existing budgets are16K points,65536 glyph quads and1M collision comparisons. Common text now uses configured external PBF glyph services. Formatted text, line placement, font files, complex text and3D layout remain pending; unsupported options reject explicitly.
Raw browser SDK callers use view.flush(); desktop/native persistent scripts use the same code. Actual Linux QuickJS, browser main thread and Worker share script checks and visible icon/text pixel verification. Device checks are separate.