@sakuzu/maplibre-gl-draw 1.0.0 → 2.0.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 +1016 -2
- package/README.ja.md +39 -19
- package/README.md +41 -21
- package/dist/api/datasets.d.ts +258 -0
- package/dist/api/document.d.ts +66 -0
- package/dist/api/draw.d.ts +135 -0
- package/dist/api/draw.js +18 -0
- package/dist/api/drawing.d.ts +87 -0
- package/dist/api/errors.d.ts +35 -0
- package/dist/api/errors.js +35 -0
- package/dist/api/events.d.ts +306 -0
- package/dist/api/extension/context.d.ts +247 -0
- package/dist/api/extension/feature-type.d.ts +129 -0
- package/dist/api/extension/mode.d.ts +123 -0
- package/dist/api/extension/plugin.d.ts +51 -0
- package/dist/api/extension/plugin.js +3 -0
- package/dist/api/extension/provider.d.ts +119 -0
- package/dist/api/extension/provider.js +3 -0
- package/dist/api/extension/render.d.ts +176 -0
- package/dist/api/extension/render.js +3 -0
- package/dist/api/extension/store.d.ts +190 -0
- package/dist/api/extension/store.js +3 -0
- package/dist/api/extensions.d.ts +306 -0
- package/dist/api/extensions.js +3 -0
- package/dist/api/features.d.ts +188 -0
- package/dist/api/features.js +3 -0
- package/dist/api/groups.d.ts +111 -0
- package/dist/api/groups.js +3 -0
- package/dist/api/hidden.d.ts +45 -0
- package/dist/api/hidden.js +3 -0
- package/dist/api/impl/adapters.js +463 -0
- package/dist/api/impl/contexts.js +466 -0
- package/dist/api/impl/create-draw.js +124 -0
- package/dist/api/impl/datasets.js +404 -0
- package/dist/api/impl/destroy-guard.js +74 -0
- package/dist/api/impl/document.js +280 -0
- package/dist/api/impl/drawing.js +180 -0
- package/dist/api/impl/engine-context.d.ts +7 -0
- package/dist/api/{context.js → impl/engine-context.js} +49 -38
- package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
- package/dist/api/impl/events.js +422 -0
- package/dist/api/impl/extension-host.js +361 -0
- package/dist/api/impl/extensions.js +229 -0
- package/dist/api/impl/features.js +445 -0
- package/dist/api/impl/geometry/apply.d.ts +32 -0
- package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
- package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
- package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
- package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
- package/dist/api/{geometry → impl/geometry}/split.js +10 -21
- package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
- package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
- package/dist/api/impl/geometry/types.js +3 -0
- package/dist/api/impl/groups.d.ts +3 -0
- package/dist/api/impl/groups.js +268 -0
- package/dist/api/impl/hidden.js +60 -0
- package/dist/api/impl/import-export/constants.d.ts +22 -0
- package/dist/api/impl/import-export/constants.js +24 -0
- package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
- package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
- package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
- package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
- package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
- package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
- package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
- package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
- package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
- package/dist/api/impl/import-export/image-import.d.ts +16 -0
- package/dist/api/impl/import-export/image-import.js +73 -0
- package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
- package/dist/api/impl/import-export/legacy-image-style.js +49 -0
- package/dist/api/impl/import-export/native-format.d.ts +14 -0
- package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
- package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
- package/dist/api/impl/import-export/native-upgrade.js +139 -0
- package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
- package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
- package/dist/api/impl/import-export/style-validation.d.ts +24 -0
- package/dist/api/impl/import-export/style-validation.js +86 -0
- package/dist/api/impl/import-export/types.d.ts +52 -0
- package/dist/api/impl/import-export/types.js +3 -0
- package/dist/api/impl/input.js +180 -0
- package/dist/api/impl/layers.js +307 -0
- package/dist/api/impl/metadata.d.ts +1 -0
- package/dist/api/impl/metadata.js +22 -0
- package/dist/api/impl/options.d.ts +1 -0
- package/dist/api/impl/options.js +822 -0
- package/dist/api/impl/placement.d.ts +1 -0
- package/dist/api/impl/placement.js +138 -0
- package/dist/api/impl/render-context.d.ts +13 -0
- package/dist/api/impl/render-context.js +272 -0
- package/dist/api/impl/rows.d.ts +1 -0
- package/dist/api/impl/rows.js +46 -0
- package/dist/api/impl/selection.d.ts +1 -0
- package/dist/api/impl/selection.js +186 -0
- package/dist/api/impl/shared.d.ts +64 -0
- package/dist/api/impl/shared.js +178 -0
- package/dist/api/impl/validate-extension.d.ts +1 -0
- package/dist/api/impl/validate-extension.js +159 -0
- package/dist/api/layers.d.ts +130 -0
- package/dist/api/layers.js +3 -0
- package/dist/api/metadata.d.ts +18 -0
- package/dist/api/metadata.js +3 -0
- package/dist/api/model.d.ts +487 -0
- package/dist/api/model.js +47 -0
- package/dist/api/options.d.ts +466 -0
- package/dist/api/options.js +3 -0
- package/dist/api/selection.d.ts +94 -0
- package/dist/api/selection.js +3 -0
- package/dist/api/state.d.ts +155 -0
- package/dist/api/state.js +12 -0
- package/dist/{display → dataset}/chunk.d.ts +1 -1
- package/dist/{display → dataset}/chunk.js +4 -3
- package/dist/{display → dataset}/dataset.js +18 -21
- package/dist/dataset/interaction.d.ts +1 -0
- package/dist/{display → dataset}/interaction.js +18 -6
- package/dist/dataset/manager.d.ts +1 -0
- package/dist/dataset/provider.d.ts +1 -0
- package/dist/{display → dataset}/retained.d.ts +1 -1
- package/dist/{display → dataset}/retained.js +8 -7
- package/dist/dataset/source.d.ts +1 -0
- package/dist/{display → dataset}/source.js +17 -4
- package/dist/dataset/spatial.d.ts +1 -0
- package/dist/{display → dataset}/spatial.js +1 -1
- package/dist/dataset/style.d.ts +1 -0
- package/dist/{display → dataset}/style.js +1 -1
- package/dist/dataset/table-source.d.ts +1 -0
- package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
- package/dist/{display → dataset}/thinning.d.ts +0 -10
- package/dist/{display → dataset}/thinning.js +3 -2
- package/dist/dataset/triangulation.d.ts +1 -0
- package/dist/{display → dataset}/triangulation.js +0 -0
- package/dist/{display → dataset}/types.d.ts +82 -121
- package/dist/dataset/types.js +61 -0
- package/dist/dispatcher/hit-test/box-strategies.js +13 -13
- package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
- package/dist/dispatcher/hit-test/globe-shape.js +5 -4
- package/dist/dispatcher/hit-test/service.d.ts +17 -0
- package/dist/dispatcher/hit-test/service.js +80 -16
- package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
- package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
- package/dist/dispatcher/hit-test/strategies/image.js +6 -18
- package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
- package/dist/dispatcher/hit-test/strategies/line.js +9 -2
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
- package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
- package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
- package/dist/dispatcher/hit-test/strategies/point.js +8 -4
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
- package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
- package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
- package/dist/dispatcher/input-router.js +152 -69
- package/dist/dispatcher/normalizer.js +6 -2
- package/dist/dispatcher/types.d.ts +6 -1
- package/dist/extension/feature-handler.d.ts +1 -182
- package/dist/extension/index.d.ts +4 -7
- package/dist/extension/renderers.d.ts +1 -208
- package/dist/geometry/angle.d.ts +0 -8
- package/dist/geometry/angle.js +0 -8
- package/dist/geometry/bbox.d.ts +4 -12
- package/dist/geometry/bbox.js +4 -12
- package/dist/geometry/boolean.d.ts +0 -51
- package/dist/geometry/boolean.js +0 -51
- package/dist/geometry/buffer.d.ts +0 -26
- package/dist/geometry/buffer.js +0 -26
- package/dist/geometry/circle.d.ts +0 -9
- package/dist/geometry/circle.js +0 -9
- package/dist/geometry/coords.d.ts +0 -16
- package/dist/geometry/coords.js +0 -16
- package/dist/geometry/distance.d.ts +0 -24
- package/dist/geometry/distance.js +0 -24
- package/dist/geometry/errors.d.ts +21 -36
- package/dist/geometry/errors.js +49 -29
- package/dist/geometry/geojson.d.ts +81 -0
- package/dist/geometry/geojson.js +164 -0
- package/dist/geometry/index.d.ts +38 -23
- package/dist/geometry/index.js +43 -31
- package/dist/geometry/measure.d.ts +0 -27
- package/dist/geometry/measure.js +0 -27
- package/dist/geometry/predicates.d.ts +0 -9
- package/dist/geometry/predicates.js +0 -9
- package/dist/geometry/public-bounds.d.ts +26 -0
- package/dist/geometry/public-bounds.js +30 -0
- package/dist/geometry/public-combine.d.ts +78 -0
- package/dist/geometry/public-combine.js +82 -0
- package/dist/geometry/public-create.d.ts +54 -0
- package/dist/geometry/public-create.js +70 -0
- package/dist/geometry/public-measure.d.ts +170 -0
- package/dist/geometry/public-measure.js +283 -0
- package/dist/geometry/public-predicates.d.ts +54 -0
- package/dist/geometry/public-predicates.js +144 -0
- package/dist/geometry/public-repair.d.ts +75 -0
- package/dist/geometry/public-repair.js +77 -0
- package/dist/geometry/simplify.d.ts +0 -7
- package/dist/geometry/simplify.js +0 -7
- package/dist/geometry/split.d.ts +0 -20
- package/dist/geometry/split.js +0 -20
- package/dist/geometry/units.d.ts +20 -12
- package/dist/geometry/units.js +20 -12
- package/dist/index.d.ts +52 -66
- package/dist/index.js +6 -18
- package/dist/messages.d.ts +7 -7
- package/dist/modes/draw/circle.js +83 -207
- package/dist/modes/draw/commit-layer.d.ts +5 -16
- package/dist/modes/draw/commit-layer.js +2 -13
- package/dist/modes/draw/freehand.js +108 -246
- package/dist/modes/draw/image.js +4 -2
- package/dist/modes/draw/index.d.ts +5 -5
- package/dist/modes/draw/index.js +5 -5
- package/dist/modes/draw/line.js +18 -354
- package/dist/modes/draw/point.js +29 -78
- package/dist/modes/draw/polygon.js +23 -368
- package/dist/modes/draw/trace-support.d.ts +43 -36
- package/dist/modes/draw/trace-support.js +95 -98
- package/dist/modes/draw/vertex-drawing.d.ts +1 -0
- package/dist/modes/draw/vertex-drawing.js +176 -0
- package/dist/modes/handler.d.ts +1 -285
- package/dist/modes/manager.d.ts +2 -2
- package/dist/modes/manager.js +3 -0
- package/dist/modes/select/box-selection.d.ts +3 -3
- package/dist/modes/select/box-selection.js +2 -1
- package/dist/modes/select/click-handler.d.ts +5 -5
- package/dist/modes/select/click-handler.js +22 -20
- package/dist/modes/select/cursor-handler.d.ts +2 -2
- package/dist/modes/select/drag/intermediate-writes.js +1 -1
- package/dist/modes/select/drag/move.js +3 -3
- package/dist/modes/select/drag/operation.d.ts +3 -3
- package/dist/modes/select/drag/radius.js +5 -4
- package/dist/modes/select/drag/transform.d.ts +2 -2
- package/dist/modes/select/drag/transform.js +11 -5
- package/dist/modes/select/drag/vertex.d.ts +2 -2
- package/dist/modes/select/drag/vertex.js +13 -8
- package/dist/modes/select/drag-handler.js +44 -25
- package/dist/modes/select/mode.js +17 -17
- package/dist/modes/select/shortcut-handler.d.ts +8 -8
- package/dist/modes/select/shortcut-handler.js +9 -7
- package/dist/operations/layer-operations.js +29 -168
- package/dist/operations/resize.d.ts +2 -2
- package/dist/operations/resize.js +5 -5
- package/dist/operations/rotate.js +5 -5
- package/dist/operations/selection-operations.d.ts +16 -1
- package/dist/operations/selection-operations.js +28 -13
- package/dist/operations/shared-vertex.js +4 -2
- package/dist/operations/trace-graph.d.ts +0 -18
- package/dist/operations/trace-graph.js +0 -18
- package/dist/operations/vertex.js +36 -35
- package/dist/shared/color.d.ts +1 -0
- package/dist/shared/color.js +245 -0
- package/dist/shared/config/constants.d.ts +1 -54
- package/dist/shared/config/constants.js +1 -58
- package/dist/shared/config/feature-style.d.ts +16 -13
- package/dist/shared/config/feature-style.js +9 -0
- package/dist/shared/config/rendering.d.ts +3 -3
- package/dist/shared/config/selection-highlight.d.ts +0 -15
- package/dist/shared/config/selection-highlight.js +4 -7
- package/dist/shared/config/selection.d.ts +2 -32
- package/dist/shared/config/selection.js +0 -18
- package/dist/shared/config/topology.d.ts +2 -2
- package/dist/shared/config/trace.d.ts +4 -4
- package/dist/shared/math/angle.d.ts +1 -1
- package/dist/shared/math/angle.js +1 -1
- package/dist/shared/math/circle.d.ts +1 -1
- package/dist/shared/math/circle.js +1 -1
- package/dist/shared/math/distance.d.ts +2 -1
- package/dist/shared/math/distance.js +3 -2
- package/dist/shared/math/index.d.ts +1 -1
- package/dist/shared/math/index.js +1 -1
- package/dist/shared/math/transform.d.ts +23 -0
- package/dist/shared/math/transform.js +47 -28
- package/dist/shared/properties.d.ts +18 -0
- package/dist/shared/properties.js +129 -0
- package/dist/shared/types/events.d.ts +15 -7
- package/dist/shared/types/model.d.ts +109 -159
- package/dist/shared/types/style.d.ts +1 -1
- package/dist/shared/utils/color.d.ts +2 -36
- package/dist/shared/utils/color.js +13 -70
- package/dist/shared/utils/coordinates.d.ts +30 -4
- package/dist/shared/utils/coordinates.js +56 -10
- package/dist/shared/utils/event-emitter.d.ts +1 -262
- package/dist/shared/utils/event-emitter.js +4 -3
- package/dist/shared/utils/feature-bbox.js +8 -7
- package/dist/shared/utils/feature-segments.js +5 -4
- package/dist/shared/utils/image.d.ts +0 -4
- package/dist/shared/utils/image.js +0 -6
- package/dist/shared/utils/name-generator.d.ts +14 -20
- package/dist/shared/utils/name-generator.js +20 -3
- package/dist/shared/utils/pixel-ratio.d.ts +9 -3
- package/dist/shared/utils/pixel-ratio.js +13 -4
- package/dist/shared/utils/property.d.ts +7 -50
- package/dist/shared/utils/property.js +22 -87
- package/dist/snapping/custom-targets.js +21 -4
- package/dist/snapping/indicator.js +20 -11
- package/dist/snapping/providers/display.d.ts +6 -1
- package/dist/snapping/providers/display.js +2 -1
- package/dist/snapping/providers/guide.d.ts +3 -43
- package/dist/snapping/providers/guide.js +1 -44
- package/dist/snapping/providers/intersection.js +1 -1
- package/dist/snapping/providers/store.js +3 -3
- package/dist/snapping/service.js +18 -7
- package/dist/snapping/types.d.ts +9 -35
- package/dist/store/draw-store.js +233 -142
- package/dist/store/local-visibility.d.ts +11 -6
- package/dist/store/local-visibility.js +38 -7
- package/dist/store/lock.d.ts +0 -6
- package/dist/store/lock.js +0 -6
- package/dist/store/memory/change-bus.d.ts +3 -3
- package/dist/store/memory/change-bus.js +12 -0
- package/dist/store/memory/file-store.d.ts +2 -2
- package/dist/store/memory/ui-state.d.ts +1 -51
- package/dist/store/memory/ui-state.js +122 -134
- package/dist/store/memory.d.ts +1 -8
- package/dist/store/memory.js +249 -45
- package/dist/store/ordering.d.ts +9 -0
- package/dist/store/ordering.js +17 -0
- package/dist/store/spatial/spatial-index.d.ts +1 -1
- package/dist/store/spatial/spatial-index.js +1 -1
- package/dist/store/spatial/store-spatial-index.d.ts +3 -1
- package/dist/store/spatial/store-spatial-index.js +9 -3
- package/dist/store/store.d.ts +66 -107
- package/dist/store/types.d.ts +1 -1
- package/dist/store/writable-layer.d.ts +1 -1
- package/dist/store/writable-layer.js +2 -2
- package/dist/table/builder.d.ts +83 -0
- package/dist/table/builder.js +381 -0
- package/dist/table/index.d.ts +37 -0
- package/dist/table/index.js +5 -0
- package/dist/table/packed-rtree.d.ts +1 -0
- package/dist/{display → table}/packed-rtree.js +1 -1
- package/dist/table/partition.d.ts +1 -0
- package/dist/{display → table}/partition.js +3 -3
- package/dist/table/prepare.d.ts +44 -0
- package/dist/table/prepare.js +136 -0
- package/dist/table/table.d.ts +1 -0
- package/dist/{display/columnar → table}/table.js +29 -25
- package/dist/{display/columnar → table}/types.d.ts +68 -72
- package/dist/table/types.js +3 -0
- package/dist/view/coordinator.js +4 -3
- package/dist/view/feature-companion.d.ts +13 -7
- package/dist/view/feature-companion.js +11 -3
- package/dist/view/globe-subdivision.js +3 -3
- package/dist/view/layer/attach.d.ts +1 -1
- package/dist/view/layer/attach.js +1 -1
- package/dist/view/layer/custom-layer.js +40 -11
- package/dist/view/layer/display-list.js +2 -1
- package/dist/view/layer/drape-planner.d.ts +2 -2
- package/dist/view/layer/frame-render.d.ts +3 -3
- package/dist/view/layer/frame-render.js +7 -2
- package/dist/view/layer/frame-state.d.ts +6 -6
- package/dist/view/layer/index.d.ts +2 -2
- package/dist/view/layer/index.js +1 -1
- package/dist/view/layer/render.d.ts +4 -4
- package/dist/view/layer/render.js +3 -8
- package/dist/view/layer/renderers.d.ts +2 -2
- package/dist/view/layer/renderers.js +1 -1
- package/dist/view/layer/slot-manager.d.ts +2 -2
- package/dist/view/layer/slot-manager.js +4 -4
- package/dist/view/layer/slots.d.ts +2 -2
- package/dist/view/layer/slots.js +1 -1
- package/dist/view/layer/store-retained-bbox.js +3 -2
- package/dist/view/layer/store-retained-classify.d.ts +5 -7
- package/dist/view/layer/store-retained-classify.js +19 -7
- package/dist/view/layer/store-retained-collect.js +8 -7
- package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
- package/dist/view/layer/store-retained-coord-patch.js +13 -4
- package/dist/view/layer/store-retained-immediate.d.ts +3 -3
- package/dist/view/layer/store-retained-immediate.js +3 -8
- package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
- package/dist/view/layer/store-retained.d.ts +2 -2
- package/dist/view/layer/store-retained.js +1 -1
- package/dist/view/renderers/batch-manager.js +8 -7
- package/dist/view/renderers/drawer.js +21 -15
- package/dist/view/renderers/image.js +13 -39
- package/dist/view/renderers/line/line-types.d.ts +3 -3
- package/dist/view/renderers/line/sdf-line.js +3 -1
- package/dist/view/renderers/point/billboard-depth.js +1 -1
- package/dist/view/renderers/point/point-instance.js +1 -1
- package/dist/view/renderers/point/point-shape.js +2 -2
- package/dist/view/renderers/point/point-style.js +48 -4
- package/dist/view/renderers/polygon/batch.js +1 -2
- package/dist/view/renderers/polygon/fill.js +3 -1
- package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
- package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
- package/dist/view/renderers/stroke.js +3 -1
- package/dist/view/shaders/helpers.d.ts +2 -42
- package/dist/view/shaders/helpers.js +0 -6
- package/dist/view/shaders/projection.d.ts +15 -7
- package/dist/view/shaders/projection.js +23 -6
- package/dist/view/shaders/quad.d.ts +16 -12
- package/dist/view/shaders/quad.js +34 -13
- package/dist/view/style-rule.d.ts +5 -42
- package/dist/view/style-rule.js +20 -44
- package/dist/view/terrain/binding.d.ts +1 -0
- package/dist/view/terrain/binding.js +29 -0
- package/dist/view/terrain/context.d.ts +3 -4
- package/dist/view/terrain/context.js +4 -5
- package/dist/view/terrain/drape/geometry.js +1 -1
- package/dist/view/terrain/drape/pass.d.ts +1 -1
- package/dist/view/terrain/drape/pass.js +8 -7
- package/dist/view/terrain/polygon.d.ts +9 -5
- package/dist/view/terrain/polygon.js +16 -2
- package/dist/view/terrain/state.d.ts +1 -1
- package/dist/view/terrain/state.js +1 -1
- package/dist/view/terrain/tessellation.d.ts +2 -2
- package/dist/view/terrain/tessellation.js +1 -1
- package/dist/view/ui/auxiliary-handles.d.ts +6 -29
- package/dist/view/ui/bounds.js +8 -12
- package/dist/view/ui/handle-test.js +2 -2
- package/dist/view/ui/handle-thinning.js +17 -17
- package/dist/view/ui/handles.js +21 -13
- package/dist/view/ui/helper.d.ts +1 -1
- package/dist/view/ui/helper.js +1 -1
- package/dist/view/ui/index.d.ts +1 -1
- package/dist/view/ui/selection-scope.js +4 -2
- package/dist/view/ui/selection-ui/bounding-box.js +6 -6
- package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
- package/dist/view/ui/selection-ui/extension-registry.js +70 -7
- package/dist/view/ui/selection-ui/index.d.ts +2 -2
- package/dist/view/ui/selection-ui/index.js +1 -1
- package/dist/view/ui/selection-ui/renderer.js +15 -38
- package/dist/view/ui/selection-ui/types.d.ts +17 -2
- package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
- package/dist/view/ui/selection-ui-drawer.js +63 -2
- package/dist/view/ui/tentative.js +1 -1
- package/dist/webgl/index.d.ts +65 -0
- package/dist/webgl/index.js +62 -0
- package/package.json +20 -9
- package/dist/api/api.d.ts +0 -1259
- package/dist/api/api.js +0 -86
- package/dist/api/context.d.ts +0 -173
- package/dist/api/display-api.js +0 -23
- package/dist/api/event-api.d.ts +0 -13
- package/dist/api/event-api.js +0 -17
- package/dist/api/extension-api.d.ts +0 -46
- package/dist/api/extension-api.js +0 -85
- package/dist/api/feature-api.d.ts +0 -11
- package/dist/api/feature-api.js +0 -101
- package/dist/api/geometry/apply.d.ts +0 -51
- package/dist/api/geometry/boolean.d.ts +0 -28
- package/dist/api/geometry/boolean.js +0 -65
- package/dist/api/geometry/types.d.ts +0 -31
- package/dist/api/geometry-operations.d.ts +0 -162
- package/dist/api/geometry-operations.js +0 -94
- package/dist/api/group-api.d.ts +0 -10
- package/dist/api/group-api.js +0 -78
- package/dist/api/import-export/constants.d.ts +0 -29
- package/dist/api/import-export/constants.js +0 -40
- package/dist/api/import-export/file-name.d.ts +0 -10
- package/dist/api/import-export/file-name.js +0 -20
- package/dist/api/import-export/geojson-export.d.ts +0 -19
- package/dist/api/import-export/image-import.d.ts +0 -12
- package/dist/api/import-export/image-import.js +0 -53
- package/dist/api/import-export/index.d.ts +0 -9
- package/dist/api/import-export/index.js +0 -107
- package/dist/api/import-export/native-format.d.ts +0 -15
- package/dist/api/import-export/style-validation.d.ts +0 -27
- package/dist/api/import-export/style-validation.js +0 -49
- package/dist/api/import-export/types.d.ts +0 -26
- package/dist/api/index.d.ts +0 -15
- package/dist/api/index.js +0 -3
- package/dist/api/input-api.d.ts +0 -158
- package/dist/api/input-api.js +0 -144
- package/dist/api/instance-api.d.ts +0 -38
- package/dist/api/instance-api.js +0 -136
- package/dist/api/layer-api.d.ts +0 -12
- package/dist/api/layer-api.js +0 -62
- package/dist/api/selection-api.d.ts +0 -7
- package/dist/api/selection-api.js +0 -78
- package/dist/api/snapping-api.d.ts +0 -125
- package/dist/api/snapping-api.js +0 -50
- package/dist/api/topology-api.d.ts +0 -30
- package/dist/api/topology-api.js +0 -16
- package/dist/api/tracing-api.d.ts +0 -31
- package/dist/api/tracing-api.js +0 -16
- package/dist/dispatcher/hit-test/index.d.ts +0 -14
- package/dist/dispatcher/hit-test/index.js +0 -9
- package/dist/dispatcher/index.d.ts +0 -15
- package/dist/dispatcher/index.js +0 -3
- package/dist/display/columnar/index.d.ts +0 -12
- package/dist/display/columnar/index.js +0 -13
- package/dist/display/columnar/prepare.d.ts +0 -42
- package/dist/display/columnar/prepare.js +0 -116
- package/dist/display/index.d.ts +0 -13
- package/dist/display/types.js +0 -43
- package/dist/maplibre-gl-draw.d.ts +0 -47
- package/dist/modes/cursor.js +0 -72
- package/dist/modes/index.d.ts +0 -7
- package/dist/operations/index.d.ts +0 -9
- package/dist/operations/index.js +0 -3
- package/dist/plugins/index.d.ts +0 -10
- package/dist/plugins/mutation-hooks.d.ts +0 -28
- package/dist/plugins/mutation-hooks.js +0 -84
- package/dist/plugins/plugin-context.js +0 -367
- package/dist/plugins/plugin-manager.d.ts +0 -103
- package/dist/plugins/plugin-manager.js +0 -316
- package/dist/plugins/plugin.d.ts +0 -529
- package/dist/shared/config/index.d.ts +0 -17
- package/dist/shared/config/index.js +0 -8
- package/dist/shared/utils/index.d.ts +0 -15
- package/dist/shared/utils/index.js +0 -24
- package/dist/snapping/index.d.ts +0 -14
- package/dist/snapping/index.js +0 -4
- package/dist/store/change-merger.js +0 -102
- package/dist/store/event-bridge.js +0 -161
- package/dist/store/index.d.ts +0 -12
- package/dist/store/index.js +0 -4
- package/dist/view/index.d.ts +0 -47
- package/dist/view/index.js +0 -20
- /package/dist/api/{geometry/types.js → datasets.js} +0 -0
- /package/dist/api/{import-export/types.js → document.js} +0 -0
- /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
- /package/dist/{display/index.js → api/events.js} +0 -0
- /package/dist/{modes/index.js → api/extension/context.js} +0 -0
- /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
- /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
- /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
- /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
- /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
- /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
- /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
- /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
- /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
- /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
- /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
- /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
- /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
- /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
- /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
- /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
- /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
- /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
- /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
- /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
- /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
- /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
- /package/dist/{display → dataset}/chunk-set.js +0 -0
- /package/dist/{display → dataset}/dataset.d.ts +0 -0
- /package/dist/{display → dataset}/manager.js +0 -0
- /package/dist/{display → dataset}/provider.js +0 -0
- /package/dist/{display → dataset}/selection.d.ts +0 -0
- /package/dist/{display → dataset}/selection.js +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { toPosition, toScreenPoint, toSnapResult } from './contexts.js';
|
|
4
|
+
/**
|
|
5
|
+
* A pointer event of the engine as the contract gives it
|
|
6
|
+
*
|
|
7
|
+
* @param event - The event as it came, before snapping
|
|
8
|
+
* @param snapped - The same event after snapping (the event itself when it was not snapped)
|
|
9
|
+
* @param snap - The snapping result, or null when the position was not snapped
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export function toPointerEvent(event, snapped = event, snap = null) {
|
|
13
|
+
return {
|
|
14
|
+
point: toScreenPoint(event.point),
|
|
15
|
+
lngLat: toPosition(event.lngLat),
|
|
16
|
+
snapped: toSnapResult(snap, toPosition(snapped.lngLat)),
|
|
17
|
+
modifiers: { ...event.modifiers },
|
|
18
|
+
pointerType: event.pointerType ?? 'mouse',
|
|
19
|
+
// The engine keeps the event of the browser it received: a pointer or mouse event, or a
|
|
20
|
+
// touch event for a finger
|
|
21
|
+
original: event.originalEvent,
|
|
22
|
+
...('programmatic' in event && event.programmatic === true && { programmatic: true }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A key event of the engine as the contract gives it
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export function toKeyEvent(event) {
|
|
31
|
+
return { key: event.key, modifiers: { ...event.modifiers }, original: event.originalEvent };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calls the receiver of an input of the contract for an event of the engine
|
|
35
|
+
*
|
|
36
|
+
* @returns True when the receiver consumed the event
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export function deliver(receivers, event, snapped, snap) {
|
|
40
|
+
const pointer = () => toPointerEvent(event, snapped, snap);
|
|
41
|
+
switch (event.type) {
|
|
42
|
+
case 'click':
|
|
43
|
+
return receivers.onClick?.(pointer()) === true;
|
|
44
|
+
case 'dblclick':
|
|
45
|
+
return receivers.onDoubleClick?.(pointer()) === true;
|
|
46
|
+
case 'mousedown':
|
|
47
|
+
return receivers.onPointerDown?.(pointer()) === true;
|
|
48
|
+
case 'mouseup':
|
|
49
|
+
return receivers.onPointerUp?.(pointer()) === true;
|
|
50
|
+
case 'mousemove':
|
|
51
|
+
return receivers.onPointerMove?.(pointer()) === true;
|
|
52
|
+
case 'dragstart':
|
|
53
|
+
return receivers.onDragStart?.(pointer()) === true;
|
|
54
|
+
case 'dragmove':
|
|
55
|
+
return receivers.onDrag?.(pointer()) === true;
|
|
56
|
+
case 'dragend':
|
|
57
|
+
return receivers.onDragEnd?.(pointer()) === true;
|
|
58
|
+
case 'dragcancel':
|
|
59
|
+
return receivers.onDragCancel?.(pointer()) === true;
|
|
60
|
+
case 'keydown':
|
|
61
|
+
return receivers.onKeyDown?.(toKeyEvent(event)) === true;
|
|
62
|
+
case 'keyup':
|
|
63
|
+
return receivers.onKeyUp?.(toKeyEvent(event)) === true;
|
|
64
|
+
default:
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** The receiver of the contract each snapped input of the engine goes to */
|
|
69
|
+
const SNAP_RECEIVERS = {
|
|
70
|
+
click: 'onClick',
|
|
71
|
+
mousemove: 'onPointerMove',
|
|
72
|
+
dragstart: 'onDragStart',
|
|
73
|
+
dragmove: 'onDrag',
|
|
74
|
+
dragend: 'onDragEnd',
|
|
75
|
+
};
|
|
76
|
+
/** Marks the handlers of the engine that run a mode of the contract */
|
|
77
|
+
const BRIDGED = Symbol('extension mode');
|
|
78
|
+
/**
|
|
79
|
+
* Wraps the handler of a mode of the contract into a handler of the mode manager of the
|
|
80
|
+
* engine. The input reaches it through {@link routeToMode}, not through the methods the
|
|
81
|
+
* engine calls on its own modes.
|
|
82
|
+
*
|
|
83
|
+
* @param onExit - Called after the mode was left, to end what its context holds
|
|
84
|
+
* @param entering - Runs the entering of the mode, so that its context knows the cursor the
|
|
85
|
+
* mode sets then
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export function bridgeMode(name, handler, onExit, entering = (run) => run()) {
|
|
89
|
+
const bridged = {
|
|
90
|
+
[BRIDGED]: handler,
|
|
91
|
+
modeName: name,
|
|
92
|
+
writesFeatures: handler.writes === true,
|
|
93
|
+
onStart() {
|
|
94
|
+
entering(() => handler.onEnter?.());
|
|
95
|
+
},
|
|
96
|
+
onStop() {
|
|
97
|
+
try {
|
|
98
|
+
handler.onExit?.();
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
onExit();
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
onExternalStateChange() {
|
|
105
|
+
handler.onCancel?.();
|
|
106
|
+
},
|
|
107
|
+
undoVertex: () => handler.onUndoVertex?.() === true,
|
|
108
|
+
redoVertex: () => handler.onRedoVertex?.() === true,
|
|
109
|
+
getSnapPreference: () => handler.snapPreference?.prefer ?? null,
|
|
110
|
+
isSnapEnabledFor(inputType) {
|
|
111
|
+
const unsnapped = handler.snapPreference?.unsnapped;
|
|
112
|
+
return !unsnapped?.includes(SNAP_RECEIVERS[inputType]);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
return bridged;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The mode of the contract a handler of the engine runs, if it runs one
|
|
119
|
+
*
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
export function bridgedHandler(handler) {
|
|
123
|
+
return handler?.[BRIDGED];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Gives an event to a mode of the contract. An Escape that the mode does not consume
|
|
127
|
+
* interrupts it (`onCancel`).
|
|
128
|
+
*
|
|
129
|
+
* @returns Whether it consumed the event, or undefined when the handler runs no mode of the
|
|
130
|
+
* contract
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
export function routeToMode(handler, event, snapped, snap) {
|
|
134
|
+
const mode = bridgedHandler(handler);
|
|
135
|
+
if (!mode)
|
|
136
|
+
return undefined;
|
|
137
|
+
const consumed = deliver(mode, event, snapped, snap);
|
|
138
|
+
if (!consumed && event.type === 'keydown' && event.key === 'Escape' && mode.onCancel) {
|
|
139
|
+
mode.onCancel();
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return consumed;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The route of the input to the plugins and the modes of the contract
|
|
146
|
+
*
|
|
147
|
+
* @param plugins - The plugins in the order they were added
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
export function createInputRoute(plugins) {
|
|
151
|
+
return {
|
|
152
|
+
toPlugins(event, snapped, snap) {
|
|
153
|
+
for (const plugin of plugins()) {
|
|
154
|
+
if (!plugin.input)
|
|
155
|
+
continue;
|
|
156
|
+
try {
|
|
157
|
+
if (deliver(plugin.input, event, snapped, snap))
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.error(`Error in the input of the plugin "${plugin.name}":`, error);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
},
|
|
166
|
+
toMode: routeToMode,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Tells the plugins and the mode of the contract that the pointer left the map
|
|
171
|
+
*
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export function deliverPointerLeave(plugins, handler) {
|
|
175
|
+
for (const plugin of plugins) {
|
|
176
|
+
if (plugin.input?.onPointerLeave?.() === true)
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
bridgedHandler(handler)?.onPointerLeave?.();
|
|
180
|
+
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DrawError } from '../errors.js';
|
|
4
|
+
import { featureLocked, filterEntries, invalidInput, isRecord, isTaken, layerLocked, locksIgnored, matches, notFound, onlyKeys, onlyLockOrVisibility, optionalBoolean, optionalIndex, optionalString, requireId, requireIds, requireRecord, } from './shared.js';
|
|
5
|
+
const INPUT_KEYS = [
|
|
6
|
+
'id',
|
|
7
|
+
'name',
|
|
8
|
+
'visible',
|
|
9
|
+
'locked',
|
|
10
|
+
'opacity',
|
|
11
|
+
'styleRule',
|
|
12
|
+
'metadata',
|
|
13
|
+
'index',
|
|
14
|
+
];
|
|
15
|
+
const PATCH_KEYS = ['name', 'visible', 'locked', 'opacity', 'styleRule', 'metadata'];
|
|
16
|
+
const FILTER_KEYS = ['visible', 'locked'];
|
|
17
|
+
/**
|
|
18
|
+
* Creates `draw.layers`
|
|
19
|
+
*
|
|
20
|
+
* @param isStackEntry - Whether an ID that is not a layer may stand in the stacking order: a
|
|
21
|
+
* dataset whose order is `layer-order`, or an entry the `isExternalEntry` option recognizes
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export function createLayers(deps, isStackEntry = () => false) {
|
|
25
|
+
const { store } = deps;
|
|
26
|
+
const require = (id) => {
|
|
27
|
+
const layer = typeof id === 'string' ? store.getLayer(id) : undefined;
|
|
28
|
+
if (!layer)
|
|
29
|
+
throw notFound('layer', id);
|
|
30
|
+
return layer;
|
|
31
|
+
};
|
|
32
|
+
/** Every layer in stacking order, from the back; a layer off the order comes last */
|
|
33
|
+
const inOrder = () => {
|
|
34
|
+
const result = [];
|
|
35
|
+
for (const id of store.getLayerOrder()) {
|
|
36
|
+
const layer = store.getLayer(id);
|
|
37
|
+
if (layer)
|
|
38
|
+
result.push(layer);
|
|
39
|
+
}
|
|
40
|
+
if (result.length < store.listLayers().length) {
|
|
41
|
+
const listed = new Set(result.map((layer) => layer.id));
|
|
42
|
+
result.push(...store.listLayers().filter((layer) => !listed.has(layer.id)));
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
const list = (filter) => {
|
|
47
|
+
const entries = filterEntries(filter, FILTER_KEYS);
|
|
48
|
+
return inOrder().filter((layer) => matches(layer, entries));
|
|
49
|
+
};
|
|
50
|
+
/** Creates prepared layers and puts each at its index of the stacking order */
|
|
51
|
+
const createAll = (prepared) => {
|
|
52
|
+
store.transact(() => {
|
|
53
|
+
for (const entry of prepared)
|
|
54
|
+
insertLayer(store, entry);
|
|
55
|
+
});
|
|
56
|
+
return prepared.map(({ layer }) => store.getLayer(layer.id));
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
get: (id) => store.getLayer(id),
|
|
60
|
+
getMany(ids) {
|
|
61
|
+
if (!Array.isArray(ids))
|
|
62
|
+
throw invalidInput('The IDs must be an array');
|
|
63
|
+
return ids.map((id) => store.getLayer(id));
|
|
64
|
+
},
|
|
65
|
+
list,
|
|
66
|
+
count: (filter) => list(filter).length,
|
|
67
|
+
has: (id) => store.getLayer(id) !== undefined,
|
|
68
|
+
create(input) {
|
|
69
|
+
const prepared = prepareLayer(deps, input, new Set());
|
|
70
|
+
if (store.isReadOnly())
|
|
71
|
+
return null;
|
|
72
|
+
return createAll([prepared])[0] ?? null;
|
|
73
|
+
},
|
|
74
|
+
createMany(inputs) {
|
|
75
|
+
if (!Array.isArray(inputs))
|
|
76
|
+
throw invalidInput('The inputs must be an array');
|
|
77
|
+
const pending = new Set();
|
|
78
|
+
const prepared = inputs.map((input) => {
|
|
79
|
+
const entry = prepareLayer(deps, input, pending);
|
|
80
|
+
pending.add(entry.layer.id);
|
|
81
|
+
return entry;
|
|
82
|
+
});
|
|
83
|
+
if (store.isReadOnly())
|
|
84
|
+
return null;
|
|
85
|
+
return createAll(prepared);
|
|
86
|
+
},
|
|
87
|
+
update(id, patch) {
|
|
88
|
+
const layer = require(id);
|
|
89
|
+
const updates = prepareLayerPatch(patch);
|
|
90
|
+
if (store.isReadOnly())
|
|
91
|
+
return null;
|
|
92
|
+
if (layerLocked(store, layer) && !onlyLockOrVisibility(patch))
|
|
93
|
+
return null;
|
|
94
|
+
store.updateLayer(layer.id, updates);
|
|
95
|
+
return store.getLayer(layer.id) ?? null;
|
|
96
|
+
},
|
|
97
|
+
updateMany(patches) {
|
|
98
|
+
if (!Array.isArray(patches))
|
|
99
|
+
throw invalidInput('The patches must be an array');
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
const prepared = patches.map((entry) => {
|
|
102
|
+
requireRecord(entry, 'Each entry');
|
|
103
|
+
const layer = require(entry.id);
|
|
104
|
+
if (seen.has(layer.id))
|
|
105
|
+
throw invalidInput(`The ID ${layer.id} is given twice`);
|
|
106
|
+
seen.add(layer.id);
|
|
107
|
+
return { layer, patch: entry.patch, updates: prepareLayerPatch(entry.patch) };
|
|
108
|
+
});
|
|
109
|
+
if (store.isReadOnly())
|
|
110
|
+
return null;
|
|
111
|
+
if (prepared.some(({ layer, patch }) => layerLocked(store, layer) && !onlyLockOrVisibility(patch))) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
store.transact(() => {
|
|
115
|
+
for (const { layer, updates } of prepared)
|
|
116
|
+
store.updateLayer(layer.id, updates);
|
|
117
|
+
});
|
|
118
|
+
return prepared.map(({ layer }) => store.getLayer(layer.id));
|
|
119
|
+
},
|
|
120
|
+
delete(id) {
|
|
121
|
+
const layer = require(id);
|
|
122
|
+
if (store.isReadOnly() || holdsLock(store, layer))
|
|
123
|
+
return false;
|
|
124
|
+
return store.deleteLayer(layer.id);
|
|
125
|
+
},
|
|
126
|
+
deleteMany(ids) {
|
|
127
|
+
const layers = requireIds(ids).map(require);
|
|
128
|
+
if (store.isReadOnly() || layers.some((layer) => holdsLock(store, layer)))
|
|
129
|
+
return false;
|
|
130
|
+
store.transact(() => {
|
|
131
|
+
for (const layer of layers)
|
|
132
|
+
store.deleteLayer(layer.id);
|
|
133
|
+
});
|
|
134
|
+
return true;
|
|
135
|
+
},
|
|
136
|
+
reorder(order) {
|
|
137
|
+
if (!Array.isArray(order) || order.some((id) => typeof id !== 'string')) {
|
|
138
|
+
throw invalidInput('The order must be an array of strings');
|
|
139
|
+
}
|
|
140
|
+
for (const id of order) {
|
|
141
|
+
if (!store.getLayer(id) && !isStackEntry(id))
|
|
142
|
+
throw notFound('layer', id);
|
|
143
|
+
}
|
|
144
|
+
const listed = new Set(order);
|
|
145
|
+
const layerCount = order.filter((id) => store.getLayer(id)).length;
|
|
146
|
+
if (listed.size !== order.length || layerCount !== store.listLayers().length) {
|
|
147
|
+
throw invalidInput('The order must list every layer once, and no entry twice');
|
|
148
|
+
}
|
|
149
|
+
if (store.isReadOnly())
|
|
150
|
+
return false;
|
|
151
|
+
// An entry left out of the order keeps its position; the entries given fill the rest
|
|
152
|
+
const next = [...order];
|
|
153
|
+
const current = store.getLayerOrder();
|
|
154
|
+
const merged = current.map((id) => listed.has(id) || store.getLayer(id) ? next.shift() : id);
|
|
155
|
+
merged.push(...next);
|
|
156
|
+
return store.setLayerOrder(merged);
|
|
157
|
+
},
|
|
158
|
+
getOrder() {
|
|
159
|
+
return Object.freeze(store.getLayerOrder().filter((id) => store.getLayer(id) !== undefined || isStackEntry(id)));
|
|
160
|
+
},
|
|
161
|
+
getActive() {
|
|
162
|
+
const id = deps.getActiveLayerId();
|
|
163
|
+
return store.getLayer(id) ?? null;
|
|
164
|
+
},
|
|
165
|
+
setActive(id) {
|
|
166
|
+
const layer = require(id);
|
|
167
|
+
if (layer.locked)
|
|
168
|
+
return false;
|
|
169
|
+
deps.setActiveLayerId(layer.id);
|
|
170
|
+
return true;
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** Whether a deletion of the layer is refused: it, or a feature or group in it, is locked */
|
|
175
|
+
function holdsLock(store, layer) {
|
|
176
|
+
if (locksIgnored(store))
|
|
177
|
+
return false;
|
|
178
|
+
if (layer.locked)
|
|
179
|
+
return true;
|
|
180
|
+
for (const itemId of layer.items) {
|
|
181
|
+
if (store.getGroup(itemId)?.locked)
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
return store
|
|
185
|
+
.listFeatures()
|
|
186
|
+
.some((feature) => feature.layerId === layer.id && featureLocked(store, feature));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Creates a prepared layer and puts it at its index of the stacking order, in the transaction
|
|
190
|
+
* of the caller
|
|
191
|
+
*
|
|
192
|
+
* @internal
|
|
193
|
+
*/
|
|
194
|
+
export function insertLayer(store, { layer, index }) {
|
|
195
|
+
store.createLayer(layer);
|
|
196
|
+
if (index !== undefined) {
|
|
197
|
+
const order = store.getLayerOrder().filter((id) => id !== layer.id);
|
|
198
|
+
order.splice(Math.min(index, order.length), 0, layer.id);
|
|
199
|
+
store.setLayerOrder(order);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Checks an input and builds the layer to store; throws DrawError on a wrong input
|
|
204
|
+
*
|
|
205
|
+
* @param pending - The IDs taken by the other entries of the same write
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
export function prepareLayer(deps, input, pending) {
|
|
209
|
+
const { store } = deps;
|
|
210
|
+
requireRecord(input, 'The input');
|
|
211
|
+
const record = input;
|
|
212
|
+
onlyKeys(record, INPUT_KEYS, 'The input');
|
|
213
|
+
checkLayerFields(record);
|
|
214
|
+
const index = optionalIndex(input.index);
|
|
215
|
+
let id;
|
|
216
|
+
if (input.id === undefined) {
|
|
217
|
+
id = deps.generateId();
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
id = requireId(input.id);
|
|
221
|
+
if (isTaken(store, id) || pending.has(id) || store.getLayerOrder().includes(id)) {
|
|
222
|
+
throw new DrawError('already-exists', `The ID ${JSON.stringify(id)} is already taken`, {
|
|
223
|
+
id,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
layer: {
|
|
229
|
+
id,
|
|
230
|
+
name: input.name ?? deps.autoNameGenerator.generateLayerName(),
|
|
231
|
+
visible: input.visible ?? true,
|
|
232
|
+
locked: input.locked ?? false,
|
|
233
|
+
opacity: input.opacity ?? 1,
|
|
234
|
+
items: [],
|
|
235
|
+
styleRule: input.styleRule,
|
|
236
|
+
metadata: input.metadata,
|
|
237
|
+
},
|
|
238
|
+
index,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/** Checks a patch and builds the updates of the Store; throws DrawError on a wrong patch */
|
|
242
|
+
function prepareLayerPatch(patch) {
|
|
243
|
+
requireRecord(patch, 'The patch');
|
|
244
|
+
const record = patch;
|
|
245
|
+
onlyKeys(record, PATCH_KEYS, 'The patch');
|
|
246
|
+
checkLayerFields(record);
|
|
247
|
+
const updates = {};
|
|
248
|
+
for (const key of PATCH_KEYS) {
|
|
249
|
+
if (!(key in record))
|
|
250
|
+
continue;
|
|
251
|
+
// A styleRule or a metadata given as undefined removes it; the other keys keep their value
|
|
252
|
+
if (record[key] === undefined && key !== 'styleRule' && key !== 'metadata')
|
|
253
|
+
continue;
|
|
254
|
+
updates[key] = record[key];
|
|
255
|
+
}
|
|
256
|
+
return updates;
|
|
257
|
+
}
|
|
258
|
+
/** Checks the fields of a layer input or patch */
|
|
259
|
+
function checkLayerFields(record) {
|
|
260
|
+
optionalString(record, 'name');
|
|
261
|
+
optionalBoolean(record, 'visible');
|
|
262
|
+
optionalBoolean(record, 'locked');
|
|
263
|
+
const { opacity, styleRule, metadata } = record;
|
|
264
|
+
if (opacity !== undefined && (typeof opacity !== 'number' || !(opacity >= 0 && opacity <= 1))) {
|
|
265
|
+
throw invalidInput('opacity must be a number from 0 to 1');
|
|
266
|
+
}
|
|
267
|
+
if (styleRule !== undefined && !isStyleRule(styleRule)) {
|
|
268
|
+
throw invalidInput('styleRule is not a valid style rule');
|
|
269
|
+
}
|
|
270
|
+
if (metadata !== undefined && !isRecord(metadata)) {
|
|
271
|
+
throw invalidInput('metadata must be an object');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/** Whether the value has the shape of a style rule */
|
|
275
|
+
function isStyleRule(value) {
|
|
276
|
+
if (!isRecord(value))
|
|
277
|
+
return false;
|
|
278
|
+
const isString = (v) => typeof v === 'string';
|
|
279
|
+
const isNumber = (v) => typeof v === 'number' && Number.isFinite(v);
|
|
280
|
+
switch (value.kind) {
|
|
281
|
+
case 'single':
|
|
282
|
+
return isString(value.color);
|
|
283
|
+
case 'categorical':
|
|
284
|
+
return (isString(value.property) &&
|
|
285
|
+
isRecord(value.map) &&
|
|
286
|
+
Object.values(value.map).every(isString) &&
|
|
287
|
+
isString(value.other));
|
|
288
|
+
case 'graduated':
|
|
289
|
+
return (isString(value.property) &&
|
|
290
|
+
Array.isArray(value.breaks) &&
|
|
291
|
+
value.breaks.every(isNumber) &&
|
|
292
|
+
Array.isArray(value.colors) &&
|
|
293
|
+
value.colors.every(isString) &&
|
|
294
|
+
value.colors.length === value.breaks.length + 1 &&
|
|
295
|
+
isString(value.other));
|
|
296
|
+
case 'continuous':
|
|
297
|
+
return (isString(value.property) &&
|
|
298
|
+
isNumber(value.min) &&
|
|
299
|
+
isNumber(value.max) &&
|
|
300
|
+
Array.isArray(value.ramp) &&
|
|
301
|
+
value.ramp.length === 2 &&
|
|
302
|
+
value.ramp.every(isString) &&
|
|
303
|
+
isString(value.other));
|
|
304
|
+
default:
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { optionalString, requireRecord } from './shared.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates `draw.metadata`
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function createMetadata(deps) {
|
|
10
|
+
const { store } = deps;
|
|
11
|
+
return {
|
|
12
|
+
get: () => store.getMetadata(),
|
|
13
|
+
update(patch) {
|
|
14
|
+
requireRecord(patch, 'The patch');
|
|
15
|
+
optionalString(patch, 'title');
|
|
16
|
+
optionalString(patch, 'description');
|
|
17
|
+
if (!store.setMetadata(patch))
|
|
18
|
+
return null;
|
|
19
|
+
return store.getMetadata();
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|