@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
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Import / export of the native format
|
|
5
|
+
*/
|
|
6
|
+
import { getDrawProperty } from '../../../shared/properties.js';
|
|
3
7
|
import { NATIVE_VERSION } from './constants.js';
|
|
8
|
+
import { upgradeNativeData } from './native-upgrade.js';
|
|
4
9
|
import { validateNativeData } from './native-validation.js';
|
|
5
10
|
/** The layer that survives the replacement (it is updated in place when the data has it) */
|
|
6
11
|
const DEFAULT_LAYER_ID = 'default-layer';
|
|
@@ -8,9 +13,9 @@ const DEFAULT_LAYER_ID = 'default-layer';
|
|
|
8
13
|
* Exports the current data in the native format
|
|
9
14
|
*/
|
|
10
15
|
export function exportNative(store, options) {
|
|
11
|
-
let features = store.
|
|
12
|
-
const layers = store.
|
|
13
|
-
const groups = store.
|
|
16
|
+
let features = store.listFeatures();
|
|
17
|
+
const layers = store.listLayers();
|
|
18
|
+
const groups = store.listGroups();
|
|
14
19
|
if (options?.featureIds && options.featureIds.length > 0) {
|
|
15
20
|
const featureIdSet = new Set(options.featureIds);
|
|
16
21
|
features = features.filter((f) => featureIdSet.has(f.id));
|
|
@@ -22,11 +27,12 @@ export function exportNative(store, options) {
|
|
|
22
27
|
// Get only the files that are in use
|
|
23
28
|
const usedFileIds = new Set();
|
|
24
29
|
for (const feature of features) {
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
const imageFileId = getDrawProperty(feature, 'imageFileId');
|
|
31
|
+
if (feature.type === 'Image' && imageFileId) {
|
|
32
|
+
usedFileIds.add(imageFileId);
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
|
-
const files = store.
|
|
35
|
+
const files = store.listFiles();
|
|
30
36
|
const filesRecord = {};
|
|
31
37
|
for (const file of files) {
|
|
32
38
|
if (usedFileIds.has(file.id)) {
|
|
@@ -49,9 +55,10 @@ export function exportNative(store, options) {
|
|
|
49
55
|
};
|
|
50
56
|
}
|
|
51
57
|
/**
|
|
52
|
-
*
|
|
58
|
+
* Reads the native format for a load that replaces the existing data: everything is checked
|
|
59
|
+
* here, and the writes are left to the transaction of the caller
|
|
53
60
|
*/
|
|
54
|
-
export async function
|
|
61
|
+
export async function prepareNative(data, deps) {
|
|
55
62
|
const { store } = deps;
|
|
56
63
|
// Validate before applying. Since store.transact does not roll back, if an exception
|
|
57
64
|
// is thrown on invalid data after the existing data has been cleared, the existing data
|
|
@@ -62,23 +69,25 @@ export async function loadNative(data, deps) {
|
|
|
62
69
|
const retainedLayerIds = new Set();
|
|
63
70
|
if (store.getLayer(DEFAULT_LAYER_ID))
|
|
64
71
|
retainedLayerIds.add(DEFAULT_LAYER_ID);
|
|
65
|
-
|
|
72
|
+
// Data of an earlier major version is brought to the current one first
|
|
73
|
+
const upgraded = upgradeNativeData(data);
|
|
74
|
+
const { layers, layerOrder, groups, features, files } = await validateNativeData(upgraded, retainedLayerIds);
|
|
66
75
|
const featureIds = features.map((f) => f.id);
|
|
67
76
|
// A kept layer the data does not list goes to the back, where it stays when the data does
|
|
68
77
|
// not mention it (every layer must be on the stacking order to be drawn)
|
|
69
78
|
const retainedUnlisted = [...retainedLayerIds].filter((id) => !layerOrder.includes(id));
|
|
70
|
-
//
|
|
71
|
-
|
|
79
|
+
// The writes, in the transaction of the caller, which makes them one change
|
|
80
|
+
const write = () => {
|
|
72
81
|
// 1. Clear the existing data
|
|
73
|
-
const existingFeatures = store.
|
|
82
|
+
const existingFeatures = store.listFeatures();
|
|
74
83
|
for (const feature of existingFeatures) {
|
|
75
84
|
store.deleteFeature(feature.id);
|
|
76
85
|
}
|
|
77
|
-
const existingGroups = store.
|
|
86
|
+
const existingGroups = store.listGroups();
|
|
78
87
|
for (const group of existingGroups) {
|
|
79
88
|
store.deleteGroup(group.id);
|
|
80
89
|
}
|
|
81
|
-
const existingLayers = store.
|
|
90
|
+
const existingLayers = store.listLayers();
|
|
82
91
|
for (const layer of existingLayers) {
|
|
83
92
|
if (layer.id !== DEFAULT_LAYER_ID) {
|
|
84
93
|
store.deleteLayer(layer.id);
|
|
@@ -86,7 +95,7 @@ export async function loadNative(data, deps) {
|
|
|
86
95
|
}
|
|
87
96
|
// The files belong to the features that were just removed, and the data brings its own
|
|
88
97
|
// (leaving them would also make a file id of the data collide)
|
|
89
|
-
for (const file of store.
|
|
98
|
+
for (const file of store.listFiles()) {
|
|
90
99
|
store.deleteFile(file.id);
|
|
91
100
|
}
|
|
92
101
|
// 2. Import the layers
|
|
@@ -114,13 +123,14 @@ export async function loadNative(data, deps) {
|
|
|
114
123
|
// nothing of the previous document is left on it
|
|
115
124
|
store.setLayerOrder([...retainedUnlisted, ...layerOrder]);
|
|
116
125
|
// 7. Import the metadata
|
|
117
|
-
if (
|
|
118
|
-
store.setMetadata(
|
|
126
|
+
if (upgraded.metadata) {
|
|
127
|
+
store.setMetadata(upgraded.metadata);
|
|
119
128
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
129
|
+
return {
|
|
130
|
+
format: 'native',
|
|
131
|
+
featureIds,
|
|
132
|
+
replaced: true,
|
|
133
|
+
};
|
|
125
134
|
};
|
|
135
|
+
return { write };
|
|
126
136
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrades native data of an earlier major version to the version this library writes
|
|
3
|
+
*
|
|
4
|
+
* @param data - the data as it was read
|
|
5
|
+
* @returns the upgraded data, or the data as it is when it is of the current major version,
|
|
6
|
+
* of a version without an upgrade, or not an object
|
|
7
|
+
*/
|
|
8
|
+
export declare function upgradeNativeData(data: unknown): unknown;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Upgrades native data written by an earlier major version to the current one
|
|
5
|
+
*
|
|
6
|
+
* Each step takes data of one major version to the next, and the steps run in a chain until
|
|
7
|
+
* the data reaches the version this library writes. A step only renames and moves fields; it
|
|
8
|
+
* checks nothing, and leaves a value it does not understand as it is, so that the validation
|
|
9
|
+
* that follows reports it. Data of a major version without a step is returned as it is, and
|
|
10
|
+
* the validation rejects its version.
|
|
11
|
+
*/
|
|
12
|
+
import { DRAW_PROPERTY_NAMES, drawPropertyKey } from '../../../shared/properties.js';
|
|
13
|
+
import { geometryFromCoordinates } from '../../../shared/utils/coordinates.js';
|
|
14
|
+
import { NATIVE_VERSION } from './constants.js';
|
|
15
|
+
import { foldLegacyImageStyle } from './legacy-image-style.js';
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
/** Whether the object has the key as an own property */
|
|
20
|
+
function hasOwnKey(value, key) {
|
|
21
|
+
return Object.getOwnPropertyDescriptor(value, key) !== undefined;
|
|
22
|
+
}
|
|
23
|
+
/** The major version of a semantic version, or null when it is not one */
|
|
24
|
+
function majorOf(version) {
|
|
25
|
+
if (typeof version !== 'string')
|
|
26
|
+
return null;
|
|
27
|
+
const match = /^(\d+)\.\d+\.\d+(?:[-+].*)?$/.exec(version);
|
|
28
|
+
return match ? Number(match[1]) : null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 2.x to 3.0.0: the document model of the 2.0 API
|
|
32
|
+
*
|
|
33
|
+
* - a feature holds a GeoJSON `geometry` instead of `coordinates`
|
|
34
|
+
* - the values of the library in `properties` get the `maplibre-gl-draw:` prefix
|
|
35
|
+
* - the `order` of a layer becomes `items`
|
|
36
|
+
* - the size, the rotation and the opacity in the style of an Image move to the prefixed
|
|
37
|
+
* `imageWidth`, `imageHeight` and `rotation` in `properties` and to `imageOpacity`
|
|
38
|
+
* - a group gets the `layerId` of the layer whose items list it (or of its first member, and
|
|
39
|
+
* `''` when it has neither)
|
|
40
|
+
*/
|
|
41
|
+
function upgradeFrom2(data) {
|
|
42
|
+
const layers = Array.isArray(data.layers)
|
|
43
|
+
? data.layers.map((layer) => {
|
|
44
|
+
if (!isRecord(layer) || !('order' in layer) || 'items' in layer)
|
|
45
|
+
return layer;
|
|
46
|
+
const { order, ...rest } = layer;
|
|
47
|
+
return { ...rest, items: order };
|
|
48
|
+
})
|
|
49
|
+
: data.layers;
|
|
50
|
+
const features = Array.isArray(data.features)
|
|
51
|
+
? data.features.map((feature) => isRecord(feature) ? upgradeFeature(feature) : feature)
|
|
52
|
+
: data.features;
|
|
53
|
+
const layerOfItem = new Map();
|
|
54
|
+
if (Array.isArray(layers)) {
|
|
55
|
+
for (const layer of layers) {
|
|
56
|
+
if (!isRecord(layer) || typeof layer.id !== 'string' || !Array.isArray(layer.items))
|
|
57
|
+
continue;
|
|
58
|
+
for (const item of layer.items) {
|
|
59
|
+
if (typeof item === 'string' && !layerOfItem.has(item))
|
|
60
|
+
layerOfItem.set(item, layer.id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const layerOfFeature = new Map();
|
|
65
|
+
if (Array.isArray(features)) {
|
|
66
|
+
for (const feature of features) {
|
|
67
|
+
if (isRecord(feature) && typeof feature.id === 'string') {
|
|
68
|
+
if (typeof feature.layerId === 'string')
|
|
69
|
+
layerOfFeature.set(feature.id, feature.layerId);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const groups = Array.isArray(data.groups)
|
|
74
|
+
? data.groups.map((group) => {
|
|
75
|
+
if (!isRecord(group) || 'layerId' in group || typeof group.id !== 'string')
|
|
76
|
+
return group;
|
|
77
|
+
const members = Array.isArray(group.featureIds) ? group.featureIds : [];
|
|
78
|
+
const layerId = layerOfItem.get(group.id) ??
|
|
79
|
+
members
|
|
80
|
+
.map((id) => (typeof id === 'string' ? layerOfFeature.get(id) : undefined))
|
|
81
|
+
.find((id) => id !== undefined);
|
|
82
|
+
// A group that no layer lists and that has no member belongs to no layer
|
|
83
|
+
return { ...group, layerId: layerId ?? '' };
|
|
84
|
+
})
|
|
85
|
+
: data.groups;
|
|
86
|
+
return { ...data, version: '3.0.0', layers, groups, features };
|
|
87
|
+
}
|
|
88
|
+
/** A feature of version 2 in the shape of version 3 */
|
|
89
|
+
function upgradeFeature(feature) {
|
|
90
|
+
let result = feature;
|
|
91
|
+
if ('coordinates' in feature && !('geometry' in feature)) {
|
|
92
|
+
const { coordinates, ...rest } = feature;
|
|
93
|
+
const geometry = typeof feature.type === 'string' && Array.isArray(coordinates)
|
|
94
|
+
? geometryFromCoordinates(feature.type, coordinates)
|
|
95
|
+
: // Left for the validation to report
|
|
96
|
+
{ type: undefined, coordinates };
|
|
97
|
+
result = { ...rest, geometry };
|
|
98
|
+
}
|
|
99
|
+
if (isRecord(feature.properties)) {
|
|
100
|
+
const properties = { ...feature.properties };
|
|
101
|
+
for (const name of DRAW_PROPERTY_NAMES) {
|
|
102
|
+
const key = drawPropertyKey(name);
|
|
103
|
+
if (hasOwnKey(properties, name) && !hasOwnKey(properties, key)) {
|
|
104
|
+
properties[key] = properties[name];
|
|
105
|
+
delete properties[name];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
result = { ...result, properties };
|
|
109
|
+
if (feature.type === 'Image' && isRecord(feature.style)) {
|
|
110
|
+
const style = { ...feature.style };
|
|
111
|
+
if (foldLegacyImageStyle(properties, style))
|
|
112
|
+
result = { ...result, style };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
/** The step that takes data of each major version to the next */
|
|
118
|
+
const UPGRADES = new Map([[2, upgradeFrom2]]);
|
|
119
|
+
/**
|
|
120
|
+
* Upgrades native data of an earlier major version to the version this library writes
|
|
121
|
+
*
|
|
122
|
+
* @param data - the data as it was read
|
|
123
|
+
* @returns the upgraded data, or the data as it is when it is of the current major version,
|
|
124
|
+
* of a version without an upgrade, or not an object
|
|
125
|
+
*/
|
|
126
|
+
export function upgradeNativeData(data) {
|
|
127
|
+
if (!isRecord(data))
|
|
128
|
+
return data;
|
|
129
|
+
const current = majorOf(NATIVE_VERSION);
|
|
130
|
+
let result = data;
|
|
131
|
+
for (let major = majorOf(result.version); major !== null && major !== current;) {
|
|
132
|
+
const step = UPGRADES.get(major);
|
|
133
|
+
if (!step)
|
|
134
|
+
break;
|
|
135
|
+
result = step(result);
|
|
136
|
+
major = majorOf(result.version);
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* deleted: a problem throws while the existing data is still intact. The checks follow the
|
|
7
7
|
* native format described in docs/reference/data-format.md.
|
|
8
8
|
*/
|
|
9
|
-
import type { Data, Feature, FileData, Group, Layer } from '
|
|
9
|
+
import type { Data, Feature, FileData, Group, Layer } from '../../../store/types.js';
|
|
10
10
|
/** Native data that passed validation, with the files normalized */
|
|
11
11
|
export interface ValidatedNativeData {
|
|
12
12
|
layers: Layer[];
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DrawError } from '../../errors.js';
|
|
3
4
|
import { NATIVE_VERSION } from './constants.js';
|
|
4
5
|
import { normalizeEmbeddedFile } from './embedded-file.js';
|
|
5
|
-
import {
|
|
6
|
+
import { describeGeometryProblem } from './geometry-validation.js';
|
|
6
7
|
import { sanitizeFeatureStyle } from './style-validation.js';
|
|
7
8
|
function fail(message) {
|
|
8
|
-
throw new
|
|
9
|
+
throw new DrawError('invalid-input', `Invalid native data: ${message}`);
|
|
9
10
|
}
|
|
10
11
|
function isRecord(value) {
|
|
11
12
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -28,8 +29,8 @@ function validateLayer(layer, index) {
|
|
|
28
29
|
if (typeof layer.opacity !== 'number' || !Number.isFinite(layer.opacity)) {
|
|
29
30
|
fail(`${where} has no finite opacity`);
|
|
30
31
|
}
|
|
31
|
-
if (!Array.isArray(layer.
|
|
32
|
-
fail(`${where} has no
|
|
32
|
+
if (!Array.isArray(layer.items) || !layer.items.every((id) => typeof id === 'string')) {
|
|
33
|
+
fail(`${where} has no items array of strings`);
|
|
33
34
|
}
|
|
34
35
|
if (layer.metadata !== undefined && !isRecord(layer.metadata)) {
|
|
35
36
|
fail(`${where} has a metadata that is not an object`);
|
|
@@ -51,6 +52,8 @@ function validateGroup(group, index) {
|
|
|
51
52
|
fail(`${where} has no boolean visible`);
|
|
52
53
|
if (typeof group.locked !== 'boolean')
|
|
53
54
|
fail(`${where} has no boolean locked`);
|
|
55
|
+
if (typeof group.layerId !== 'string')
|
|
56
|
+
fail(`${where} has no string layerId`);
|
|
54
57
|
if (!Array.isArray(group.featureIds) || !group.featureIds.every((id) => typeof id === 'string')) {
|
|
55
58
|
fail(`${where} has no featureIds array of strings`);
|
|
56
59
|
}
|
|
@@ -95,9 +98,9 @@ function validateFeature(feature, index, layerIds, groupIds) {
|
|
|
95
98
|
const where = `feature "${feature.id}"`;
|
|
96
99
|
if (!isNonEmptyString(feature.type))
|
|
97
100
|
fail(`${where} has no string type`);
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
fail(`${where} has ${
|
|
101
|
+
const geometryProblem = describeGeometryProblem(feature.type, feature.geometry);
|
|
102
|
+
if (geometryProblem)
|
|
103
|
+
fail(`${where} has ${geometryProblem}`);
|
|
101
104
|
if (typeof feature.layerId !== 'string' || !layerIds.has(feature.layerId)) {
|
|
102
105
|
fail(`${where} refers to a layer that does not exist`);
|
|
103
106
|
}
|
|
@@ -115,12 +118,10 @@ function validateFeature(feature, index, layerIds, groupIds) {
|
|
|
115
118
|
if (typeof feature.locked !== 'boolean')
|
|
116
119
|
fail(`${where} has no boolean locked`);
|
|
117
120
|
// A style key of the wrong type or form is dropped rather than rejecting the file: the
|
|
118
|
-
// store accepts any value through its API, so the library's own export can carry one
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const style = sanitizeFeatureStyle(feature.style);
|
|
123
|
-
return (style === undefined ? rest : { ...rest, style });
|
|
121
|
+
// store accepts any value through its API, so the library's own export can carry one. A
|
|
122
|
+
// feature without a usable style gets the empty style
|
|
123
|
+
const style = feature.style === undefined ? undefined : sanitizeFeatureStyle(feature.style);
|
|
124
|
+
return { ...feature, style: style ?? {} };
|
|
124
125
|
}
|
|
125
126
|
async function validateFiles(files) {
|
|
126
127
|
if (files === undefined)
|
|
@@ -190,7 +191,7 @@ export async function validateNativeData(data, retainedLayerIds) {
|
|
|
190
191
|
layerIds.add(layer.id);
|
|
191
192
|
}
|
|
192
193
|
const layerOrder = validateLayerOrder(data.layerOrder, layers);
|
|
193
|
-
// Feature and group IDs share the entries of layer.
|
|
194
|
+
// Feature and group IDs share the entries of layer.items, so they must not collide either
|
|
194
195
|
const itemIds = new Set();
|
|
195
196
|
const groups = (data.groups ?? []).map(validateGroup);
|
|
196
197
|
const groupIds = new Set();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FeatureStyle } from '../../../store/types.js';
|
|
2
|
+
type Check = (value: unknown) => boolean;
|
|
3
|
+
/** A CSS color */
|
|
4
|
+
export declare const isCssColor: Check;
|
|
5
|
+
/**
|
|
6
|
+
* Returns the usable part of an imported style
|
|
7
|
+
*
|
|
8
|
+
* A key of FeatureStyle whose value fails its check is dropped; every other key is kept.
|
|
9
|
+
*
|
|
10
|
+
* @param value The style as read from the file
|
|
11
|
+
* @returns The style, or undefined when the value is not an object or nothing is left
|
|
12
|
+
*/
|
|
13
|
+
export declare function sanitizeFeatureStyle(value: unknown): FeatureStyle | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Describes the first key of a style whose value fails its check
|
|
16
|
+
*
|
|
17
|
+
* A key given as `undefined` is not checked (it removes the key in a patch), and a key this
|
|
18
|
+
* library does not define is not checked either.
|
|
19
|
+
*
|
|
20
|
+
* @param value The style
|
|
21
|
+
* @returns A short description of the problem, or null when there is none
|
|
22
|
+
*/
|
|
23
|
+
export declare function describeStyleProblem(value: unknown): string | null;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Validation of an imported feature style
|
|
5
|
+
*
|
|
6
|
+
* A style arrives from a file (the maplibre-gl-draw:style property of GeoJSON, the style of a
|
|
7
|
+
* native feature, the simplestyle-spec keys) and reaches the renderer, which parses the
|
|
8
|
+
* colors as CSS colors and uses the numbers as they are. A value of the wrong type or form (a
|
|
9
|
+
* number or null for a color, a string that is not a CSS color, an opacity of 5) would be
|
|
10
|
+
* drawn wrong, so each known key is checked here and a key that fails is dropped. Keys this
|
|
11
|
+
* library does not define are kept unchanged, whatever their value: they belong to the host or
|
|
12
|
+
* to an extension, which gives features keys of its own and checks their values where it reads
|
|
13
|
+
* them (values reach the Store through updateFeature and a replaced store as well, without
|
|
14
|
+
* passing here).
|
|
15
|
+
*/
|
|
16
|
+
import { isColor } from '../../../shared/color.js';
|
|
17
|
+
import { setOwnProperty } from './own-property.js';
|
|
18
|
+
/** A CSS color */
|
|
19
|
+
export const isCssColor = isColor;
|
|
20
|
+
const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
|
|
21
|
+
const isOpacity = (value) => isFiniteNumber(value) && value >= 0 && value <= 1;
|
|
22
|
+
const isNonNegative = (value) => isFiniteNumber(value) && value >= 0;
|
|
23
|
+
const oneOf = (...values) => (value) => typeof value === 'string' && values.includes(value);
|
|
24
|
+
/** The check of every key of FeatureStyle */
|
|
25
|
+
const STYLE_CHECK_TABLE = {
|
|
26
|
+
fillColor: isCssColor,
|
|
27
|
+
fillOpacity: isOpacity,
|
|
28
|
+
strokeColor: isCssColor,
|
|
29
|
+
strokeWidth: isNonNegative,
|
|
30
|
+
strokeOpacity: isOpacity,
|
|
31
|
+
lineStyle: oneOf('solid', 'dashed', 'dotted'),
|
|
32
|
+
pointRadius: isNonNegative,
|
|
33
|
+
pointColor: isCssColor,
|
|
34
|
+
pointShape: oneOf('circle', 'square', 'triangle', 'star'),
|
|
35
|
+
pointOpacity: isOpacity,
|
|
36
|
+
pointStrokeColor: isCssColor,
|
|
37
|
+
pointStrokeWidth: isNonNegative,
|
|
38
|
+
imageOpacity: isOpacity,
|
|
39
|
+
};
|
|
40
|
+
const STYLE_CHECKS = new Map(Object.entries(STYLE_CHECK_TABLE));
|
|
41
|
+
function isRecord(value) {
|
|
42
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns the usable part of an imported style
|
|
46
|
+
*
|
|
47
|
+
* A key of FeatureStyle whose value fails its check is dropped; every other key is kept.
|
|
48
|
+
*
|
|
49
|
+
* @param value The style as read from the file
|
|
50
|
+
* @returns The style, or undefined when the value is not an object or nothing is left
|
|
51
|
+
*/
|
|
52
|
+
export function sanitizeFeatureStyle(value) {
|
|
53
|
+
if (!isRecord(value))
|
|
54
|
+
return undefined;
|
|
55
|
+
const style = {};
|
|
56
|
+
let kept = 0;
|
|
57
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
58
|
+
const check = STYLE_CHECKS.get(key);
|
|
59
|
+
if (check && !check(entry))
|
|
60
|
+
continue;
|
|
61
|
+
setOwnProperty(style, key, entry);
|
|
62
|
+
kept++;
|
|
63
|
+
}
|
|
64
|
+
return kept > 0 ? style : undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Describes the first key of a style whose value fails its check
|
|
68
|
+
*
|
|
69
|
+
* A key given as `undefined` is not checked (it removes the key in a patch), and a key this
|
|
70
|
+
* library does not define is not checked either.
|
|
71
|
+
*
|
|
72
|
+
* @param value The style
|
|
73
|
+
* @returns A short description of the problem, or null when there is none
|
|
74
|
+
*/
|
|
75
|
+
export function describeStyleProblem(value) {
|
|
76
|
+
if (!isRecord(value))
|
|
77
|
+
return 'a style that is not an object';
|
|
78
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
79
|
+
if (entry === undefined)
|
|
80
|
+
continue;
|
|
81
|
+
const check = STYLE_CHECKS.get(key);
|
|
82
|
+
if (check && !check(entry))
|
|
83
|
+
return `a style whose ${key} is not valid`;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types internal to the Import/Export module
|
|
3
|
+
*/
|
|
4
|
+
import type { Feature, FileData, LoadResult } from '../../../store/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* A load whose source is read, checked and decoded: what is left is to write it, inside the
|
|
7
|
+
* transaction of the caller. Nothing that can fail is left to `write`, because a transaction
|
|
8
|
+
* does not roll back.
|
|
9
|
+
*/
|
|
10
|
+
export interface PreparedLoad {
|
|
11
|
+
/** Writes what was read and returns what was loaded */
|
|
12
|
+
write(): LoadResult;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* GeoJSON import result (internal use).
|
|
16
|
+
*
|
|
17
|
+
* For a feature that contains image data, fileData is returned alongside it.
|
|
18
|
+
*/
|
|
19
|
+
export interface ConvertedFeatureResult {
|
|
20
|
+
feature: Feature;
|
|
21
|
+
fileData?: FileData;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options for GeoJSON import
|
|
25
|
+
*/
|
|
26
|
+
export interface GeoJSONImportOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Whether to expand Multi* geometries into features with a single geometry
|
|
29
|
+
*
|
|
30
|
+
* The default is false, which keeps MultiPoint / MultiLineString / MultiPolygon
|
|
31
|
+
* as Multi features as they are (so properties are not duplicated).
|
|
32
|
+
* Setting it to true expands them as before, assigning a new ID to each part.
|
|
33
|
+
*/
|
|
34
|
+
flattenMulti?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The layer every feature goes into, over the layer a feature names itself with
|
|
37
|
+
* `maplibre-gl-draw:layerId`. A group of another layer is then dropped from the feature
|
|
38
|
+
*/
|
|
39
|
+
layerId?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the features and the groups of the document are replaced: they are deleted in the
|
|
42
|
+
* same transaction that writes the features of the file, and the layers stay
|
|
43
|
+
*/
|
|
44
|
+
replace?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether every feature goes into one layer (the one of `layerId`, else the current one) and
|
|
47
|
+
* leaves the group it names, because the load puts them all into a new group
|
|
48
|
+
*/
|
|
49
|
+
oneGroup?: boolean;
|
|
50
|
+
/** IDs the features must not take, such as those of a layer and a group the load creates */
|
|
51
|
+
reservedIds?: ReadonlySet<string>;
|
|
52
|
+
}
|