@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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { groupLocked, invalidInput, isRecord, layerLocked, notFound, optionalIndex, requireId, } from './shared.js';
|
|
4
|
+
/**
|
|
5
|
+
* Checks a move target and looks up what it names
|
|
6
|
+
*
|
|
7
|
+
* @throws DrawError `invalid-input` for a target of the wrong shape, `not-found` for a layer
|
|
8
|
+
* or a group that does not exist
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export function resolveMoveTarget(store, to) {
|
|
12
|
+
if (!isRecord(to))
|
|
13
|
+
throw invalidInput('The target must be an object');
|
|
14
|
+
const hasLayer = 'layerId' in to;
|
|
15
|
+
const hasGroup = 'groupId' in to;
|
|
16
|
+
if (hasLayer === hasGroup) {
|
|
17
|
+
throw invalidInput('The target must have either layerId or groupId');
|
|
18
|
+
}
|
|
19
|
+
const index = optionalIndex(to.index);
|
|
20
|
+
if (hasLayer) {
|
|
21
|
+
const layerId = requireId(to.layerId, 'layerId');
|
|
22
|
+
const layer = store.getLayer(layerId);
|
|
23
|
+
if (!layer)
|
|
24
|
+
throw notFound('layer', layerId);
|
|
25
|
+
return { kind: 'layer', layer, index, locked: layerLocked(store, layer) };
|
|
26
|
+
}
|
|
27
|
+
if (to.groupId === null)
|
|
28
|
+
return { kind: 'ungroup', index, locked: false };
|
|
29
|
+
const groupId = requireId(to.groupId, 'groupId');
|
|
30
|
+
const group = store.getGroup(groupId);
|
|
31
|
+
if (!group)
|
|
32
|
+
throw notFound('group', groupId);
|
|
33
|
+
return { kind: 'group', group, index, locked: groupLocked(store, group) };
|
|
34
|
+
}
|
|
35
|
+
/** Inserts the IDs into the list at the index, or at the end when it is undefined */
|
|
36
|
+
function insertAt(list, ids, index) {
|
|
37
|
+
const at = index === undefined ? list.length : Math.min(index, list.length);
|
|
38
|
+
list.splice(at, 0, ...ids);
|
|
39
|
+
return list;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Moves features to a target, in one transaction
|
|
43
|
+
*
|
|
44
|
+
* @param features The features, in stacking order
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export function moveFeatures(store, features, target) {
|
|
48
|
+
const ids = features.map((feature) => feature.id);
|
|
49
|
+
const moved = new Set(ids);
|
|
50
|
+
store.transact(() => {
|
|
51
|
+
if (target.kind === 'layer') {
|
|
52
|
+
const layerId = target.layer.id;
|
|
53
|
+
for (const feature of features) {
|
|
54
|
+
if (feature.layerId !== layerId || feature.groupId !== undefined) {
|
|
55
|
+
store.updateFeature(feature.id, { layerId, groupId: undefined });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const items = (store.getLayer(layerId)?.items ?? []).filter((id) => !moved.has(id));
|
|
59
|
+
store.updateLayer(layerId, { items: insertAt(items, ids, target.index) });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (target.kind === 'group') {
|
|
63
|
+
const { group } = target;
|
|
64
|
+
for (const feature of features) {
|
|
65
|
+
if (feature.groupId !== group.id) {
|
|
66
|
+
store.updateFeature(feature.id, { layerId: group.layerId, groupId: group.id });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const featureIds = (store.getGroup(group.id)?.featureIds ?? []).filter((id) => !moved.has(id));
|
|
70
|
+
store.updateGroup(group.id, { featureIds: insertAt(featureIds, ids, target.index) });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Out of their groups: each feature stays in its layer
|
|
74
|
+
const byLayer = new Map();
|
|
75
|
+
for (const feature of features) {
|
|
76
|
+
const list = byLayer.get(feature.layerId) ?? [];
|
|
77
|
+
list.push(feature);
|
|
78
|
+
byLayer.set(feature.layerId, list);
|
|
79
|
+
}
|
|
80
|
+
for (const [layerId, inLayer] of byLayer) {
|
|
81
|
+
const before = [...(store.getLayer(layerId)?.items ?? [])];
|
|
82
|
+
const blocks = new Map();
|
|
83
|
+
for (const feature of inLayer) {
|
|
84
|
+
if (feature.groupId === undefined)
|
|
85
|
+
continue;
|
|
86
|
+
const block = blocks.get(feature.groupId) ?? [];
|
|
87
|
+
block.push(feature.id);
|
|
88
|
+
blocks.set(feature.groupId, block);
|
|
89
|
+
}
|
|
90
|
+
for (const feature of inLayer) {
|
|
91
|
+
if (feature.groupId !== undefined)
|
|
92
|
+
store.updateFeature(feature.id, { groupId: undefined });
|
|
93
|
+
}
|
|
94
|
+
let items;
|
|
95
|
+
if (target.index === undefined) {
|
|
96
|
+
// Just in front of their group, or in its place when it was left empty and deleted
|
|
97
|
+
items = [];
|
|
98
|
+
for (const itemId of before) {
|
|
99
|
+
if (!blocks.has(itemId) || store.getGroup(itemId))
|
|
100
|
+
items.push(itemId);
|
|
101
|
+
items.push(...(blocks.get(itemId) ?? []));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const layerIds = inLayer.map((feature) => feature.id);
|
|
106
|
+
const inThisLayer = new Set(layerIds);
|
|
107
|
+
items = (store.getLayer(layerId)?.items ?? []).filter((id) => !inThisLayer.has(id));
|
|
108
|
+
insertAt(items, layerIds, target.index);
|
|
109
|
+
}
|
|
110
|
+
store.updateLayer(layerId, { items });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Moves groups to a layer, in one transaction
|
|
116
|
+
*
|
|
117
|
+
* @param groups The groups, in stacking order
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
export function moveGroups(store, groups, layer, index) {
|
|
121
|
+
const ids = groups.map((group) => group.id);
|
|
122
|
+
const moved = new Set(ids);
|
|
123
|
+
store.transact(() => {
|
|
124
|
+
for (const group of groups) {
|
|
125
|
+
if (group.layerId === layer.id)
|
|
126
|
+
continue;
|
|
127
|
+
const source = store.getLayer(group.layerId);
|
|
128
|
+
if (source) {
|
|
129
|
+
store.updateLayer(source.id, { items: source.items.filter((id) => id !== group.id) });
|
|
130
|
+
}
|
|
131
|
+
for (const featureId of group.featureIds) {
|
|
132
|
+
store.updateFeature(featureId, { layerId: layer.id });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const items = (store.getLayer(layer.id)?.items ?? []).filter((id) => !moved.has(id));
|
|
136
|
+
store.updateLayer(layer.id, { items: insertAt(items, ids, index) });
|
|
137
|
+
});
|
|
138
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EngineOverlayRenderer } from '../../extension/renderers.js';
|
|
2
|
+
import type { TerrainContext } from '../../view/terrain/context.js';
|
|
3
|
+
import type { TerrainAnchors } from '../extension/context.js';
|
|
4
|
+
/** What the adapters of the renderers read from the instance */
|
|
5
|
+
export interface RenderAdapterDeps {
|
|
6
|
+
/** The terrain anchors of a terrain state */
|
|
7
|
+
anchors(terrain: TerrainContext): TerrainAnchors;
|
|
8
|
+
}
|
|
9
|
+
/** Where the overlays of the contract are put into the engine */
|
|
10
|
+
export interface OverlayHost {
|
|
11
|
+
/** Adds a renderer of the engine; returns the function that removes it */
|
|
12
|
+
addOverlay(renderer: EngineOverlayRenderer): () => void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { toColor } from '../../shared/color.js';
|
|
4
|
+
import { applyDrawBlendState } from '../../view/layer/blend.js';
|
|
5
|
+
import { calculateOffsetUniforms } from '../../view/shaders/helpers.js';
|
|
6
|
+
import { bindTerrainState } from '../../view/terrain/binding.js';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Terrain anchors
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/** The anchors of each terrain state, so that a frame does not build them again */
|
|
11
|
+
const anchorsByTerrain = new WeakMap();
|
|
12
|
+
/**
|
|
13
|
+
* The terrain anchors of the contract over the terrain state of an instance
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export function terrainAnchorsOf(terrain, build) {
|
|
18
|
+
let anchors = anchorsByTerrain.get(terrain);
|
|
19
|
+
if (!anchors) {
|
|
20
|
+
anchors = build(terrain);
|
|
21
|
+
anchorsByTerrain.set(terrain, anchors);
|
|
22
|
+
}
|
|
23
|
+
return anchors;
|
|
24
|
+
}
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// The render context
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/** The offsets of each projection matrix of a frame */
|
|
29
|
+
const offsetsByMatrix = new WeakMap();
|
|
30
|
+
function offsetOf(base) {
|
|
31
|
+
let offset = offsetsByMatrix.get(base.mainMatrixArray);
|
|
32
|
+
if (!offset) {
|
|
33
|
+
offset = calculateOffsetUniforms(base.centerLngLat, base.mainMatrixArray);
|
|
34
|
+
offsetsByMatrix.set(base.mainMatrixArray, offset);
|
|
35
|
+
}
|
|
36
|
+
return offset;
|
|
37
|
+
}
|
|
38
|
+
/** A position as the `[lng, lat]` pair the shared renderers take */
|
|
39
|
+
function pair(position) {
|
|
40
|
+
return [position[0], position[1]];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Builds the render context of the contract for one draw call
|
|
44
|
+
*
|
|
45
|
+
* @param gl - The WebGL context the renderer was added with
|
|
46
|
+
* @param base - The context the engine gives its own renderers in this draw call
|
|
47
|
+
* @param anchors - The terrain anchors of the terrain state of `base`
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export function createRenderContext(gl, base, projection, zoom, anchors) {
|
|
51
|
+
const line = {
|
|
52
|
+
draw(coordinates, style, options = {}) {
|
|
53
|
+
const coords = coordinates.map(pair);
|
|
54
|
+
const stroke = {
|
|
55
|
+
width: style.width,
|
|
56
|
+
color: toColor(style.color),
|
|
57
|
+
opacity: style.opacity,
|
|
58
|
+
lineStyle: style.lineStyle,
|
|
59
|
+
...(style.dashArray !== undefined && { dashArray: style.dashArray }),
|
|
60
|
+
};
|
|
61
|
+
const common = {
|
|
62
|
+
widthUnit: options.widthUnit ?? 'pixels',
|
|
63
|
+
...(options.createdZoom !== undefined && { createdZoom: options.createdZoom }),
|
|
64
|
+
};
|
|
65
|
+
if (options.closed) {
|
|
66
|
+
base.sdfLineRenderer.drawClosed(coords, stroke, common, zoom, projection);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
base.sdfLineRenderer.draw(coords, stroke, { ...common, closed: false }, zoom, projection);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const fill = {
|
|
74
|
+
draw(rings, style) {
|
|
75
|
+
const [r, g, b, a] = toColor(style.color);
|
|
76
|
+
base.fillShaderManager.drawPolygonRings(rings.map((ring) => ring.map(pair)), [r, g, b, a * style.opacity], projection, zoom);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const point = {
|
|
80
|
+
draw(position, style, options = {}) {
|
|
81
|
+
base.pointShapeRenderer.draw(pair(position), {
|
|
82
|
+
shape: style.shape,
|
|
83
|
+
size: style.size,
|
|
84
|
+
fillColor: toColor(style.fillColor),
|
|
85
|
+
fillOpacity: style.fillOpacity,
|
|
86
|
+
strokeColor: toColor(style.strokeColor),
|
|
87
|
+
strokeWidth: style.strokeWidth,
|
|
88
|
+
strokeOpacity: style.strokeOpacity,
|
|
89
|
+
}, zoom, undefined, options.elevationMeters);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
const context = {
|
|
93
|
+
gl,
|
|
94
|
+
shader: base.shaderData,
|
|
95
|
+
offset: offsetOf(base),
|
|
96
|
+
projection,
|
|
97
|
+
zoom,
|
|
98
|
+
pixelRatio: base.pixelRatio,
|
|
99
|
+
opacity: base.opacity,
|
|
100
|
+
terrain: anchors,
|
|
101
|
+
line,
|
|
102
|
+
fill,
|
|
103
|
+
point,
|
|
104
|
+
};
|
|
105
|
+
// The building blocks of the second entry find the terrain state behind the context
|
|
106
|
+
bindTerrainState(context, base.terrain);
|
|
107
|
+
return context;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Remembers the last render context, so that the features drawn one after another in a frame
|
|
111
|
+
* share one
|
|
112
|
+
*/
|
|
113
|
+
function createContextCache(deps) {
|
|
114
|
+
let last = null;
|
|
115
|
+
return (gl, base, projection, zoom) => {
|
|
116
|
+
if (last &&
|
|
117
|
+
last.base === base &&
|
|
118
|
+
last.projection === projection &&
|
|
119
|
+
last.zoom === zoom &&
|
|
120
|
+
last.context.gl === gl) {
|
|
121
|
+
return last.context;
|
|
122
|
+
}
|
|
123
|
+
const context = createRenderContext(gl, base, projection, zoom, deps.anchors(base.terrain));
|
|
124
|
+
last = { base, projection, zoom, context };
|
|
125
|
+
return context;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The renderer of the engine that draws the features of a custom type through a renderer of
|
|
130
|
+
* the contract
|
|
131
|
+
*
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
134
|
+
export function adaptFeatureRenderer(type, renderer, deps) {
|
|
135
|
+
let attachment = null;
|
|
136
|
+
const contextFor = createContextCache(deps);
|
|
137
|
+
return {
|
|
138
|
+
name: type,
|
|
139
|
+
onAdd(gl, map) {
|
|
140
|
+
attachment = { map, gl };
|
|
141
|
+
renderer.onAdd(map, gl);
|
|
142
|
+
},
|
|
143
|
+
draw(feature, projectionData, zoom, context) {
|
|
144
|
+
if (!attachment)
|
|
145
|
+
return;
|
|
146
|
+
renderer.draw(feature, contextFor(attachment.gl, context, projectionData, zoom));
|
|
147
|
+
},
|
|
148
|
+
onRemove() {
|
|
149
|
+
if (!attachment)
|
|
150
|
+
return;
|
|
151
|
+
const { map, gl } = attachment;
|
|
152
|
+
attachment = null;
|
|
153
|
+
renderer.onRemove(map, gl);
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The drawing of a companion through the contract, for one provider
|
|
159
|
+
*
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export function createCompanionDrawer(deps, getGl) {
|
|
163
|
+
const contextFor = createContextCache(deps);
|
|
164
|
+
return (draw, feature, projectionData, zoom, context) => {
|
|
165
|
+
const gl = getGl();
|
|
166
|
+
if (!gl)
|
|
167
|
+
return;
|
|
168
|
+
draw(feature, contextFor(gl, context, projectionData, zoom));
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Creates the overlays of the contract of one instance
|
|
173
|
+
*
|
|
174
|
+
* They are drawn by two renderers of the engine, added while at least one overlay exists: one
|
|
175
|
+
* draws `draw` of every overlay above the features and the selection, the other draws
|
|
176
|
+
* `drawForLayer` after each layer and `drawVertices` above everything. Within each, the overlays
|
|
177
|
+
* go by `order`, then by the order they were added.
|
|
178
|
+
*
|
|
179
|
+
* @internal
|
|
180
|
+
*/
|
|
181
|
+
export function createOverlayStack(host, deps) {
|
|
182
|
+
const overlays = [];
|
|
183
|
+
let seq = 0;
|
|
184
|
+
let attachment = null;
|
|
185
|
+
let removeRenderers = null;
|
|
186
|
+
const contextFor = createContextCache(deps);
|
|
187
|
+
const sorted = () => [...overlays]
|
|
188
|
+
.sort((a, b) => (a.overlay.order ?? 0) - (b.overlay.order ?? 0) || a.seq - b.seq)
|
|
189
|
+
.map((entry) => entry.overlay);
|
|
190
|
+
const each = (projectionData, zoom, context, call) => {
|
|
191
|
+
if (!attachment)
|
|
192
|
+
return;
|
|
193
|
+
const ctx = contextFor(attachment.gl, context, projectionData, zoom);
|
|
194
|
+
for (const overlay of sorted()) {
|
|
195
|
+
call(overlay, ctx);
|
|
196
|
+
applyDrawBlendState(attachment.gl);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const onAdd = (gl, map) => {
|
|
200
|
+
if (attachment)
|
|
201
|
+
return;
|
|
202
|
+
attachment = { gl, map };
|
|
203
|
+
for (const overlay of sorted())
|
|
204
|
+
overlay.onAdd(map, gl);
|
|
205
|
+
};
|
|
206
|
+
const onRemove = () => {
|
|
207
|
+
if (!attachment)
|
|
208
|
+
return;
|
|
209
|
+
const { map, gl } = attachment;
|
|
210
|
+
attachment = null;
|
|
211
|
+
for (const overlay of sorted())
|
|
212
|
+
overlay.onRemove(map, gl);
|
|
213
|
+
};
|
|
214
|
+
const above = {
|
|
215
|
+
name: 'extension-overlays',
|
|
216
|
+
order: 'overlay',
|
|
217
|
+
onAdd,
|
|
218
|
+
draw(projectionData, zoom, context) {
|
|
219
|
+
each(projectionData, zoom, context, (overlay, ctx) => overlay.draw(ctx));
|
|
220
|
+
},
|
|
221
|
+
onRemove,
|
|
222
|
+
hasPendingWork: () => overlays.some((entry) => entry.overlay.hasPendingWork?.() === true),
|
|
223
|
+
};
|
|
224
|
+
const perLayer = {
|
|
225
|
+
name: 'extension-overlays-per-layer',
|
|
226
|
+
order: 'overlay',
|
|
227
|
+
// The resources are created and released by the other renderer
|
|
228
|
+
onAdd() { },
|
|
229
|
+
draw() { },
|
|
230
|
+
onRemove() { },
|
|
231
|
+
drawForLayer(layerId, projectionData, zoom, context) {
|
|
232
|
+
each(projectionData, zoom, context, (overlay, ctx) => overlay.drawForLayer?.(layerId, ctx));
|
|
233
|
+
},
|
|
234
|
+
drawVertices(projectionData, zoom, context) {
|
|
235
|
+
each(projectionData, zoom, context, (overlay, ctx) => overlay.drawVertices?.(ctx));
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
return {
|
|
239
|
+
add(overlay) {
|
|
240
|
+
const entry = { overlay, seq: seq++ };
|
|
241
|
+
overlays.push(entry);
|
|
242
|
+
if (!removeRenderers) {
|
|
243
|
+
const removeAbove = host.addOverlay(above);
|
|
244
|
+
const removePerLayer = host.addOverlay(perLayer);
|
|
245
|
+
removeRenderers = () => {
|
|
246
|
+
removePerLayer();
|
|
247
|
+
removeAbove();
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
else if (attachment) {
|
|
251
|
+
overlay.onAdd(attachment.map, attachment.gl);
|
|
252
|
+
}
|
|
253
|
+
return () => {
|
|
254
|
+
const index = overlays.indexOf(entry);
|
|
255
|
+
if (index === -1)
|
|
256
|
+
return;
|
|
257
|
+
if (overlays.length === 1 && removeRenderers) {
|
|
258
|
+
// The last one goes with the renderers of the engine, which release it
|
|
259
|
+
const remove = removeRenderers;
|
|
260
|
+
removeRenderers = null;
|
|
261
|
+
remove();
|
|
262
|
+
overlays.splice(overlays.indexOf(entry), 1);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
overlays.splice(index, 1);
|
|
266
|
+
if (attachment)
|
|
267
|
+
overlay.onRemove(attachment.map, attachment.gl);
|
|
268
|
+
};
|
|
269
|
+
},
|
|
270
|
+
gl: () => attachment?.gl ?? null,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* A row of a dataset as a GeoJSON feature: its ID, its geometry (`null` for a row without
|
|
5
|
+
* one) and its properties, and its look under `style` when it has one
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function toDatasetRow(feature) {
|
|
10
|
+
const row = {
|
|
11
|
+
type: 'Feature',
|
|
12
|
+
id: feature.id,
|
|
13
|
+
geometry: hasGeometry(feature) ? feature.geometry : null,
|
|
14
|
+
properties: feature.properties ?? {},
|
|
15
|
+
};
|
|
16
|
+
if (feature.style && Object.keys(feature.style).length > 0)
|
|
17
|
+
row.style = feature.style;
|
|
18
|
+
return row;
|
|
19
|
+
}
|
|
20
|
+
/** Whether a row has a geometry (a row without one is kept as a hidden point at NaN) */
|
|
21
|
+
function hasGeometry(feature) {
|
|
22
|
+
const { geometry } = feature;
|
|
23
|
+
if (feature.visible !== false || geometry.type !== 'Point')
|
|
24
|
+
return true;
|
|
25
|
+
return !Number.isNaN(geometry.coordinates[0]);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The range of a `BBox` (`[west, south, east, north]`, or with the heights
|
|
29
|
+
* `[west, south, low, east, north, high]`)
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export function toBoundingBox(bbox) {
|
|
34
|
+
if (bbox.length === 6) {
|
|
35
|
+
return { minX: bbox[0], minY: bbox[1], maxX: bbox[3], maxY: bbox[4] };
|
|
36
|
+
}
|
|
37
|
+
return { minX: bbox[0], minY: bbox[1], maxX: bbox[2], maxY: bbox[3] };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A range as a `BBox`, `[west, south, east, north]`
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export function toBBox(bounds) {
|
|
45
|
+
return [bounds.minX, bounds.minY, bounds.maxX, bounds.maxY];
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* `draw.selection` and `draw.vertexSelection`: what this client has selected
|
|
5
|
+
*/
|
|
6
|
+
import { groupSelection, ungroupSelection } from '../../operations/layer-operations.js';
|
|
7
|
+
import { deleteSelectedItems, deleteSelectedVertices, } from '../../operations/selection-operations.js';
|
|
8
|
+
import { coordinatesOf, supportsVertexEditing } from '../../shared/utils/coordinates.js';
|
|
9
|
+
import { isFeatureLocked } from '../../store/lock.js';
|
|
10
|
+
import { listEveryFeatureInOrder } from '../../store/ordering.js';
|
|
11
|
+
import { getItem, invalidInput, isRecord, isShown, notFound, requireId, requireIds, } from './shared.js';
|
|
12
|
+
const SELECTION_TYPES = ['feature', 'group', 'layer'];
|
|
13
|
+
/**
|
|
14
|
+
* Creates `draw.selection`
|
|
15
|
+
*
|
|
16
|
+
* The selection holds only what can be seen: an item that is hidden (by its visible flag, the
|
|
17
|
+
* one of its group or layer, or by this client) cannot be selected.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export function createSelection(deps, collections) {
|
|
22
|
+
const { store } = deps;
|
|
23
|
+
/** Throws unless every ID names an item of the type */
|
|
24
|
+
const requireItems = (type, ids) => {
|
|
25
|
+
const list = requireIds(ids);
|
|
26
|
+
for (const id of list) {
|
|
27
|
+
if (!getItem(store, type, id))
|
|
28
|
+
throw notFound(type, id);
|
|
29
|
+
}
|
|
30
|
+
return list;
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
get: () => store.getSelection(),
|
|
34
|
+
set(type, ids) {
|
|
35
|
+
if (!SELECTION_TYPES.includes(type)) {
|
|
36
|
+
throw invalidInput('type must be feature, group or layer');
|
|
37
|
+
}
|
|
38
|
+
const selectable = requireItems(type, ids).filter((id) => isShown(store, type, id));
|
|
39
|
+
if (selectable.length === 0)
|
|
40
|
+
return false;
|
|
41
|
+
store.setSelection(type, selectable);
|
|
42
|
+
return true;
|
|
43
|
+
},
|
|
44
|
+
add(ids) {
|
|
45
|
+
const current = store.getSelection();
|
|
46
|
+
const list = requireIds(ids);
|
|
47
|
+
// With nothing selected, the type is the one of the first ID
|
|
48
|
+
const type = current.type ?? SELECTION_TYPES.find((t) => getItem(store, t, list[0] ?? ''));
|
|
49
|
+
if (type === undefined) {
|
|
50
|
+
if (list.length === 0)
|
|
51
|
+
return false;
|
|
52
|
+
throw notFound('feature, group or layer', list[0]);
|
|
53
|
+
}
|
|
54
|
+
const added = requireItems(type, list).filter((id) => !current.ids.includes(id) && isShown(store, type, id));
|
|
55
|
+
if (added.length === 0)
|
|
56
|
+
return false;
|
|
57
|
+
store.setSelection(type, [...current.ids, ...added]);
|
|
58
|
+
return true;
|
|
59
|
+
},
|
|
60
|
+
remove(ids) {
|
|
61
|
+
const current = store.getSelection();
|
|
62
|
+
const removed = new Set(requireIds(ids).filter((id) => current.ids.includes(id)));
|
|
63
|
+
if (removed.size === 0)
|
|
64
|
+
return false;
|
|
65
|
+
const kept = current.ids.filter((id) => !removed.has(id));
|
|
66
|
+
store.setSelection(kept.length > 0 ? current.type : null, kept);
|
|
67
|
+
return true;
|
|
68
|
+
},
|
|
69
|
+
clear() {
|
|
70
|
+
store.setSelection(null, []);
|
|
71
|
+
},
|
|
72
|
+
features() {
|
|
73
|
+
const { type, ids } = store.getSelection();
|
|
74
|
+
if (type === 'feature') {
|
|
75
|
+
return ids
|
|
76
|
+
.map((id) => store.getFeature(id))
|
|
77
|
+
.filter((feature) => feature !== undefined);
|
|
78
|
+
}
|
|
79
|
+
if (type === null)
|
|
80
|
+
return [];
|
|
81
|
+
const wanted = new Set(ids);
|
|
82
|
+
const inside = (feature) => type === 'group'
|
|
83
|
+
? feature.groupId !== undefined && wanted.has(feature.groupId)
|
|
84
|
+
: wanted.has(feature.layerId);
|
|
85
|
+
return listEveryFeatureInOrder(store).filter(inside);
|
|
86
|
+
},
|
|
87
|
+
delete() {
|
|
88
|
+
return deleteSelectedItems(store);
|
|
89
|
+
},
|
|
90
|
+
group() {
|
|
91
|
+
if (store.isReadOnly())
|
|
92
|
+
return null;
|
|
93
|
+
const id = groupSelection(store, deps.generateId, deps.autoNameGenerator);
|
|
94
|
+
return id === null ? null : (store.getGroup(id) ?? null);
|
|
95
|
+
},
|
|
96
|
+
ungroup() {
|
|
97
|
+
// The same operation as the ungroup shortcut
|
|
98
|
+
if (store.isReadOnly())
|
|
99
|
+
return false;
|
|
100
|
+
return ungroupSelection(store);
|
|
101
|
+
},
|
|
102
|
+
move(to) {
|
|
103
|
+
const { type, ids } = store.getSelection();
|
|
104
|
+
if (type === 'feature' && ids.length > 0)
|
|
105
|
+
return collections.features.moveMany(ids, to);
|
|
106
|
+
if (type === 'group' && ids.length > 0)
|
|
107
|
+
return collections.groups.moveMany(ids, to);
|
|
108
|
+
return false;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Creates `draw.vertexSelection`
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export function createVertexSelection(deps) {
|
|
118
|
+
const { store } = deps;
|
|
119
|
+
return {
|
|
120
|
+
get: () => store.getVertexSelection(),
|
|
121
|
+
set(featureId, vertices) {
|
|
122
|
+
const id = requireId(featureId, 'featureId');
|
|
123
|
+
const feature = store.getFeature(id);
|
|
124
|
+
if (!feature)
|
|
125
|
+
throw notFound('feature', id);
|
|
126
|
+
if (!Array.isArray(vertices))
|
|
127
|
+
throw invalidInput('The vertices must be an array');
|
|
128
|
+
const refs = vertices.map((vertex) => {
|
|
129
|
+
if (!isVertexRef(vertex))
|
|
130
|
+
throw invalidInput('A vertex must be { part?, ring, index }');
|
|
131
|
+
if (!vertexExists(feature, vertex)) {
|
|
132
|
+
throw notFound('vertex', vertex);
|
|
133
|
+
}
|
|
134
|
+
return { ...vertex };
|
|
135
|
+
});
|
|
136
|
+
if (isFeatureLocked(feature, store))
|
|
137
|
+
return false;
|
|
138
|
+
store.setSelectedVertices(refs.length > 0 ? { featureId: id, vertices: refs } : null);
|
|
139
|
+
return true;
|
|
140
|
+
},
|
|
141
|
+
clear() {
|
|
142
|
+
store.setSelectedVertices(null);
|
|
143
|
+
},
|
|
144
|
+
delete() {
|
|
145
|
+
const selection = store.getVertexSelection();
|
|
146
|
+
if (!selection || selection.vertices.length === 0)
|
|
147
|
+
return false;
|
|
148
|
+
if (store.isReadOnly() || store.isInteractionLocked())
|
|
149
|
+
return false;
|
|
150
|
+
return deleteSelectedVertices(store, selection) > 0;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/** Whether the value has the shape of a vertex reference */
|
|
155
|
+
function isVertexRef(value) {
|
|
156
|
+
if (!isRecord(value))
|
|
157
|
+
return false;
|
|
158
|
+
const isIndex = (v) => typeof v === 'number' && Number.isInteger(v) && v >= 0;
|
|
159
|
+
return ((value.part === undefined || isIndex(value.part)) && isIndex(value.ring) && isIndex(value.index));
|
|
160
|
+
}
|
|
161
|
+
/** Whether the vertex exists on the feature (the closing position of a ring is not a vertex) */
|
|
162
|
+
function vertexExists(feature, ref) {
|
|
163
|
+
if (!supportsVertexEditing(feature.type))
|
|
164
|
+
return false;
|
|
165
|
+
const part = ref.part ?? 0;
|
|
166
|
+
const coordinates = coordinatesOf(feature);
|
|
167
|
+
const ringVertices = (ring) => Array.isArray(ring) ? Math.max(0, ring.length - 1) : 0;
|
|
168
|
+
switch (feature.geometry.type) {
|
|
169
|
+
case 'LineString':
|
|
170
|
+
return part === 0 && ref.ring === 0 && ref.index < coordinates.length;
|
|
171
|
+
case 'Polygon':
|
|
172
|
+
return part === 0 && ref.index < ringVertices(coordinates[ref.ring]);
|
|
173
|
+
case 'MultiPoint':
|
|
174
|
+
return ref.ring === 0 && ref.index === 0 && part < coordinates.length;
|
|
175
|
+
case 'MultiLineString': {
|
|
176
|
+
const line = coordinates[part];
|
|
177
|
+
return ref.ring === 0 && Array.isArray(line) && ref.index < line.length;
|
|
178
|
+
}
|
|
179
|
+
case 'MultiPolygon': {
|
|
180
|
+
const polygon = coordinates[part];
|
|
181
|
+
return Array.isArray(polygon) && ref.index < ringVertices(polygon[ref.ring]);
|
|
182
|
+
}
|
|
183
|
+
default:
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|