Generate GeoJSON ​
Pass a control-measure kind, a list of control points, and any kind-specific options to @orbat-mapper/control-measures. It returns MIL-STD-2525 and APP-6 graphics as GeoJSON, ready for a browser, a Node service, a test, or an SVG pipeline. No map engine or canvas is required.
Install ​
pnpm add @orbat-mapper/control-measuresnpm install @orbat-mapper/control-measuresRender a control measure ​
Call renderControlMeasure(measure, options?) with a ControlMeasure:
idis a stable identifier for this instance.kindselects the control-measure type, such as"ambush"or"block".controlPointscontains[longitude, latitude]pairs.optionscustomizes the selected kind (optional).style,textAmplifiers, andpropertiesare also optional.
import { renderControlMeasure } from "@orbat-mapper/control-measures";
const render = renderControlMeasure({
id: "ambush-1",
kind: "ambush",
controlPoints: [
[-0.871, 49.369],
[-0.861, 49.369],
[-0.866, 49.374],
],
});
// `render` is a GeoJSON FeatureCollection ready for a map or other renderer.
render.features.forEach((f) => console.log(f.id, f.geometry.type));The function is pure: it never mutates the measure, and the same input always produces the same output.
What the render contains ​
A single graphic usually produces several features, one per part: an arrow's shaft and head, a label, a fill. Each feature has:
id:${measure.id}:${part}:${index}. The ID is stable across renders, so you can match parts before and after an edit. Recover the measure ID withcontrolMeasureIdFromFeature(feature).properties.part: the part name, such as"label".properties.style: the final resolved paint values (strokeColor,fillColor,strokeWidth,strokeDash,fillPattern). See Styling.- For labels:
text,rotation(radians),textAnchor, and the screen-space offsettextAnchorGapandtextBaselineShift. See Labels and text amplifiers.
The full property shape is exported as FeaturePartProps.
How many points does a control measure need? ​
Each kind declares the minimum number of control points it needs and, where applicable, a maximum. Read these limits from its metadata:
import {
listControlMeasureMetadata,
getControlMeasureMetadata,
} from "@orbat-mapper/control-measures";
// Every kind, with geometry, point requirements, options, and symbology.
const all = listControlMeasureMetadata();
const ambush = getControlMeasureMetadata("ambush");
ambush.minCoordinates; // 3
ambush.maxCoordinates; // 3
ambush.geometry; // "line"When minCoordinates equals maxCoordinates, the kind has a fixed number of points. Otherwise, the user may add more, up to maxCoordinates if one is set. Points beyond the maximum are ignored.
The catalog presents the same metadata for every supported kind.
Find a kind from a symbol code ​
Each kind's value is its MIL-STD-2525D entity code (entity, type, and subtype digits). Use it to map a SIDC from another system to a kind:
import { getControlMeasureMetadataByValue } from "@orbat-mapper/control-measures";
getControlMeasureMetadataByValue("110100")?.id; // "boundary"It returns undefined for codes the library does not support.
Options and defaults ​
Most kinds expose options such as arrowhead size, tooth count, or fill. Start with getDefaultOptions, then override only what you need:
import { getDefaultOptions, renderControlMeasure } from "@orbat-mapper/control-measures";
const options = { ...getDefaultOptions("ambush"), arrowheadLengthRatio: 0.25 };
const render = renderControlMeasure({
id: "ambush-1",
kind: "ambush",
controlPoints,
options,
});getDefaultOptions returns a fresh copy, so you can change it freely. Options are typed per kind: OptionsByKind["ambush"] is the ambush option type, and isKind(measure, "ambush") narrows a ControlMeasure to it.
See the catalog for each kind's option names, types, and defaults. Colors and strokes are covered in Styling. Options that come in pixel/meter pairs are covered in Pixel and meter sizes.
Validation ​
Invalid input, such as too few points or non-finite coordinates, returns an empty render by default. Set validationMode for a warning or an exception:
renderControlMeasure(measure, { validationMode: "warn" }); // "silent" | "warn" | "throw"Valid points that cannot form a shape, such as two identical points, always return an empty render without a message. This is normal while a user is still placing points. See Points and validity.
Render options ​
The second argument to renderControlMeasure accepts:
| Option | Description |
|---|---|
validationMode | "silent" (default), "warn", or "throw". |
graphicsStyle | Lowest-priority default style for this call. See Style priority. |
symbolColors | Doctrinal default colors, such as the obstacle green. See Styling. |
Next steps ​
- Labels and text amplifiers: add designations and other text.
- Styling: colors, fills, patterns, and opacity.
- TacticalDraw: let users draw and edit measures on a map.
- Map sheets: print measures at a true scale.