Skip to content

spatial-monorepo


spatial-monorepo / editor/src / EditorController

Class: EditorController

Defined in: packages/editor/src/EditorController.ts:61

EditorController — manages editor modes, feature CRUD, and patch-based undo/redo. Terra Draw integration is optional; the controller manages its own feature store.

Constructors

Constructor

new EditorController(map, options?): EditorController

Defined in: packages/editor/src/EditorController.ts:86

Parameters

map

any

options?

EditorControllerOptions

Returns

EditorController

Accessors

hasPendingPaste

Get Signature

get hasPendingPaste(): boolean

Defined in: packages/editor/src/EditorController.ts:558

Returns

boolean

Methods

addFeature()

addFeature(feature): string

Defined in: packages/editor/src/EditorController.ts:348

Parameters

feature

Feature

Returns

string


applyOffset()

applyOffset(geometry, offset): void

Defined in: packages/editor/src/EditorController.ts:889

Parameters

geometry

Geometry

offset

[number, number]

Returns

void


applyPatches()

applyPatches(patches): void

Defined in: packages/editor/src/EditorController.ts:725

Parameters

patches

JsonPatch[]

Returns

void


beginBatch()

beginBatch(): void

Defined in: packages/editor/src/EditorController.ts:659

Marks the start of a batch operation. All mutations until commitBatch() or rollbackBatch() are buffered and will be committed as a single undo entry. Supports nesting via internal depth counter.

Returns

void


cancelPaste()

cancelPaste(): void

Defined in: packages/editor/src/EditorController.ts:566

Returns

void


canRedo()

canRedo(): boolean

Defined in: packages/editor/src/EditorController.ts:685

Returns

boolean


canUndo()

canUndo(): boolean

Defined in: packages/editor/src/EditorController.ts:681

Returns

boolean


clearClipboard()

clearClipboard(): void

Defined in: packages/editor/src/EditorController.ts:646

Returns

void


commitBatch()

commitBatch(): void

Defined in: packages/editor/src/EditorController.ts:666

Commits all buffered patches as a single undo entry when the outermost batch ends.

Returns

void


confirmPaste()

confirmPaste(): void

Defined in: packages/editor/src/EditorController.ts:562

Returns

void


continueWall()

continueWall(point): void

Defined in: packages/editor/src/EditorController.ts:431

Extends the in-progress wall with another point.

Parameters

point

[number, number]

Returns

void


copyFeatures()

copyFeatures(ids): void

Defined in: packages/editor/src/EditorController.ts:506

Copies the features identified by ids into the internal clipboard. Deep-clones each feature; new IDs are assigned on paste, not here.

Parameters

ids

string[]

Returns

void


copyToBuilding()

copyToBuilding(featureIds, targetBuildingId, targetFloorId, options?): Feature`<Geometry, GeoJsonProperties>`[]

Defined in: packages/editor/src/EditorController.ts:623

Copies featureIds into targetBuildingId/targetFloorId, applying the composite transform H_dst ∘ H_src^{-1} to every coordinate so meter-space geometry re-projects to the destination building's lat/lon frame.

Both homography matrices are 9-element row-major arrays (H[8] = 1). All copies are a single undo entry.

Parameters

featureIds

string[]

targetBuildingId

string

targetFloorId

string

options?
carry?

"geometry" | "geometry+metadata" | "geometry+metadata+sensorBindings"

conflict?

"replace" | "merge" | "skip" | "offset"

dstHomography?

number[]

idRemap?

Record`<string, string>`

srcHomography?

number[]

Returns

Feature`<Geometry, GeoJsonProperties>`[]


copyToFloors()

copyToFloors(featureIds, targetFloorIds, options?): Feature`<Geometry, GeoJsonProperties>`[]

Defined in: packages/editor/src/EditorController.ts:598

Copies the features identified by featureIds to each of the targetFloorIds, producing featureIds.length × targetFloorIds.length new features.

Each copy receives:

  • a fresh UUID (or a stable per-floor id when options.conflict is set — see below)
  • properties.floorId set to the target floor
  • optional IMDF ID rebinding via options.idRemap (applied to room_id and unit_id)
  • optional carry filtering via options.carry (same semantics as pasteFeatures/copyToBuilding)

options.conflict (default: undefined → always create a fresh copy, no conflict check) mirrors pasteFeatures, but is scoped per (source feature, target floor) rather than to the source feature's own id — so a repeated copyToFloors call for the same feature/floor pair can skip/replace/merge into its own prior copy without ever touching the original feature. Never carried by the return of the first, no-conflict call.

All additions are committed as a single undo entry. Original features are untouched.

Parameters

featureIds

string[]

IDs of features to copy (missing IDs are silently skipped).

targetFloorIds

string[]

Floor IDs to copy into.

options?
carry?

"geometry" | "geometry+metadata" | "geometry+metadata+sensorBindings"

