Skip to content

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 nothing

Entries 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.

Released under the MIT License; the drawings derive from Apache-2.0 work.