Many symbols
A thousand tracks are usually a dozen kinds of symbol. buildSymbolAtlas draws each distinct one once onto a single canvas and says where each sits, for a renderer that draws icons from a sprite sheet.
ts
import {buildSymbolAtlas, deckIconMapping} from '@zaes/military-symbols';
const atlas = buildSymbolAtlas([
'130310000012110000000000000000',
{id: 'hostile-armor', sidc: '130610000012050000000000000000', options: {size: 30}},
], {pixelRatio: 2});
atlas.canvas; // the sheet
atlas.entries['hostile-armor']; // {x, y, width, height, anchorX, anchorY, problems}, device pixels
atlas.skipped; // codes that drew nothingEntries are packed tallest first, padding apart so a sampled edge never takes a neighbour's.
deck.gl
ts
new IconLayer({
iconAtlas: atlas.canvas,
iconMapping: deckIconMapping(atlas),
getIcon: (d) => d.kind,
// ...
});MapLibre's own icons
ts
import {atlasImage, atlasIconOffset} from '@zaes/military-symbols';
map.addImage('hostile-armor', atlasImage(atlas, 'hostile-armor')!, {pixelRatio: atlas.pixelRatio});
// MapLibre centres an icon; this offset puts the symbol's anchor on the point.
map.setLayoutProperty('tracks', 'icon-offset', atlasIconOffset(atlas, 'hostile-armor'));In a worker
The atlas draws on an OffscreenCanvas where there is one, so it can be built off the page's thread. symbolBitmap(code, options) draws one symbol to an ImageBitmap to transfer back.