@zwishing/emap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/LICENSE +373 -0
- package/README.md +294 -0
- package/SECURITY.md +56 -0
- package/dist/adapter/mapshaper-adapter.d.ts +282 -0
- package/dist/core/drag-pan-handler.d.ts +28 -0
- package/dist/core/events.d.ts +16 -0
- package/dist/core/interactions.d.ts +20 -0
- package/dist/core/mapshaper-worker-pool.d.ts +151 -0
- package/dist/core/tween.d.ts +26 -0
- package/dist/edit/commands/composite.d.ts +16 -0
- package/dist/edit/commands/dataset-replace.d.ts +43 -0
- package/dist/edit/commands/feature-affine.d.ts +72 -0
- package/dist/edit/commands/feature-create.d.ts +47 -0
- package/dist/edit/commands/feature-delete.d.ts +72 -0
- package/dist/edit/commands/feature-property-change.d.ts +34 -0
- package/dist/edit/commands/feature-translate.d.ts +55 -0
- package/dist/edit/commands/field-add.d.ts +24 -0
- package/dist/edit/commands/field-remove.d.ts +20 -0
- package/dist/edit/commands/field-rename.d.ts +19 -0
- package/dist/edit/commands/split-shared-arcs.d.ts +71 -0
- package/dist/edit/commands/vertex-delete.d.ts +26 -0
- package/dist/edit/commands/vertex-insert.d.ts +26 -0
- package/dist/edit/commands/vertex-move.d.ts +45 -0
- package/dist/edit/edit-command.d.ts +72 -0
- package/dist/edit/edit-history.d.ts +130 -0
- package/dist/edit/transaction.d.ts +59 -0
- package/dist/emap-worker.js +1 -0
- package/dist/emap.css +157 -0
- package/dist/emap.js +5 -0
- package/dist/emap.mjs +5 -0
- package/dist/geo/bounds.d.ts +18 -0
- package/dist/geo/crs-resolver.d.ts +35 -0
- package/dist/geo/projection.d.ts +28 -0
- package/dist/geo/transform.d.ts +19 -0
- package/dist/geo/viewport.d.ts +52 -0
- package/dist/index.d.ts +86 -0
- package/dist/map/attribute-ops.d.ts +61 -0
- package/dist/map/command-args.d.ts +28 -0
- package/dist/map/edit-sessions.d.ts +97 -0
- package/dist/map/edit-state-store.d.ts +41 -0
- package/dist/map/emap-host.d.ts +79 -0
- package/dist/map/feature-accessor.d.ts +43 -0
- package/dist/map/feature-query.d.ts +58 -0
- package/dist/map/highlight-manager.d.ts +17 -0
- package/dist/map/layer-registry.d.ts +33 -0
- package/dist/map/layer.d.ts +29 -0
- package/dist/map/map.d.ts +386 -0
- package/dist/map/mapshaper-ops.d.ts +56 -0
- package/dist/map/op-result.d.ts +46 -0
- package/dist/map/ops/_context.d.ts +41 -0
- package/dist/map/ops/_runner.d.ts +55 -0
- package/dist/map/ops/affine.d.ts +4 -0
- package/dist/map/ops/buffer.d.ts +4 -0
- package/dist/map/ops/check-geometry.d.ts +4 -0
- package/dist/map/ops/clean.d.ts +4 -0
- package/dist/map/ops/clip-erase.d.ts +5 -0
- package/dist/map/ops/data-fill.d.ts +4 -0
- package/dist/map/ops/dissolve.d.ts +20 -0
- package/dist/map/ops/divide.d.ts +4 -0
- package/dist/map/ops/drop-layer.d.ts +4 -0
- package/dist/map/ops/each-filter.d.ts +5 -0
- package/dist/map/ops/explode.d.ts +4 -0
- package/dist/map/ops/filter-fields.d.ts +4 -0
- package/dist/map/ops/filter-geom.d.ts +4 -0
- package/dist/map/ops/filter-islands.d.ts +4 -0
- package/dist/map/ops/filter-slivers.d.ts +4 -0
- package/dist/map/ops/innerlines.d.ts +4 -0
- package/dist/map/ops/intersection-points.d.ts +4 -0
- package/dist/map/ops/join-table.d.ts +4 -0
- package/dist/map/ops/lines.d.ts +4 -0
- package/dist/map/ops/merge-layers.d.ts +4 -0
- package/dist/map/ops/mosaic.d.ts +4 -0
- package/dist/map/ops/points.d.ts +4 -0
- package/dist/map/ops/polygons.d.ts +4 -0
- package/dist/map/ops/project.d.ts +4 -0
- package/dist/map/ops/rebuild-topology.d.ts +4 -0
- package/dist/map/ops/rename-fields.d.ts +4 -0
- package/dist/map/ops/rename-layer.d.ts +4 -0
- package/dist/map/ops/simplify.d.ts +4 -0
- package/dist/map/ops/snap.d.ts +4 -0
- package/dist/map/ops/sort-features.d.ts +4 -0
- package/dist/map/ops/split-layer.d.ts +4 -0
- package/dist/map/ops/union.d.ts +4 -0
- package/dist/map/ops/unique-features.d.ts +4 -0
- package/dist/map/selection.d.ts +73 -0
- package/dist/map/types.d.ts +1072 -0
- package/dist/map/worker-routing.d.ts +40 -0
- package/dist/mapshaper-vendor.js +1 -0
- package/dist/renderer/canvas-painter.d.ts +50 -0
- package/dist/renderer/edit-overlay-renderer.d.ts +22 -0
- package/dist/renderer/painter.d.ts +52 -0
- package/dist/shim.d.ts +1 -0
- package/dist/source/display-arcs.d.ts +49 -0
- package/dist/source/layer-utils.d.ts +12 -0
- package/dist/source/mapshaper-runner.d.ts +22 -0
- package/dist/source/source.d.ts +80 -0
- package/dist/source/topology-source.d.ts +145 -0
- package/dist/types/mapshaper-types.d.ts +182 -0
- package/dist/ui/basemap-control.d.ts +35 -0
- package/dist/ui/box-select-control.d.ts +67 -0
- package/dist/ui/control.d.ts +6 -0
- package/dist/ui/draw-feature-control.d.ts +82 -0
- package/dist/ui/edit-toolbar.d.ts +27 -0
- package/dist/ui/history-control.d.ts +29 -0
- package/dist/ui/lasso-select-control.d.ts +96 -0
- package/dist/ui/navigation-control.d.ts +16 -0
- package/dist/ui/simplify-control.d.ts +40 -0
- package/dist/ui/status-control.d.ts +23 -0
- package/dist/ui/vertex-edit-control.d.ts +111 -0
- package/dist/validation/builtin/topology.d.ts +19 -0
- package/dist/validation/registry.d.ts +23 -0
- package/dist/validation/validator.d.ts +47 -0
- package/package.json +90 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CorePainter } from '../renderer/painter';
|
|
2
|
+
import { AffineTransform } from '../geo/transform';
|
|
3
|
+
import { TopologySource } from '../source/source';
|
|
4
|
+
import type { HighlightStyle, HighlightFeatureRef, QueriedFeature } from './map';
|
|
5
|
+
/**
|
|
6
|
+
* Manages feature highlighting state and rendering.
|
|
7
|
+
* Extracted from Emap to isolate highlight concerns.
|
|
8
|
+
*/
|
|
9
|
+
export declare class HighlightManager {
|
|
10
|
+
private _highlighted;
|
|
11
|
+
private _highlightStyle;
|
|
12
|
+
get size(): number;
|
|
13
|
+
setHighlightedFeatures(features: Array<QueriedFeature | HighlightFeatureRef>, style?: HighlightStyle): void;
|
|
14
|
+
clearHighlightedFeatures(): boolean;
|
|
15
|
+
setHighlightStyle(style: HighlightStyle): boolean;
|
|
16
|
+
renderHighlights(painter: CorePainter, sources: globalThis.Map<string, TopologySource>, transform: AffineTransform, lineScale: number, visibleLayers?: Set<string>): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TopologySource } from '../source/source';
|
|
2
|
+
import type { MapshaperLayer } from '../types/mapshaper-types';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve `layerId` against an ad-hoc layer list. Callable as a free
|
|
5
|
+
* function so ops that take a dataset snapshot (and don't have a host
|
|
6
|
+
* reference) can share the same matching rule. Use {@link LayerRegistry.resolve}
|
|
7
|
+
* when you have a `(sourceId, layerId)` tuple instead.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveLayerInList(layers: ReadonlyArray<MapshaperLayer>, layerId: string): MapshaperLayer | null;
|
|
10
|
+
export declare class LayerRegistry {
|
|
11
|
+
private readonly _sources;
|
|
12
|
+
constructor(_sources: globalThis.Map<string, TopologySource>);
|
|
13
|
+
/**
|
|
14
|
+
* Resolve `(sourceId, layerId)` to the underlying MapshaperLayer, or
|
|
15
|
+
* `null` when neither the source nor any layer name/id match.
|
|
16
|
+
*
|
|
17
|
+
* `layerId` is matched in this priority order:
|
|
18
|
+
* 1. The canonical id from `getLayerId(layer, idx)` — i.e. layer.name,
|
|
19
|
+
* then layer.id, then the positional `'layer-N'` fallback.
|
|
20
|
+
* 2. `layer.name` (exact match).
|
|
21
|
+
* 3. `layer.id` (exact match).
|
|
22
|
+
*
|
|
23
|
+
* Returns the FIRST hit; in a well-formed dataset every layer's
|
|
24
|
+
* `getLayerId` is unique so the priority list is theoretical.
|
|
25
|
+
*/
|
|
26
|
+
resolve(sourceId: string, layerId: string): MapshaperLayer | null;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a layer id against an ad-hoc layer list — used by ops that
|
|
29
|
+
* snapshot the dataset before a mapshaper command runs (the source's
|
|
30
|
+
* registered dataset has already advanced).
|
|
31
|
+
*/
|
|
32
|
+
resolveInLayers(layers: ReadonlyArray<MapshaperLayer>, layerId: string): MapshaperLayer | null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StrokeStyle, PointStyle } from '../types/mapshaper-types';
|
|
2
|
+
export type LayerType = 'fill' | 'line' | 'circle';
|
|
3
|
+
export interface FillPaint {
|
|
4
|
+
'fill-color'?: string;
|
|
5
|
+
'fill-opacity'?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface LinePaint {
|
|
8
|
+
'line-color'?: string;
|
|
9
|
+
'line-width'?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface CirclePaint {
|
|
12
|
+
'circle-color'?: string;
|
|
13
|
+
'circle-radius'?: number;
|
|
14
|
+
'circle-fill'?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export type LayerPaint = FillPaint | LinePaint | CirclePaint;
|
|
17
|
+
export interface LayerLayout {
|
|
18
|
+
visibility?: 'visible' | 'none';
|
|
19
|
+
}
|
|
20
|
+
export interface LayerSpecification {
|
|
21
|
+
id: string;
|
|
22
|
+
type: LayerType;
|
|
23
|
+
source: string;
|
|
24
|
+
'source-layer'?: string;
|
|
25
|
+
paint?: LayerPaint;
|
|
26
|
+
layout?: LayerLayout;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveStrokeStyle(paint: LinePaint | FillPaint | undefined, lineScale: number): StrokeStyle;
|
|
29
|
+
export declare function resolvePointStyle(paint: CirclePaint | undefined): PointStyle;
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { EventDispatcher } from '../core/events';
|
|
2
|
+
import { Bounds } from '../geo/bounds';
|
|
3
|
+
import { AffineTransform } from '../geo/transform';
|
|
4
|
+
import { Painter } from '../renderer/painter';
|
|
5
|
+
import { MapshaperOps } from './mapshaper-ops';
|
|
6
|
+
import { EditSessions } from './edit-sessions';
|
|
7
|
+
import { AttributeOps } from './attribute-ops';
|
|
8
|
+
import { type EditMode } from './edit-state-store';
|
|
9
|
+
import { LayerRegistry } from './layer-registry';
|
|
10
|
+
import { TopologySource } from '../source/source';
|
|
11
|
+
import { MapshaperWorkerPool } from '../core/mapshaper-worker-pool';
|
|
12
|
+
import { FeatureAccessor } from './feature-accessor';
|
|
13
|
+
import { ValidatorRegistry } from '../validation/registry';
|
|
14
|
+
import { Selection, SelectMode, SelectionDiff } from './selection';
|
|
15
|
+
import { EditHistory } from '../edit/edit-history';
|
|
16
|
+
import type { EditCommand } from '../edit/edit-command';
|
|
17
|
+
import { Transaction, type TransactionInternal } from '../edit/transaction';
|
|
18
|
+
import { Control, ControlPosition } from '../ui/control';
|
|
19
|
+
import type { LayerSpecification } from './layer';
|
|
20
|
+
import type { MapshaperLayer } from '../types/mapshaper-types';
|
|
21
|
+
export * from './types';
|
|
22
|
+
import { type ExpressionEvaluationPolicy, type MapOptions, type QueryFeaturesOptions, type QueriedFeature, type FeatureRef, type HighlightFeatureRef, type ExportSnapshotOptions, type LoadSnapshotOptions, type HighlightStyle, type EditVertexState, type EditDrawState } from './types';
|
|
23
|
+
export declare class Emap extends EventDispatcher {
|
|
24
|
+
private _container;
|
|
25
|
+
private _canvasContainer;
|
|
26
|
+
private _canvas;
|
|
27
|
+
private _painter;
|
|
28
|
+
private _editOverlay;
|
|
29
|
+
private _viewport;
|
|
30
|
+
private _projection;
|
|
31
|
+
_sources: globalThis.Map<string, TopologySource>;
|
|
32
|
+
/**
|
|
33
|
+
* Single resolution surface for `(sourceId, layerId) → MapshaperLayer`.
|
|
34
|
+
* Exposed to managers via `EmapHostInternal.layers`. Reads `_sources`
|
|
35
|
+
* lazily so it stays in sync with `addSource`/`removeSource` without
|
|
36
|
+
* needing its own listener. Constructed on first access so test paths
|
|
37
|
+
* that bypass the constructor via `Object.create(Emap.prototype)` still
|
|
38
|
+
* see a working registry once they `setPrivate(map, '_sources', ...)`.
|
|
39
|
+
*/
|
|
40
|
+
private _layersCache?;
|
|
41
|
+
get layers(): LayerRegistry;
|
|
42
|
+
private _sourceListeners;
|
|
43
|
+
private _layers;
|
|
44
|
+
private _effectiveLayersCache;
|
|
45
|
+
private _defaultLayersDirty;
|
|
46
|
+
private _layerArcFlagsCache;
|
|
47
|
+
private _mouseWheel;
|
|
48
|
+
private _dragPan;
|
|
49
|
+
private _pendingRender;
|
|
50
|
+
private _rafId;
|
|
51
|
+
private _controlContainers;
|
|
52
|
+
private _controls;
|
|
53
|
+
private _highlightManager;
|
|
54
|
+
private _featureQuery;
|
|
55
|
+
/**
|
|
56
|
+
* Read-side feature accessor — `engine.features.get(ref)` returns one
|
|
57
|
+
* feature's geometry + frozen properties; `iter(sourceId, layerId)`
|
|
58
|
+
* walks a layer; `count(...)` is O(1). Constructed lazily in the
|
|
59
|
+
* Emap constructor so test paths that bypass it via
|
|
60
|
+
* `Object.create(Emap.prototype)` still see a working accessor once
|
|
61
|
+
* they wire up the host.
|
|
62
|
+
*/
|
|
63
|
+
features: FeatureAccessor;
|
|
64
|
+
_selection: Selection;
|
|
65
|
+
_history: EditHistory;
|
|
66
|
+
/**
|
|
67
|
+
* Currently active transaction, or `null`. Mutated by
|
|
68
|
+
* `Transaction`'s constructor / commit / rollback. Exposed via the
|
|
69
|
+
* `EmapHostInternal` contract so the runner can record per-source
|
|
70
|
+
* snapshots without threading a transaction param through every op
|
|
71
|
+
* signature.
|
|
72
|
+
*/
|
|
73
|
+
_activeTransaction: TransactionInternal | null;
|
|
74
|
+
/**
|
|
75
|
+
* Post-commit validator registry. Validators registered here run
|
|
76
|
+
* after every `historychange` event; failures surface via
|
|
77
|
+
* `validationfailed` (no auto-undo — apps decide how to react).
|
|
78
|
+
*
|
|
79
|
+
* Public-facing alias is `engine.validators` (see initialiser below).
|
|
80
|
+
*/
|
|
81
|
+
readonly _validators: ValidatorRegistry;
|
|
82
|
+
/** Public alias for the validator registry. */
|
|
83
|
+
get validators(): ValidatorRegistry;
|
|
84
|
+
private _historyShortcutUnbind;
|
|
85
|
+
private _ops?;
|
|
86
|
+
private _editSession?;
|
|
87
|
+
private _attributes?;
|
|
88
|
+
/** Mapshaper layer ops (clip / dissolve / buffer / project / ...). */
|
|
89
|
+
get ops(): MapshaperOps;
|
|
90
|
+
/** Selection editing (translate / rotate / scale + live drag sessions). */
|
|
91
|
+
get editSession(): EditSessions;
|
|
92
|
+
/** Per-feature property and per-layer field editing. */
|
|
93
|
+
get attributes(): AttributeOps;
|
|
94
|
+
private _editState;
|
|
95
|
+
_workerPool: MapshaperWorkerPool | null;
|
|
96
|
+
_workerMode: boolean | 'auto';
|
|
97
|
+
_workerThreshold: number;
|
|
98
|
+
/**
|
|
99
|
+
* Optional caller-supplied routing decision. When set, `_runDatasetCommand`
|
|
100
|
+
* forwards every command-info bundle to it and uses the boolean result
|
|
101
|
+
* verbatim. Pass `MapOptions.workerRouting` to install one. Read by
|
|
102
|
+
* `MapshaperOps` via the host.
|
|
103
|
+
*/
|
|
104
|
+
_workerRouting?: import('./worker-routing').WorkerRoutingFn;
|
|
105
|
+
private _expressionPolicy;
|
|
106
|
+
constructor(options: MapOptions);
|
|
107
|
+
/**
|
|
108
|
+
* Hard-cancel any in-flight worker jobs. Safe to call when no worker
|
|
109
|
+
* pool exists (no-op). The pool stays usable — subsequent dataset-replace
|
|
110
|
+
* ops re-spawn a fresh worker.
|
|
111
|
+
*
|
|
112
|
+
* mapshaper isn't interruptible mid-command, so this is the only sound
|
|
113
|
+
* abandonment path: terminate the worker, lose any other queued jobs as
|
|
114
|
+
* collateral, and let the next op start over.
|
|
115
|
+
*/
|
|
116
|
+
cancelWorkerJobs(): void;
|
|
117
|
+
setExpressionPolicy(policy: ExpressionEvaluationPolicy): void;
|
|
118
|
+
getExpressionPolicy(): ExpressionEvaluationPolicy;
|
|
119
|
+
_allowExpressionEvaluation(values: Array<string | undefined>, operation: string): boolean;
|
|
120
|
+
getCanvasContainer(): HTMLElement;
|
|
121
|
+
getEditMode(): EditMode;
|
|
122
|
+
setEditMode(mode: EditMode): void;
|
|
123
|
+
setEditVertexState(state: EditVertexState): void;
|
|
124
|
+
clearEditVertexState(): void;
|
|
125
|
+
setEditDrawState(state: EditDrawState): void;
|
|
126
|
+
clearEditDrawState(): void;
|
|
127
|
+
private _attachEventListeners;
|
|
128
|
+
private _createCanvasContainer;
|
|
129
|
+
private _updateSize;
|
|
130
|
+
addSource(id: string, source: TopologySource): void;
|
|
131
|
+
removeSource(id: string): void;
|
|
132
|
+
getSource(id: string): TopologySource | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Pack every topology source on this map into one `.msx` snapshot Blob via
|
|
135
|
+
* mapshaper's session pack pipeline. Source IDs are preserved in a custom
|
|
136
|
+
* `emap.sources` field on the packed object so {@link loadSnapshot} can
|
|
137
|
+
* re-register sources under their original IDs.
|
|
138
|
+
*
|
|
139
|
+
* Sources that have no dataset yet (load not completed) are skipped.
|
|
140
|
+
*
|
|
141
|
+
* The output file is a valid mapshaper `.msx` — vanilla mapshaper will
|
|
142
|
+
* load it (just dropping the `emap` metadata).
|
|
143
|
+
*/
|
|
144
|
+
exportSnapshot(opts?: ExportSnapshotOptions): Promise<Blob>;
|
|
145
|
+
/**
|
|
146
|
+
* Restore one or more topology sources from a `.msx` snapshot via
|
|
147
|
+
* mapshaper's session unpack pipeline. Returns the list of registered
|
|
148
|
+
* source IDs in registration order.
|
|
149
|
+
*
|
|
150
|
+
* ID resolution priority (per restored dataset, in order):
|
|
151
|
+
* 1. `opts.idPrefix` + ID from snapshot's `emap.sources[i].id` (if metadata present)
|
|
152
|
+
* 2. `opts.idPrefix` + `opts.defaultIds[i]` (if supplied)
|
|
153
|
+
* 3. `opts.idPrefix` + `snapshot-<i>` fallback
|
|
154
|
+
*
|
|
155
|
+
* On ID collision: `replace: true` (default) removes the existing source
|
|
156
|
+
* first; `replace: false` rejects without registering anything.
|
|
157
|
+
*
|
|
158
|
+
* Edit history and selection are cleared because feature IDs in the
|
|
159
|
+
* replayed history would point to features that no longer exist after
|
|
160
|
+
* dataset replacement. Same semantics as the dataset-replace family
|
|
161
|
+
* (clip, dissolve, mosaic, ...).
|
|
162
|
+
*/
|
|
163
|
+
loadSnapshot(input: Blob | Uint8Array | ArrayBuffer, opts?: LoadSnapshotOptions): Promise<string[]>;
|
|
164
|
+
addLayer(layer: LayerSpecification, before?: string): void;
|
|
165
|
+
removeLayer(id: string): void;
|
|
166
|
+
getLayer(id: string): LayerSpecification | undefined;
|
|
167
|
+
getLayers(): LayerSpecification[];
|
|
168
|
+
setLayerVisibility(id: string, visibility: 'visible' | 'none'): void;
|
|
169
|
+
setPaintProperty(id: string, name: string, value: unknown): void;
|
|
170
|
+
moveLayer(id: string, beforeId?: string): void;
|
|
171
|
+
private _getEffectiveLayers;
|
|
172
|
+
private _resolveSourceLayer;
|
|
173
|
+
/**
|
|
174
|
+
* Generates a boolean flag array for arcs that belong to a specific source layer.
|
|
175
|
+
* Cached to prevent walking shapes on every frame.
|
|
176
|
+
*
|
|
177
|
+
* Only meaningful for path layers (polygon/polyline). Point layers have no
|
|
178
|
+
* arc references, so iterating their shapes contributes nothing — caller
|
|
179
|
+
* should filter by `isPathLayer` before invoking.
|
|
180
|
+
*/
|
|
181
|
+
private _getLayerArcFlags;
|
|
182
|
+
private _getVisibleLayerKeys;
|
|
183
|
+
getPainter(): Painter;
|
|
184
|
+
getCRS(): string;
|
|
185
|
+
setCRS(crs: string): void;
|
|
186
|
+
reproject(targetCrs: string): Promise<void>;
|
|
187
|
+
getCenter(): [number, number];
|
|
188
|
+
getZoom(): number;
|
|
189
|
+
getTransform(): AffineTransform;
|
|
190
|
+
getExtent(): Bounds;
|
|
191
|
+
setExtent(bounds: Bounds): void;
|
|
192
|
+
reset(): void;
|
|
193
|
+
addControl(control: Control, position?: ControlPosition): void;
|
|
194
|
+
removeControl(control: Control): void;
|
|
195
|
+
zoomIn(): void;
|
|
196
|
+
zoomOut(): void;
|
|
197
|
+
_scheduleRender(): void;
|
|
198
|
+
private _doRender;
|
|
199
|
+
render(): void;
|
|
200
|
+
private _renderLayers;
|
|
201
|
+
private _renderLineLayer;
|
|
202
|
+
private _renderFillLayer;
|
|
203
|
+
private _combineArcFilters;
|
|
204
|
+
private _renderHighlight;
|
|
205
|
+
project(x: number, y: number): [number, number];
|
|
206
|
+
unproject(px: number, py: number): [number, number];
|
|
207
|
+
resize(): void;
|
|
208
|
+
queryFeatures(geometryOrOptions?: [number, number] | [[number, number], [number, number]] | QueryFeaturesOptions, options?: QueryFeaturesOptions): QueriedFeature[];
|
|
209
|
+
/**
|
|
210
|
+
* Eagerly build the per-layer Flatbush spatial index for one source (or
|
|
211
|
+
* every registered source when `sourceId` is omitted). Useful for paying
|
|
212
|
+
* the build cost in idle time before the user's first hit-test.
|
|
213
|
+
*
|
|
214
|
+
* Idempotent — already-cached layer indexes are skipped. No-op for
|
|
215
|
+
* sources without a dataset.
|
|
216
|
+
*
|
|
217
|
+
* Subsequent `queryFeatures` calls automatically use whatever's
|
|
218
|
+
* cached, regardless of whether `prebuildSpatialIndex` was called.
|
|
219
|
+
*/
|
|
220
|
+
prebuildSpatialIndex(sourceId?: string): void;
|
|
221
|
+
/**
|
|
222
|
+
* Drop cached per-layer spatial indexes for one source (or all sources
|
|
223
|
+
* when `sourceId` is omitted).
|
|
224
|
+
*
|
|
225
|
+
* Required after in-place geometry edits (`translateSelected`,
|
|
226
|
+
* `rotateSelected`, vertex commands) that mutate arc coordinates without
|
|
227
|
+
* changing shape or arc counts — the cache key wouldn't notice and
|
|
228
|
+
* subsequent queries would return prefilter-stale results.
|
|
229
|
+
*
|
|
230
|
+
* Dataset-replace ops (clip / dissolve / etc.) automatically invalidate
|
|
231
|
+
* via shape-count or arc-count change; this method is only needed for
|
|
232
|
+
* in-place edits.
|
|
233
|
+
*/
|
|
234
|
+
clearSpatialIndex(sourceId?: string): void;
|
|
235
|
+
_clearSpatialIndexesForSources(sourceIds: Iterable<string>): void;
|
|
236
|
+
setHighlightedFeatures(features: Array<QueriedFeature | HighlightFeatureRef>, style?: HighlightStyle): void;
|
|
237
|
+
clearHighlightedFeatures(): void;
|
|
238
|
+
setHighlightStyle(style: HighlightStyle): void;
|
|
239
|
+
/**
|
|
240
|
+
* Mutate the persistent feature selection.
|
|
241
|
+
*
|
|
242
|
+
* @param features Refs to apply. `QueriedFeature` is structurally
|
|
243
|
+
* compatible with `FeatureRef`, so results from `queryFeatures` can
|
|
244
|
+
* be passed directly.
|
|
245
|
+
* @param options.mode `'replace'` (default) wipes prior contents,
|
|
246
|
+
* `'add'` unions, `'toggle'` flips membership.
|
|
247
|
+
*
|
|
248
|
+
* Fires a `selectionchange` event with `{ selected, added, removed }` only
|
|
249
|
+
* when the set actually changes.
|
|
250
|
+
*/
|
|
251
|
+
select(features: ReadonlyArray<FeatureRef>, options?: {
|
|
252
|
+
mode?: SelectMode;
|
|
253
|
+
}): void;
|
|
254
|
+
/** Remove the listed features from the selection. No-op if absent. */
|
|
255
|
+
deselect(features: ReadonlyArray<FeatureRef>): void;
|
|
256
|
+
/** Empty the selection. No-op (and no event) if it was already empty. */
|
|
257
|
+
clearSelection(): void;
|
|
258
|
+
/** Snapshot of the current selection as a flat list of refs. */
|
|
259
|
+
getSelection(): FeatureRef[];
|
|
260
|
+
/** Test whether a single feature is currently selected. */
|
|
261
|
+
isSelected(feature: FeatureRef): boolean;
|
|
262
|
+
_fireSelectionChange(diff: SelectionDiff): void;
|
|
263
|
+
/**
|
|
264
|
+
* Delete every currently-selected feature in one undoable history step.
|
|
265
|
+
*
|
|
266
|
+
* Returns `true` when at least one feature was deleted, `false` when the
|
|
267
|
+
* selection was empty (in which case nothing is pushed and no events fire).
|
|
268
|
+
*
|
|
269
|
+
* Implementation matches mapshaper's `deleteFeature` / `insertFeature`
|
|
270
|
+
* pair: shape + data record are spliced out (and back in on undo). Within
|
|
271
|
+
* each layer, deletes proceed in descending-id order so each delete's
|
|
272
|
+
* index stays valid; a single Ctrl+Z reverses the entire batch.
|
|
273
|
+
*
|
|
274
|
+
* The selection is cleared on success — the deleted refs no longer exist.
|
|
275
|
+
*/
|
|
276
|
+
deleteSelected(): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Drop derived caches (line-layer arc flags + spatial index) for the given
|
|
279
|
+
* sources. Call after any edit that mutates `layer.shapes` so subsequent
|
|
280
|
+
* frames and `queryFeatures` calls don't reference stale features.
|
|
281
|
+
*/
|
|
282
|
+
_invalidateShapeCachesForSources(sourceIds: Iterable<string>): void;
|
|
283
|
+
/**
|
|
284
|
+
* Push an executed `EditCommand` onto the undo stack.
|
|
285
|
+
*
|
|
286
|
+
* Per the memento pattern, the caller is expected to have already performed
|
|
287
|
+
* the work; the command captures what changed so the operation can be
|
|
288
|
+
* reversed on undo. `pushCommand` does NOT call `cmd.do()`. It clears any
|
|
289
|
+
* pending redo entries and fires `historychange`.
|
|
290
|
+
*/
|
|
291
|
+
pushCommand(cmd: EditCommand): void;
|
|
292
|
+
/**
|
|
293
|
+
* Reverse the most recent command. No-op when there is nothing to undo.
|
|
294
|
+
* Fires `historychange` and schedules a re-render after the reversal.
|
|
295
|
+
*/
|
|
296
|
+
undo(): boolean;
|
|
297
|
+
/**
|
|
298
|
+
* Re-apply the most recently undone command. No-op when there is nothing
|
|
299
|
+
* to redo. Fires `historychange` and schedules a re-render.
|
|
300
|
+
*/
|
|
301
|
+
redo(): boolean;
|
|
302
|
+
/** Drop every shape-derived cache. Used by undo/redo where per-source
|
|
303
|
+
* invalidation isn't tracked. */
|
|
304
|
+
private _invalidateAllShapeCaches;
|
|
305
|
+
canUndo(): boolean;
|
|
306
|
+
canRedo(): boolean;
|
|
307
|
+
/** Empty both undo and redo stacks. Fires `historychange` if non-empty. */
|
|
308
|
+
clearHistory(): void;
|
|
309
|
+
/**
|
|
310
|
+
* Begin an atomic multi-step edit. Every op or edit command pushed
|
|
311
|
+
* during the returned transaction's lifetime is staged; on
|
|
312
|
+
* `commit(label)` they collapse into a single undo entry, on
|
|
313
|
+
* `rollback()` every touched source's dataset is restored to its
|
|
314
|
+
* pre-transaction state and the selection is reverted.
|
|
315
|
+
*
|
|
316
|
+
* Throws if a transaction is already active — nesting isn't supported.
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* const tx = engine.beginTransaction();
|
|
320
|
+
* const r1 = await engine.ops.clipLayer({ source, target, mask });
|
|
321
|
+
* if (!r1.ok) { tx.rollback(); return; }
|
|
322
|
+
* const r2 = await engine.ops.dissolveLayer({ source, target, field: 'STATE' });
|
|
323
|
+
* if (!r2.ok) { tx.rollback(); return; }
|
|
324
|
+
* await tx.commit('Process boundaries');
|
|
325
|
+
*/
|
|
326
|
+
beginTransaction(): Transaction;
|
|
327
|
+
/**
|
|
328
|
+
* Bind Ctrl/Cmd+Z (undo) and Ctrl/Cmd+Shift+Z / Ctrl+Y (redo) on the given
|
|
329
|
+
* element (default: the canvas container). Returns an unbind function. Calls
|
|
330
|
+
* to this method are idempotent — subsequent calls unbind the prior binding.
|
|
331
|
+
*/
|
|
332
|
+
bindHistoryShortcuts(target?: HTMLElement): () => void;
|
|
333
|
+
_fireHistoryChange(): void;
|
|
334
|
+
/**
|
|
335
|
+
* Internal — fan out every `'after-commit'` validator and fire
|
|
336
|
+
* `validationfailed` for the subset whose report is `!ok`. Skipped
|
|
337
|
+
* cheaply when no validators are registered (no microtask, no
|
|
338
|
+
* allocations).
|
|
339
|
+
*
|
|
340
|
+
* Ignored when the host has been removed mid-flight; the validator
|
|
341
|
+
* may have started against a dataset that's no longer the current
|
|
342
|
+
* one but its result is irrelevant once the host is gone.
|
|
343
|
+
*/
|
|
344
|
+
private _runAfterCommitValidators;
|
|
345
|
+
/**
|
|
346
|
+
* Clip a layer to the polygons in a mask layer using mapshaper's `-clip`
|
|
347
|
+
* pipeline. Target and mask must live in the same source. Returns `true`
|
|
348
|
+
* on success, `false` for unresolvable source / target / mask.
|
|
349
|
+
*
|
|
350
|
+
* The operation is recorded as a single undoable history entry. Note that
|
|
351
|
+
* dataset-replace operations clear prior fine-grained edit history (see
|
|
352
|
+
* design.md for the rationale).
|
|
353
|
+
*/
|
|
354
|
+
/**
|
|
355
|
+
* Translate every selected feature by `(dx, dy)` in source-data coordinates.
|
|
356
|
+
* Returns `false` for an empty selection or zero offset.
|
|
357
|
+
*
|
|
358
|
+
* Lightweight in-place mutation — does not replace the dataset, does not
|
|
359
|
+
* clear the selection, composes freely with other commands in one undo
|
|
360
|
+
* timeline. For multi-source selections, one `FeatureTranslateCommand` is
|
|
361
|
+
* built per source and they are wrapped in a single `CompositeCommand` so
|
|
362
|
+
* one undo reverses the whole nudge.
|
|
363
|
+
*
|
|
364
|
+
* Known limitation: arcs shared with unselected features will be translated
|
|
365
|
+
* along with the selection, distorting the unselected neighbours. Safe for
|
|
366
|
+
* isolated features and contiguous polygon subsets; documented in the spec.
|
|
367
|
+
*/
|
|
368
|
+
/**
|
|
369
|
+
* @deprecated Prefer `emap.layers.resolve(sourceId, layerId)`. Kept as a
|
|
370
|
+
* thin shim while the composed managers migrate over.
|
|
371
|
+
*/
|
|
372
|
+
_resolveLayer(sourceId: string, layerId: string): MapshaperLayer | null;
|
|
373
|
+
/**
|
|
374
|
+
* Tear the map down: cancel pending renders, detach every `data` listener
|
|
375
|
+
* we attached to sources, release each registered control, kill the worker
|
|
376
|
+
* pool, and unmount the canvas. Idempotent — calling it twice is safe.
|
|
377
|
+
*
|
|
378
|
+
* After `remove()` the instance must not be reused. Public methods that
|
|
379
|
+
* touch DOM / timers are left in place for now (they will fail naturally
|
|
380
|
+
* when the underlying resources are gone), but `_scheduleRender` is
|
|
381
|
+
* guarded so post-teardown event firings don't queue another frame.
|
|
382
|
+
*/
|
|
383
|
+
remove(): void;
|
|
384
|
+
/** Read by composed managers via `EmapHostInternal._removed`. */
|
|
385
|
+
_removed: boolean;
|
|
386
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { EmapHostInternal } from './emap-host';
|
|
2
|
+
import type { OpResult } from './op-result';
|
|
3
|
+
import type { AffineLayerOptions, ApplyExpressionOptions, BufferOptions, CleanOptions, CheckGeometryOptions, ClipEraseOptions, DataFillOptions, DivideOptions, DropLayerOptions, DissolveOptions, ExplodeOptions, FilterFieldsOptions, FilterGeomOptions, FilterIslandsOptions, FilterOptions, FilterSliversOptions, GeometryCheckReport, InnerlinesOptions, IntersectionPointsLayerOptions, JoinTableOptions, LinesOptions, MergeLayersOptions, MosaicOptions, PointsOptions, PolygonsOptions, ProjectOptions, RebuildTopologyOptions, RenameFieldsOptions, RenameLayerOptions, SimplifyOptions, SnapOptions, SortFeaturesOptions, SplitLayerOptions, UniqueFeaturesOptions, UnionOptions } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Mapshaper command manager. Owned by Emap and exposed as `emap.ops`.
|
|
6
|
+
* Every method delegates straight to the corresponding free function
|
|
7
|
+
* under `src/map/ops/`. Construction takes the host; the per-call
|
|
8
|
+
* `OpContext` is rebuilt on each access of `_ctx` so test paths that
|
|
9
|
+
* substitute the manager via `Object.create(MapshaperOps.prototype)`
|
|
10
|
+
* still see a working context once they wire up the host.
|
|
11
|
+
*/
|
|
12
|
+
export declare class MapshaperOps {
|
|
13
|
+
private _emap;
|
|
14
|
+
constructor(_emap: EmapHostInternal);
|
|
15
|
+
/**
|
|
16
|
+
* Lazily-built `OpContext` handed to every op function. Recomputed
|
|
17
|
+
* on every call so nothing captures a stale `this`.
|
|
18
|
+
*/
|
|
19
|
+
private get _ctx();
|
|
20
|
+
clipLayer(opts: ClipEraseOptions): Promise<OpResult>;
|
|
21
|
+
eraseLayer(opts: ClipEraseOptions): Promise<OpResult>;
|
|
22
|
+
dissolveLayer(opts: DissolveOptions): Promise<OpResult>;
|
|
23
|
+
bufferLayer(opts: BufferOptions): Promise<OpResult>;
|
|
24
|
+
applyExpression(opts: ApplyExpressionOptions): Promise<OpResult>;
|
|
25
|
+
filterFeatures(opts: FilterOptions): Promise<OpResult>;
|
|
26
|
+
filterIslands(opts: FilterIslandsOptions): Promise<OpResult>;
|
|
27
|
+
filterSlivers(opts: FilterSliversOptions): Promise<OpResult>;
|
|
28
|
+
filterGeom(opts: FilterGeomOptions): Promise<OpResult>;
|
|
29
|
+
explodeLayer(opts: ExplodeOptions): Promise<OpResult>;
|
|
30
|
+
innerlinesLayer(opts: InnerlinesOptions): Promise<OpResult>;
|
|
31
|
+
snapLayer(opts: SnapOptions): Promise<OpResult>;
|
|
32
|
+
cleanLayer(opts: CleanOptions): Promise<OpResult>;
|
|
33
|
+
mosaicLayer(opts: MosaicOptions): Promise<OpResult>;
|
|
34
|
+
unionLayers(opts: UnionOptions): Promise<OpResult>;
|
|
35
|
+
divideLayer(opts: DivideOptions): Promise<OpResult>;
|
|
36
|
+
pointsLayer(opts: PointsOptions): Promise<OpResult>;
|
|
37
|
+
linesLayer(opts: LinesOptions): Promise<OpResult>;
|
|
38
|
+
polygonsLayer(opts: PolygonsOptions): Promise<OpResult>;
|
|
39
|
+
simplifyLayer(opts: SimplifyOptions): Promise<OpResult>;
|
|
40
|
+
projectLayer(opts: ProjectOptions): Promise<OpResult>;
|
|
41
|
+
affineLayer(opts: AffineLayerOptions): Promise<OpResult>;
|
|
42
|
+
renameLayer(opts: RenameLayerOptions): Promise<OpResult>;
|
|
43
|
+
mergeLayers(opts: MergeLayersOptions): Promise<OpResult>;
|
|
44
|
+
splitLayer(opts: SplitLayerOptions): Promise<OpResult>;
|
|
45
|
+
dropLayer(opts: DropLayerOptions): Promise<OpResult>;
|
|
46
|
+
sortFeatures(opts: SortFeaturesOptions): Promise<OpResult>;
|
|
47
|
+
uniqueFeatures(opts: UniqueFeaturesOptions): Promise<OpResult>;
|
|
48
|
+
filterFields(opts: FilterFieldsOptions): Promise<OpResult>;
|
|
49
|
+
renameFields(opts: RenameFieldsOptions): Promise<OpResult>;
|
|
50
|
+
joinTable(opts: JoinTableOptions): Promise<OpResult>;
|
|
51
|
+
dataFill(opts: DataFillOptions): Promise<OpResult>;
|
|
52
|
+
rebuildTopology(opts: RebuildTopologyOptions): Promise<OpResult>;
|
|
53
|
+
checkGeometry(opts: CheckGeometryOptions): Promise<OpResult<GeometryCheckReport>>;
|
|
54
|
+
intersectionPointsLayer(opts: IntersectionPointsLayerOptions): Promise<OpResult>;
|
|
55
|
+
mergeSelected(): Promise<OpResult>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Categories of failure surfaced by `MapshaperOps` methods. */
|
|
2
|
+
export type OpError = {
|
|
3
|
+
kind: 'not-found';
|
|
4
|
+
what: 'source' | 'layer' | 'mask' | 'divider' | 'field';
|
|
5
|
+
id: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'validation';
|
|
8
|
+
field: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'expression-disabled';
|
|
12
|
+
operation: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'mapshaper';
|
|
15
|
+
cause: unknown;
|
|
16
|
+
cmd?: string;
|
|
17
|
+
operation?: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'host-removed';
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Sum type returned by every op. `ok: true` carries an optional `value`
|
|
23
|
+
* (most ops have nothing to return; some — like `checkGeometry` — carry
|
|
24
|
+
* a report); `ok: false` carries the structured `error`.
|
|
25
|
+
*/
|
|
26
|
+
export type OpResult<T = void> = {
|
|
27
|
+
ok: true;
|
|
28
|
+
value: T;
|
|
29
|
+
} | {
|
|
30
|
+
ok: false;
|
|
31
|
+
error: OpError;
|
|
32
|
+
};
|
|
33
|
+
/** Singleton "successful, no payload" result. Cheap to return. */
|
|
34
|
+
export declare const OK: OpResult<void>;
|
|
35
|
+
/** Build a successful result with a payload value. */
|
|
36
|
+
export declare function okValue<T>(value: T): OpResult<T>;
|
|
37
|
+
export declare const Err: Readonly<{
|
|
38
|
+
notFound(what: "source" | "layer" | "mask" | "divider" | "field", id: string): OpResult<never>;
|
|
39
|
+
validation(field: string, reason: string): OpResult<never>;
|
|
40
|
+
expressionDisabled(operation: string): OpResult<never>;
|
|
41
|
+
mapshaper(cause: unknown, opts?: {
|
|
42
|
+
cmd?: string;
|
|
43
|
+
operation?: string;
|
|
44
|
+
}): OpResult<never>;
|
|
45
|
+
hostRemoved(): OpResult<never>;
|
|
46
|
+
}>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { EmapHostInternal } from '../emap-host';
|
|
2
|
+
import type { MapshaperDataset } from '../../types/mapshaper-types';
|
|
3
|
+
import type { OpResult } from '../op-result';
|
|
4
|
+
import type { ParsedCommand } from '../../adapter/mapshaper-adapter';
|
|
5
|
+
/**
|
|
6
|
+
* Run a CLI-style mapshaper command against a source's dataset, snapshotting
|
|
7
|
+
* for undo and pushing a `DatasetReplaceCommand`. Provided to ops via the
|
|
8
|
+
* `OpContext` rather than as a method on a class so unit tests can mock the
|
|
9
|
+
* whole pipeline by injecting a stub function.
|
|
10
|
+
*/
|
|
11
|
+
export type RunDatasetCommand = (sourceId: string, cmd: string, label: string, inputFiles?: Record<string, Uint8Array | string>) => Promise<OpResult>;
|
|
12
|
+
/**
|
|
13
|
+
* PR-4b parsed-command runner. Same dataset-replace pipeline as
|
|
14
|
+
* {@link RunDatasetCommand} but accepts pre-built `ParsedCommand[]`. New
|
|
15
|
+
* ops should prefer this — it skips the CLI parser, eliminating an entire
|
|
16
|
+
* class of escaping bugs.
|
|
17
|
+
*/
|
|
18
|
+
export type RunDatasetCommandParsed = (sourceId: string, commands: ParsedCommand[], label: string, inputFiles?: Record<string, Uint8Array | string>) => Promise<OpResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Worker-only path used by `intersectionPointsLayer` / `rebuildTopology`
|
|
21
|
+
* which bypass `parseCommands` and call mapshaper internals directly to
|
|
22
|
+
* produce the `after` dataset. Centralised here so the dataset-replace
|
|
23
|
+
* bookkeeping (history barrier flag, selection clear, render schedule)
|
|
24
|
+
* stays consistent across every op that produces an `after` snapshot.
|
|
25
|
+
*/
|
|
26
|
+
export type ApplyDatasetReplace = (sourceId: string, before: MapshaperDataset, after: MapshaperDataset, label: string) => OpResult;
|
|
27
|
+
/**
|
|
28
|
+
* Everything an op function needs from the host. Intentionally narrow —
|
|
29
|
+
* adding new fields here is a deliberate signal that the op surface is
|
|
30
|
+
* growing.
|
|
31
|
+
*/
|
|
32
|
+
export interface OpContext {
|
|
33
|
+
/** Internal host surface (sources, history, selection, worker config…). */
|
|
34
|
+
host: EmapHostInternal;
|
|
35
|
+
/** Shared CLI-command runner; see {@link RunDatasetCommand}. */
|
|
36
|
+
runDatasetCommand: RunDatasetCommand;
|
|
37
|
+
/** Parsed-command runner (PR-4b); see {@link RunDatasetCommandParsed}. */
|
|
38
|
+
runDatasetCommandParsed: RunDatasetCommandParsed;
|
|
39
|
+
/** Direct dataset-replace path; see {@link ApplyDatasetReplace}. */
|
|
40
|
+
applyDatasetReplace: ApplyDatasetReplace;
|
|
41
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { MapshaperDataset } from '../../types/mapshaper-types';
|
|
2
|
+
import type { EmapHostInternal } from '../emap-host';
|
|
3
|
+
import { type OpResult } from '../op-result';
|
|
4
|
+
import { type ParsedCommand } from '../../adapter/mapshaper-adapter';
|
|
5
|
+
/**
|
|
6
|
+
* What a dataset-replace op CHANGES about the dataset. Drives the
|
|
7
|
+
* selection-preservation policy in `_applyDatasetReplace`:
|
|
8
|
+
*
|
|
9
|
+
* - `shape-count` — features added / removed / reordered. Selection
|
|
10
|
+
* refs by feature id are stale; clear.
|
|
11
|
+
* - `topology-only` — arc storage rebuilt (clean / snap / simplify /
|
|
12
|
+
* rebuildTopology / mosaic). Feature ids may
|
|
13
|
+
* shift; clear conservatively.
|
|
14
|
+
* - `attribute-only` — only data-table fields changed (each / join /
|
|
15
|
+
* rename-fields / filter-fields / sort / etc.).
|
|
16
|
+
* Feature ids stay; preserve selection.
|
|
17
|
+
* - `crs-only` — coords reprojected, ids unchanged. Preserve.
|
|
18
|
+
* - `unknown` — no information — fall back to clearing for
|
|
19
|
+
* safety. Treated identically to `shape-count`.
|
|
20
|
+
*/
|
|
21
|
+
export type OpEffect = 'shape-count' | 'topology-only' | 'attribute-only' | 'crs-only' | 'unknown';
|
|
22
|
+
/**
|
|
23
|
+
* Infer the effect category of a CLI command. Considers every `-NAME`
|
|
24
|
+
* head in the command string and returns the **strongest** effect (in
|
|
25
|
+
* the order `shape-count` > `topology-only` > `crs-only` > `attribute-only`).
|
|
26
|
+
* `target` (a no-op selector head) is ignored.
|
|
27
|
+
*/
|
|
28
|
+
export declare function inferEffect(cmd: string): OpEffect;
|
|
29
|
+
/**
|
|
30
|
+
* Same as {@link inferEffect} but consuming a pre-extracted heads array.
|
|
31
|
+
* Used by the parsed-command runner so we don't reconstruct then re-parse
|
|
32
|
+
* a CLI string just to classify the effect.
|
|
33
|
+
*/
|
|
34
|
+
export declare function inferEffectForHeads(heads: string[]): OpEffect;
|
|
35
|
+
export declare function _runDatasetCommand(host: EmapHostInternal, sourceId: string, cmd: string, label: string, inputFiles?: Record<string, Uint8Array | string>): Promise<OpResult>;
|
|
36
|
+
/**
|
|
37
|
+
* PR-4b parsed-command path. Same dataset-replace pipeline as
|
|
38
|
+
* {@link _runDatasetCommand} but consumes a pre-built `ParsedCommand[]`
|
|
39
|
+
* instead of a CLI string. Eliminates the escape/re-parse round-trip
|
|
40
|
+
* and the class of bugs that come with it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function _runDatasetCommandParsed(host: EmapHostInternal, sourceId: string, commands: ParsedCommand[], label: string, inputFiles?: Record<string, Uint8Array | string>): Promise<OpResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Stage C in isolation: swap the source dataset, push the
|
|
45
|
+
* DatasetReplaceCommand (which flags prior commands stale), conditionally
|
|
46
|
+
* clear selection (PR-10 — depends on `effect`), schedule a render. Used
|
|
47
|
+
* directly by ops that produce an `after` dataset via mapshaper internal
|
|
48
|
+
* primitives instead of the CLI runner — `intersectionPointsLayer`,
|
|
49
|
+
* `rebuildTopology`.
|
|
50
|
+
*
|
|
51
|
+
* `effect` defaults to `'unknown'` (= clear selection) for safety. Ops
|
|
52
|
+
* that know they only changed attributes / CRS should pass the more
|
|
53
|
+
* specific value so the UI's selection survives the operation.
|
|
54
|
+
*/
|
|
55
|
+
export declare function _applyDatasetReplace(host: EmapHostInternal, sourceId: string, before: MapshaperDataset, after: MapshaperDataset, label: string, effect?: OpEffect): OpResult;
|