@orbat-mapper/control-measures
v0.13.0
Published
Library for drawing tactical graphics and control measures according to MIL-STD-2525 and APP-6 standards.
Maintainers
Readme
@orbat-mapper/control-measures
Generates tactical control measures as GeoJSON, following MIL-STD-2525 and APP-6 conventions.
The output is plain GeoJSON, so it drops into Leaflet, MapLibre, OpenLayers,
or any other consumer without a mapping dependency of its own. Everything
goes through one entry point, renderControlMeasure(cm, options), backed by
a metadata catalog for discovering the available measures and their options,
plus an optional validationMode per render for catching bad input.
Installation
# npm
npm install @orbat-mapper/control-measures
# pnpm
pnpm add @orbat-mapper/control-measuresQuick Start
Describe a control measure as a ControlMeasure object — kind,
controlPoints, and optional options — then render it:
import { renderControlMeasure, type ControlMeasure } from "@orbat-mapper/control-measures";
const mainAttack: ControlMeasure<"main-attack"> = {
id: "alpha",
kind: "main-attack",
controlPoints: [
[10, 10], // tip
[5, 5], // spine
[0, 0], // neck
[2, 6], // width control
],
};
const render = renderControlMeasure(mainAttack, { validationMode: "warn" });
// render is a ControlMeasureRender: a GeoJSON FeatureCollection whose features
// carry stable ids (`${cm.id}:${part}:${index}`) and resolved style hints.renderControlMeasure returns a ControlMeasureRender — a GeoJSON
FeatureCollection of FeaturePartProps-typed features.
Discovering measures and options
Skip the per-measure imports and query the catalog instead:
import {
CONTROL_MEASURE_IDS,
listControlMeasureMetadata,
getControlMeasureMetadata,
getDefaultOptions,
} from "@orbat-mapper/control-measures";
CONTROL_MEASURE_IDS; // readonly list of every control-measure id
listControlMeasureMetadata(); // metadata (geometry, required points, params, symbology)
getControlMeasureMetadata("block"); // metadata for one measure
getDefaultOptions("block"); // default options object for one measureEach measure also exports its options type and defaults constant, e.g.
BlockOptions / DEFAULT_BLOCK_OPTIONS, MainAttackOptions /
DEFAULT_MAIN_ATTACK_OPTIONS.
Validation behavior
renderControlMeasure accepts a RenderOptions object whose validationMode
controls how invalid coordinate input is handled:
validationMode: "silent" | "warn" | "throw"
When omitted, validation defaults to silent mode — invalid input yields an
empty render. "throw" is useful for strict integrations and tests.
Supported control measures
Grouped by APP-6/MIL-STD-2525 entity type, with each measure's 2525E symbol code.
Command and Control Lines
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | boundary | Boundary | 110100 |
| | light-line | Light line | 110200 |
| | engineer-work-line | Engineer work line | 110300 |
| | generic-c2-line | Generic command and control line | 110400 |
Command and Control Areas
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | area-of-operations | Area of operations | 120100 |
| | named-area-of-interest | Named area of interest | 120200 |
| | target-area-of-interest | Target area of interest | 120300 |
| | airfield-zone | Airfield zone | 120400 |
| | base-camp | Base camp | 120500 |
| | guerrilla-base | Guerrilla base | 120600 |
| | generic-c2-area | Generic command and control area | 120700 |
Maneuver Lines
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | flot | Forward line of own troops (FLOT) | 140100 |
| | phase-line | Phase line | 140300 |
| | forward-edge-of-battle-area | Forward edge of the battle area | 140400 |
| | final-protective-fire-left | Final Protective Fire (Left) | 140501 |
| | final-protective-fire-right | Final Protective Fire (Right) | 140502 |
| | principal-direction-of-fire | Principal Direction of Fire | 140503 |
| | secondary-direction-of-fire | Secondary Direction of Fire | 140504 |
| | direction-of-attack-aviation | Direction of Attack — Airborne/Aviation | 140601 |
| | direction-of-main-attack | Direction of Main Attack | 140602 |
| | direction-of-supporting-attack | Direction of Supporting Attack | 140603 |
| | final-coordination-line | Final coordination line | 140700 |
| | limit-of-advance | Limit of advance | 140900 |
| | line-of-departure | Line of departure | 141000 |
| | line-of-departure-contact | Line of departure / line of contact | 141100 |
| | probable-line-of-deployment | Probable line of deployment | 141200 |
| | airhead-line | Airhead line | 141300 |
| | bridgehead-line | Bridgehead line | 141400 |
| | holding-line | Holding line | 141500 |
| | release-line | Release line | 141600 |
| | ambush | Ambush | 141700 |
| | handover-line | Handover line | 141800 |
| | battle-handover-line | Battle handover line | 141900 |
Maneuver Areas
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | area | Area | 150100 |
| | assembly-area | Assembly area | 150200 |
| | joint-tactical-action-area | Joint tactical action area | 150501 |
| | submarine-action-area | Submarine action area | 150502 |
| | submarine-generated-action-area | Submarine-generated action area | 150503 |
| | drop-zone | Drop zone | 150600 |
| | extraction-zone | Extraction zone | 150700 |
| | landing-zone | Landing zone | 150800 |
| | pickup-zone | Pickup zone | 150900 |
| | fortified-area | Fortified Area | 151000 |
| | limited-access-area | Limited Access Area | 151100 |
| | battle-position | Battle Position | 151200 |
| | battle-position-prepared | Battle Position Prepared (P) but not Occupied | 151202 |
| | strong-point | Strong Point | 151203 |
| | contain | Contain | 151204 |
| | retain | Retain | 151205 |
| | engagement-area | Engagement area | 151300 |
| | airborne-attack | Airborne Attack | 151401 |
| | attack-helicopter | Attack Helicopter | 151402 |
| | main-attack | Main Attack | 151403 |
| | supporting-attack | Supporting Attack | 151404 |
| | assault-position | Assault position | 151500 |
| | attack-position | Attack position | 151600 |
| | objective-area | Objective area | 151700 |
| | encirclement | Encirclement | 151800 |
| | penetration-box | Penetration box | 151900 |
| | attack-by-fire | Attack by Fire | 152000 |
| | support-by-fire | Support By Fire | 152100 |
| | search-area | Search Area | 152200 |
| | area-defense | Area Defense | 152600 |
| | frontal-attack | Frontal Attack | 152700 |
| | mobile-defense | Mobile Defense | 152800 |
| | turning-movement | Turning Movement | 152900 |
Maritime Control Areas
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | radar-search-doctrine | Radar Search Doctrine | 200700 |
Fire Areas
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | no-fire-area-irregular | No Fire Area (NFA) – Irregular | 240301 |
Protection Areas
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | block | Block | 270501 |
| | disrupt | Disrupt | 270502 |
| | fix | Fix | 270503 |
| | turn | Turn | 270504 |
| | obstacle-bypass-easy | Obstacle Bypass Easy | 270601 |
| | obstacle-bypass-difficult | Obstacle Bypass Difficult | 270602 |
| | obstacle-bypass-impossible | Obstacle Bypass Impossible | 270603 |
| | minefield | Minefield | 270701 |
| | minefield-dynamic | Minefield (Dynamic) | 270707 |
| | mined-area | Mined Area | 270800 |
| | bridge-or-gap | Bridge or Gap | 271100 |
Protection Lines
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | antitank-ditch-under-construction | Ditch - Under Construction | 290201 |
| | antitank-ditch-completed | Ditch - Completed | 290202 |
| | antitank-wall | Antitank Wall | 290204 |
| | fortified-line | Fortified Line | 290900 |
Mission Tasks
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | block-mission-task | Block | 340100 |
| | breach | Breach | 340200 |
| | bypass | Bypass | 340300 |
| | canalize | Canalize | 340400 |
| | clear | Clear | 340500 |
| | counterattack | Counterattack | 340600 |
| | counterattack-by-fire | Counterattack by Fire | 340700 |
| | delay | Delay | 340800 |
| | disrupt-mission-task | Disrupt | 341000 |
| | fix-mission-task | Fix | 341100 |
| | isolate | Isolate | 341500 |
| | penetrate | Penetrate | 341800 |
| | retire | Retire/Retirement | 342000 |
| | cover | Cover | 342201 |
| | guard | Guard | 342202 |
| | screen | Screen | 342203 |
| | seize | Seize | 342300 |
| | withdraw | Withdraw | 342400 |
| | withdraw-under-pressure | Withdraw Under Pressure | 342500 |
| | envelopment | Envelopment | 343500 |
| | infiltration | Infiltration | 343800 |
| | rearward-passage-of-lines | Rearward Passage of Lines | 344200 |
| | disengage | Disengage | 344400 |
Generic Graphics
| Preview | kind | Measure | 2525E Value |
| --- | --- | --- | --- |
| | block-arrow | Block Arrow | 990001 |
| | classic-arrow | Classic Arrow | 990002 |
| | line | Line | 990101 |
| | polygon | Polygon | 990102 |
| | rectangle | Rectangle | 990103 |
| | circle | Circle | 990104 |
| | sector | Sector | 990105 |
| | text | Text | 990201 |
This table and the preview SVGs are generated; run
pnpm --filter @orbat-mapper/control-measures generate-docs after adding or
changing a measure to refresh both.
License
MIT
