@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +373 -0
  3. package/README.md +294 -0
  4. package/SECURITY.md +56 -0
  5. package/dist/adapter/mapshaper-adapter.d.ts +282 -0
  6. package/dist/core/drag-pan-handler.d.ts +28 -0
  7. package/dist/core/events.d.ts +16 -0
  8. package/dist/core/interactions.d.ts +20 -0
  9. package/dist/core/mapshaper-worker-pool.d.ts +151 -0
  10. package/dist/core/tween.d.ts +26 -0
  11. package/dist/edit/commands/composite.d.ts +16 -0
  12. package/dist/edit/commands/dataset-replace.d.ts +43 -0
  13. package/dist/edit/commands/feature-affine.d.ts +72 -0
  14. package/dist/edit/commands/feature-create.d.ts +47 -0
  15. package/dist/edit/commands/feature-delete.d.ts +72 -0
  16. package/dist/edit/commands/feature-property-change.d.ts +34 -0
  17. package/dist/edit/commands/feature-translate.d.ts +55 -0
  18. package/dist/edit/commands/field-add.d.ts +24 -0
  19. package/dist/edit/commands/field-remove.d.ts +20 -0
  20. package/dist/edit/commands/field-rename.d.ts +19 -0
  21. package/dist/edit/commands/split-shared-arcs.d.ts +71 -0
  22. package/dist/edit/commands/vertex-delete.d.ts +26 -0
  23. package/dist/edit/commands/vertex-insert.d.ts +26 -0
  24. package/dist/edit/commands/vertex-move.d.ts +45 -0
  25. package/dist/edit/edit-command.d.ts +72 -0
  26. package/dist/edit/edit-history.d.ts +130 -0
  27. package/dist/edit/transaction.d.ts +59 -0
  28. package/dist/emap-worker.js +1 -0
  29. package/dist/emap.css +157 -0
  30. package/dist/emap.js +5 -0
  31. package/dist/emap.mjs +5 -0
  32. package/dist/geo/bounds.d.ts +18 -0
  33. package/dist/geo/crs-resolver.d.ts +35 -0
  34. package/dist/geo/projection.d.ts +28 -0
  35. package/dist/geo/transform.d.ts +19 -0
  36. package/dist/geo/viewport.d.ts +52 -0
  37. package/dist/index.d.ts +86 -0
  38. package/dist/map/attribute-ops.d.ts +61 -0
  39. package/dist/map/command-args.d.ts +28 -0
  40. package/dist/map/edit-sessions.d.ts +97 -0
  41. package/dist/map/edit-state-store.d.ts +41 -0
  42. package/dist/map/emap-host.d.ts +79 -0
  43. package/dist/map/feature-accessor.d.ts +43 -0
  44. package/dist/map/feature-query.d.ts +58 -0
  45. package/dist/map/highlight-manager.d.ts +17 -0
  46. package/dist/map/layer-registry.d.ts +33 -0
  47. package/dist/map/layer.d.ts +29 -0
  48. package/dist/map/map.d.ts +386 -0
  49. package/dist/map/mapshaper-ops.d.ts +56 -0
  50. package/dist/map/op-result.d.ts +46 -0
  51. package/dist/map/ops/_context.d.ts +41 -0
  52. package/dist/map/ops/_runner.d.ts +55 -0
  53. package/dist/map/ops/affine.d.ts +4 -0
  54. package/dist/map/ops/buffer.d.ts +4 -0
  55. package/dist/map/ops/check-geometry.d.ts +4 -0
  56. package/dist/map/ops/clean.d.ts +4 -0
  57. package/dist/map/ops/clip-erase.d.ts +5 -0
  58. package/dist/map/ops/data-fill.d.ts +4 -0
  59. package/dist/map/ops/dissolve.d.ts +20 -0
  60. package/dist/map/ops/divide.d.ts +4 -0
  61. package/dist/map/ops/drop-layer.d.ts +4 -0
  62. package/dist/map/ops/each-filter.d.ts +5 -0
  63. package/dist/map/ops/explode.d.ts +4 -0
  64. package/dist/map/ops/filter-fields.d.ts +4 -0
  65. package/dist/map/ops/filter-geom.d.ts +4 -0
  66. package/dist/map/ops/filter-islands.d.ts +4 -0
  67. package/dist/map/ops/filter-slivers.d.ts +4 -0
  68. package/dist/map/ops/innerlines.d.ts +4 -0
  69. package/dist/map/ops/intersection-points.d.ts +4 -0
  70. package/dist/map/ops/join-table.d.ts +4 -0
  71. package/dist/map/ops/lines.d.ts +4 -0
  72. package/dist/map/ops/merge-layers.d.ts +4 -0
  73. package/dist/map/ops/mosaic.d.ts +4 -0
  74. package/dist/map/ops/points.d.ts +4 -0
  75. package/dist/map/ops/polygons.d.ts +4 -0
  76. package/dist/map/ops/project.d.ts +4 -0
  77. package/dist/map/ops/rebuild-topology.d.ts +4 -0
  78. package/dist/map/ops/rename-fields.d.ts +4 -0
  79. package/dist/map/ops/rename-layer.d.ts +4 -0
  80. package/dist/map/ops/simplify.d.ts +4 -0
  81. package/dist/map/ops/snap.d.ts +4 -0
  82. package/dist/map/ops/sort-features.d.ts +4 -0
  83. package/dist/map/ops/split-layer.d.ts +4 -0
  84. package/dist/map/ops/union.d.ts +4 -0
  85. package/dist/map/ops/unique-features.d.ts +4 -0
  86. package/dist/map/selection.d.ts +73 -0
  87. package/dist/map/types.d.ts +1072 -0
  88. package/dist/map/worker-routing.d.ts +40 -0
  89. package/dist/mapshaper-vendor.js +1 -0
  90. package/dist/renderer/canvas-painter.d.ts +50 -0
  91. package/dist/renderer/edit-overlay-renderer.d.ts +22 -0
  92. package/dist/renderer/painter.d.ts +52 -0
  93. package/dist/shim.d.ts +1 -0
  94. package/dist/source/display-arcs.d.ts +49 -0
  95. package/dist/source/layer-utils.d.ts +12 -0
  96. package/dist/source/mapshaper-runner.d.ts +22 -0
  97. package/dist/source/source.d.ts +80 -0
  98. package/dist/source/topology-source.d.ts +145 -0
  99. package/dist/types/mapshaper-types.d.ts +182 -0
  100. package/dist/ui/basemap-control.d.ts +35 -0
  101. package/dist/ui/box-select-control.d.ts +67 -0
  102. package/dist/ui/control.d.ts +6 -0
  103. package/dist/ui/draw-feature-control.d.ts +82 -0
  104. package/dist/ui/edit-toolbar.d.ts +27 -0
  105. package/dist/ui/history-control.d.ts +29 -0
  106. package/dist/ui/lasso-select-control.d.ts +96 -0
  107. package/dist/ui/navigation-control.d.ts +16 -0
  108. package/dist/ui/simplify-control.d.ts +40 -0
  109. package/dist/ui/status-control.d.ts +23 -0
  110. package/dist/ui/vertex-edit-control.d.ts +111 -0
  111. package/dist/validation/builtin/topology.d.ts +19 -0
  112. package/dist/validation/registry.d.ts +23 -0
  113. package/dist/validation/validator.d.ts +47 -0
  114. package/package.json +90 -0
