@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,280 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DrawError } from '../errors.js';
|
|
4
|
+
import { insertGroup, prepareGroupShell } from './groups.js';
|
|
5
|
+
import { isGeoJSONFeatureCollection, isNativeFormat } from './import-export/format-detection.js';
|
|
6
|
+
import { exportGeoJSON } from './import-export/geojson-export.js';
|
|
7
|
+
import { prepareGeoJSON } from './import-export/geojson-import.js';
|
|
8
|
+
import { prepareImage } from './import-export/image-import.js';
|
|
9
|
+
import { exportNative, prepareNative } from './import-export/native-format.js';
|
|
10
|
+
import { insertLayer, prepareLayer } from './layers.js';
|
|
11
|
+
import { invalidInput, isRecord, isTaken, notFound } from './shared.js';
|
|
12
|
+
const GEOMETRY_TYPES = new Set([
|
|
13
|
+
'Point',
|
|
14
|
+
'LineString',
|
|
15
|
+
'Polygon',
|
|
16
|
+
'MultiPoint',
|
|
17
|
+
'MultiLineString',
|
|
18
|
+
'MultiPolygon',
|
|
19
|
+
'GeometryCollection',
|
|
20
|
+
]);
|
|
21
|
+
/** The source of the writes of a load, of every format, as its notification carries it */
|
|
22
|
+
const LOAD_SOURCE = 'load';
|
|
23
|
+
/** The keys of the group of the options of a load */
|
|
24
|
+
const GROUP_KEYS = ['id', 'name', 'visible', 'locked'];
|
|
25
|
+
/**
|
|
26
|
+
* Creates `draw.document`
|
|
27
|
+
*
|
|
28
|
+
* @param onLoaded - Called after each load that read something, with the result and the source
|
|
29
|
+
* its writes carried
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export function createDocument(deps, onLoaded) {
|
|
33
|
+
const { store } = deps;
|
|
34
|
+
/**
|
|
35
|
+
* Reads a source, or null when the document is read-only; every failure is a DrawError
|
|
36
|
+
*
|
|
37
|
+
* @param pending - The IDs the layers and groups of the same write take, added to
|
|
38
|
+
* @param createdLayers - The IDs of the layers the earlier items of the same write create,
|
|
39
|
+
* added to: a later item may name one with `layerId`
|
|
40
|
+
*/
|
|
41
|
+
const prepare = async (source, options, pending, createdLayers) => {
|
|
42
|
+
try {
|
|
43
|
+
return await read(source, options, pending, createdLayers);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
// Whatever went wrong, the promise rejects with a DrawError
|
|
47
|
+
throw asDrawError('invalid-input', error);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Writes the loads that were read in one transaction and announces each one, or returns
|
|
52
|
+
* null when the document became read-only while they were read
|
|
53
|
+
*/
|
|
54
|
+
const writeAll = (prepared) => {
|
|
55
|
+
if (store.isReadOnly())
|
|
56
|
+
return null;
|
|
57
|
+
// An ID given to a new layer or group may have been taken while the sources were read;
|
|
58
|
+
// nothing may throw once the writing has started
|
|
59
|
+
for (const { layer, group } of prepared) {
|
|
60
|
+
for (const id of [layer?.layer.id, group?.id]) {
|
|
61
|
+
if (id !== undefined && isTaken(store, id)) {
|
|
62
|
+
throw new DrawError('already-exists', `The ID ${JSON.stringify(id)} is already taken`, {
|
|
63
|
+
id,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const results = store.transact(() => prepared.map(writeItem), LOAD_SOURCE);
|
|
69
|
+
for (const result of results)
|
|
70
|
+
onLoaded?.(result, LOAD_SOURCE);
|
|
71
|
+
return results;
|
|
72
|
+
};
|
|
73
|
+
/** Writes one load: its new layer first, then its features, then the group of them */
|
|
74
|
+
const writeItem = ({ load, layer, group }) => {
|
|
75
|
+
if (layer)
|
|
76
|
+
insertLayer(store, layer);
|
|
77
|
+
const result = load.write();
|
|
78
|
+
if (layer)
|
|
79
|
+
result.layerId = layer.layer.id;
|
|
80
|
+
const first = store.getFeature(result.featureIds[0] ?? '');
|
|
81
|
+
if (group && first) {
|
|
82
|
+
// The features of a grouped load are all in one layer
|
|
83
|
+
const featureIds = result.featureIds.filter((id) => store.getFeature(id)?.layerId === first.layerId);
|
|
84
|
+
insertGroup(store, { ...group, layerId: first.layerId, featureIds });
|
|
85
|
+
result.groupId = group.id;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
async load(source, options) {
|
|
91
|
+
const prepared = await prepare(source, options, new Set(), new Set());
|
|
92
|
+
return prepared ? (writeAll([prepared])?.[0] ?? null) : null;
|
|
93
|
+
},
|
|
94
|
+
async loadMany(items) {
|
|
95
|
+
if (!Array.isArray(items))
|
|
96
|
+
throw invalidInput('The items must be an array');
|
|
97
|
+
for (const item of items) {
|
|
98
|
+
if (!isRecord(item) || !('source' in item)) {
|
|
99
|
+
throw invalidInput('Each item must be an object with a source');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Everything is read before anything is written, so a failure writes nothing
|
|
103
|
+
const prepared = [];
|
|
104
|
+
const pending = new Set();
|
|
105
|
+
const createdLayers = new Set();
|
|
106
|
+
for (const { source, options } of items) {
|
|
107
|
+
const item = await prepare(source, options, pending, createdLayers);
|
|
108
|
+
if (!item)
|
|
109
|
+
return null;
|
|
110
|
+
prepared.push(item);
|
|
111
|
+
}
|
|
112
|
+
return writeAll(prepared);
|
|
113
|
+
},
|
|
114
|
+
toJSON: () => exportNative(store),
|
|
115
|
+
toGeoJSON: () => exportGeoJSON(store),
|
|
116
|
+
};
|
|
117
|
+
async function read(source, given, pending, createdLayers) {
|
|
118
|
+
const options = given ?? {};
|
|
119
|
+
if (!isRecord(options))
|
|
120
|
+
throw invalidInput('The options must be an object');
|
|
121
|
+
const mode = options.mode;
|
|
122
|
+
if (mode !== undefined && mode !== 'replace' && mode !== 'merge') {
|
|
123
|
+
throw invalidInput('mode must be replace or merge');
|
|
124
|
+
}
|
|
125
|
+
if (options.layer !== undefined && options.layerId !== undefined) {
|
|
126
|
+
throw invalidInput('layer and layerId cannot be given together');
|
|
127
|
+
}
|
|
128
|
+
// A layer an earlier item of the same write creates is known: it is written before this one
|
|
129
|
+
if (options.layerId !== undefined &&
|
|
130
|
+
!store.getLayer(options.layerId) &&
|
|
131
|
+
!createdLayers.has(options.layerId)) {
|
|
132
|
+
throw notFound('layer', options.layerId);
|
|
133
|
+
}
|
|
134
|
+
// The new layer and group take their IDs now, so that the items of one write differ
|
|
135
|
+
const layer = options.layer !== undefined ? prepareLayer(deps, options.layer, pending) : undefined;
|
|
136
|
+
if (layer) {
|
|
137
|
+
pending.add(layer.layer.id);
|
|
138
|
+
createdLayers.add(layer.layer.id);
|
|
139
|
+
}
|
|
140
|
+
const group = options.group !== undefined
|
|
141
|
+
? prepareGroupShell(deps, options.group, GROUP_KEYS, pending)
|
|
142
|
+
: undefined;
|
|
143
|
+
if (group)
|
|
144
|
+
pending.add(group.id);
|
|
145
|
+
if (store.isReadOnly())
|
|
146
|
+
return null;
|
|
147
|
+
const load = await readLoad(source, options, layer?.layer.id ?? options.layerId, {
|
|
148
|
+
grouped: group !== undefined,
|
|
149
|
+
creates: layer !== undefined || group !== undefined,
|
|
150
|
+
reservedIds: pending,
|
|
151
|
+
});
|
|
152
|
+
return { load, layer, group };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Reads a source into a load of its format
|
|
156
|
+
*
|
|
157
|
+
* @param layerId - The layer every feature goes into: the one given, or the one the load
|
|
158
|
+
* creates
|
|
159
|
+
*/
|
|
160
|
+
async function readLoad(source, options, layerId, extra) {
|
|
161
|
+
const mode = options.mode;
|
|
162
|
+
const read = await readSource(source);
|
|
163
|
+
const importDeps = {
|
|
164
|
+
store,
|
|
165
|
+
autoNameGenerator: deps.autoNameGenerator,
|
|
166
|
+
generateFeatureId: deps.generateId,
|
|
167
|
+
// The layer of the options, unless another load of the same transaction removed it
|
|
168
|
+
getCurrentLayerId: () => layerId !== undefined && store.getLayer(layerId) ? layerId : deps.getActiveLayerId(),
|
|
169
|
+
};
|
|
170
|
+
if (read.kind === 'image') {
|
|
171
|
+
if (!options.coordinate)
|
|
172
|
+
throw invalidInput('An image needs the coordinate option');
|
|
173
|
+
const replace = mode === 'replace';
|
|
174
|
+
const prepared = await prepareImage(read.file, {
|
|
175
|
+
coordinate: options.coordinate,
|
|
176
|
+
zoom: options.zoom,
|
|
177
|
+
layerId,
|
|
178
|
+
flattenMulti: options.flattenMulti,
|
|
179
|
+
}, importDeps,
|
|
180
|
+
// With replace, the features and groups go in the transaction that adds the image
|
|
181
|
+
replace ? () => deleteFeaturesAndGroups(store) : undefined);
|
|
182
|
+
if (!replace)
|
|
183
|
+
return prepared;
|
|
184
|
+
return { write: () => ({ ...prepared.write(), replaced: true }) };
|
|
185
|
+
}
|
|
186
|
+
const { data } = read;
|
|
187
|
+
if (isNativeFormat(data)) {
|
|
188
|
+
if (mode === 'merge') {
|
|
189
|
+
throw invalidInput('A document of the library can only replace the document');
|
|
190
|
+
}
|
|
191
|
+
if (extra.creates) {
|
|
192
|
+
throw invalidInput('A document of the library brings its own layers and groups');
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
return await prepareNative(data, { store });
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
throw asDrawError('invalid-input', error);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const collection = toFeatureCollection(data);
|
|
202
|
+
if (collection === null) {
|
|
203
|
+
throw new DrawError('unsupported-format', 'The source is neither a document of the library nor GeoJSON');
|
|
204
|
+
}
|
|
205
|
+
// The layer given to the load wins over the one a feature names; with replace, the
|
|
206
|
+
// features and groups are replaced in the transaction that writes the new ones
|
|
207
|
+
return prepareGeoJSON(collection, importDeps, {
|
|
208
|
+
flattenMulti: options.flattenMulti,
|
|
209
|
+
layerId,
|
|
210
|
+
replace: mode === 'replace',
|
|
211
|
+
oneGroup: extra.grouped,
|
|
212
|
+
reservedIds: extra.reservedIds,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** Deletes every feature and group of the document, keeping the layers */
|
|
217
|
+
function deleteFeaturesAndGroups(store) {
|
|
218
|
+
for (const feature of store.listFeatures())
|
|
219
|
+
store.deleteFeature(feature.id);
|
|
220
|
+
for (const group of store.listGroups())
|
|
221
|
+
store.deleteGroup(group.id);
|
|
222
|
+
}
|
|
223
|
+
/** Reads a file or a string into data, or keeps an image file as it is */
|
|
224
|
+
async function readSource(source) {
|
|
225
|
+
if (typeof Blob !== 'undefined' && source instanceof Blob) {
|
|
226
|
+
const name = typeof File !== 'undefined' && source instanceof File ? source.name : '';
|
|
227
|
+
if (source.type.startsWith('image/')) {
|
|
228
|
+
const file = typeof File !== 'undefined' && source instanceof File
|
|
229
|
+
? source
|
|
230
|
+
: new File([source], name || 'image', { type: source.type });
|
|
231
|
+
return { kind: 'image', file };
|
|
232
|
+
}
|
|
233
|
+
let text;
|
|
234
|
+
try {
|
|
235
|
+
text = await source.text();
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
throw asDrawError('unsupported-format', error);
|
|
239
|
+
}
|
|
240
|
+
return { kind: 'data', data: parseJSON(text) };
|
|
241
|
+
}
|
|
242
|
+
if (typeof source === 'string')
|
|
243
|
+
return { kind: 'data', data: parseJSON(source) };
|
|
244
|
+
return { kind: 'data', data: source };
|
|
245
|
+
}
|
|
246
|
+
/** Parses JSON text; text that is not JSON cannot be read */
|
|
247
|
+
function parseJSON(text) {
|
|
248
|
+
try {
|
|
249
|
+
return JSON.parse(text);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
throw asDrawError('unsupported-format', error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/** A FeatureCollection from GeoJSON data (a collection, a feature or a geometry), or null */
|
|
256
|
+
function toFeatureCollection(data) {
|
|
257
|
+
if (isGeoJSONFeatureCollection(data))
|
|
258
|
+
return data;
|
|
259
|
+
if (!isRecord(data))
|
|
260
|
+
return null;
|
|
261
|
+
if (data.type === 'Feature') {
|
|
262
|
+
return { type: 'FeatureCollection', features: [data] };
|
|
263
|
+
}
|
|
264
|
+
if (typeof data.type === 'string' && GEOMETRY_TYPES.has(data.type)) {
|
|
265
|
+
return {
|
|
266
|
+
type: 'FeatureCollection',
|
|
267
|
+
features: [
|
|
268
|
+
{ type: 'Feature', properties: {}, geometry: data },
|
|
269
|
+
],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
/** Wraps an error of a reader into a DrawError with the code */
|
|
275
|
+
function asDrawError(code, error) {
|
|
276
|
+
if (error instanceof DrawError)
|
|
277
|
+
return error;
|
|
278
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
279
|
+
return new DrawError(code, message, { cause: error });
|
|
280
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { INITIAL_DRAPE_DEBUG } from '../../view/terrain/context.js';
|
|
4
|
+
import { getTerrainDrapeDebug, getTerrainRenderState, INACTIVE_TERRAIN_STATE, } from '../../view/terrain/state.js';
|
|
5
|
+
import { invalidInput } from './shared.js';
|
|
6
|
+
/**
|
|
7
|
+
* `getLayerStack`, `hasPendingWork` and `debug` over the engine
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export function createDrawing(engine) {
|
|
12
|
+
const { customLayer } = engine;
|
|
13
|
+
return {
|
|
14
|
+
getLayerStack() {
|
|
15
|
+
return Object.freeze(customLayer
|
|
16
|
+
.getStackSlots()
|
|
17
|
+
.map(({ layerId, from, to }) => Object.freeze({ layerId, from, to })));
|
|
18
|
+
},
|
|
19
|
+
hasPendingWork: () => customLayer.hasPendingWork(),
|
|
20
|
+
debug: {
|
|
21
|
+
terrain() {
|
|
22
|
+
const terrain = customLayer.getTerrainContext();
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
render: toRenderDiagnostics(terrain ? getTerrainRenderState(terrain) : INACTIVE_TERRAIN_STATE),
|
|
25
|
+
drape: Object.freeze({
|
|
26
|
+
...(terrain ? getTerrainDrapeDebug(terrain) : INITIAL_DRAPE_DEBUG),
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** The plain numbers of a terrain state, without the GL objects and the internal plans */
|
|
34
|
+
function toRenderDiagnostics(state) {
|
|
35
|
+
return Object.freeze({
|
|
36
|
+
active: state.active,
|
|
37
|
+
atlasRect: Object.freeze([
|
|
38
|
+
...state.atlasRect,
|
|
39
|
+
]),
|
|
40
|
+
atlasSize: Object.freeze([
|
|
41
|
+
...state.atlasSize,
|
|
42
|
+
]),
|
|
43
|
+
elevationScale: state.elevationScale,
|
|
44
|
+
liftMeters: state.liftMeters,
|
|
45
|
+
stepMeters: state.stepMeters,
|
|
46
|
+
stepGrid: state.stepGrid,
|
|
47
|
+
generation: state.generation,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// draw.drawing
|
|
52
|
+
// ============================================================================
|
|
53
|
+
/** No modifier key held */
|
|
54
|
+
const NO_MODIFIERS = Object.freeze({
|
|
55
|
+
shift: false,
|
|
56
|
+
ctrl: false,
|
|
57
|
+
alt: false,
|
|
58
|
+
meta: false,
|
|
59
|
+
});
|
|
60
|
+
/** Throws unless the value is a position of two finite numbers, and returns them */
|
|
61
|
+
function requirePosition(value) {
|
|
62
|
+
if (!Array.isArray(value) ||
|
|
63
|
+
value.length < 2 ||
|
|
64
|
+
typeof value[0] !== 'number' ||
|
|
65
|
+
typeof value[1] !== 'number' ||
|
|
66
|
+
!Number.isFinite(value[0]) ||
|
|
67
|
+
!Number.isFinite(value[1])) {
|
|
68
|
+
throw invalidInput('The position must be [longitude, latitude] of finite numbers');
|
|
69
|
+
}
|
|
70
|
+
return [value[0], value[1]];
|
|
71
|
+
}
|
|
72
|
+
/** An event of the browser that has what a receiver reads, where the browser has none to make */
|
|
73
|
+
function inertEvent(fields) {
|
|
74
|
+
return {
|
|
75
|
+
target: null,
|
|
76
|
+
currentTarget: null,
|
|
77
|
+
defaultPrevented: false,
|
|
78
|
+
isTrusted: false,
|
|
79
|
+
preventDefault() { },
|
|
80
|
+
stopPropagation() { },
|
|
81
|
+
stopImmediatePropagation() { },
|
|
82
|
+
...fields,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The event of the browser a made pointer event carries: a `PointerEvent` (or a `MouseEvent`)
|
|
87
|
+
* where the browser can make one, otherwise an object with the same fields
|
|
88
|
+
*/
|
|
89
|
+
function makePointerOriginal(type, point, container) {
|
|
90
|
+
const rect = container?.getBoundingClientRect?.();
|
|
91
|
+
const init = {
|
|
92
|
+
clientX: (rect?.left ?? 0) + point.x,
|
|
93
|
+
clientY: (rect?.top ?? 0) + point.y,
|
|
94
|
+
button: 0,
|
|
95
|
+
buttons: 0,
|
|
96
|
+
};
|
|
97
|
+
const eventType = type === 'mousemove' ? 'pointermove' : type;
|
|
98
|
+
if (typeof PointerEvent === 'function') {
|
|
99
|
+
return new PointerEvent(eventType, { ...init, pointerType: 'mouse', isPrimary: true });
|
|
100
|
+
}
|
|
101
|
+
if (typeof MouseEvent === 'function')
|
|
102
|
+
return new MouseEvent(eventType, init);
|
|
103
|
+
return inertEvent({ type: eventType, ...init });
|
|
104
|
+
}
|
|
105
|
+
/** The event of the browser a made key event carries */
|
|
106
|
+
function makeKeyOriginal(key) {
|
|
107
|
+
if (typeof KeyboardEvent === 'function')
|
|
108
|
+
return new KeyboardEvent('keydown', { key, code: key });
|
|
109
|
+
return inertEvent({ type: 'keydown', key, code: key, repeat: false });
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* `draw.drawing` over the engine: the input it makes goes through the router of the input,
|
|
113
|
+
* the same way as the input of the map
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export function createDrawingResource(engine) {
|
|
118
|
+
const { map, modeManager, inputRouter } = engine;
|
|
119
|
+
const { store } = engine.context;
|
|
120
|
+
const isDrawing = () => store.getTentative() !== null;
|
|
121
|
+
const isActive = () => isDrawing() || modeManager.getHandler()?.writesFeatures === true;
|
|
122
|
+
const pointer = (type, [lng, lat]) => {
|
|
123
|
+
const projected = map.project([lng, lat]);
|
|
124
|
+
const point = { x: projected.x, y: projected.y };
|
|
125
|
+
const event = {
|
|
126
|
+
type,
|
|
127
|
+
point,
|
|
128
|
+
lngLat: { lng, lat },
|
|
129
|
+
originalEvent: makePointerOriginal(type, point, map.getContainer?.()),
|
|
130
|
+
modifiers: { ...NO_MODIFIERS },
|
|
131
|
+
pointerType: 'mouse',
|
|
132
|
+
// The position is used as it is: it is not snapped, and no click tolerance applies
|
|
133
|
+
snap: false,
|
|
134
|
+
programmatic: true,
|
|
135
|
+
};
|
|
136
|
+
return inputRouter.dispatch(event);
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
isActive,
|
|
140
|
+
isDrawing,
|
|
141
|
+
addVertex(position) {
|
|
142
|
+
const at = requirePosition(position);
|
|
143
|
+
if (!isActive())
|
|
144
|
+
return false;
|
|
145
|
+
// A click comes after the pointer moved to where it clicks, and the modes read that move
|
|
146
|
+
// (a click on the closing vertex finishes the shape)
|
|
147
|
+
pointer('mousemove', at);
|
|
148
|
+
return pointer('click', at);
|
|
149
|
+
},
|
|
150
|
+
moveTo(position) {
|
|
151
|
+
const at = requirePosition(position);
|
|
152
|
+
if (!isActive())
|
|
153
|
+
return;
|
|
154
|
+
pointer('mousemove', at);
|
|
155
|
+
},
|
|
156
|
+
finish() {
|
|
157
|
+
if (!isDrawing())
|
|
158
|
+
return false;
|
|
159
|
+
const event = {
|
|
160
|
+
type: 'keydown',
|
|
161
|
+
key: 'Enter',
|
|
162
|
+
code: 'Enter',
|
|
163
|
+
modifiers: { ...NO_MODIFIERS },
|
|
164
|
+
originalEvent: makeKeyOriginal('Enter'),
|
|
165
|
+
};
|
|
166
|
+
return inputRouter.dispatch(event) && !isDrawing();
|
|
167
|
+
},
|
|
168
|
+
cancel() {
|
|
169
|
+
if (!isDrawing())
|
|
170
|
+
return false;
|
|
171
|
+
// The mode drops what it was drawing (onCancel of a mode of the contract)
|
|
172
|
+
modeManager.notifyStateReset();
|
|
173
|
+
if (store.getTentative() !== null)
|
|
174
|
+
store.setTentative(null);
|
|
175
|
+
return true;
|
|
176
|
+
},
|
|
177
|
+
undoVertex: () => modeManager.undoVertex(),
|
|
178
|
+
redoVertex: () => modeManager.redoVertex(),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -1,35 +1,32 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
-
import { createCoreBoxSelectionStrategies } from '
|
|
4
|
-
import { BoxSelectionStrategyRegistry } from '
|
|
5
|
-
import { createGlobeShapeResolver } from '
|
|
6
|
-
import { HitTestServiceImpl } from '
|
|
7
|
-
import { DEFAULT_HIT_TEST_OPTIONS } from '
|
|
8
|
-
import { resolveMessages } from '
|
|
9
|
-
import { ModeManagerImpl } from '
|
|
10
|
-
import { DEFAULT_FEATURE_STYLE_CONFIG, mergeFeatureStyleConfig, } from '
|
|
11
|
-
import { DEFAULT_RENDERING_CONFIG, mergeRenderingConfig } from '
|
|
12
|
-
import { DEFAULT_SELECTION_CONFIG, mergeSelectionUIConfig } from '
|
|
13
|
-
import { DEFAULT_TOPOLOGY_CONFIG, mergeTopologyConfig } from '
|
|
14
|
-
import { DEFAULT_TRACE_CONFIG, mergeTraceConfig } from '
|
|
15
|
-
import { getAnchorProjector } from '
|
|
16
|
-
import { EventEmitterImpl } from '
|
|
17
|
-
import { createId } from '
|
|
18
|
-
import { AutoNameGenerator } from '
|
|
19
|
-
import { createPixelRatioSource } from '
|
|
20
|
-
import { createSnapTargetsRegistry } from '
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
* @internal
|
|
32
|
-
*/
|
|
3
|
+
import { createCoreBoxSelectionStrategies } from '../../dispatcher/hit-test/box-strategies.js';
|
|
4
|
+
import { BoxSelectionStrategyRegistry } from '../../dispatcher/hit-test/box-strategy.js';
|
|
5
|
+
import { createGlobeShapeResolver } from '../../dispatcher/hit-test/globe-shape.js';
|
|
6
|
+
import { HitTestServiceImpl } from '../../dispatcher/hit-test/service.js';
|
|
7
|
+
import { DEFAULT_HIT_TEST_OPTIONS } from '../../dispatcher/hit-test/strategies/base.js';
|
|
8
|
+
import { resolveMessages } from '../../messages.js';
|
|
9
|
+
import { ModeManagerImpl } from '../../modes/manager.js';
|
|
10
|
+
import { DEFAULT_FEATURE_STYLE_CONFIG, mergeFeatureStyleConfig, } from '../../shared/config/feature-style.js';
|
|
11
|
+
import { DEFAULT_RENDERING_CONFIG, mergeRenderingConfig } from '../../shared/config/rendering.js';
|
|
12
|
+
import { DEFAULT_SELECTION_CONFIG, mergeSelectionUIConfig } from '../../shared/config/selection.js';
|
|
13
|
+
import { DEFAULT_TOPOLOGY_CONFIG, mergeTopologyConfig } from '../../shared/config/topology.js';
|
|
14
|
+
import { DEFAULT_TRACE_CONFIG, mergeTraceConfig } from '../../shared/config/trace.js';
|
|
15
|
+
import { getAnchorProjector } from '../../shared/math/index.js';
|
|
16
|
+
import { EventEmitterImpl } from '../../shared/utils/event-emitter.js';
|
|
17
|
+
import { createId } from '../../shared/utils/id.js';
|
|
18
|
+
import { AutoNameGenerator } from '../../shared/utils/name-generator.js';
|
|
19
|
+
import { createPixelRatioSource } from '../../shared/utils/pixel-ratio.js';
|
|
20
|
+
import { createSnapTargetsRegistry, } from '../../snapping/custom-targets.js';
|
|
21
|
+
import { createSnapIndicatorLook } from '../../snapping/indicator.js';
|
|
22
|
+
import { createSnapService } from '../../snapping/service.js';
|
|
23
|
+
import { DEFAULT_SNAP_OPTIONS, resolveGuideStepDegrees, resolveSnapKinds, } from '../../snapping/types.js';
|
|
24
|
+
import { toStore } from '../../store/draw-store.js';
|
|
25
|
+
import { MemoryStore } from '../../store/memory.js';
|
|
26
|
+
import { StoreSpatialIndex } from '../../store/spatial/store-spatial-index.js';
|
|
27
|
+
import { resolveWritableLayerId } from '../../store/writable-layer.js';
|
|
28
|
+
import { pointMarkerReachPx } from '../../view/renderers/point/point-style.js';
|
|
29
|
+
import { createSelectionScope } from '../../view/ui/selection-scope.js';
|
|
33
30
|
export const DEFAULT_OPTIONS = {
|
|
34
31
|
defaultMode: 'select',
|
|
35
32
|
// One default for the hit test and the topmost hit (see DEFAULT_HIT_TEST_OPTIONS)
|
|
@@ -64,10 +61,10 @@ export function createContext(map, options = {}) {
|
|
|
64
61
|
? mergeRenderingConfig(DEFAULT_RENDERING_CONFIG, options.renderingStyle)
|
|
65
62
|
: DEFAULT_RENDERING_CONFIG;
|
|
66
63
|
// Merge the topology configuration (everything is disabled by default). It is the actual
|
|
67
|
-
// object
|
|
64
|
+
// object the runtime options change, so always copy it so that the default is not shared
|
|
68
65
|
const topology = mergeTopologyConfig(DEFAULT_TOPOLOGY_CONFIG, options.topology ?? {});
|
|
69
|
-
// Merge the trace configuration (it is enabled by default). It is the actual object
|
|
70
|
-
//
|
|
66
|
+
// Merge the trace configuration (it is enabled by default). It is the actual object the
|
|
67
|
+
// runtime options change, so always copy it so that the default is not shared
|
|
71
68
|
const trace = mergeTraceConfig(DEFAULT_TRACE_CONFIG, options.trace ?? {});
|
|
72
69
|
// The internal components
|
|
73
70
|
const store = options.store ? toStore(options.store) : new MemoryStore();
|
|
@@ -85,6 +82,9 @@ export function createContext(map, options = {}) {
|
|
|
85
82
|
},
|
|
86
83
|
// On the globe the edges are tested along the path they are drawn along
|
|
87
84
|
drawnShape: createGlobeShapeResolver(map),
|
|
85
|
+
// A click on the marker of a point hits the point (the look of a point is read at each
|
|
86
|
+
// hit, so a change of the style option applies at once)
|
|
87
|
+
pointMarkerReachPx: (feature) => pointMarkerReachPx(feature.style, featureStyle.point.point),
|
|
88
88
|
});
|
|
89
89
|
// Create the BoxSelectionStrategyRegistry and register the core strategies
|
|
90
90
|
const boxSelectionRegistry = new BoxSelectionStrategyRegistry();
|
|
@@ -98,8 +98,8 @@ export function createContext(map, options = {}) {
|
|
|
98
98
|
canEnter: (handler) => !handler.writesFeatures || getWritableLayerId() !== '',
|
|
99
99
|
});
|
|
100
100
|
// Create the snapping service (enabled by default, tolerance 10px, temporarily disabled
|
|
101
|
-
// with Alt). The candidates come
|
|
102
|
-
//
|
|
101
|
+
// with Alt). The candidates come from the built-in providers (the vertices and edges of the
|
|
102
|
+
// Store); the snap providers of the extensions are added through the extension host.
|
|
103
103
|
const snapOptions = {
|
|
104
104
|
...DEFAULT_SNAP_OPTIONS,
|
|
105
105
|
...options.snap,
|
|
@@ -108,7 +108,15 @@ export function createContext(map, options = {}) {
|
|
|
108
108
|
guideStepDegrees: resolveGuideStepDegrees(options.snap?.guideStepDegrees),
|
|
109
109
|
};
|
|
110
110
|
// The registries of the extension points belong to this instance (nothing is module-level)
|
|
111
|
-
const selectionScope = createSelectionScope(
|
|
111
|
+
const selectionScope = createSelectionScope({
|
|
112
|
+
// The frame of a point spans its marker, as far as a click on it hits it (the reach of the
|
|
113
|
+
// built-in type, or of an override of it for the points it keeps): a plain point has a
|
|
114
|
+
// 16 px frame before the margin, and a larger marker a larger one
|
|
115
|
+
defaultPointFrameExtent: (feature) => {
|
|
116
|
+
const reach = hitTestService.getStrategy?.(feature.type)?.reachPx?.(feature) ?? 0;
|
|
117
|
+
return reach > 0 ? { halfWidth: reach, halfHeight: reach } : null;
|
|
118
|
+
},
|
|
119
|
+
});
|
|
112
120
|
const snapTargets = createSnapTargetsRegistry();
|
|
113
121
|
// The messages table belongs to this instance as well
|
|
114
122
|
const messages = resolveMessages(options.messages);
|
|
@@ -132,7 +140,9 @@ export function createContext(map, options = {}) {
|
|
|
132
140
|
visible: true,
|
|
133
141
|
locked: false,
|
|
134
142
|
opacity: 1.0,
|
|
135
|
-
|
|
143
|
+
items: [],
|
|
144
|
+
styleRule: undefined,
|
|
145
|
+
metadata: undefined,
|
|
136
146
|
};
|
|
137
147
|
store.createLayer(defaultLayer);
|
|
138
148
|
activeLayerId = 'default-layer';
|
|
@@ -152,7 +162,7 @@ export function createContext(map, options = {}) {
|
|
|
152
162
|
const getActiveLayerId = () => {
|
|
153
163
|
// If the active layer was deleted, make the first layer active
|
|
154
164
|
if (!store.getLayer(activeLayerId)) {
|
|
155
|
-
const layers = store.
|
|
165
|
+
const layers = store.listLayers();
|
|
156
166
|
if (layers.length > 0) {
|
|
157
167
|
activeLayerId = layers[0].id;
|
|
158
168
|
}
|
|
@@ -180,6 +190,7 @@ export function createContext(map, options = {}) {
|
|
|
180
190
|
pixelRatioSource: createPixelRatioSource(options.pixelRatio, () => map.getPixelRatio()),
|
|
181
191
|
snapOptions,
|
|
182
192
|
snapService,
|
|
193
|
+
snapIndicator: createSnapIndicatorLook(),
|
|
183
194
|
autoNameGenerator,
|
|
184
195
|
boxSelectionRegistry,
|
|
185
196
|
selectionScope,
|