@orbat-mapper/tactical-draw
v0.2.0-alpha.23
Published
Engine-agnostic draw/edit core for tactical control measures (MIL-STD-2525 / APP-6). The MapAdapter ABI and bring-your-own-engine entry point for the tactical-draw package family.
Downloads
2,786
Maintainers
Readme
@orbat-mapper/tactical-draw
The engine-agnostic draw/edit core for @orbat-mapper tactical graphics:
draw and edit controllers, sessions and draw rules, the MapAdapter contract
and base adapter, pixel-space hit-testing, handle rendering, interaction
styles, and pick helpers.
It only depends on @orbat-mapper/control-measures and geojson, with no
concrete map engine in sight. Bring your own: pair this package with one of
the engine adapters, or implement MapAdapter against whatever you're
already using.
Point symbols are also optional: the core contains only their lightweight
model and capability interface. Add @orbat-mapper/point-symbols and
milsymbol when an application needs MIL-STD-2525/APP-6 unit icons.
Installation
# npm
npm install @orbat-mapper/tactical-draw @orbat-mapper/control-measures
# pnpm
pnpm add @orbat-mapper/tactical-draw @orbat-mapper/control-measuresThen add an engine adapter (or implement MapAdapter against your own engine):
# pick one — npm
npm install @orbat-mapper/tactical-draw-adapter-openlayers ol
npm install @orbat-mapper/tactical-draw-adapter-maplibre maplibre-gl
npm install @orbat-mapper/tactical-draw-adapter-leaflet leaflet
# pick one — pnpm
pnpm add @orbat-mapper/tactical-draw-adapter-openlayers ol
pnpm add @orbat-mapper/tactical-draw-adapter-maplibre maplibre-gl
pnpm add @orbat-mapper/tactical-draw-adapter-leaflet leafletWhat's inside
TacticalDraw— the draw/edit controller hosting draw and edit sessions driven by per-measure draw rules.MapAdapter— the type-only ABI every engine adapter implements, plusBaseMapAdapterwith the shared implementation to extend.- Hit-testing & pointer driver — pixel-space
hitTestFeature, hit tolerances, and theEditPointerDrivercontract adapters implement for the edit controller. - Interaction styles —
coerceHandleStyleand theInteractionStyle/GuideStyle/HandleStyleshapes. (Handle rendering itself is not part of the public API.) - Pick helpers — hit tolerance and control-measure identification utilities.
Pick to edit
Use onGraphicPick to subscribe to committed graphics without accessing
internal layer ids:
const unsubscribe = td.onGraphicPick((event) => {
const graphic = graphics.find((candidate) => candidate.id === event.id);
if (graphic) void td.edit(graphic);
});The handler receives the full PickEvent, with event.id set to the graphic
id. The returned unsubscribe function is idempotent, and
onGraphicPick(handler, { signal }) also supports abort-driven teardown.
Cancel and inspect the active interaction
Use cancel() for a host Cancel button. It aborts draws and edits, including
fixed-length draws that do not expose a session:
cancelButton.onclick = () => td.cancel();activeSession exposes the live DrawSession or EditSession when one exists,
and returns null while idle or during a fixed-length draw:
const session = td.activeSession;
if (session && "canCommit" in session) {
doneButton.disabled = !session.canCommit;
}Live edit and transform sessions expose a session-local history. Completed
gestures and authored programmatic mutations are undoable without settling the
session; pointer-move preview frames are not history steps:
const active = td.activeSession;
const history =
(active && "history" in active ? active.history : null) ?? td.activeTransformSession?.history;
if (history) history.undo();history.subscribe(...) reports canUndo, canRedo, and optional operation
labels. Committing folds only the selected working state into the host document
as one operation. Changing a transform session's members with setGraphics()
establishes a new local baseline and clears both stacks.
Bring your own engine
Implement MapAdapter (or extend BaseMapAdapter) against your map engine
and hand it to TacticalDraw. The controllers, sessions, gestures, and
handle rendering above the adapter don't need to know or care which engine
is underneath.
License
MIT