@@ -0,0 +1,1072 @@
1
+ import type { MapshaperWorkerPool } from '../core/mapshaper-worker-pool';
2
+ import type { AffineMatrix } from '../edit/commands/feature-affine';
3
+ import type { DrawOverlayState, DrawOverlaySnapKind } from '../renderer/painter';
4
+ export type EditDrawState = DrawOverlayState;
5
+ export type SnapKind = DrawOverlaySnapKind;
6
+ export type ExpressionEvaluationPolicy = 'trusted' | 'disabled';
7
+ export interface MapOptions {
8
+ container: string | HTMLElement;
9
+ interactive?: boolean;
10
+ /**
11
+ * Controls APIs that forward JavaScript expressions to mapshaper
12
+ * (`applyExpression`, `filterFeatures`, `sortFeatures`, `splitLayer`, and
13
+ * command options such as `where` / `calc`).
14
+ *
15
+ * Defaults to `'disabled'` so apps loading untrusted layer config or
16
+ * remote datasets cannot accidentally execute arbitrary JavaScript.
17
+ * Apps that load only their own data may opt in to `'trusted'` here or
18
+ * via {@link Emap.setExpressionPolicy}.
19
+ *
20
+ * BREAKING: prior to this release the default was `'trusted'`.
21
+ */
22
+ expressionPolicy?: ExpressionEvaluationPolicy;
23
+ /**
24
+ * Routing for dataset-replace operations (clip, dissolve, union,
25
+ * mosaic, simplify, project, ...).
26
+ *
27
+ * - `false` (default) — every op runs synchronously on the main thread.
28
+ * - `true` — every op routes through a Web Worker, freeing the main
29
+ * thread during heavy work. Adds ~50-100ms pack/unpack overhead per
30
+ * op so it's a slowdown for tiny datasets.
31
+ * - `'auto'` — route through the worker only when the source dataset's
32
+ * arc vertex count is at least {@link workerThreshold}. Best of both
33
+ * worlds for mixed-size workloads.
34
+ *
35
+ * Selection-level operations (translateSelected, rotateSelected,
36
+ * vertex commands) always run on the main thread regardless of this
37
+ * flag — their per-vertex cost is far below the worker round-trip
38
+ * overhead.
39
+ */
40
+ useWorker?: boolean | 'auto';
41
+ /**
42
+ * Vertex-count threshold for `useWorker: 'auto'`. Datasets whose
43
+ * `arcs.getPointCount()` is at least this large route through the
44
+ * worker; smaller datasets stay on the main thread. Default `50000`.
45
+ * Ignored when `useWorker` is a boolean.
46
+ */
47
+ workerThreshold?: number;
48
+ /**
49
+ * URL of the worker bundle (`emap-worker.js`). Resolved against
50
+ * `document.baseURI` when relative. Only consulted when `useWorker`
51
+ * is truthy. Defaults to `'emap-worker.js'` (sibling of the page).
52
+ */
53
+ workerUrl?: string;
54
+ /**
55
+ * Number of worker threads to maintain. Each adds one mapshaper
56
+ * instance, so peak parallelism = `workerPoolSize`. Default `1`
57
+ * (single-worker, the historical behaviour). Set to e.g.
58
+ * `navigator.hardwareConcurrency - 1` to scale up — useful when
59
+ * the app dispatches multiple independent dataset-replace ops in
60
+ * parallel (one per source). Workers spawn lazily, so a high
61
+ * `workerPoolSize` doesn't pay the spawn cost up-front.
62
+ *
63
+ * Ignored when `workerPool` is supplied (the caller's pool already
64
+ * configures its own size).
65
+ */
66
+ workerPoolSize?: number;
67
+ /**
68
+ * Pre-constructed worker pool. Only consulted when `useWorker` is
69
+ * truthy; takes precedence over `workerUrl` / `workerPoolSize`.
70
+ * Used by tests to inject a mock pool, and by power users who
71
+ * want to share one pool across multiple `Emap` instances.
72
+ */
73
+ workerPool?: MapshaperWorkerPool;
74
+ /**
75
+ * Override the engine's per-call routing decision when `useWorker`
76
+ * is `'auto'`. Receives the parsed command head set, vertex count,
77
+ * and the engine's default decision; return `true` to route through
78
+ * the worker, `false` to keep on the main thread. The default
79
+ * decision tree handles cheap commands (rename-fields / sort / …)
80
+ * and expensive ones (buffer / clean / dissolve / …) but apps with
81
+ * domain knowledge can refine it here. Ignored when `useWorker` is
82
+ * `true` / `false`.
83
+ */
84
+ workerRouting?: import('./worker-routing').WorkerRoutingFn;
85
+ }
86
+ export interface QueryFeaturesOptions {
87
+ layers?: string[];
88
+ }
89
+ export interface QueriedFeature {
90
+ id: number;
91
+ source: string;
92
+ layer: string;
93
+ geometryType: string;
94
+ properties: Record<string, unknown>;
95
+ }
96
+ /** Common options accepted by all selection-drag sessions. */
97
+ export interface DragSessionOptions {
98
+ /**
99
+ * When `true` (default), arcs shared between the selection and any
100
+ * unselected feature are duplicated at session start so the unselected
101
+ * neighbour stays put when the selection moves. The duplication is
102
+ * recorded as one extra command alongside the transform on commit, and
103
+ * is reversed on cancel.
104
+ *
105
+ * Set to `false` to keep mapshaper's classic shared-topology behaviour
106
+ * (the boundary moves and unselected features deform along with it).
107
+ */
108
+ splitSharedArcs?: boolean;
109
+ }
110
+ /**
111
+ * Live "drag" handle for translating the selection without spamming the
112
+ * undo stack. Returned by `Emap.beginTranslateSession`.
113
+ */
114
+ export interface FeatureTranslateSession {
115
+ /** Apply an incremental translate; geometry mutates immediately. No history entry. */
116
+ move(dx: number, dy: number): void;
117
+ /**
118
+ * Push ONE cumulative `FeatureTranslateCommand` (or `CompositeCommand`
119
+ * for multi-source selections) to history and close the session. Returns
120
+ * `false` when the cumulative offset is zero (nothing to record).
121
+ */
122
+ commit(): boolean;
123
+ /** Roll geometry back to the pre-session state and close. No history entry. */
124
+ cancel(): void;
125
+ /** Total `(dx, dy)` applied since the session began. */
126
+ getAccumulated(): [number, number];
127
+ }
128
+ /**
129
+ * Live affine-transform handle (rotate / scale / mixed) returned by
130
+ * `Emap.beginAffineSession`. Same idea as {@link FeatureTranslateSession}:
131
+ * every `applyDelta(matrix)` mutates geometry in place, only `commit()`
132
+ * writes a single history entry built from the cumulative composed matrix.
133
+ */
134
+ export interface FeatureAffineSession {
135
+ /**
136
+ * Pivot picked at session start (selection bbox centroid by default).
137
+ * Callers should build their delta matrices around this point so all
138
+ * frames share a single fixed origin — composing rotations/scales then
139
+ * stays equivalent to a single cumulative transform.
140
+ */
141
+ readonly origin: [number, number];
142
+ /** Apply a delta matrix to the current geometry. Composes onto the cumulative. */
143
+ applyDelta(matrix: AffineMatrix): void;
144
+ /**
145
+ * Push ONE cumulative `FeatureAffineCommand` (or `CompositeCommand`)
146
+ * to history and close. Returns `false` when the cumulative is identity
147
+ * (nothing to record). `label` overrides the auto-generated label.
148
+ */
149
+ commit(label?: string): boolean;
150
+ /** Roll geometry back to the pre-session state and close. No history entry. */
151
+ cancel(): void;
152
+ /** Cumulative composed matrix (a · prev) since the session began. */
153
+ getCumulative(): AffineMatrix;
154
+ }
155
+ export interface FeatureRef {
156
+ id: number;
157
+ source: string;
158
+ layer: string;
159
+ }
160
+ /** @deprecated Use {@link FeatureRef}. Kept as an alias for back-compat. */
161
+ export type HighlightFeatureRef = FeatureRef;
162
+ /**
163
+ * Options for the `Emap.clipLayer` / `Emap.eraseLayer` polygon operations.
164
+ * Both target and mask must reside in the same emap source — cross-source
165
+ * masks require a future explicit merge step.
166
+ */
167
+ export interface ClipEraseOptions {
168
+ /** Source ID containing the target layer (and optionally the mask layer). */
169
+ source: string;
170
+ /** Layer name (or id) of the target to be clipped/erased. */
171
+ target: string;
172
+ /**
173
+ * Layer name (or id) of the polygon mask living in the same source.
174
+ * Mutually exclusive with {@link bbox} — supply exactly one.
175
+ */
176
+ mask?: string;
177
+ /**
178
+ * Rectangular clip / erase region as `[xmin, ymin, xmax, ymax]` in
179
+ * source-data coordinates. Convenient when no full mask layer exists
180
+ * (e.g. crop to viewport, drop everything outside a bounding box).
181
+ * Mutually exclusive with {@link mask}.
182
+ */
183
+ bbox?: [number, number, number, number];
184
+ /**
185
+ * Run mapshaper's `cleanup` step after clip / erase to fix sliver
186
+ * polygons / unclosed rings. Recommended when the mask geometry is
187
+ * coarse or the target has overlapping shapes.
188
+ */
189
+ cleanup?: boolean;
190
+ /**
191
+ * Drop sliver polygons produced by the clip / erase. Implies a
192
+ * post-step similar to `filter-slivers`.
193
+ */
194
+ removeSlivers?: boolean;
195
+ }
196
+ /**
197
+ * Options for `Emap.dissolveLayer`. With no `field` / `fields`, mapshaper
198
+ * merges every feature in the target layer into one. With a grouping key,
199
+ * features sharing that key's value are merged together.
200
+ *
201
+ * `field` is shorthand for the single-field case; `fields` is the
202
+ * multi-field array form. They are mutually exclusive — supplying both
203
+ * is a configuration error and the call returns `false`.
204
+ */
205
+ export interface DissolveOptions {
206
+ /** Source ID containing the target layer. */
207
+ source: string;
208
+ /** Layer name (or id) of the layer to dissolve. */
209
+ target: string;
210
+ /**
211
+ * Optional single attribute field to group features by. Convenience
212
+ * shorthand for `fields: [field]`. Mutually exclusive with `fields`.
213
+ */
214
+ field?: string;
215
+ /**
216
+ * Multi-field group-by. Comma-bearing entries are filtered out (same
217
+ * pattern as `filterFields`). An empty array is treated as if unset.
218
+ */
219
+ fields?: string[];
220
+ /**
221
+ * Fields whose numeric values should be summed across each dissolved
222
+ * group (mapshaper's `sum-fields=` option). Comma-bearing entries are
223
+ * filtered out.
224
+ */
225
+ sumFields?: string[];
226
+ /**
227
+ * Fields whose values should be carried through the dissolve unchanged
228
+ * (mapshaper's `copy-fields=` option). The first feature in each group
229
+ * provides the value. Comma-bearing entries are filtered out.
230
+ */
231
+ copyFields?: string[];
232
+ /**
233
+ * Custom JS aggregation expression evaluated per dissolve group
234
+ * (mapshaper's `calc=` option). Has access to the standard mapshaper
235
+ * aggregation context. Forwarded verbatim, quoted.
236
+ */
237
+ calc?: string;
238
+ /**
239
+ * Pre-filter expression — only records where `where` evaluates truthy
240
+ * are included in the dissolve (mapshaper's `where=` option).
241
+ */
242
+ where?: string;
243
+ /**
244
+ * Make multipart features instead of dissolving polygon boundaries
245
+ * (mapshaper's `multipart` flag).
246
+ */
247
+ multipart?: boolean;
248
+ /** Optional name for the output layer (mapshaper's `name=` option). */
249
+ name?: string;
250
+ /** Keep the original layer alongside the new dissolved output. */
251
+ noReplace?: boolean;
252
+ }
253
+ /** Options for `Emap.bufferLayer`. */
254
+ export interface BufferOptions {
255
+ /** Source ID containing the target layer. */
256
+ source: string;
257
+ /** Layer name (or id) of the layer to buffer. */
258
+ target: string;
259
+ /**
260
+ * Buffer radius. Either a positive finite `number` or a mapshaper
261
+ * expression string (evaluated per record).
262
+ *
263
+ * Unit semantics:
264
+ * - **point** layers — always **metres** (mapshaper does geodetic
265
+ * circles via `getGeodeticSegmentFunction`), unless {@link planar}
266
+ * is `true`, in which case it's source-CRS units.
267
+ * - **polyline / polygon** layers — source-CRS units (degrees for
268
+ * EPSG:4326, metres for a projected CRS).
269
+ */
270
+ radius: number | string;
271
+ /** Buffer cap style. Default is `round`. Mainly affects polyline output. */
272
+ capStyle?: 'flat' | 'round';
273
+ /** Vertices used to approximate a point-buffer circle. Positive integer. */
274
+ vertices?: number;
275
+ /** Segments per quarter-circle in joins and caps. Positive integer. */
276
+ arcQuality?: number;
277
+ /** Curve-approximation tolerance. Positive finite number. */
278
+ tolerance?: number;
279
+ /** Single-sided buffer; meaningful for polyline layers. */
280
+ type?: 'left' | 'right' | 'outer' | 'inner';
281
+ /** Force planar (Cartesian) computation even for lat/lng data. */
282
+ planar?: boolean;
283
+ /** Enable the v2 buffering algorithm. */
284
+ v2?: boolean;
285
+ /** Max path segments per buffer slice. Performance knob. Positive int. */
286
+ sliceLength?: number;
287
+ /** Backtrack distance, mapshaper-internal performance knob. Positive int. */
288
+ backtrack?: number;
289
+ }
290
+ /**
291
+ * Options for `Emap.applyExpression` — bulk attribute updates via
292
+ * mapshaper's `-each` JS expression engine.
293
+ *
294
+ * SECURITY: `expression` and `where` are evaluated as JavaScript by
295
+ * mapshaper (it builds a `Function` per record). Pass only trusted,
296
+ * authoring-time strings — never untrusted end-user input. The same
297
+ * applies to `where` on {@link InnerlinesOptions}, `expression` on
298
+ * {@link FilterOptions}, and any `calc=` / `where=` arg forwarded to a
299
+ * mapshaper command.
300
+ */
301
+ export interface ApplyExpressionOptions {
302
+ /** Source ID containing the target layer. */
303
+ source: string;
304
+ /** Layer name (or id) of the layer to update. */
305
+ target: string;
306
+ /**
307
+ * JS expression evaluated per feature. Use `this.<field>` to read or write
308
+ * record attributes; mapshaper's standard feature context (`this.id`,
309
+ * `this.area`, `this.bounds`, etc.) is also available. Multiple
310
+ * comma-separated assignments are allowed: `this.a = 1, this.b = 2`.
311
+ */
312
+ expression: string;
313
+ /**
314
+ * Optional filter expression. Only records for which `where` evaluates to
315
+ * a truthy value have `expression` applied. Same JS context as
316
+ * `expression`. Mirrors mapshaper CLI's `-each EXPR where=...`.
317
+ */
318
+ where?: string;
319
+ }
320
+ /** Options for `Emap.explodeLayer`. */
321
+ export interface ExplodeOptions {
322
+ /** Source ID containing the target layer. */
323
+ source: string;
324
+ /** Layer name (or id) of the layer whose multi-part features will be split. */
325
+ target: string;
326
+ }
327
+ /** Options for `Emap.innerlinesLayer`. */
328
+ export interface InnerlinesOptions {
329
+ /** Source ID containing the polygon target layer. */
330
+ source: string;
331
+ /** Layer name (or id) of the polygon layer to extract shared edges from. */
332
+ target: string;
333
+ /**
334
+ * Optional polygon-boundary filter expression. Evaluated with `A` and `B`
335
+ * in scope — the two polygons on either side of each candidate boundary —
336
+ * so e.g. `A.STATE !== B.STATE` keeps only inter-state borders. Mirrors
337
+ * mapshaper's `-innerlines where=...`.
338
+ */
339
+ where?: string;
340
+ /** Optional name for the output polyline layer. */
341
+ name?: string;
342
+ /**
343
+ * If true, the original polygon layer is preserved alongside the new
344
+ * polyline layer (mapshaper's `no-replace` flag). Default replaces.
345
+ */
346
+ noReplace?: boolean;
347
+ }
348
+ /** Options for `Emap.filterFeatures`. */
349
+ export interface FilterOptions {
350
+ /** Source ID containing the target layer. */
351
+ source: string;
352
+ /** Layer name (or id) of the layer to filter. */
353
+ target: string;
354
+ /**
355
+ * JS expression evaluated per feature. Records that evaluate to false are
356
+ * deleted (mapshaper convention). Same `this` context as
357
+ * `Emap.applyExpression`: `this.<field>`, `this.id`, etc.
358
+ */
359
+ expression?: string;
360
+ /** Flip the predicate (mapshaper's `invert` flag). */
361
+ invert?: boolean;
362
+ /** Also delete features with null geometry (mapshaper's `remove-empty`). */
363
+ removeEmpty?: boolean;
364
+ }
365
+ /** Options for `Emap.snapLayer`. */
366
+ export interface SnapOptions {
367
+ /** Source ID containing the target layer. */
368
+ source: string;
369
+ /** Layer name (or id) of the layer to snap. */
370
+ target: string;
371
+ /**
372
+ * Snap distance in source-CRS units. When omitted, mapshaper picks a
373
+ * small default based on the dataset.
374
+ */
375
+ interval?: number;
376
+ /** Snap only line endpoints (mapshaper's `endpoints` flag). */
377
+ endpoints?: boolean;
378
+ /** Round all coordinates to a given decimal precision (e.g. 0.000001). */
379
+ precision?: number;
380
+ /**
381
+ * Run a post-snap intersection-cut pass to repair geometry artefacts
382
+ * introduced by rounding / snapping (mapshaper's `fix-geometry` flag).
383
+ * Recommended when `precision` or `interval` aggressively collapse
384
+ * vertices.
385
+ */
386
+ fixGeometry?: boolean;
387
+ }
388
+ /**
389
+ * Options for `Emap.rebuildTopology`. Forwarded into mapshaper's
390
+ * `addIntersectionCuts` (with snake_case key conversion).
391
+ */
392
+ export interface RebuildTopologyOptions {
393
+ /** Source ID whose dataset will be rebuilt. */
394
+ source: string;
395
+ /**
396
+ * Coincident-vertex snap distance in source-CRS units. When omitted,
397
+ * mapshaper auto-detects based on the dataset bounds.
398
+ */
399
+ snapInterval?: number;
400
+ /**
401
+ * Skip the snap pre-pass entirely. Faster, but won't fix near-coincident
402
+ * vertices that should share an arc.
403
+ */
404
+ noSnap?: boolean;
405
+ /**
406
+ * Force a `buildTopology` rerun even when the cut-detection pass found
407
+ * no changes. Useful after pure translates that didn't intersect anything
408
+ * new but still need shared arcs re-derived against neighbours.
409
+ */
410
+ rebuildTopology?: boolean;
411
+ }
412
+ /** Options for `Emap.renameLayer`. */
413
+ export interface RenameLayerOptions {
414
+ /** Source ID containing the target layer. */
415
+ source: string;
416
+ /** Layer name (or id) to rename. */
417
+ target: string;
418
+ /** New layer name. Trimmed; must be non-empty and not collide with another existing layer. */
419
+ name: string;
420
+ }
421
+ /** Options for `Emap.splitLayer`. */
422
+ export interface SplitLayerOptions {
423
+ /** Source ID containing the target layer. */
424
+ source: string;
425
+ /** Layer name (or id) to partition. */
426
+ target: string;
427
+ /**
428
+ * Field name (e.g. `'STATE'`) or JS expression for grouping. mapshaper
429
+ * auto-detects: a bare field reference uses that field's value; otherwise
430
+ * the string is evaluated per feature as JS. Forwarded verbatim.
431
+ */
432
+ expression: string;
433
+ /** Keep the original layer alongside the new split outputs. */
434
+ noReplace?: boolean;
435
+ }
436
+ /** Options for `Emap.dropLayer`. */
437
+ export interface DropLayerOptions {
438
+ /** Source ID containing the layer to delete. */
439
+ source: string;
440
+ /** Layer name (or id) to remove from the source dataset. */
441
+ target: string;
442
+ }
443
+ /** Options for `Emap.sortFeatures`. */
444
+ export interface SortFeaturesOptions {
445
+ /** Source ID containing the target layer. */
446
+ source: string;
447
+ /** Layer name (or id) whose features will be sorted in place. */
448
+ target: string;
449
+ /**
450
+ * JS expression evaluated per feature to produce the sort key. Bare field
451
+ * names (`'POP'`) work because mapshaper exposes record fields as locals.
452
+ */
453
+ expression: string;
454
+ /** Sort descending. Default `false` (ascending). */
455
+ descending?: boolean;
456
+ }
457
+ /** Options for `Emap.uniqueFeatures`. */
458
+ export interface UniqueFeaturesOptions {
459
+ /** Source ID containing the target layer. */
460
+ source: string;
461
+ /** Layer name (or id) to dedupe within. */
462
+ target: string;
463
+ /**
464
+ * JS expression evaluated per feature to produce the dedupe id. Forwarded
465
+ * verbatim (a bare field name like `'STATE_FIPS'` works). For full-record
466
+ * dedupe pass `'JSON.stringify(this.properties)'`.
467
+ */
468
+ expression: string;
469
+ /**
470
+ * Maximum features per id; default `1`. Must be a positive integer when
471
+ * supplied (`> 0`).
472
+ */
473
+ maxCount?: number;
474
+ /** Keep duplicates and drop unique features instead (mapshaper's `invert`). */
475
+ invert?: boolean;
476
+ }
477
+ /** Options for `Emap.filterFields`. */
478
+ export interface FilterFieldsOptions {
479
+ /** Source ID containing the target layer. */
480
+ source: string;
481
+ /** Layer name (or id) whose attribute schema will be slimmed. */
482
+ target: string;
483
+ /**
484
+ * Field names to retain. Each entry must be a non-empty string with no
485
+ * `,` characters. Use `['*']` for "drop all" (mapshaper convention).
486
+ */
487
+ fields: string[];
488
+ /** Drop the listed fields and keep the rest (mapshaper's `invert` flag). */
489
+ invert?: boolean;
490
+ }
491
+ /**
492
+ * Options for `Emap.filterIslands` — drop tiny disconnected polygon
493
+ * parts (e.g. cartographic cleanup of digitisation noise). Wraps
494
+ * mapshaper's `-filter-islands`.
495
+ *
496
+ * Supply at least one of `minArea` / `minVertices` — mapshaper requires
497
+ * a threshold or it's a no-op.
498
+ */
499
+ export interface FilterIslandsOptions {
500
+ /** Source ID containing the target layer. */
501
+ source: string;
502
+ /** Layer name (or id) of the polygon layer to clean. */
503
+ target: string;
504
+ /** Drop islands smaller than this area (source-CRS units²). */
505
+ minArea?: number;
506
+ /** Drop islands with fewer than this many vertices (after dedup). */
507
+ minVertices?: number;
508
+ /**
509
+ * After dropping islands, also drop features whose shape array becomes
510
+ * empty (mapshaper's `remove-empty`). Defaults to keeping empties.
511
+ */
512
+ removeEmpty?: boolean;
513
+ }
514
+ /**
515
+ * Options for `Emap.filterSlivers` — drop sliver polygons (tiny
516
+ * polygons left over from clip / erase / dissolve operations). Wraps
517
+ * mapshaper's `-filter-slivers`.
518
+ */
519
+ export interface FilterSliversOptions {
520
+ /** Source ID containing the target layer. */
521
+ source: string;
522
+ /** Layer name (or id) of the polygon layer to clean. */
523
+ target: string;
524
+ /**
525
+ * Drop polygons whose area falls below this threshold (source-CRS
526
+ * units²). Required — mapshaper has no implicit default.
527
+ */
528
+ minArea: number;
529
+ /**
530
+ * Use a perimeter-weighted area metric (mapshaper's `weighted` flag).
531
+ * Better for elongated slivers where bare area undershoots the
532
+ * "looks like a sliver" intuition.
533
+ */
534
+ weighted?: boolean;
535
+ }
536
+ /**
537
+ * Options for `Emap.filterGeom` — geometric (vs attribute) filter.
538
+ * Currently mapshaper's `-filter-geom` only supports a single bbox
539
+ * predicate, so the option is required. Use `filterFeatures` for
540
+ * attribute predicates (`expression`).
541
+ */
542
+ export interface FilterGeomOptions {
543
+ /** Source ID containing the target layer. */
544
+ source: string;
545
+ /** Layer name (or id) to filter in place. */
546
+ target: string;
547
+ /**
548
+ * Bounding box `[xmin, ymin, xmax, ymax]` in source coords. Features
549
+ * whose geometry intersects this box are kept; the rest are dropped.
550
+ */
551
+ bbox: [number, number, number, number];
552
+ }
553
+ /**
554
+ * Options for `Emap.affineLayer` — apply an affine transform to every
555
+ * vertex in a layer (or the whole dataset if `target` is omitted).
556
+ * Wraps mapshaper's `-affine`.
557
+ *
558
+ * Distinct from `editSession.beginAffineSession()`: that one is
559
+ * selection-driven (transform only the selected features and split
560
+ * shared arcs first); this op transforms an entire layer in one shot
561
+ * with no shared-arc handling.
562
+ */
563
+ export interface AffineLayerOptions {
564
+ /** Source ID containing the target layer. */
565
+ source: string;
566
+ /** Layer name (or id). When omitted, the whole dataset is transformed. */
567
+ target?: string;
568
+ /** Translate by `[dx, dy]` in source coords. */
569
+ shift?: [number, number];
570
+ /** Rotate by this many degrees (positive = counter-clockwise). */
571
+ rotate?: number;
572
+ /**
573
+ * Scale factor. A single number scales uniformly; a `[sx, sy]` pair
574
+ * scales each axis independently.
575
+ */
576
+ scale?: number | [number, number];
577
+ /**
578
+ * Anchor `[x, y]` for rotation / scale. Defaults to the layer's
579
+ * bbox centre when omitted.
580
+ */
581
+ anchor?: [number, number];
582
+ /**
583
+ * Optional JS predicate — only features matching `where` are
584
+ * transformed. Subject to `expressionPolicy` gating.
585
+ */
586
+ where?: string;
587
+ }
588
+ /**
589
+ * Options for `Emap.dataFill` — fill missing attribute values from
590
+ * adjacent features. Useful for cleaning gappy administrative-region
591
+ * datasets where some polygons lack a code/name field.
592
+ *
593
+ * Wraps mapshaper's `-data-fill`. Currently scoped to a single field
594
+ * per call (mapshaper's API limit).
595
+ */
596
+ export interface DataFillOptions {
597
+ /** Source ID containing the target layer. */
598
+ source: string;
599
+ /** Layer name (or id). */
600
+ target: string;
601
+ /** Field name whose null/empty values should be back-filled. */
602
+ field: string;
603
+ /**
604
+ * Optional weighting field — when filling from multiple eligible
605
+ * neighbours, prefer the one with the largest value of this field
606
+ * (e.g. weight by `area` so big neighbours dominate).
607
+ */
608
+ weightField?: string;
609
+ /**
610
+ * Restrict fills so a contiguous block of features can only adopt
611
+ * one value (mapshaper's `contiguous` flag). Without it, isolated
612
+ * pockets within a region can pick up different fill values.
613
+ */
614
+ contiguous?: boolean;
615
+ }
616
+ /** Options for `Emap.checkGeometry`. Read-only topology validation. */
617
+ export interface CheckGeometryOptions {
618
+ /** Source ID whose dataset will be inspected. */
619
+ source: string;
620
+ /**
621
+ * Optional layer name. Reserved for future per-layer scoping; v1 always
622
+ * scans the whole dataset's arcs regardless. The name is still validated
623
+ * up-front so a typo shows up immediately as a `null` return.
624
+ */
625
+ target?: string;
626
+ /**
627
+ * Override the auto-derived intersection-tolerance epsilon. Forwarded to
628
+ * `findSegmentIntersections.tolerance`. Source-CRS units.
629
+ */
630
+ tolerance?: number;
631
+ }
632
+ /** Result shape returned from `Emap.checkGeometry`. */
633
+ export interface GeometryCheckReport {
634
+ /** `true` iff the report has zero issues across every category. */
635
+ ok: boolean;
636
+ /** Detected segment-intersection points. */
637
+ intersections: Array<{
638
+ x: number;
639
+ y: number;
640
+ }>;
641
+ /** Convenience: `intersections.length`. */
642
+ intersectionCount: number;
643
+ }
644
+ /**
645
+ * Options for `Emap.intersectionPointsLayer`. Materializes the
646
+ * self-intersection points of a polygon or polyline target as a new
647
+ * point layer in the same source's dataset.
648
+ */
649
+ export interface IntersectionPointsLayerOptions {
650
+ /** Source ID containing the target. */
651
+ source: string;
652
+ /** Polygon or polyline layer name (or id) whose self-intersections will be extracted. */
653
+ target: string;
654
+ /**
655
+ * Optional name for the new point layer. Defaults to
656
+ * `${target}-intersections`. Must not collide with an existing layer
657
+ * in the same dataset.
658
+ */
659
+ name?: string;
660
+ /**
661
+ * Override the auto-derived intersection-tolerance epsilon. Forwarded
662
+ * to `findSegmentIntersections.tolerance`. Source-CRS units. Must be
663
+ * a positive finite number when supplied.
664
+ */
665
+ tolerance?: number;
666
+ }
667
+ /** Source-data shape for `Emap.joinTable`. Discriminated union: */
668
+ export type JoinTableData =
669
+ /** CSV content (string or bytes). Saved as `.emap-join.csv` in the runner cache. */
670
+ {
671
+ csv: string | Uint8Array;
672
+ json?: never;
673
+ layer?: never;
674
+ }
675
+ /** JSON content. Plain arrays/objects are auto-stringified before injection. */
676
+ | {
677
+ json: string | Uint8Array | unknown[] | Record<string, unknown>;
678
+ csv?: never;
679
+ layer?: never;
680
+ }
681
+ /** Reference to another layer in the same source by name. */
682
+ | {
683
+ layer: string;
684
+ csv?: never;
685
+ json?: never;
686
+ };
687
+ /** Options for `Emap.joinTable`. */
688
+ export interface JoinTableOptions {
689
+ /** Source ID containing the target layer. */
690
+ source: string;
691
+ /** Target layer name (or id) to receive joined attributes. */
692
+ target: string;
693
+ /** Where to read the source records from. */
694
+ data: JoinTableData;
695
+ /**
696
+ * Join keys, `[targetKey, sourceKey]`. Both must be non-empty trimmed
697
+ * strings. Forwarded as `keys=<target>,<source>`.
698
+ */
699
+ keys: [string, string];
700
+ /** Fields to copy from the source. Defaults to all but the source key. */
701
+ fields?: string[];
702
+ /** Prefix for joined-in field names (e.g. `'p_'` → `p_pop`, `p_gdp`). */
703
+ prefix?: string;
704
+ /** JS expression to filter source records before join. */
705
+ where?: string;
706
+ /** JS expression for many-to-one aggregation. */
707
+ calc?: string;
708
+ /** Keep target records that didn't match any source record (mapshaper's `unjoined`). */
709
+ unjoined?: boolean;
710
+ /** Output unmatched source records as a separate layer (mapshaper's `unmatched`). */
711
+ unmatched?: boolean;
712
+ }
713
+ /** Options for `Emap.renameFields`. */
714
+ export interface RenameFieldsOptions {
715
+ /** Source ID containing the target layer. */
716
+ source: string;
717
+ /** Layer name (or id) whose fields will be renamed. */
718
+ target: string;
719
+ /**
720
+ * Map of `oldName -> newName`. Both keys and values must be non-empty
721
+ * after trimming and contain neither `,` nor `=` (those would break
722
+ * the comma-and-equals serialization mapshaper expects).
723
+ */
724
+ mapping: Record<string, string>;
725
+ }
726
+ /** Options for `Emap.mergeLayers`. Requires `targets.length >= 2`. */
727
+ export interface MergeLayersOptions {
728
+ /** Source ID containing every target layer. */
729
+ source: string;
730
+ /** Two or more layer names (or ids) to combine into one. */
731
+ targets: string[];
732
+ /** Optional name for the output layer. */
733
+ name?: string;
734
+ /**
735
+ * Allow merging layers with different geometry types or inconsistent data
736
+ * fields (mapshaper's `force` flag). Without this, mismatched-geometry
737
+ * targets are rejected up-front to avoid an opaque mid-pipeline error.
738
+ */
739
+ force?: boolean;
740
+ /**
741
+ * For polygon merges: rebuild as a flat mosaic with higher-id polygons
742
+ * winning overlaps (mapshaper's `flatten` flag). Ignored by mapshaper
743
+ * for non-polygon inputs.
744
+ */
745
+ flatten?: boolean;
746
+ }
747
+ /** Simplification algorithm exposed by mapshaper's `-simplify`. */
748
+ export type SimplifyMethod = 'dp' | 'visvalingam' | 'weighted';
749
+ /**
750
+ * Options for `Emap.projectLayer`. Reprojection via mapshaper's `-proj`
751
+ * (Proj.4-backed). `crs` is the destination CRS string; mapshaper accepts
752
+ * EPSG codes (`'EPSG:3857'`), named aliases (`'webmercator'`, `'robinson'`),
753
+ * or full Proj.4 definitions (`'+proj=utm +zone=10'`).
754
+ */
755
+ export interface ProjectOptions {
756
+ /** Source ID containing the layer(s) to reproject. */
757
+ source: string;
758
+ /** Destination CRS. Required, non-empty after trimming. */
759
+ crs: string;
760
+ /**
761
+ * Optional layer name to scope the operation. When omitted, the whole
762
+ * source dataset is reprojected (mapshaper CLI default).
763
+ */
764
+ target?: string;
765
+ /**
766
+ * Source CRS override. Useful when the dataset doesn't have a stored
767
+ * CRS or when the stored value is wrong. Same string formats as `crs`.
768
+ */
769
+ init?: string;
770
+ /**
771
+ * Add intermediate vertices along straight segments to approximate
772
+ * curves under the destination projection (mapshaper's `densify` flag).
773
+ * Recommended when projecting from EPSG:4326 to azimuthal or pseudo-
774
+ * cylindrical projections to avoid visible angular distortion of long
775
+ * geodesic segments.
776
+ */
777
+ densify?: boolean;
778
+ }
779
+ /**
780
+ * Options for `Emap.simplifyLayer`. Exactly one of `percentage`,
781
+ * `interval`, or `resolution` MUST be supplied — they correspond to
782
+ * mapshaper's three threshold modes and are mutually exclusive.
783
+ */
784
+ export interface SimplifyOptions {
785
+ /** Source ID. Simplification operates on the source's shared arcs. */
786
+ source: string;
787
+ /**
788
+ * Optional layer name to scope the operation. When omitted, simplify
789
+ * applies to every layer in the source dataset (mapshaper CLI default).
790
+ */
791
+ target?: string;
792
+ /**
793
+ * Percentage of removable vertices to retain, e.g. `10` → `10%`. Must be
794
+ * within `[0, 100]`. Mutually exclusive with `interval` and `resolution`.
795
+ */
796
+ percentage?: number;
797
+ /**
798
+ * Output resolution as a positive distance in source-CRS units. Mutually
799
+ * exclusive with `percentage` and `resolution`.
800
+ */
801
+ interval?: number;
802
+ /**
803
+ * Output resolution as a grid string (e.g. `"1000x500"`). Mutually
804
+ * exclusive with `percentage` and `interval`.
805
+ */
806
+ resolution?: string;
807
+ /**
808
+ * Simplification algorithm. Default is `'weighted'` (weighted-Visvalingam),
809
+ * matching mapshaper's CLI default.
810
+ */
811
+ method?: SimplifyMethod;
812
+ /** Weighted-Visvalingam coefficient (mapshaper default 0.7). */
813
+ weighting?: number;
814
+ /** Treat coordinates as planar (degrees), not 3D spherical. */
815
+ planar?: boolean;
816
+ /** Keep small polygon features that would otherwise vanish. */
817
+ keepShapes?: boolean;
818
+ /** Pin vertices that lie on the dataset bounding box. */
819
+ lockBox?: boolean;
820
+ /** Skip the post-simplify topology repair pass. */
821
+ noRepair?: boolean;
822
+ }
823
+ /**
824
+ * Options for `Emap.cleanLayer`. Heavy topology-repair pass — O(N²) on
825
+ * polygon counts in the worst case — so opt in via explicit invocation. Every
826
+ * field is optional; omitting them lets mapshaper apply its built-in defaults.
827
+ */
828
+ export interface CleanOptions {
829
+ /** Source ID containing the target layer. */
830
+ source: string;
831
+ /** Layer name (or id) of the polygon layer to clean. */
832
+ target: string;
833
+ /**
834
+ * Maximum area (in source-CRS units²) of gaps to fill in. Gaps larger
835
+ * than this are kept as holes. Maps to mapshaper's `gap-fill-area=N`.
836
+ */
837
+ gapFillArea?: number;
838
+ /**
839
+ * Sliver-detection sensitivity, typically `0..1`. Lower keeps more
840
+ * features; higher removes more. Maps to `sliver-control=N`.
841
+ */
842
+ sliverControl?: number;
843
+ /** Coincident-vertex snap distance for the topology-build pre-pass. */
844
+ snapInterval?: number;
845
+ /** Skip the snap pre-pass entirely (mapshaper's `no-snap` flag). */
846
+ noSnap?: boolean;
847
+ /**
848
+ * Allow output polygons to overlap (disables gap fill).
849
+ * Maps to mapshaper's `allow-overlaps` flag.
850
+ */
851
+ allowOverlaps?: boolean;
852
+ /**
853
+ * Tie-breaking rule when overlapping polygons are merged: which input
854
+ * record's attributes win. Maps to `overlap-rule=...`.
855
+ */
856
+ overlapRule?: 'min-id' | 'max-id' | 'min-area' | 'max-area';
857
+ /**
858
+ * Keep features with null geometry instead of removing them.
859
+ * Maps to mapshaper's `allow-empty` flag.
860
+ */
861
+ allowEmpty?: boolean;
862
+ /**
863
+ * Fix CW/CCW winding-order errors in polygon rings.
864
+ * Maps to mapshaper's `rewind` flag.
865
+ */
866
+ rewind?: boolean;
867
+ /**
868
+ * Only delete unused arcs, don't repair gaps / overlaps.
869
+ * Maps to mapshaper's `only-arcs` flag.
870
+ */
871
+ onlyArcs?: boolean;
872
+ /**
873
+ * Skip the arc-dissolve sub-step.
874
+ * Maps to mapshaper's `no-arc-dissolve` flag.
875
+ */
876
+ noArcDissolve?: boolean;
877
+ }
878
+ /** Options for `Emap.mosaicLayer`. */
879
+ export interface MosaicOptions {
880
+ /** Source ID containing the target polygon layer. */
881
+ source: string;
882
+ /** Layer name (or id) of the polygon layer to flatten. */
883
+ target: string;
884
+ /** Snap distance for the topology-build pre-pass (mapshaper's `snap-interval=`). */
885
+ snapInterval?: number;
886
+ /** Skip the snap pre-pass entirely (mapshaper's `no-snap` flag). */
887
+ noSnap?: boolean;
888
+ /** Keep the original layer alongside the new mosaic (mapshaper's `no-replace`). */
889
+ noReplace?: boolean;
890
+ /** Optional name for the output layer. */
891
+ name?: string;
892
+ /**
893
+ * JS expression evaluated per output mosaic feature to compute aggregate
894
+ * attribute values (mapshaper's `calc=` option). The expression has access
895
+ * to the standard mapshaper aggregation context — `sum()`, `min()`,
896
+ * `max()`, `count()`, etc. — over the records that contributed to the
897
+ * mosaic feature. Forwarded verbatim, quoted.
898
+ */
899
+ calc?: string;
900
+ }
901
+ /** Options for `Emap.unionLayers`. Requires `targets.length >= 2`. */
902
+ export interface UnionOptions {
903
+ /** Source ID containing every target layer. */
904
+ source: string;
905
+ /** Two or more polygon layer names to overlay. */
906
+ targets: string[];
907
+ /** Optional list of fields to retain in the output. */
908
+ fields?: string[];
909
+ /** Optional name for the output layer. */
910
+ name?: string;
911
+ /** Keep the original layers alongside the new union output. */
912
+ noReplace?: boolean;
913
+ }
914
+ /**
915
+ * Options for `Emap.divideLayer`. Splits a polyline `target` layer at
916
+ * the boundaries of a polygon `divider` layer (both in the same source) and
917
+ * copies the underlying polygon's attributes onto each resulting line
918
+ * segment.
919
+ */
920
+ export interface DivideOptions {
921
+ /** Source ID containing both target and divider layers. */
922
+ source: string;
923
+ /** Polyline layer name (or id) to be cut by polygon boundaries. */
924
+ target: string;
925
+ /** Polygon layer name (or id) used as the divider. */
926
+ divider: string;
927
+ /**
928
+ * Polygon fields to copy onto each line segment. Defaults to all fields of
929
+ * the divider layer.
930
+ */
931
+ fields?: string[];
932
+ /** Replace existing same-named fields on the line records. */
933
+ force?: boolean;
934
+ }
935
+ /**
936
+ * Modes for `Emap.pointsLayer`, mapping 1:1 to mapshaper's mutually
937
+ * exclusive `-points` flags.
938
+ */
939
+ export type PointsMode = 'centroid' | 'inner' | 'vertices' | 'endpoints' | 'midpoints' | 'interpolated';
940
+ /**
941
+ * Options for `Emap.linesLayer`. Converts a polygon `target` into a
942
+ * polyline layer made of its boundary arcs. With `fields`, the boundaries
943
+ * are emitted hierarchically by category (e.g. outer hull vs. inter-region
944
+ * boundaries vs. inter-subregion boundaries).
945
+ */
946
+ export interface LinesOptions {
947
+ /** Source ID containing the polygon target. */
948
+ source: string;
949
+ /** Polygon layer name (or id) to extract boundaries from. */
950
+ target: string;
951
+ /**
952
+ * Optional category fields. Each polygon boundary inherits the value of
953
+ * the most-coarse field that differs across it; mapshaper emits the
954
+ * boundary at the topmost layer in the hierarchy.
955
+ */
956
+ fields?: string[];
957
+ /** Optional name for the new polyline layer. */
958
+ name?: string;
959
+ /** Keep the original polygon layer alongside the new polyline output. */
960
+ noReplace?: boolean;
961
+ }
962
+ /**
963
+ * Options for `Emap.polygonsLayer`. Inverse of {@link LinesOptions} —
964
+ * forms enclosed polygons from a polyline target.
965
+ */
966
+ export interface PolygonsOptions {
967
+ /** Source ID containing the polyline target. */
968
+ source: string;
969
+ /** Polyline layer name (or id) to be polygonized. */
970
+ target: string;
971
+ /**
972
+ * Gap-snapping tolerance in source-CRS units. Forwarded only when
973
+ * positive; otherwise mapshaper picks its own default.
974
+ */
975
+ gapTolerance?: number;
976
+ /**
977
+ * If true, take the fast path that assumes the input is already a layer
978
+ * of closed paths (mapshaper's `from-rings` flag).
979
+ */
980
+ fromRings?: boolean;
981
+ }
982
+ /** Options for `Emap.pointsLayer`. */
983
+ export interface PointsOptions {
984
+ /** Source ID containing the target layer. */
985
+ source: string;
986
+ /** Layer name (or id) of the layer whose points will be extracted. */
987
+ target: string;
988
+ /**
989
+ * Extraction mode. Each mode constrains the input geometry: `centroid` /
990
+ * `inner` need polygons; `midpoints` / `interpolated` need polylines;
991
+ * `vertices` / `endpoints` accept either polygons or polylines.
992
+ */
993
+ type: PointsMode;
994
+ /**
995
+ * Sample interval in source-CRS units. Required (and must be positive) for
996
+ * `type: 'interpolated'`; ignored otherwise.
997
+ */
998
+ interval?: number;
999
+ /** Optional name for the output point layer. */
1000
+ name?: string;
1001
+ /** Keep the original layer alongside the new point layer (mapshaper's `no-replace`). */
1002
+ noReplace?: boolean;
1003
+ }
1004
+ /** Options for `Emap.exportSnapshot`. */
1005
+ export interface ExportSnapshotOptions {
1006
+ /**
1007
+ * Bake simplification thresholds and gzip-compress arc buffers
1008
+ * (mapshaper's `compact` flag). Default `true` — matches mapshaper CLI's
1009
+ * on-disk snapshot.
1010
+ */
1011
+ compact?: boolean;
1012
+ }
1013
+ /** Options for `Emap.loadSnapshot`. */
1014
+ export interface LoadSnapshotOptions {
1015
+ /**
1016
+ * Prepended to every restored source ID — useful when loading a snapshot
1017
+ * alongside existing sources to namespace them apart. Applies to both
1018
+ * IDs read from the snapshot's `emap` metadata and fallback IDs.
1019
+ */
1020
+ idPrefix?: string;
1021
+ /**
1022
+ * When a restored ID collides with an already-registered source:
1023
+ * - `true` (default) — the existing source is removed first.
1024
+ * - `false` — the promise rejects without registering anything new.
1025
+ */
1026
+ replace?: boolean;
1027
+ /**
1028
+ * Used when the snapshot has no `emap` metadata (e.g. a vanilla mapshaper
1029
+ * `.msx` file). One ID per restored dataset, in order. If the array is
1030
+ * shorter than the dataset count, the tail falls back to `snapshot-<i>`.
1031
+ */
1032
+ defaultIds?: string[];
1033
+ }
1034
+ export interface HighlightStyle {
1035
+ color?: string;
1036
+ width?: number;
1037
+ radius?: number;
1038
+ fill?: boolean;
1039
+ }
1040
+ export type EditVertexShapePart = import('../types/mapshaper-types').PathPart;
1041
+ export type EditVertexShape = import('../types/mapshaper-types').PathShape;
1042
+ export interface EditVertexArcs {
1043
+ getArcIter(arcId: number): {
1044
+ x: number;
1045
+ y: number;
1046
+ hasNext(): boolean;
1047
+ };
1048
+ getShapeIter?(part: number[]): {
1049
+ x: number;
1050
+ y: number;
1051
+ hasNext(): boolean;
1052
+ };
1053
+ }
1054
+ export interface EditVertexState {
1055
+ shapes: EditVertexShape[];
1056
+ arcs: EditVertexArcs;
1057
+ hoverVertex: [number, number] | null;
1058
+ /**
1059
+ * Whether `hoverVertex` is an actual vertex on an arc (`'vertex'`) or
1060
+ * the interpolated midpoint of an edge (`'interpolated'`, drag to insert
1061
+ * a new vertex). Renderers draw a circle for `'vertex'` and a square for
1062
+ * `'interpolated'`, mirroring the convention used in DrawFeatureControl.
1063
+ */
1064
+ hoverType?: 'vertex' | 'interpolated' | null;
1065
+ /** CSS color string for polygon fill in vertex edit mode. Null = no fill. */
1066
+ polygonFill?: string | null;
1067
+ geometryType?: string;
1068
+ /** Neighbor shapes sharing the hovered arc (different polygon fill) */
1069
+ neighborShapes?: EditVertexShape[];
1070
+ }
1071
+ /** Default vertex-count threshold for `useWorker: 'auto'`. */
1072
+ export declare const DEFAULT_WORKER_THRESHOLD = 50000;