🚧 These docs are a work in progress — content is incomplete and may change without notice.
Skip to content

Styling ​

Control measures are monocolor by doctrine: one color paints every part of a graphic, whether stroked or filled. Set that color — and optional overrides — via ControlMeasureStyle; the renderer resolves it onto each output feature's properties.style.

Tweak the controls below to see renderControlMeasure re-run and the SVG repaint from resolved per-feature styles — no map engine involved.

measure.style = {
  "color": "#c1121f",
  "strokeWidth": 2
}

The style shape ​

ts
interface ControlMeasureStyle {
  color?: string; // the single symbol color (input only)
  strokeColor?: string; // per-channel override
  strokeWidth?: number;
  strokeDash?: number[];
  fillColor?: string; // per-channel override
}

color is the normal knob: set it and stroke and fill of every part follow. strokeColor / fillColor are escape hatches when outline and fill must differ. With nothing set, the render is black (#000000).

Where style comes from ​

Style resolves from three layers, highest priority first:

  1. Generator hint — color-free markers a generator emits on a specific feature (e.g. "this part is filled"). The symbol color picks the hue, not the generator.
  2. measure.style — the per-measure style attached to a ControlMeasure.
  3. graphicsStyle — a facade-level default passed at render time.
ts
import { renderControlMeasure } from "@orbat-mapper/control-measures";

const render = renderControlMeasure(
  {
    id: "block-1",
    kind: "block",
    controlPoints,
    style: { color: "#c1121f", strokeWidth: 2 }, // layer 2
  },
  {
    graphicsStyle: { color: "#1d3557" }, // layer 3 — only used if layer 2 omits color
  },
);

Each emitted feature gets a resolved properties.style with concrete strokeColor / fillColor — color is never emitted on output.

Exporting to simplestyle-spec ​

If your consumer reads the simplestyle-spec (stroke, fill, stroke-width, …) instead of a nested style object — geojson.io and most GeoJSON viewers — run the render through toSimpleStyle:

ts
import { renderControlMeasure, toSimpleStyle } from "@orbat-mapper/control-measures";

const simple = toSimpleStyle(renderControlMeasure(measure));
// features now carry flat `stroke`, `fill`, `stroke-width`, `*-opacity` keys.

This is lossy: strokeDash has no simplestyle equivalent (dashed lines render solid), and colors must be hex or rgb()/rgba() — other forms are omitted.

Engine styling

When you draw and edit on a live map with TacticalDraw, the engine adapter renders these same resolved styles. The library stays the single source of truth for what a control measure looks like.