conflict?

"replace" | "merge" | "skip" | "offset"

idRemap?

Record`<string, string>`

Map of source IMDF room/unit IDs to target IDs.

offsetMeters?

number

Returns

Feature`<Geometry, GeoJsonProperties>`[]

Array of newly created feature copies (in order: feature0→floor0, feature0→floor1, …).


cutFeatures()

cutFeatures(ids): void

Defined in: packages/editor/src/EditorController.ts:514

Same as copyFeatures but also removes the originals from the store, pushing a single batched undo entry covering all removals.

Parameters

ids

string[]

Returns

void


deleteSelected()

deleteSelected(selection): void

Defined in: packages/editor/src/EditorController.ts:489

Removes all features whose ids appear in selection as a single batched undo entry (so Cmd+Z restores all deleted features at once).

Parameters

selection

Set`<string>`

Returns

void


destroy()

destroy(): void

Defined in: packages/editor/src/EditorController.ts:701

Returns

void


finishWall()

finishWall(): { openingCandidates: Feature`<Geometry, GeoJsonProperties>[]; wall: Feature; \} \| null`

Defined in: packages/editor/src/EditorController.ts:442

Commits the in-progress wall as a LineString feature and creates a paired Opening candidate Point at each endpoint (PRD F16). All three features are committed as a single undo entry so Cmd+Z removes the wall and its candidates.

Returns null if no wall is in progress or fewer than 2 points collected.

Returns

{ openingCandidates: Feature`<Geometry, GeoJsonProperties>[]; wall: Feature; \} \| null`


getClipboard()

getClipboard(): Feature`<Geometry, GeoJsonProperties>`[]

Defined in: packages/editor/src/EditorController.ts:642

Returns a deep clone of the clipboard contents so callers cannot mutate the internal clipboard.

Returns

Feature`<Geometry, GeoJsonProperties>`[]


getFeature()

getFeature(id): Feature`<Geometry, GeoJsonProperties>\|undefined`

Defined in: packages/editor/src/EditorController.ts:873

Parameters

id

string

Returns

Feature`<Geometry, GeoJsonProperties>\|undefined`


getFeatures()

getFeatures(): Feature`<Geometry, GeoJsonProperties>`[]

Defined in: packages/editor/src/EditorController.ts:344

Returns

Feature`<Geometry, GeoJsonProperties>`[]


getFeaturesInsideLasso()

getFeaturesInsideLasso(lassoRing): string[]

Defined in: packages/editor/src/EditorController.ts:477

Returns the IDs of all features whose bounding-box centres lie inside the given polygon ring (lasso). Used by lasso multi-select mode. lassoRing should be a closed ring of [lng, lat] pairs.

Parameters

lassoRing

[number, number][]

Returns

string[]


getMode()

getMode(): EditorMode

Defined in: packages/editor/src/EditorController.ts:291

Returns

EditorMode


getSnapping()

getSnapping(): boolean

Defined in: packages/editor/src/EditorController.ts:303

Returns

boolean


hasFeature()

hasFeature(id): boolean

Defined in: packages/editor/src/EditorController.ts:877

Parameters

id

string

Returns

boolean


isExplodedView()

isExplodedView(): boolean

Defined in: packages/editor/src/EditorController.ts:336

Returns the current exploded-view state.

Returns

boolean


isReadOnly()

isReadOnly(): boolean

Defined in: packages/editor/src/EditorController.ts:315

Returns

boolean


pasteFeatures()

pasteFeatures(options?): Feature`<Geometry, GeoJsonProperties>`[]

Defined in: packages/editor/src/EditorController.ts:536

Creates new features from the clipboard, assigns fresh UUIDs (or preserves source IDs for conflict resolution), applies optional carry/conflict/offset semantics and/or target floor/building assignment, and pushes a single batched undo entry for all additions.

carry (default: 'geometry+metadata+sensorBindings'):

  • 'geometry' — strip all properties, keep only geometry
  • 'geometry+metadata' — keep all properties except sensorBindings
  • 'geometry+metadata+sensorBindings'— keep everything (legacy default)

conflict (default: undefined → always assign new UUID, never conflict-check):

  • 'skip' — if a feature with the same source id already exists, skip it
  • 'replace' — overwrite the existing feature with the clipboard copy
  • 'merge' — deep-merge properties; incoming wins on key collision; geometry from incoming
  • 'offset' — assign a new UUID and shift geometry by offsetMeters (default 0.5)

The clipboard is NOT cleared after paste.

Parameters

options?
carry?

"geometry" | "geometry+metadata" | "geometry+metadata+sensorBindings"

confirm?

boolean

When true, auto-confirms this paste immediately — pasted features never carry properties.pending and are never added to the pending-paste set. Used by programmatic paste paths (e.g. copyToFloor) that never call confirmPaste(), so the flag can't leak forever (issue #442).

conflict?

"replace" | "merge" | "skip" | "offset"

offset?

[number, number]

offsetMeters?

number

targetBuildingId?

string

targetFloorId?

string

Returns

Feature`<Geometry, GeoJsonProperties>`[]


placeDoor()

placeDoor(point, options?): Feature

Defined in: packages/editor/src/EditorController.ts:453

Places a door as a Point feature at point with optional width and angle.

Parameters

point

[number, number]

options?
angle?

number

width?

number

Returns

Feature


placeFixture()

placeFixture(point, options?): Feature

Defined in: packages/editor/src/EditorController.ts:464

Places a fixture as a Point feature at point with optional type and label.

Parameters

point

[number, number]

options?
label?

string

type?

string

Returns

Feature


recordUndoEntry()

recordUndoEntry(entry, forwardPatch, reversePatch): void

Defined in: packages/editor/src/EditorController.ts:885

Parameters

entry

UndoEntry

forwardPatch

JsonPatch

reversePatch

JsonPatch

Returns

void


redo()

redo(): void

Defined in: packages/editor/src/EditorController.ts:693

Returns

void


removeFeature()

removeFeature(id): void

Defined in: packages/editor/src/EditorController.ts:362

Parameters

id

string

Returns

void


reprojectGeometry()

reprojectGeometry(geometry, srcH, dstH): void

Defined in: packages/editor/src/EditorController.ts:893

Parameters

geometry

Geometry

srcH

number[]

dstH

number[]

Returns

void


rollbackBatch()

rollbackBatch(): void

Defined in: packages/editor/src/EditorController.ts:673

Reverts all changes since the outermost beginBatch() without pushing to the undo stack.

Returns

void


setFeatureDirect()

setFeatureDirect(id, feature): void

Defined in: packages/editor/src/EditorController.ts:881

Parameters

id

string

feature

Feature

Returns

void


setFeatureType()

setFeatureType(id, featureType): void

Defined in: packages/editor/src/EditorController.ts:412

Sets (or clears, when featureType is undefined) a feature's properties.featureType tag — the same convention DrawingTools hardcodes at creation time for wall/door/fixture (issue #427), made available here as a standalone, undoable retag for features created through a plain Terra Draw mode (e.g. linestring) instead of a dedicated drawing-tool method.

Minimal authoring path for issue #478's path-network override: draw a corridor centerline in linestring mode (a standard Terra Draw mode, unchanged), then call setFeatureType(id, 'path-network') — e.g. from a layer-panel button (see SpatialEditor's layer panel) — to mark it as an authored routable network for @diginestai/wayfinding's path-network engine. No-op if id doesn't exist. Thin wrapper over updateFeature, so it is a single undo entry like any other feature edit.

Parameters

id

string

featureType

string | undefined

Returns

void


setMap()

setMap(map): void

Defined in: packages/editor/src/EditorController.ts:116

(Re)attaches the controller to a MapLibre map instance.

SpatialEditor constructs its EditorController once (via a lazy ref) so accumulated features/undo history survive re-renders, but the map itself may not exist yet at that point — a map prop can arrive later, or useSpatialMap()'s context value flips from null to the real instance only after the underlying <SpatialMap>'s load event fires. setMap lets the map be supplied (or swapped) after construction without losing any editor state: it only tears down and rebuilds the map-bound pieces (Terra Draw + the click/dblclick listeners), never _features or the undo stack.

No-ops if map is already the currently-attached map instance.

Parameters

map

any

Returns

void


setMode()

setMode(mode): void

Defined in: packages/editor/src/EditorController.ts:267

Parameters

mode

EditorMode

Returns

void


setReadOnly()

setReadOnly(readOnly): void

Defined in: packages/editor/src/EditorController.ts:311

Parameters

readOnly

boolean

Returns

void


setSnapping()

setSnapping(enabled): void

Defined in: packages/editor/src/EditorController.ts:299

Parameters

enabled

boolean

Returns

void


startWall()

startWall(point): void

Defined in: packages/editor/src/EditorController.ts:424

Begins a new wall LineString. If point is within 0.5 metres (haversine great-circle distance over lng/lat) of an existing wall feature endpoint, snaps to that endpoint.

Parameters

point

[number, number]

Returns

void


toggleExplodedView()

toggleExplodedView(): void

Defined in: packages/editor/src/EditorController.ts:328

Toggles the exploded-view state (floors spread vs. stacked). Raises a custom DOM event diginest:exploded-view-changed on document so the map shell can respond without tight coupling.

Returns

void


undo()

undo(): void

Defined in: packages/editor/src/EditorController.ts:689

Returns

void


updateFeature()

updateFeature(id, updates): void

Defined in: packages/editor/src/EditorController.ts:374

Parameters

id

string

updates

Partial`<GeoJSON.Feature>`

Returns

void

Released under commercial licensing.