@sakuzu/maplibre-gl-draw 1.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 +43 -0
- package/LICENSE +661 -0
- package/README.ja.md +248 -0
- package/README.md +255 -0
- package/THIRD_PARTY_NOTICES.md +275 -0
- package/dist/api/api.d.ts +1259 -0
- package/dist/api/api.js +86 -0
- package/dist/api/context.d.ts +173 -0
- package/dist/api/context.js +193 -0
- package/dist/api/display-api.d.ts +1 -0
- package/dist/api/display-api.js +23 -0
- package/dist/api/event-api.d.ts +13 -0
- package/dist/api/event-api.js +17 -0
- package/dist/api/extension-api.d.ts +46 -0
- package/dist/api/extension-api.js +85 -0
- package/dist/api/feature-api.d.ts +11 -0
- package/dist/api/feature-api.js +101 -0
- package/dist/api/geometry/apply.d.ts +51 -0
- package/dist/api/geometry/apply.js +114 -0
- package/dist/api/geometry/boolean.d.ts +28 -0
- package/dist/api/geometry/boolean.js +65 -0
- package/dist/api/geometry/buffer.d.ts +11 -0
- package/dist/api/geometry/buffer.js +105 -0
- package/dist/api/geometry/split.d.ts +16 -0
- package/dist/api/geometry/split.js +75 -0
- package/dist/api/geometry/targets.d.ts +76 -0
- package/dist/api/geometry/targets.js +158 -0
- package/dist/api/geometry/types.d.ts +31 -0
- package/dist/api/geometry/types.js +3 -0
- package/dist/api/geometry-operations.d.ts +162 -0
- package/dist/api/geometry-operations.js +94 -0
- package/dist/api/group-api.d.ts +10 -0
- package/dist/api/group-api.js +78 -0
- package/dist/api/import-export/constants.d.ts +29 -0
- package/dist/api/import-export/constants.js +40 -0
- package/dist/api/import-export/embedded-file.d.ts +13 -0
- package/dist/api/import-export/embedded-file.js +31 -0
- package/dist/api/import-export/file-name.d.ts +10 -0
- package/dist/api/import-export/file-name.js +20 -0
- package/dist/api/import-export/format-detection.d.ts +12 -0
- package/dist/api/import-export/format-detection.js +29 -0
- package/dist/api/import-export/geojson-export.d.ts +19 -0
- package/dist/api/import-export/geojson-export.js +262 -0
- package/dist/api/import-export/geojson-import.d.ts +34 -0
- package/dist/api/import-export/geojson-import.js +538 -0
- package/dist/api/import-export/geometry-validation.d.ts +20 -0
- package/dist/api/import-export/geometry-validation.js +107 -0
- package/dist/api/import-export/image-import.d.ts +12 -0
- package/dist/api/import-export/image-import.js +53 -0
- package/dist/api/import-export/index.d.ts +9 -0
- package/dist/api/import-export/index.js +107 -0
- package/dist/api/import-export/native-format.d.ts +15 -0
- package/dist/api/import-export/native-format.js +126 -0
- package/dist/api/import-export/native-validation.d.ts +28 -0
- package/dist/api/import-export/native-validation.js +212 -0
- package/dist/api/import-export/own-property.d.ts +10 -0
- package/dist/api/import-export/own-property.js +19 -0
- package/dist/api/import-export/style-validation.d.ts +27 -0
- package/dist/api/import-export/style-validation.js +49 -0
- package/dist/api/import-export/types.d.ts +26 -0
- package/dist/api/import-export/types.js +3 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.js +3 -0
- package/dist/api/input-api.d.ts +158 -0
- package/dist/api/input-api.js +144 -0
- package/dist/api/instance-api.d.ts +38 -0
- package/dist/api/instance-api.js +136 -0
- package/dist/api/layer-api.d.ts +12 -0
- package/dist/api/layer-api.js +62 -0
- package/dist/api/selection-api.d.ts +7 -0
- package/dist/api/selection-api.js +78 -0
- package/dist/api/snapping-api.d.ts +125 -0
- package/dist/api/snapping-api.js +50 -0
- package/dist/api/topology-api.d.ts +30 -0
- package/dist/api/topology-api.js +16 -0
- package/dist/api/tracing-api.d.ts +31 -0
- package/dist/api/tracing-api.js +16 -0
- package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
- package/dist/dispatcher/hit-test/box-strategies.js +275 -0
- package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
- package/dist/dispatcher/hit-test/box-strategy.js +37 -0
- package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
- package/dist/dispatcher/hit-test/globe-shape.js +70 -0
- package/dist/dispatcher/hit-test/index.d.ts +14 -0
- package/dist/dispatcher/hit-test/index.js +9 -0
- package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
- package/dist/dispatcher/hit-test/local-frame.js +112 -0
- package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
- package/dist/dispatcher/hit-test/segment-grid.js +79 -0
- package/dist/dispatcher/hit-test/service.d.ts +120 -0
- package/dist/dispatcher/hit-test/service.js +333 -0
- package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
- package/dist/dispatcher/hit-test/strategies/base.js +66 -0
- package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
- package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
- package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
- package/dist/dispatcher/hit-test/strategies/image.js +115 -0
- package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
- package/dist/dispatcher/hit-test/strategies/index.js +10 -0
- package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
- package/dist/dispatcher/hit-test/strategies/line.js +30 -0
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
- package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
- package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
- package/dist/dispatcher/hit-test/strategies/point.js +29 -0
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
- package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
- package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
- package/dist/dispatcher/hit-test/topmost.js +157 -0
- package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
- package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
- package/dist/dispatcher/index.d.ts +15 -0
- package/dist/dispatcher/index.js +3 -0
- package/dist/dispatcher/input-router.d.ts +1 -0
- package/dist/dispatcher/input-router.js +288 -0
- package/dist/dispatcher/normalizer.d.ts +1 -0
- package/dist/dispatcher/normalizer.js +513 -0
- package/dist/dispatcher/types.d.ts +144 -0
- package/dist/dispatcher/types.js +15 -0
- package/dist/display/chunk-set.d.ts +24 -0
- package/dist/display/chunk-set.js +533 -0
- package/dist/display/chunk.d.ts +1 -0
- package/dist/display/chunk.js +104 -0
- package/dist/display/columnar/index.d.ts +12 -0
- package/dist/display/columnar/index.js +13 -0
- package/dist/display/columnar/prepare.d.ts +42 -0
- package/dist/display/columnar/prepare.js +116 -0
- package/dist/display/columnar/source.d.ts +1 -0
- package/dist/display/columnar/source.js +531 -0
- package/dist/display/columnar/table.d.ts +1 -0
- package/dist/display/columnar/table.js +471 -0
- package/dist/display/columnar/types.d.ts +223 -0
- package/dist/display/columnar/types.js +3 -0
- package/dist/display/dataset.d.ts +2 -0
- package/dist/display/dataset.js +891 -0
- package/dist/display/index.d.ts +13 -0
- package/dist/display/index.js +3 -0
- package/dist/display/interaction.d.ts +1 -0
- package/dist/display/interaction.js +90 -0
- package/dist/display/manager.d.ts +1 -0
- package/dist/display/manager.js +440 -0
- package/dist/display/packed-rtree.d.ts +1 -0
- package/dist/display/packed-rtree.js +244 -0
- package/dist/display/partition.d.ts +1 -0
- package/dist/display/partition.js +226 -0
- package/dist/display/provider.d.ts +1 -0
- package/dist/display/provider.js +342 -0
- package/dist/display/retained.d.ts +40 -0
- package/dist/display/retained.js +898 -0
- package/dist/display/selection.d.ts +13 -0
- package/dist/display/selection.js +226 -0
- package/dist/display/source.d.ts +1 -0
- package/dist/display/source.js +119 -0
- package/dist/display/spatial.d.ts +1 -0
- package/dist/display/spatial.js +71 -0
- package/dist/display/style.d.ts +1 -0
- package/dist/display/style.js +126 -0
- package/dist/display/thinning.d.ts +65 -0
- package/dist/display/thinning.js +910 -0
- package/dist/display/triangulation.d.ts +1 -0
- package/dist/display/triangulation.js +0 -0
- package/dist/display/types.d.ts +561 -0
- package/dist/display/types.js +43 -0
- package/dist/extension/feature-handler.d.ts +182 -0
- package/dist/extension/feature-handler.js +3 -0
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.js +3 -0
- package/dist/extension/renderers.d.ts +208 -0
- package/dist/extension/renderers.js +3 -0
- package/dist/geometry/angle.d.ts +47 -0
- package/dist/geometry/angle.js +44 -0
- package/dist/geometry/bbox.d.ts +48 -0
- package/dist/geometry/bbox.js +83 -0
- package/dist/geometry/boolean.d.ts +162 -0
- package/dist/geometry/boolean.js +331 -0
- package/dist/geometry/buffer.d.ts +72 -0
- package/dist/geometry/buffer.js +218 -0
- package/dist/geometry/circle.d.ts +55 -0
- package/dist/geometry/circle.js +107 -0
- package/dist/geometry/coords.d.ts +97 -0
- package/dist/geometry/coords.js +149 -0
- package/dist/geometry/distance.d.ts +79 -0
- package/dist/geometry/distance.js +111 -0
- package/dist/geometry/errors.d.ts +74 -0
- package/dist/geometry/errors.js +104 -0
- package/dist/geometry/index.d.ts +28 -0
- package/dist/geometry/index.js +38 -0
- package/dist/geometry/measure.d.ts +81 -0
- package/dist/geometry/measure.js +236 -0
- package/dist/geometry/predicates.d.ts +62 -0
- package/dist/geometry/predicates.js +132 -0
- package/dist/geometry/simplify.d.ts +74 -0
- package/dist/geometry/simplify.js +159 -0
- package/dist/geometry/split.d.ts +68 -0
- package/dist/geometry/split.js +430 -0
- package/dist/geometry/types.d.ts +95 -0
- package/dist/geometry/types.js +3 -0
- package/dist/geometry/units.d.ts +35 -0
- package/dist/geometry/units.js +41 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +20 -0
- package/dist/maplibre-gl-draw.d.ts +47 -0
- package/dist/maplibre-gl-draw.js +407 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.js +36 -0
- package/dist/modes/cursor.d.ts +1 -0
- package/dist/modes/cursor.js +72 -0
- package/dist/modes/draw/circle.d.ts +1 -0
- package/dist/modes/draw/circle.js +222 -0
- package/dist/modes/draw/commit-layer.d.ts +26 -0
- package/dist/modes/draw/commit-layer.js +31 -0
- package/dist/modes/draw/freehand.d.ts +1 -0
- package/dist/modes/draw/freehand.js +264 -0
- package/dist/modes/draw/image.d.ts +1 -0
- package/dist/modes/draw/image.js +60 -0
- package/dist/modes/draw/index.d.ts +9 -0
- package/dist/modes/draw/index.js +11 -0
- package/dist/modes/draw/line.d.ts +1 -0
- package/dist/modes/draw/line.js +363 -0
- package/dist/modes/draw/point.d.ts +1 -0
- package/dist/modes/draw/point.js +87 -0
- package/dist/modes/draw/polygon.d.ts +1 -0
- package/dist/modes/draw/polygon.js +378 -0
- package/dist/modes/draw/trace-support.d.ts +79 -0
- package/dist/modes/draw/trace-support.js +161 -0
- package/dist/modes/handler.d.ts +285 -0
- package/dist/modes/handler.js +3 -0
- package/dist/modes/index.d.ts +7 -0
- package/dist/modes/index.js +3 -0
- package/dist/modes/manager.d.ts +15 -0
- package/dist/modes/manager.js +196 -0
- package/dist/modes/select/box-selection.d.ts +52 -0
- package/dist/modes/select/box-selection.js +140 -0
- package/dist/modes/select/click-handler.d.ts +32 -0
- package/dist/modes/select/click-handler.js +166 -0
- package/dist/modes/select/cursor-handler.d.ts +15 -0
- package/dist/modes/select/cursor-handler.js +59 -0
- package/dist/modes/select/drag/auxiliary.d.ts +26 -0
- package/dist/modes/select/drag/auxiliary.js +56 -0
- package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
- package/dist/modes/select/drag/intermediate-writes.js +171 -0
- package/dist/modes/select/drag/move.d.ts +24 -0
- package/dist/modes/select/drag/move.js +59 -0
- package/dist/modes/select/drag/operation.d.ts +30 -0
- package/dist/modes/select/drag/operation.js +18 -0
- package/dist/modes/select/drag/radius.d.ts +15 -0
- package/dist/modes/select/drag/radius.js +49 -0
- package/dist/modes/select/drag/transform.d.ts +17 -0
- package/dist/modes/select/drag/transform.js +155 -0
- package/dist/modes/select/drag/vertex.d.ts +17 -0
- package/dist/modes/select/drag/vertex.js +163 -0
- package/dist/modes/select/drag-handler.d.ts +1 -0
- package/dist/modes/select/drag-handler.js +254 -0
- package/dist/modes/select/hit-helpers.d.ts +40 -0
- package/dist/modes/select/hit-helpers.js +51 -0
- package/dist/modes/select/mode.d.ts +1 -0
- package/dist/modes/select/mode.js +397 -0
- package/dist/modes/select/shortcut-handler.d.ts +40 -0
- package/dist/modes/select/shortcut-handler.js +128 -0
- package/dist/operations/index.d.ts +9 -0
- package/dist/operations/index.js +3 -0
- package/dist/operations/layer-operations.d.ts +1 -0
- package/dist/operations/layer-operations.js +350 -0
- package/dist/operations/resize.d.ts +71 -0
- package/dist/operations/resize.js +252 -0
- package/dist/operations/rotate.d.ts +17 -0
- package/dist/operations/rotate.js +166 -0
- package/dist/operations/selection-operations.d.ts +20 -0
- package/dist/operations/selection-operations.js +159 -0
- package/dist/operations/shared-vertex.d.ts +1 -0
- package/dist/operations/shared-vertex.js +210 -0
- package/dist/operations/trace-graph.d.ts +96 -0
- package/dist/operations/trace-graph.js +283 -0
- package/dist/operations/vertex.d.ts +1 -0
- package/dist/operations/vertex.js +538 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/mutation-hooks.d.ts +28 -0
- package/dist/plugins/mutation-hooks.js +84 -0
- package/dist/plugins/plugin-context.d.ts +1 -0
- package/dist/plugins/plugin-context.js +367 -0
- package/dist/plugins/plugin-manager.d.ts +103 -0
- package/dist/plugins/plugin-manager.js +316 -0
- package/dist/plugins/plugin.d.ts +529 -0
- package/dist/plugins/plugin.js +3 -0
- package/dist/shared/config/constants.d.ts +66 -0
- package/dist/shared/config/constants.js +60 -0
- package/dist/shared/config/feature-style.d.ts +155 -0
- package/dist/shared/config/feature-style.js +154 -0
- package/dist/shared/config/index.d.ts +17 -0
- package/dist/shared/config/index.js +8 -0
- package/dist/shared/config/rendering.d.ts +107 -0
- package/dist/shared/config/rendering.js +33 -0
- package/dist/shared/config/selection-highlight.d.ts +29 -0
- package/dist/shared/config/selection-highlight.js +35 -0
- package/dist/shared/config/selection.d.ts +273 -0
- package/dist/shared/config/selection.js +266 -0
- package/dist/shared/config/topology.d.ts +33 -0
- package/dist/shared/config/topology.js +17 -0
- package/dist/shared/config/trace.d.ts +40 -0
- package/dist/shared/config/trace.js +17 -0
- package/dist/shared/math/angle.d.ts +21 -0
- package/dist/shared/math/angle.js +34 -0
- package/dist/shared/math/circle.d.ts +6 -0
- package/dist/shared/math/circle.js +10 -0
- package/dist/shared/math/constants.d.ts +48 -0
- package/dist/shared/math/constants.js +59 -0
- package/dist/shared/math/distance.d.ts +78 -0
- package/dist/shared/math/distance.js +147 -0
- package/dist/shared/math/globe-subdivision.d.ts +62 -0
- package/dist/shared/math/globe-subdivision.js +99 -0
- package/dist/shared/math/index.d.ts +17 -0
- package/dist/shared/math/index.js +21 -0
- package/dist/shared/math/intersection.d.ts +63 -0
- package/dist/shared/math/intersection.js +236 -0
- package/dist/shared/math/longitude.d.ts +20 -0
- package/dist/shared/math/longitude.js +31 -0
- package/dist/shared/math/mercator-plane.d.ts +27 -0
- package/dist/shared/math/mercator-plane.js +26 -0
- package/dist/shared/math/obb.d.ts +65 -0
- package/dist/shared/math/obb.js +107 -0
- package/dist/shared/math/rotation.d.ts +93 -0
- package/dist/shared/math/rotation.js +186 -0
- package/dist/shared/math/segment-grid.d.ts +69 -0
- package/dist/shared/math/segment-grid.js +159 -0
- package/dist/shared/math/transform.d.ts +140 -0
- package/dist/shared/math/transform.js +189 -0
- package/dist/shared/types/events.d.ts +128 -0
- package/dist/shared/types/events.js +3 -0
- package/dist/shared/types/model.d.ts +950 -0
- package/dist/shared/types/model.js +3 -0
- package/dist/shared/types/selection-box.d.ts +23 -0
- package/dist/shared/types/selection-box.js +3 -0
- package/dist/shared/types/style.d.ts +68 -0
- package/dist/shared/types/style.js +3 -0
- package/dist/shared/utils/color.d.ts +49 -0
- package/dist/shared/utils/color.js +180 -0
- package/dist/shared/utils/coordinates.d.ts +52 -0
- package/dist/shared/utils/coordinates.js +75 -0
- package/dist/shared/utils/embedded-image.d.ts +34 -0
- package/dist/shared/utils/embedded-image.js +161 -0
- package/dist/shared/utils/event-emitter.d.ts +262 -0
- package/dist/shared/utils/event-emitter.js +44 -0
- package/dist/shared/utils/feature-bbox.d.ts +8 -0
- package/dist/shared/utils/feature-bbox.js +207 -0
- package/dist/shared/utils/feature-segments.d.ts +23 -0
- package/dist/shared/utils/feature-segments.js +179 -0
- package/dist/shared/utils/id.d.ts +1 -0
- package/dist/shared/utils/id.js +35 -0
- package/dist/shared/utils/image.d.ts +34 -0
- package/dist/shared/utils/image.js +106 -0
- package/dist/shared/utils/index.d.ts +15 -0
- package/dist/shared/utils/index.js +24 -0
- package/dist/shared/utils/map.d.ts +26 -0
- package/dist/shared/utils/map.js +35 -0
- package/dist/shared/utils/name-generator.d.ts +197 -0
- package/dist/shared/utils/name-generator.js +337 -0
- package/dist/shared/utils/pixel-ratio.d.ts +111 -0
- package/dist/shared/utils/pixel-ratio.js +85 -0
- package/dist/shared/utils/property.d.ts +88 -0
- package/dist/shared/utils/property.js +140 -0
- package/dist/shared/utils/vertex-ref.d.ts +23 -0
- package/dist/shared/utils/vertex-ref.js +20 -0
- package/dist/snapping/custom-targets.d.ts +1 -0
- package/dist/snapping/custom-targets.js +21 -0
- package/dist/snapping/geometry.d.ts +1 -0
- package/dist/snapping/geometry.js +61 -0
- package/dist/snapping/index.d.ts +14 -0
- package/dist/snapping/index.js +4 -0
- package/dist/snapping/indicator.d.ts +19 -0
- package/dist/snapping/indicator.js +145 -0
- package/dist/snapping/providers/display.d.ts +72 -0
- package/dist/snapping/providers/display.js +268 -0
- package/dist/snapping/providers/guide.d.ts +69 -0
- package/dist/snapping/providers/guide.js +187 -0
- package/dist/snapping/providers/intersection.d.ts +1 -0
- package/dist/snapping/providers/intersection.js +92 -0
- package/dist/snapping/providers/shared.d.ts +39 -0
- package/dist/snapping/providers/shared.js +146 -0
- package/dist/snapping/providers/store.d.ts +1 -0
- package/dist/snapping/providers/store.js +132 -0
- package/dist/snapping/service.d.ts +1 -0
- package/dist/snapping/service.js +272 -0
- package/dist/snapping/types.d.ts +267 -0
- package/dist/snapping/types.js +66 -0
- package/dist/store/change-merger.d.ts +1 -0
- package/dist/store/change-merger.js +102 -0
- package/dist/store/draw-store.d.ts +1 -0
- package/dist/store/draw-store.js +396 -0
- package/dist/store/event-bridge.d.ts +1 -0
- package/dist/store/event-bridge.js +161 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +4 -0
- package/dist/store/local-visibility.d.ts +21 -0
- package/dist/store/local-visibility.js +27 -0
- package/dist/store/lock.d.ts +67 -0
- package/dist/store/lock.js +54 -0
- package/dist/store/memory/change-bus.d.ts +60 -0
- package/dist/store/memory/change-bus.js +232 -0
- package/dist/store/memory/file-store.d.ts +15 -0
- package/dist/store/memory/file-store.js +33 -0
- package/dist/store/memory/frozen.d.ts +21 -0
- package/dist/store/memory/frozen.js +51 -0
- package/dist/store/memory/ui-state.d.ts +51 -0
- package/dist/store/memory/ui-state.js +223 -0
- package/dist/store/memory.d.ts +26 -0
- package/dist/store/memory.js +708 -0
- package/dist/store/spatial/index.d.ts +6 -0
- package/dist/store/spatial/index.js +4 -0
- package/dist/store/spatial/spatial-index.d.ts +90 -0
- package/dist/store/spatial/spatial-index.js +148 -0
- package/dist/store/spatial/store-spatial-index.d.ts +60 -0
- package/dist/store/spatial/store-spatial-index.js +125 -0
- package/dist/store/store.d.ts +417 -0
- package/dist/store/store.js +3 -0
- package/dist/store/types.d.ts +8 -0
- package/dist/store/types.js +3 -0
- package/dist/store/writable-layer.d.ts +35 -0
- package/dist/store/writable-layer.js +20 -0
- package/dist/view/cache/buffer.d.ts +28 -0
- package/dist/view/cache/buffer.js +176 -0
- package/dist/view/cache/earcut.d.ts +1 -0
- package/dist/view/cache/earcut.js +122 -0
- package/dist/view/cache/style-rule.d.ts +1 -0
- package/dist/view/cache/style-rule.js +97 -0
- package/dist/view/cache/terrain-fill.d.ts +30 -0
- package/dist/view/cache/terrain-fill.js +60 -0
- package/dist/view/cache/texture.d.ts +14 -0
- package/dist/view/cache/texture.js +292 -0
- package/dist/view/coordinator.d.ts +27 -0
- package/dist/view/coordinator.js +72 -0
- package/dist/view/feature-companion.d.ts +173 -0
- package/dist/view/feature-companion.js +108 -0
- package/dist/view/globe-subdivision.d.ts +78 -0
- package/dist/view/globe-subdivision.js +128 -0
- package/dist/view/index.d.ts +47 -0
- package/dist/view/index.js +20 -0
- package/dist/view/layer/attach.d.ts +20 -0
- package/dist/view/layer/attach.js +47 -0
- package/dist/view/layer/blend.d.ts +57 -0
- package/dist/view/layer/blend.js +14 -0
- package/dist/view/layer/custom-layer.d.ts +1 -0
- package/dist/view/layer/custom-layer.js +509 -0
- package/dist/view/layer/depth-state.d.ts +14 -0
- package/dist/view/layer/depth-state.js +44 -0
- package/dist/view/layer/display-list.d.ts +1 -0
- package/dist/view/layer/display-list.js +111 -0
- package/dist/view/layer/drape-planner.d.ts +139 -0
- package/dist/view/layer/drape-planner.js +726 -0
- package/dist/view/layer/frame-render.d.ts +57 -0
- package/dist/view/layer/frame-render.js +209 -0
- package/dist/view/layer/frame-state.d.ts +147 -0
- package/dist/view/layer/frame-state.js +484 -0
- package/dist/view/layer/gl-state.d.ts +77 -0
- package/dist/view/layer/gl-state.js +132 -0
- package/dist/view/layer/index.d.ts +6 -0
- package/dist/view/layer/index.js +5 -0
- package/dist/view/layer/render-scope.d.ts +30 -0
- package/dist/view/layer/render-scope.js +28 -0
- package/dist/view/layer/render.d.ts +87 -0
- package/dist/view/layer/render.js +187 -0
- package/dist/view/layer/renderers.d.ts +81 -0
- package/dist/view/layer/renderers.js +142 -0
- package/dist/view/layer/slot-manager.d.ts +26 -0
- package/dist/view/layer/slot-manager.js +133 -0
- package/dist/view/layer/slots.d.ts +33 -0
- package/dist/view/layer/slots.js +50 -0
- package/dist/view/layer/store-retained-bbox.d.ts +36 -0
- package/dist/view/layer/store-retained-bbox.js +188 -0
- package/dist/view/layer/store-retained-chunk.d.ts +97 -0
- package/dist/view/layer/store-retained-chunk.js +94 -0
- package/dist/view/layer/store-retained-classify.d.ts +34 -0
- package/dist/view/layer/store-retained-classify.js +88 -0
- package/dist/view/layer/store-retained-collect.d.ts +24 -0
- package/dist/view/layer/store-retained-collect.js +121 -0
- package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
- package/dist/view/layer/store-retained-coord-patch.js +168 -0
- package/dist/view/layer/store-retained-immediate.d.ts +63 -0
- package/dist/view/layer/store-retained-immediate.js +49 -0
- package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
- package/dist/view/layer/store-retained-invalidation.js +192 -0
- package/dist/view/layer/store-retained.d.ts +198 -0
- package/dist/view/layer/store-retained.js +430 -0
- package/dist/view/layer/terrain-resolver.d.ts +1 -0
- package/dist/view/layer/terrain-resolver.js +174 -0
- package/dist/view/renderers/batch-manager.d.ts +61 -0
- package/dist/view/renderers/batch-manager.js +718 -0
- package/dist/view/renderers/draw-factors.d.ts +60 -0
- package/dist/view/renderers/draw-factors.js +35 -0
- package/dist/view/renderers/drawer.d.ts +1 -0
- package/dist/view/renderers/drawer.js +346 -0
- package/dist/view/renderers/image.d.ts +1 -0
- package/dist/view/renderers/image.js +255 -0
- package/dist/view/renderers/line/dash.d.ts +31 -0
- package/dist/view/renderers/line/dash.js +152 -0
- package/dist/view/renderers/line/line-geometry.d.ts +39 -0
- package/dist/view/renderers/line/line-geometry.js +460 -0
- package/dist/view/renderers/line/line-gl.d.ts +1 -0
- package/dist/view/renderers/line/line-gl.js +236 -0
- package/dist/view/renderers/line/line-shader.d.ts +1 -0
- package/dist/view/renderers/line/line-shader.js +364 -0
- package/dist/view/renderers/line/line-types.d.ts +43 -0
- package/dist/view/renderers/line/line-types.js +3 -0
- package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
- package/dist/view/renderers/line/line-uniforms.js +390 -0
- package/dist/view/renderers/line/sdf-line.d.ts +92 -0
- package/dist/view/renderers/line/sdf-line.js +567 -0
- package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
- package/dist/view/renderers/point/billboard-depth.js +56 -0
- package/dist/view/renderers/point/point-instance.d.ts +124 -0
- package/dist/view/renderers/point/point-instance.js +738 -0
- package/dist/view/renderers/point/point-sdf.d.ts +58 -0
- package/dist/view/renderers/point/point-sdf.js +170 -0
- package/dist/view/renderers/point/point-shape.d.ts +99 -0
- package/dist/view/renderers/point/point-shape.js +504 -0
- package/dist/view/renderers/point/point-style.d.ts +1 -0
- package/dist/view/renderers/point/point-style.js +46 -0
- package/dist/view/renderers/polygon/batch.d.ts +26 -0
- package/dist/view/renderers/polygon/batch.js +336 -0
- package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
- package/dist/view/renderers/polygon/earcut-input.js +55 -0
- package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
- package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
- package/dist/view/renderers/polygon/fill.d.ts +74 -0
- package/dist/view/renderers/polygon/fill.js +251 -0
- package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
- package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
- package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
- package/dist/view/renderers/polygon/terrain-cull.js +14 -0
- package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
- package/dist/view/renderers/polygon/triangulator.js +3 -0
- package/dist/view/renderers/retained.d.ts +43 -0
- package/dist/view/renderers/retained.js +3 -0
- package/dist/view/renderers/stroke.d.ts +121 -0
- package/dist/view/renderers/stroke.js +621 -0
- package/dist/view/shaders/frame.d.ts +8 -0
- package/dist/view/shaders/frame.js +37 -0
- package/dist/view/shaders/helpers.d.ts +238 -0
- package/dist/view/shaders/helpers.js +611 -0
- package/dist/view/shaders/initializer.d.ts +27 -0
- package/dist/view/shaders/initializer.js +125 -0
- package/dist/view/shaders/projection.d.ts +123 -0
- package/dist/view/shaders/projection.js +299 -0
- package/dist/view/shaders/quad-grid.d.ts +77 -0
- package/dist/view/shaders/quad-grid.js +128 -0
- package/dist/view/shaders/quad.d.ts +189 -0
- package/dist/view/shaders/quad.js +582 -0
- package/dist/view/shaders/retained-origin.d.ts +50 -0
- package/dist/view/shaders/retained-origin.js +67 -0
- package/dist/view/shaders/terrain-shade.d.ts +23 -0
- package/dist/view/shaders/terrain-shade.js +93 -0
- package/dist/view/style-rule.d.ts +166 -0
- package/dist/view/style-rule.js +300 -0
- package/dist/view/terrain/anchor.d.ts +135 -0
- package/dist/view/terrain/anchor.js +226 -0
- package/dist/view/terrain/context.d.ts +132 -0
- package/dist/view/terrain/context.js +437 -0
- package/dist/view/terrain/dem-atlas.d.ts +97 -0
- package/dist/view/terrain/dem-atlas.js +534 -0
- package/dist/view/terrain/detect.d.ts +126 -0
- package/dist/view/terrain/detect.js +198 -0
- package/dist/view/terrain/drape/bin-store.d.ts +179 -0
- package/dist/view/terrain/drape/bin-store.js +529 -0
- package/dist/view/terrain/drape/binning.d.ts +259 -0
- package/dist/view/terrain/drape/binning.js +604 -0
- package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
- package/dist/view/terrain/drape/edge-constrain.js +175 -0
- package/dist/view/terrain/drape/geometry.d.ts +95 -0
- package/dist/view/terrain/drape/geometry.js +260 -0
- package/dist/view/terrain/drape/mesh.d.ts +50 -0
- package/dist/view/terrain/drape/mesh.js +86 -0
- package/dist/view/terrain/drape/pass.d.ts +122 -0
- package/dist/view/terrain/drape/pass.js +379 -0
- package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
- package/dist/view/terrain/drape/quad-glyphs.js +117 -0
- package/dist/view/terrain/drape/quad.d.ts +249 -0
- package/dist/view/terrain/drape/quad.js +835 -0
- package/dist/view/terrain/drape/renderer.d.ts +184 -0
- package/dist/view/terrain/drape/renderer.js +706 -0
- package/dist/view/terrain/drape/shared.d.ts +80 -0
- package/dist/view/terrain/drape/shared.js +173 -0
- package/dist/view/terrain/drape/stitch.d.ts +155 -0
- package/dist/view/terrain/drape/stitch.js +228 -0
- package/dist/view/terrain/ground.d.ts +72 -0
- package/dist/view/terrain/ground.js +151 -0
- package/dist/view/terrain/metrics.d.ts +180 -0
- package/dist/view/terrain/metrics.js +231 -0
- package/dist/view/terrain/occlusion.d.ts +11 -0
- package/dist/view/terrain/occlusion.js +129 -0
- package/dist/view/terrain/polygon.d.ts +86 -0
- package/dist/view/terrain/polygon.js +301 -0
- package/dist/view/terrain/shade.d.ts +48 -0
- package/dist/view/terrain/shade.js +45 -0
- package/dist/view/terrain/state.d.ts +99 -0
- package/dist/view/terrain/state.js +186 -0
- package/dist/view/terrain/tessellation.d.ts +265 -0
- package/dist/view/terrain/tessellation.js +924 -0
- package/dist/view/terrain/tiling.d.ts +56 -0
- package/dist/view/terrain/tiling.js +155 -0
- package/dist/view/terrain/upstream-terrain.d.ts +82 -0
- package/dist/view/terrain/upstream-terrain.js +116 -0
- package/dist/view/ui/auxiliary-handles.d.ts +151 -0
- package/dist/view/ui/auxiliary-handles.js +22 -0
- package/dist/view/ui/bounds.d.ts +53 -0
- package/dist/view/ui/bounds.js +149 -0
- package/dist/view/ui/box-selection.d.ts +1 -0
- package/dist/view/ui/box-selection.js +83 -0
- package/dist/view/ui/handle-test.d.ts +1 -0
- package/dist/view/ui/handle-test.js +437 -0
- package/dist/view/ui/handle-thinning.d.ts +122 -0
- package/dist/view/ui/handle-thinning.js +430 -0
- package/dist/view/ui/handles.d.ts +25 -0
- package/dist/view/ui/handles.js +673 -0
- package/dist/view/ui/helper.d.ts +19 -0
- package/dist/view/ui/helper.js +76 -0
- package/dist/view/ui/index.d.ts +15 -0
- package/dist/view/ui/index.js +15 -0
- package/dist/view/ui/selection-scope.d.ts +25 -0
- package/dist/view/ui/selection-scope.js +34 -0
- package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
- package/dist/view/ui/selection-ui/bounding-box.js +240 -0
- package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
- package/dist/view/ui/selection-ui/extension-registry.js +78 -0
- package/dist/view/ui/selection-ui/index.d.ts +12 -0
- package/dist/view/ui/selection-ui/index.js +12 -0
- package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
- package/dist/view/ui/selection-ui/renderer.js +227 -0
- package/dist/view/ui/selection-ui/types.d.ts +55 -0
- package/dist/view/ui/selection-ui/types.js +3 -0
- package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
- package/dist/view/ui/selection-ui-drawer.js +329 -0
- package/dist/view/ui/tentative.d.ts +1 -0
- package/dist/view/ui/tentative.js +320 -0
- package/dist/view/viewport.d.ts +119 -0
- package/dist/view/viewport.js +254 -0
- package/package.json +113 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Deletes the group if it has become empty (the standard behavior of canvas tools).
|
|
5
|
+
* Called at the end of each path that moves or removes a feature out of a group.
|
|
6
|
+
*/
|
|
7
|
+
function deleteGroupIfEmpty(store, groupId) {
|
|
8
|
+
const group = store.getGroup(groupId);
|
|
9
|
+
if (group && group.featureIds.length === 0) {
|
|
10
|
+
store.deleteGroup(groupId);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Moves a feature or a group to another layer
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export function moveToLayer(store, itemId, targetLayerId) {
|
|
19
|
+
const feature = store.getFeature(itemId);
|
|
20
|
+
const group = store.getGroup(itemId);
|
|
21
|
+
if (feature) {
|
|
22
|
+
moveFeatureToLayer(store, feature, itemId, targetLayerId);
|
|
23
|
+
}
|
|
24
|
+
else if (group) {
|
|
25
|
+
moveGroupToLayer(store, group, itemId, targetLayerId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function moveFeatureToLayer(store, feature, itemId, targetLayerId) {
|
|
29
|
+
const targetLayer = store.getLayer(targetLayerId);
|
|
30
|
+
if (!targetLayer)
|
|
31
|
+
return;
|
|
32
|
+
// Do nothing when it is already in the same layer
|
|
33
|
+
if (feature.layerId === targetLayerId && !feature.groupId)
|
|
34
|
+
return;
|
|
35
|
+
const previousGroupId = feature.groupId;
|
|
36
|
+
store.transact(() => {
|
|
37
|
+
// When it belongs to a group, remove it from the group
|
|
38
|
+
if (feature.groupId) {
|
|
39
|
+
const currentGroup = store.getGroup(feature.groupId);
|
|
40
|
+
if (currentGroup) {
|
|
41
|
+
store.updateGroup(feature.groupId, {
|
|
42
|
+
featureIds: currentGroup.featureIds.filter((id) => id !== itemId),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// When it is a standalone feature, remove it from the original layer
|
|
48
|
+
const sourceLayer = store.getLayer(feature.layerId);
|
|
49
|
+
if (sourceLayer) {
|
|
50
|
+
const sourceOrder = sourceLayer.order.filter((id) => id !== itemId);
|
|
51
|
+
store.updateLayer(sourceLayer.id, { order: sourceOrder });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Add it to the new layer
|
|
55
|
+
store.updateLayer(targetLayerId, { order: [...targetLayer.order, itemId] });
|
|
56
|
+
// Update the layerId of the feature and clear its groupId
|
|
57
|
+
store.updateFeature(itemId, { layerId: targetLayerId, groupId: undefined });
|
|
58
|
+
// Delete the source group when it has become empty
|
|
59
|
+
if (previousGroupId) {
|
|
60
|
+
deleteGroupIfEmpty(store, previousGroupId);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function moveGroupToLayer(store, group, itemId, targetLayerId) {
|
|
65
|
+
// Find the layer the group belongs to
|
|
66
|
+
let sourceLayerId = null;
|
|
67
|
+
for (const layer of store.getAllLayers()) {
|
|
68
|
+
if (layer.order.includes(itemId)) {
|
|
69
|
+
sourceLayerId = layer.id;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (sourceLayerId && sourceLayerId !== targetLayerId) {
|
|
74
|
+
const sourceLayer = store.getLayer(sourceLayerId);
|
|
75
|
+
const targetLayer = store.getLayer(targetLayerId);
|
|
76
|
+
if (sourceLayer && targetLayer) {
|
|
77
|
+
store.transact(() => {
|
|
78
|
+
// Remove it from the original layer
|
|
79
|
+
const sourceOrder = sourceLayer.order.filter((id) => id !== itemId);
|
|
80
|
+
store.updateLayer(sourceLayerId, { order: sourceOrder });
|
|
81
|
+
// Add it to the new layer
|
|
82
|
+
store.updateLayer(targetLayerId, { order: [...targetLayer.order, itemId] });
|
|
83
|
+
// Update the layerId of the features inside the group
|
|
84
|
+
for (const featureId of group.featureIds) {
|
|
85
|
+
store.updateFeature(featureId, { layerId: targetLayerId });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Adds a feature to a group
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
export function addFeatureToGroup(store, featureId, groupId, index) {
|
|
97
|
+
const feature = store.getFeature(featureId);
|
|
98
|
+
const group = store.getGroup(groupId);
|
|
99
|
+
if (!feature || !group)
|
|
100
|
+
return;
|
|
101
|
+
// Do nothing when it is already included in this group
|
|
102
|
+
if (group.featureIds.includes(featureId))
|
|
103
|
+
return;
|
|
104
|
+
// Find the layer the group belongs to
|
|
105
|
+
let targetLayerId = null;
|
|
106
|
+
for (const layer of store.getAllLayers()) {
|
|
107
|
+
if (layer.order.includes(groupId)) {
|
|
108
|
+
targetLayerId = layer.id;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
store.transact(() => {
|
|
113
|
+
// When the feature already belongs to another group, remove it from that group
|
|
114
|
+
if (feature.groupId && feature.groupId !== groupId) {
|
|
115
|
+
const oldGroupId = feature.groupId;
|
|
116
|
+
const oldGroup = store.getGroup(oldGroupId);
|
|
117
|
+
if (oldGroup) {
|
|
118
|
+
store.updateGroup(oldGroupId, {
|
|
119
|
+
featureIds: oldGroup.featureIds.filter((id) => id !== featureId),
|
|
120
|
+
});
|
|
121
|
+
// Delete the source group when it has become empty
|
|
122
|
+
deleteGroupIfEmpty(store, oldGroupId);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Remove the feature from the order of the layer (when it is included in order on its own)
|
|
126
|
+
const layer = store.getLayer(feature.layerId);
|
|
127
|
+
if (layer?.order.includes(featureId)) {
|
|
128
|
+
const newOrder = layer.order.filter((id) => id !== featureId);
|
|
129
|
+
store.updateLayer(layer.id, { order: newOrder });
|
|
130
|
+
}
|
|
131
|
+
// Add the feature to the group (when an index is given, insert it at that position)
|
|
132
|
+
const newFeatureIds = [...group.featureIds];
|
|
133
|
+
if (index !== undefined && index >= 0 && index <= newFeatureIds.length) {
|
|
134
|
+
newFeatureIds.splice(index, 0, featureId);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
newFeatureIds.push(featureId);
|
|
138
|
+
}
|
|
139
|
+
store.updateGroup(groupId, { featureIds: newFeatureIds });
|
|
140
|
+
// Set the groupId and the layerId (when needed) on the feature
|
|
141
|
+
const updates = { groupId };
|
|
142
|
+
if (targetLayerId && feature.layerId !== targetLayerId) {
|
|
143
|
+
updates.layerId = targetLayerId;
|
|
144
|
+
}
|
|
145
|
+
store.updateFeature(featureId, updates);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Removes a feature from a group
|
|
150
|
+
*
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
export function removeFeatureFromGroup(store, featureId) {
|
|
154
|
+
const feature = store.getFeature(featureId);
|
|
155
|
+
if (!feature?.groupId)
|
|
156
|
+
return;
|
|
157
|
+
const group = store.getGroup(feature.groupId);
|
|
158
|
+
if (!group)
|
|
159
|
+
return;
|
|
160
|
+
// Find the layer the group belongs to
|
|
161
|
+
let layerId = null;
|
|
162
|
+
for (const layer of store.getAllLayers()) {
|
|
163
|
+
if (layer.order.includes(group.id)) {
|
|
164
|
+
layerId = layer.id;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
store.transact(() => {
|
|
169
|
+
// Remove the feature from the group
|
|
170
|
+
const newFeatureIds = group.featureIds.filter((id) => id !== featureId);
|
|
171
|
+
store.updateGroup(group.id, { featureIds: newFeatureIds });
|
|
172
|
+
// Remove the groupId from the feature
|
|
173
|
+
store.updateFeature(featureId, { groupId: undefined });
|
|
174
|
+
// Add the feature to the order of the layer (right after the group)
|
|
175
|
+
if (layerId) {
|
|
176
|
+
const layer = store.getLayer(layerId);
|
|
177
|
+
if (layer) {
|
|
178
|
+
const groupIndex = layer.order.indexOf(group.id);
|
|
179
|
+
const newOrder = [...layer.order];
|
|
180
|
+
newOrder.splice(groupIndex + 1, 0, featureId);
|
|
181
|
+
store.updateLayer(layerId, { order: newOrder });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Delete the group when it has become empty (after the feature has been moved out
|
|
185
|
+
// directly under the layer)
|
|
186
|
+
deleteGroupIfEmpty(store, group.id);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Groups the selected features
|
|
191
|
+
*
|
|
192
|
+
* @returns The group ID, or null when grouping was not possible
|
|
193
|
+
*
|
|
194
|
+
* @internal
|
|
195
|
+
*/
|
|
196
|
+
export function groupSelection(store, generateFeatureId, autoNameGenerator) {
|
|
197
|
+
const selection = store.getSelection();
|
|
198
|
+
// Do nothing when it is not a feature selection
|
|
199
|
+
if (selection.type !== 'feature')
|
|
200
|
+
return null;
|
|
201
|
+
const selectedIds = selection.ids;
|
|
202
|
+
// Condition 1: two or more features are selected
|
|
203
|
+
const features = selectedIds
|
|
204
|
+
.map((id) => store.getFeature(id))
|
|
205
|
+
.filter((f) => f !== undefined);
|
|
206
|
+
if (features.length < 2)
|
|
207
|
+
return null;
|
|
208
|
+
// Condition 2: they all belong to the same layer
|
|
209
|
+
const layerIds = new Set(features.map((f) => f.layerId));
|
|
210
|
+
if (layerIds.size !== 1)
|
|
211
|
+
return null;
|
|
212
|
+
const layerId = features[0].layerId;
|
|
213
|
+
// Condition 3: they do not yet belong to a group that actually exists.
|
|
214
|
+
// When the groupId is a stale value that points to a deleted group, it is regarded as
|
|
215
|
+
// belonging to nothing and regrouping is allowed (createGroup overwrites the groupId of the
|
|
216
|
+
// members with the new value, so it is repaired automatically here).
|
|
217
|
+
if (features.some((f) => f.groupId !== undefined && store.getGroup(f.groupId) !== undefined)) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
// Create the group
|
|
221
|
+
const groupId = generateFeatureId();
|
|
222
|
+
const groupName = autoNameGenerator.generateGroupName();
|
|
223
|
+
const group = {
|
|
224
|
+
id: groupId,
|
|
225
|
+
name: groupName,
|
|
226
|
+
featureIds: [...selectedIds],
|
|
227
|
+
locked: false,
|
|
228
|
+
visible: true,
|
|
229
|
+
};
|
|
230
|
+
store.transact(() => {
|
|
231
|
+
// Remove the feature IDs from the order of the layer and add the group ID
|
|
232
|
+
const layer = store.getLayer(layerId);
|
|
233
|
+
if (layer) {
|
|
234
|
+
// Find the frontmost one (the largest index) among the selected features
|
|
235
|
+
let frontmostSelectedId = null;
|
|
236
|
+
for (let i = layer.order.length - 1; i >= 0; i--) {
|
|
237
|
+
if (selectedIds.includes(layer.order[i])) {
|
|
238
|
+
frontmostSelectedId = layer.order[i];
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Build the new order (insert the group at the position of the frontmost selected feature)
|
|
243
|
+
const newOrder = [];
|
|
244
|
+
for (const id of layer.order) {
|
|
245
|
+
if (selectedIds.includes(id)) {
|
|
246
|
+
// Insert the group at the position of the frontmost selected feature
|
|
247
|
+
if (id === frontmostSelectedId) {
|
|
248
|
+
newOrder.push(groupId);
|
|
249
|
+
}
|
|
250
|
+
// The selected features are excluded from the order
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
newOrder.push(id);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Even when not a single selected feature is included in order (for example when they
|
|
257
|
+
// are missing from order because of stale data), the group is appended at the tail so
|
|
258
|
+
// that it is not left out of order.
|
|
259
|
+
if (frontmostSelectedId === null) {
|
|
260
|
+
newOrder.push(groupId);
|
|
261
|
+
}
|
|
262
|
+
store.updateLayer(layerId, { order: newOrder });
|
|
263
|
+
}
|
|
264
|
+
// Create the group
|
|
265
|
+
store.createGroup(group);
|
|
266
|
+
});
|
|
267
|
+
return groupId;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Dissolves a group (outside a transaction, a pure mutation).
|
|
271
|
+
* It removes the group from the order, expands its member features into the same position,
|
|
272
|
+
* and then deletes the group itself. The caller must wrap it in store.transact.
|
|
273
|
+
*/
|
|
274
|
+
function dissolveGroup(store, groupId) {
|
|
275
|
+
const group = store.getGroup(groupId);
|
|
276
|
+
if (!group)
|
|
277
|
+
return;
|
|
278
|
+
// Identify the layer the group belongs to
|
|
279
|
+
let targetLayerId = null;
|
|
280
|
+
for (const layer of store.getAllLayers()) {
|
|
281
|
+
if (layer.order.includes(groupId)) {
|
|
282
|
+
targetLayerId = layer.id;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!targetLayerId)
|
|
287
|
+
return;
|
|
288
|
+
// Remove the group ID from the order of the layer and expand the feature IDs into the same
|
|
289
|
+
// position
|
|
290
|
+
const layer = store.getLayer(targetLayerId);
|
|
291
|
+
if (layer) {
|
|
292
|
+
const groupIndex = layer.order.indexOf(groupId);
|
|
293
|
+
const newOrder = [...layer.order];
|
|
294
|
+
newOrder.splice(groupIndex, 1, ...group.featureIds);
|
|
295
|
+
store.updateLayer(targetLayerId, { order: newOrder });
|
|
296
|
+
}
|
|
297
|
+
// Delete the group
|
|
298
|
+
store.deleteGroup(groupId);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Dissolves the given group (it does not depend on the selection).
|
|
302
|
+
* For "ungroup that group" in a panel menu and the like.
|
|
303
|
+
*
|
|
304
|
+
* @internal
|
|
305
|
+
*/
|
|
306
|
+
export function ungroupGroup(store, groupId) {
|
|
307
|
+
store.transact(() => {
|
|
308
|
+
dissolveGroup(store, groupId);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Takes the selection out of the group structure (following Felt).
|
|
313
|
+
*
|
|
314
|
+
* - When a group is selected -> that group is dissolved (its children are expanded into the
|
|
315
|
+
* original position)
|
|
316
|
+
* - When a member feature of a group is selected -> only that feature is taken out of the
|
|
317
|
+
* group (the group is kept; the member is placed right after the group by
|
|
318
|
+
* removeFeatureFromGroup, and the group is deleted automatically when it becomes empty).
|
|
319
|
+
* The group is not dissolved as a whole
|
|
320
|
+
* - Otherwise (a feature that is not a member / no selection) -> nothing is done
|
|
321
|
+
*
|
|
322
|
+
* Even with several targets it is gathered into one transaction, making it one undo unit.
|
|
323
|
+
*
|
|
324
|
+
* @internal
|
|
325
|
+
*/
|
|
326
|
+
export function ungroupSelection(store) {
|
|
327
|
+
const selection = store.getSelection();
|
|
328
|
+
if (selection.ids.length === 0)
|
|
329
|
+
return;
|
|
330
|
+
// A group selection -> dissolve
|
|
331
|
+
if (selection.type === 'group') {
|
|
332
|
+
store.transact(() => {
|
|
333
|
+
for (const groupId of selection.ids) {
|
|
334
|
+
dissolveGroup(store, groupId);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
// A feature selection -> take only the selected members out of the group (do not dissolve)
|
|
340
|
+
if (selection.type === 'feature') {
|
|
341
|
+
const memberIds = selection.ids.filter((id) => store.getFeature(id)?.groupId !== undefined);
|
|
342
|
+
if (memberIds.length === 0)
|
|
343
|
+
return;
|
|
344
|
+
store.transact(() => {
|
|
345
|
+
for (const id of memberIds) {
|
|
346
|
+
removeFeatureFromGroup(store, id);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resize operation
|
|
3
|
+
*
|
|
4
|
+
* The operation that resizes features. It computes in Web Mercator (see mercator-plane.ts),
|
|
5
|
+
* so a handle follows the pointer on the map at any latitude. The extension points of the
|
|
6
|
+
* draw instance are passed in as an argument ({@link ResizeExtensions}).
|
|
7
|
+
*/
|
|
8
|
+
import type { CustomResizeResult } from '../extension/index.js';
|
|
9
|
+
import type { HandleType } from '../shared/config/constants.js';
|
|
10
|
+
import type { BoundingBoxCoords } from '../shared/types/selection-box.js';
|
|
11
|
+
import type { Feature, FeatureCoordinates } from '../store/types.js';
|
|
12
|
+
/**
|
|
13
|
+
* A custom resize computation of a feature type
|
|
14
|
+
*/
|
|
15
|
+
export type ResizeCalculator = (handle: HandleType, state: ResizeState, currentLngLat: {
|
|
16
|
+
lng: number;
|
|
17
|
+
lat: number;
|
|
18
|
+
}, feature: Feature) => CustomResizeResult | null;
|
|
19
|
+
/**
|
|
20
|
+
* The extension points the resize reads from the draw instance
|
|
21
|
+
*
|
|
22
|
+
* The draw instance's selection extension registry satisfies it.
|
|
23
|
+
*/
|
|
24
|
+
export interface ResizeExtensions {
|
|
25
|
+
getResizeStrategy(type: string): 'scale' | 'coordinates' | undefined;
|
|
26
|
+
getCustomResizeCalculator(type: string): ResizeCalculator | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The result of the resize
|
|
30
|
+
*/
|
|
31
|
+
export interface ResizeResult {
|
|
32
|
+
coordinates: FeatureCoordinates;
|
|
33
|
+
/** The new scale value of a feature that has a scale property */
|
|
34
|
+
scale?: number;
|
|
35
|
+
/** The new radius for a Circle (meters) */
|
|
36
|
+
radiusMeters?: number;
|
|
37
|
+
/** The width (pixels) - for a custom resize */
|
|
38
|
+
width?: number;
|
|
39
|
+
/** The height (pixels) - for a custom resize */
|
|
40
|
+
height?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The state of a resize drag, captured when the drag starts.
|
|
44
|
+
*/
|
|
45
|
+
export interface ResizeState {
|
|
46
|
+
/** The handle being dragged */
|
|
47
|
+
handle: HandleType;
|
|
48
|
+
/** The pointer position at the start, in degrees */
|
|
49
|
+
startLngLat: {
|
|
50
|
+
lng: number;
|
|
51
|
+
lat: number;
|
|
52
|
+
};
|
|
53
|
+
/** The selection box at the start, corners in degrees */
|
|
54
|
+
startBbox: BoundingBoxCoords;
|
|
55
|
+
/** The coordinates of each feature at the start, by feature id */
|
|
56
|
+
initialCoordinates: Map<string, FeatureCoordinates>;
|
|
57
|
+
/** The scale of a feature that has a scale property, at the start */
|
|
58
|
+
initialScales: Map<string, number>;
|
|
59
|
+
/** The radius of a Circle at the start (meters) */
|
|
60
|
+
initialRadiusMeters: Map<string, number>;
|
|
61
|
+
/** The width at the start (pixels) - for a custom resize */
|
|
62
|
+
initialWidth: Map<string, number>;
|
|
63
|
+
/** The height at the start (pixels) - for a custom resize */
|
|
64
|
+
initialHeight: Map<string, number>;
|
|
65
|
+
/**
|
|
66
|
+
* The extent of the bounding box (Web Mercator world units, 1 = the width of the world)
|
|
67
|
+
* below which it is not stretched along that axis. The caller converts a screen distance
|
|
68
|
+
* at the current zoom. 0 when omitted (only a box of no extent is left alone)
|
|
69
|
+
*/
|
|
70
|
+
minAxisExtent?: number;
|
|
71
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { fromPlane, toPlane } from '../shared/math/mercator-plane.js';
|
|
4
|
+
import { mapCoordinatesDeep } from '../shared/utils/coordinates.js';
|
|
5
|
+
import { getCircleRadius, getImageProperties } from '../shared/utils/property.js';
|
|
6
|
+
/**
|
|
7
|
+
* Decides whether a feature has a scale property
|
|
8
|
+
*
|
|
9
|
+
* For features that have a scale property (Text, Image, custom features and so on)
|
|
10
|
+
*/
|
|
11
|
+
function hasScaleProperty(feature, extensions) {
|
|
12
|
+
// Get resizeStrategy from the draw instance's registry
|
|
13
|
+
const strategy = extensions?.getResizeStrategy(feature.type);
|
|
14
|
+
if (strategy === 'scale') {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (strategy === 'coordinates') {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
// The built-in types of the core
|
|
21
|
+
if (feature.type === 'Image') {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
// Generic check (decided by the presence of a scale property)
|
|
25
|
+
return (feature.properties !== null &&
|
|
26
|
+
typeof feature.properties === 'object' &&
|
|
27
|
+
'scale' in feature.properties);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets the value of the scale property of a feature
|
|
31
|
+
*/
|
|
32
|
+
function getFeatureScale(feature) {
|
|
33
|
+
if (feature.type === 'Image') {
|
|
34
|
+
const props = getImageProperties(feature);
|
|
35
|
+
return props.scale ?? 1;
|
|
36
|
+
}
|
|
37
|
+
const props = feature.properties;
|
|
38
|
+
return typeof props.scale === 'number' ? props.scale : 1;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Gets the anchor (the fixed point) from the handle position
|
|
42
|
+
*/
|
|
43
|
+
function getAnchorFromHandle(handle, bbox) {
|
|
44
|
+
switch (handle) {
|
|
45
|
+
case 'resize-nw':
|
|
46
|
+
return { anchor: bbox.bottomRight, scaleX: -1, scaleY: 1 };
|
|
47
|
+
case 'resize-n':
|
|
48
|
+
return {
|
|
49
|
+
anchor: [(bbox.bottomLeft[0] + bbox.bottomRight[0]) / 2, bbox.bottomLeft[1]],
|
|
50
|
+
scaleX: 0,
|
|
51
|
+
scaleY: 1,
|
|
52
|
+
};
|
|
53
|
+
case 'resize-ne':
|
|
54
|
+
return { anchor: bbox.bottomLeft, scaleX: 1, scaleY: 1 };
|
|
55
|
+
case 'resize-e':
|
|
56
|
+
return {
|
|
57
|
+
anchor: [
|
|
58
|
+
(bbox.topLeft[0] + bbox.bottomLeft[0]) / 2,
|
|
59
|
+
(bbox.topLeft[1] + bbox.bottomLeft[1]) / 2,
|
|
60
|
+
],
|
|
61
|
+
scaleX: 1,
|
|
62
|
+
scaleY: 0,
|
|
63
|
+
};
|
|
64
|
+
case 'resize-se':
|
|
65
|
+
return { anchor: bbox.topLeft, scaleX: 1, scaleY: -1 };
|
|
66
|
+
case 'resize-s':
|
|
67
|
+
return {
|
|
68
|
+
anchor: [(bbox.topLeft[0] + bbox.topRight[0]) / 2, bbox.topLeft[1]],
|
|
69
|
+
scaleX: 0,
|
|
70
|
+
scaleY: -1,
|
|
71
|
+
};
|
|
72
|
+
case 'resize-sw':
|
|
73
|
+
return { anchor: bbox.topRight, scaleX: -1, scaleY: -1 };
|
|
74
|
+
case 'resize-w':
|
|
75
|
+
return {
|
|
76
|
+
anchor: [
|
|
77
|
+
(bbox.topRight[0] + bbox.bottomRight[0]) / 2,
|
|
78
|
+
(bbox.topRight[1] + bbox.bottomRight[1]) / 2,
|
|
79
|
+
],
|
|
80
|
+
scaleX: -1,
|
|
81
|
+
scaleY: 0,
|
|
82
|
+
};
|
|
83
|
+
default:
|
|
84
|
+
return { anchor: bbox.center, scaleX: 1, scaleY: 1 };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Scales a coordinate in the transform plane around an anchor given in the plane
|
|
89
|
+
*/
|
|
90
|
+
function scaleCoordinate(coord, anchor, scaleX, scaleY) {
|
|
91
|
+
const [x, y] = toPlane(coord);
|
|
92
|
+
return fromPlane(anchor[0] + (x - anchor[0]) * scaleX, anchor[1] + (y - anchor[1]) * scaleY);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Scales an array of coordinates
|
|
96
|
+
*
|
|
97
|
+
* It uses a common traversal that does not depend on the nesting depth, so Multi
|
|
98
|
+
* geometries (a MultiPolygon is nested 4 levels deep) can be transformed as they
|
|
99
|
+
* are.
|
|
100
|
+
*/
|
|
101
|
+
function scaleCoordinates(coords, anchor, scaleX, scaleY) {
|
|
102
|
+
return mapCoordinatesDeep(coords, (coord) => scaleCoordinate(coord, anchor, scaleX, scaleY));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The distance between 2 points of the transform plane
|
|
106
|
+
*/
|
|
107
|
+
function planeDistance(a, b) {
|
|
108
|
+
return Math.hypot(a[0] - b[0], a[1] - b[1]);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Computes the resize
|
|
112
|
+
*
|
|
113
|
+
* @param extensions The draw instance's extension points (custom resize calculators)
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export function computeResize(state, currentLngLat, features, extensions) {
|
|
118
|
+
const { handle, startLngLat, startBbox } = state;
|
|
119
|
+
const { anchor: anchorLngLat, scaleX: scaleDirectionX, scaleY: scaleDirectionY, } = getAnchorFromHandle(handle, startBbox);
|
|
120
|
+
const anchor = toPlane(anchorLngLat);
|
|
121
|
+
const start = toPlane([startLngLat.lng, startLngLat.lat]);
|
|
122
|
+
const current = toPlane([currentLngLat.lng, currentLngLat.lat]);
|
|
123
|
+
// Compute the scale from the distance to the anchor (this handles rotation)
|
|
124
|
+
const startDistance = planeDistance(start, anchor);
|
|
125
|
+
const currentDistance = planeDistance(current, anchor);
|
|
126
|
+
// Compute the scale from the rate of change of the distance
|
|
127
|
+
// Note: for a small feature (Text and so on) startDistance becomes a very small value, so
|
|
128
|
+
// only a distance of exactly zero is left alone
|
|
129
|
+
let uniformScale = 1;
|
|
130
|
+
if (startDistance > 0) {
|
|
131
|
+
uniformScale = currentDistance / startDistance;
|
|
132
|
+
}
|
|
133
|
+
// Limit the minimum scale
|
|
134
|
+
uniformScale = Math.max(uniformScale, 0.1);
|
|
135
|
+
// The scale along the axes (for non-rotated features)
|
|
136
|
+
// Compute the amount of movement
|
|
137
|
+
const dx = current[0] - start[0];
|
|
138
|
+
const dy = current[1] - start[1];
|
|
139
|
+
// The size of the bounding box (valid only when it is not rotated). A box thinner than the
|
|
140
|
+
// caller's minimum extent (a screen distance) is not stretched along that axis, because the
|
|
141
|
+
// division would turn a pixel of pointer movement into a huge scale
|
|
142
|
+
const topLeft = toPlane(startBbox.topLeft);
|
|
143
|
+
const bboxWidth = Math.abs(toPlane(startBbox.topRight)[0] - topLeft[0]);
|
|
144
|
+
const bboxHeight = Math.abs(topLeft[1] - toPlane(startBbox.bottomLeft)[1]);
|
|
145
|
+
const minExtent = Math.max(0, state.minAxisExtent ?? 0);
|
|
146
|
+
let scaleX = 1;
|
|
147
|
+
let scaleY = 1;
|
|
148
|
+
if (scaleDirectionX !== 0 && bboxWidth > minExtent) {
|
|
149
|
+
scaleX = 1 + (scaleDirectionX * dx) / bboxWidth;
|
|
150
|
+
}
|
|
151
|
+
if (scaleDirectionY !== 0 && bboxHeight > minExtent) {
|
|
152
|
+
scaleY = 1 + (scaleDirectionY * dy) / bboxHeight;
|
|
153
|
+
}
|
|
154
|
+
// Limit the minimum scale
|
|
155
|
+
scaleX = Math.max(scaleX, 0.1);
|
|
156
|
+
scaleY = Math.max(scaleY, 0.1);
|
|
157
|
+
// Compute the new coordinates of each feature
|
|
158
|
+
const result = new Map();
|
|
159
|
+
for (const feature of features) {
|
|
160
|
+
const initialCoords = state.initialCoordinates.get(feature.id);
|
|
161
|
+
if (!initialCoords)
|
|
162
|
+
continue;
|
|
163
|
+
// Use the custom resize calculator first if there is one
|
|
164
|
+
const customCalculator = extensions?.getCustomResizeCalculator(feature.type);
|
|
165
|
+
if (customCalculator) {
|
|
166
|
+
const customResult = customCalculator(handle, state, currentLngLat, feature);
|
|
167
|
+
if (customResult) {
|
|
168
|
+
result.set(feature.id, {
|
|
169
|
+
coordinates: customResult.coordinates,
|
|
170
|
+
width: customResult.width,
|
|
171
|
+
height: customResult.height,
|
|
172
|
+
});
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Which features scale by property was decided when the resize started (initialScales)
|
|
177
|
+
if (state.initialScales.has(feature.id)) {
|
|
178
|
+
// For a feature that has a scale property:
|
|
179
|
+
// with the anchor as the fixed point, scale the center coordinate too and change scale
|
|
180
|
+
const initialScale = state.initialScales.get(feature.id) ?? 1;
|
|
181
|
+
const newScale = initialScale * uniformScale;
|
|
182
|
+
const newCoords = scaleCoordinates(initialCoords, anchor, uniformScale, uniformScale);
|
|
183
|
+
result.set(feature.id, {
|
|
184
|
+
coordinates: newCoords,
|
|
185
|
+
scale: newScale,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else if (feature.type === 'Circle') {
|
|
189
|
+
// For a Circle: scale the center coordinate and scale the radius too
|
|
190
|
+
const initialRadius = state.initialRadiusMeters.get(feature.id) ?? 0;
|
|
191
|
+
const newRadius = initialRadius * uniformScale;
|
|
192
|
+
const newCoords = scaleCoordinates(initialCoords, anchor, uniformScale, uniformScale);
|
|
193
|
+
result.set(feature.id, {
|
|
194
|
+
coordinates: newCoords,
|
|
195
|
+
radiusMeters: newRadius,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
// For Point, LineString, Polygon and Freehand: change only the coordinates
|
|
200
|
+
const newCoords = scaleCoordinates(initialCoords, anchor, scaleX, scaleY);
|
|
201
|
+
result.set(feature.id, { coordinates: newCoords });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Starts the resize operation
|
|
208
|
+
*
|
|
209
|
+
* @param extensions The draw instance's extension points (resize strategies of custom types)
|
|
210
|
+
* @param minAxisExtent The extent of the bounding box (Web Mercator world units) below which
|
|
211
|
+
* it is not stretched along that axis; the caller converts a screen distance at its zoom
|
|
212
|
+
*
|
|
213
|
+
* @internal
|
|
214
|
+
*/
|
|
215
|
+
export function startResize(handle, startLngLat, bbox, features, extensions, minAxisExtent = 0) {
|
|
216
|
+
const initialCoordinates = new Map();
|
|
217
|
+
const initialScales = new Map();
|
|
218
|
+
const initialRadiusMeters = new Map();
|
|
219
|
+
const initialWidth = new Map();
|
|
220
|
+
const initialHeight = new Map();
|
|
221
|
+
for (const feature of features) {
|
|
222
|
+
initialCoordinates.set(feature.id, JSON.parse(JSON.stringify(feature.coordinates)));
|
|
223
|
+
// For a feature that has a scale property, store the initial scale
|
|
224
|
+
if (hasScaleProperty(feature, extensions)) {
|
|
225
|
+
initialScales.set(feature.id, getFeatureScale(feature));
|
|
226
|
+
}
|
|
227
|
+
// For a Circle, store the initial radius
|
|
228
|
+
if (feature.type === 'Circle') {
|
|
229
|
+
const radiusMeters = getCircleRadius(feature);
|
|
230
|
+
initialRadiusMeters.set(feature.id, radiusMeters ?? 0);
|
|
231
|
+
}
|
|
232
|
+
// For a feature that has width / height properties (Note and so on), store the initial size
|
|
233
|
+
const props = feature.properties;
|
|
234
|
+
if (typeof props.width === 'number') {
|
|
235
|
+
initialWidth.set(feature.id, props.width);
|
|
236
|
+
}
|
|
237
|
+
if (typeof props.height === 'number') {
|
|
238
|
+
initialHeight.set(feature.id, props.height);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
handle,
|
|
243
|
+
startLngLat,
|
|
244
|
+
startBbox: bbox,
|
|
245
|
+
initialCoordinates,
|
|
246
|
+
initialScales,
|
|
247
|
+
initialRadiusMeters,
|
|
248
|
+
initialWidth,
|
|
249
|
+
initialHeight,
|
|
250
|
+
minAxisExtent,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FeatureCoordinates } from '../store/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The extension points the rotation reads from the draw instance
|
|
4
|
+
*
|
|
5
|
+
* The draw instance's selection extension registry satisfies it.
|
|
6
|
+
*/
|
|
7
|
+
export interface RotateExtensions {
|
|
8
|
+
getResizeStrategy(type: string): 'scale' | 'coordinates' | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The result of the rotation
|
|
12
|
+
*/
|
|
13
|
+
export interface RotateResult {
|
|
14
|
+
coordinates: FeatureCoordinates;
|
|
15
|
+
/** The new rotation value of a feature that has a rotation property (degrees) */
|
|
16
|
+
rotation?: number;
|
|
17
|
+
}
|