@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,146 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Shared helpers of the built-in snapping providers
|
|
5
|
+
*
|
|
6
|
+
* They gather the narrowing down of candidate features and the listing of edges that
|
|
7
|
+
* the providers originating from the Store (vertex, edge, intersection) use in
|
|
8
|
+
* common. The behavior is the same as in the original providers/store.ts; only the
|
|
9
|
+
* location was moved so that the intersection provider can reuse it.
|
|
10
|
+
*/
|
|
11
|
+
import { getSegmentGrid, querySegmentIndicesInBBox, SEGMENT_INDEX_THRESHOLD, } from '../../shared/math/segment-grid.js';
|
|
12
|
+
import { forEachPart, hasSnapEdges, isClosedCoords, isInBBox, makeRefFactory, } from '../../shared/utils/feature-segments.js';
|
|
13
|
+
import { isSameVertexRef } from '../../shared/utils/vertex-ref.js';
|
|
14
|
+
import { isLocallyHidden } from '../../store/local-visibility.js';
|
|
15
|
+
import { computeVertexHandles } from '../../view/ui/handles.js';
|
|
16
|
+
export { collectFeatureSegments, collectFeatureSegmentsInBBox, hasSnapEdges, segmentIntersectsBBox, } from '../../shared/utils/feature-segments.js';
|
|
17
|
+
/**
|
|
18
|
+
* Whether the feature is a snapping target (whether it is displayed)
|
|
19
|
+
*
|
|
20
|
+
* It looks at both the shared visible cascade (feature / group / layer) and the local
|
|
21
|
+
* hiding that applies to this client only.
|
|
22
|
+
*/
|
|
23
|
+
export function isSnapVisible(feature, store) {
|
|
24
|
+
if (!feature.visible)
|
|
25
|
+
return false;
|
|
26
|
+
if (!store.getLayer(feature.layerId)?.visible)
|
|
27
|
+
return false;
|
|
28
|
+
if (feature.groupId && store.getGroup(feature.groupId)?.visible === false)
|
|
29
|
+
return false;
|
|
30
|
+
return !isLocallyHidden(feature, store);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Lists the candidate features near the bbox
|
|
34
|
+
*/
|
|
35
|
+
export function queryFeatures(deps, bbox, ctx) {
|
|
36
|
+
const lng = (bbox.minX + bbox.maxX) / 2;
|
|
37
|
+
const lat = (bbox.minY + bbox.maxY) / 2;
|
|
38
|
+
// findNear queries a square extent, so the larger of the tolerances is used
|
|
39
|
+
const tolerance = Math.max(bbox.maxX - lng, bbox.maxY - lat);
|
|
40
|
+
const features = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
for (const id of deps.spatialIndex.findNear([lng, lat], tolerance)) {
|
|
43
|
+
if (seen.has(id))
|
|
44
|
+
continue;
|
|
45
|
+
seen.add(id);
|
|
46
|
+
if (id === ctx.excludeFeatureId)
|
|
47
|
+
continue;
|
|
48
|
+
if (ctx.excludeFeatureIds?.has(id))
|
|
49
|
+
continue;
|
|
50
|
+
const feature = deps.store.getFeature(id);
|
|
51
|
+
if (!feature)
|
|
52
|
+
continue;
|
|
53
|
+
if (!isSnapVisible(feature, deps.store))
|
|
54
|
+
continue;
|
|
55
|
+
features.push(feature);
|
|
56
|
+
}
|
|
57
|
+
return features;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether the vertex is to be excluded
|
|
61
|
+
*/
|
|
62
|
+
export function isExcludedVertex(featureId, vertex, ctx) {
|
|
63
|
+
const exclude = ctx.excludeVertex;
|
|
64
|
+
if (!exclude || !vertex)
|
|
65
|
+
return false;
|
|
66
|
+
return exclude.featureId === featureId && isSameVertexRef(vertex, exclude.vertex);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Gathers the vertices of one coordinate sequence (a line / a ring) that are inside
|
|
70
|
+
* the bbox
|
|
71
|
+
*
|
|
72
|
+
* The vertices and the vertex references listed are exactly the same as in
|
|
73
|
+
* computeVertexHandles (view/ui/handles.ts). The last item of a ring is a copy of the
|
|
74
|
+
* first one, so no handle is produced for it (through the index, the last item is
|
|
75
|
+
* normalized to index 0 and the duplicate is dropped). A line produces a handle on
|
|
76
|
+
* its last vertex even when it is closed, so it is not normalized.
|
|
77
|
+
*/
|
|
78
|
+
function collectPartVerticesInBBox(coords, ring, part, isRing, bbox, out) {
|
|
79
|
+
const closedRing = isRing && isClosedCoords(coords);
|
|
80
|
+
const vertexCount = closedRing ? coords.length - 1 : coords.length;
|
|
81
|
+
if (vertexCount === 0)
|
|
82
|
+
return;
|
|
83
|
+
const toRef = makeRefFactory(ring, part);
|
|
84
|
+
// For a small part, building an index costs more, so it is scanned as it is
|
|
85
|
+
if (coords.length < SEGMENT_INDEX_THRESHOLD) {
|
|
86
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
87
|
+
if (!isInBBox(coords[i], bbox))
|
|
88
|
+
continue;
|
|
89
|
+
out.push({ position: coords[i], vertexRef: toRef(i) });
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Both ends of an edge that falls within the bbox become vertex candidates. For a
|
|
94
|
+
// vertex inside the bbox, an edge touching it always falls within the bbox, so
|
|
95
|
+
// nothing is missed
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
const indices = [];
|
|
98
|
+
for (const segment of querySegmentIndicesInBBox(getSegmentGrid(coords), bbox)) {
|
|
99
|
+
for (const raw of [segment, segment + 1]) {
|
|
100
|
+
const index = closedRing && raw === vertexCount ? 0 : raw;
|
|
101
|
+
if (index >= vertexCount)
|
|
102
|
+
continue;
|
|
103
|
+
if (seen.has(index))
|
|
104
|
+
continue;
|
|
105
|
+
seen.add(index);
|
|
106
|
+
indices.push(index);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Aligned to the same order as a full scan (ascending by index)
|
|
110
|
+
indices.sort((a, b) => a - b);
|
|
111
|
+
for (const index of indices) {
|
|
112
|
+
if (!isInBBox(coords[index], bbox))
|
|
113
|
+
continue;
|
|
114
|
+
out.push({ position: coords[index], vertexRef: toRef(index) });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Gathers the vertices of a feature that are inside the bbox
|
|
119
|
+
*
|
|
120
|
+
* The bbox is the cursor position +- the tolerance (in longitude and in latitude),
|
|
121
|
+
* and the distance test of SnapService measures the pixel distance with the same
|
|
122
|
+
* conversion. A vertex outside the bbox can therefore never be inside the tolerance,
|
|
123
|
+
* and discarding it here does not change the candidates.
|
|
124
|
+
*
|
|
125
|
+
* For types without edges (Point / MultiPoint / custom types), the full listing of
|
|
126
|
+
* computeVertexHandles is simply narrowed down by the bbox, as before.
|
|
127
|
+
*/
|
|
128
|
+
export function collectVertexCandidatesInBBox(feature, bbox) {
|
|
129
|
+
const candidates = [];
|
|
130
|
+
if (!hasSnapEdges(feature.type)) {
|
|
131
|
+
for (const handle of computeVertexHandles(feature)) {
|
|
132
|
+
// Only Point / MultiPoint reach this path, and a vertex reference is always
|
|
133
|
+
// attached
|
|
134
|
+
if (!handle.vertexRef)
|
|
135
|
+
continue;
|
|
136
|
+
if (!isInBBox(handle.position, bbox))
|
|
137
|
+
continue;
|
|
138
|
+
candidates.push({ position: handle.position, vertexRef: handle.vertexRef });
|
|
139
|
+
}
|
|
140
|
+
return candidates;
|
|
141
|
+
}
|
|
142
|
+
forEachPart(feature, (coords, ring, part, isRing) => {
|
|
143
|
+
collectPartVerticesInBBox(coords, ring, part, isRing, bbox, candidates);
|
|
144
|
+
});
|
|
145
|
+
return candidates;
|
|
146
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { StoreSnapProviderDeps } from './shared.js';
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Built-in snapping providers (the vertices and edges of the Store)
|
|
5
|
+
*
|
|
6
|
+
* It narrows down the features near the cursor with SpatialIndex.findNear and lists
|
|
7
|
+
* the vertex and edge candidates per type. Intersections are handled by
|
|
8
|
+
* providers/intersection.ts, and construction guides by providers/guide.ts.
|
|
9
|
+
*
|
|
10
|
+
* What is left out.
|
|
11
|
+
*
|
|
12
|
+
* - Hidden features (both the shared visible flag and local hiding)
|
|
13
|
+
* - The features of ctx.excludeFeatureId / ctx.excludeFeatureIds
|
|
14
|
+
* - The vertex of ctx.excludeVertex and the edges touching it (the vertex being
|
|
15
|
+
* dragged sits on the cursor, so the edges touching it would always be at a
|
|
16
|
+
* distance of 0)
|
|
17
|
+
* - The tentative feature being drawn (it is not a feature of the Store, so it never
|
|
18
|
+
* enters in the first place)
|
|
19
|
+
*
|
|
20
|
+
* For a custom feature type, CustomFeatureHandler.getSnapTargets is used when it is
|
|
21
|
+
* registered (the vertex provider calls it).
|
|
22
|
+
*/
|
|
23
|
+
import { resolveMessages } from '../../messages.js';
|
|
24
|
+
import { DEFAULT_SNAP_OPTIONS, } from '../types.js';
|
|
25
|
+
import { createSteppedGuideSnapProvider } from './guide.js';
|
|
26
|
+
import { createStoreIntersectionSnapProvider } from './intersection.js';
|
|
27
|
+
import { collectFeatureSegmentsInBBox, collectVertexCandidatesInBBox, hasSnapEdges, isExcludedVertex, queryFeatures, segmentIntersectsBBox, } from './shared.js';
|
|
28
|
+
/**
|
|
29
|
+
* Builds the vertex provider for the Store
|
|
30
|
+
*
|
|
31
|
+
* The vertices and the vertex references per type are aligned with the vertex
|
|
32
|
+
* handles of the selection UI (computeVertexHandles). The inner rings (holes) of a
|
|
33
|
+
* Polygon and the parts of the Multi variants are targets as they are. The listing
|
|
34
|
+
* is narrowed down to the extent that falls within the bbox (a huge feature uses the
|
|
35
|
+
* index).
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export function createStoreVertexSnapProvider(deps) {
|
|
40
|
+
return {
|
|
41
|
+
name: 'core:store-vertex',
|
|
42
|
+
candidates(bbox, ctx) {
|
|
43
|
+
const candidates = [];
|
|
44
|
+
for (const feature of queryFeatures(deps, bbox, ctx)) {
|
|
45
|
+
// A custom type is left to the registered getSnapTargets
|
|
46
|
+
const custom = deps.snapTargets?.get(feature.type);
|
|
47
|
+
if (custom) {
|
|
48
|
+
for (const candidate of custom(feature, ctx)) {
|
|
49
|
+
const featureId = candidate.featureId ?? feature.id;
|
|
50
|
+
if (!('start' in candidate) && isExcludedVertex(featureId, candidate.vertex, ctx)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
candidates.push({ ...candidate, featureId });
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
for (const vertex of collectVertexCandidatesInBBox(feature, bbox)) {
|
|
58
|
+
if (isExcludedVertex(feature.id, vertex.vertexRef, ctx))
|
|
59
|
+
continue;
|
|
60
|
+
const candidate = {
|
|
61
|
+
kind: 'vertex',
|
|
62
|
+
coordinate: vertex.position,
|
|
63
|
+
featureId: feature.id,
|
|
64
|
+
vertex: vertex.vertexRef,
|
|
65
|
+
};
|
|
66
|
+
candidates.push(candidate);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return candidates;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Builds the edge provider for the Store
|
|
75
|
+
*
|
|
76
|
+
* The candidates are returned as segments (2 end points), and the computation of the
|
|
77
|
+
* point closest to the cursor is left to SnapService. The vertex references of both
|
|
78
|
+
* ends are included as well (tracing reads them).
|
|
79
|
+
*
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export function createStoreEdgeSnapProvider(deps) {
|
|
83
|
+
return {
|
|
84
|
+
name: 'core:store-edge',
|
|
85
|
+
candidates(bbox, ctx) {
|
|
86
|
+
const candidates = [];
|
|
87
|
+
for (const feature of queryFeatures(deps, bbox, ctx)) {
|
|
88
|
+
// The candidates of a custom type are returned by the vertex provider
|
|
89
|
+
// (getSnapTargets)
|
|
90
|
+
if (deps.snapTargets?.get(feature.type))
|
|
91
|
+
continue;
|
|
92
|
+
if (!hasSnapEdges(feature.type))
|
|
93
|
+
continue;
|
|
94
|
+
collectFeatureSegmentsInBBox(feature, bbox, (start, end, startRef, endRef) => {
|
|
95
|
+
if (!segmentIntersectsBBox(start, end, bbox))
|
|
96
|
+
return;
|
|
97
|
+
// An edge touching the vertex being dragged passes over the cursor, so it is
|
|
98
|
+
// excluded
|
|
99
|
+
if (isExcludedVertex(feature.id, startRef, ctx))
|
|
100
|
+
return;
|
|
101
|
+
if (isExcludedVertex(feature.id, endRef, ctx))
|
|
102
|
+
return;
|
|
103
|
+
const candidate = {
|
|
104
|
+
kind: 'edge',
|
|
105
|
+
start,
|
|
106
|
+
end,
|
|
107
|
+
startRef,
|
|
108
|
+
endRef,
|
|
109
|
+
featureId: feature.id,
|
|
110
|
+
};
|
|
111
|
+
candidates.push(candidate);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return candidates;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Builds the full set of built-in providers (in the order vertex -> edge ->
|
|
120
|
+
* intersection -> guide)
|
|
121
|
+
*
|
|
122
|
+
* @internal
|
|
123
|
+
*/
|
|
124
|
+
export function createBuiltInSnapProviders(deps, options = {}) {
|
|
125
|
+
const messages = resolveMessages(options.messages);
|
|
126
|
+
return [
|
|
127
|
+
createStoreVertexSnapProvider(deps),
|
|
128
|
+
createStoreEdgeSnapProvider(deps),
|
|
129
|
+
createStoreIntersectionSnapProvider({ ...deps, messages }),
|
|
130
|
+
createSteppedGuideSnapProvider({ store: deps.store }, options.getNorthStepDegrees ?? (() => DEFAULT_SNAP_OPTIONS.guideStepDegrees), { tileSize: options.tileSize, messages }),
|
|
131
|
+
];
|
|
132
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DEFAULT_TILE_SIZE } from '../shared/math/index.js';
|
|
4
|
+
import { nearestLongitude, wrapLongitude } from '../shared/math/longitude.js';
|
|
5
|
+
import { isSameVertexRef } from '../shared/utils/vertex-ref.js';
|
|
6
|
+
import { degreesPerPixel, distanceInPixels, nearestPointOnSegment } from './geometry.js';
|
|
7
|
+
import { createBuiltInSnapProviders } from './providers/store.js';
|
|
8
|
+
import { DEFAULT_SNAP_OPTIONS, isSegmentCandidate, resolveGuideStepDegrees, resolveSnapKinds, SNAP_KIND_PRIORITY, } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Whether it is temporarily disabled by a modifier key
|
|
11
|
+
*/
|
|
12
|
+
function isDisabledByModifier(modifiers, key) {
|
|
13
|
+
if (key === 'none')
|
|
14
|
+
return false;
|
|
15
|
+
return modifiers[key];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Whether the vertex references are the same (two unspecified ones also count as the
|
|
19
|
+
* same)
|
|
20
|
+
*/
|
|
21
|
+
function isSameVertex(a, b) {
|
|
22
|
+
if (a === undefined || b === undefined)
|
|
23
|
+
return a === b;
|
|
24
|
+
return isSameVertexRef(a, b);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether the segments of the snapping targets are the same (two unspecified ones also
|
|
28
|
+
* count as the same)
|
|
29
|
+
*
|
|
30
|
+
* Even when the snapped point does not move, a different segment means a different
|
|
31
|
+
* snapping target, so it is treated as a change.
|
|
32
|
+
*/
|
|
33
|
+
function isSameSegment(a, b) {
|
|
34
|
+
if (a === undefined || b === undefined)
|
|
35
|
+
return a === b;
|
|
36
|
+
return (a.start[0] === b.start[0] &&
|
|
37
|
+
a.start[1] === b.start[1] &&
|
|
38
|
+
a.end[0] === b.end[0] &&
|
|
39
|
+
a.end[1] === b.end[1]);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether the 2 results are the same (used to decide whether to emit an event)
|
|
43
|
+
*/
|
|
44
|
+
function isSameResult(a, b) {
|
|
45
|
+
// The first resolution counts as a change only when something was snapped to (not
|
|
46
|
+
// being snapped is the default state)
|
|
47
|
+
if (!a)
|
|
48
|
+
return b.target === undefined;
|
|
49
|
+
if (a.target === undefined && b.target === undefined)
|
|
50
|
+
return true;
|
|
51
|
+
if (a.target === undefined || b.target === undefined)
|
|
52
|
+
return false;
|
|
53
|
+
return (a.target.kind === b.target.kind &&
|
|
54
|
+
a.target.featureId === b.target.featureId &&
|
|
55
|
+
a.target.datasetId === b.target.datasetId &&
|
|
56
|
+
a.target.description === b.target.description &&
|
|
57
|
+
isSameVertex(a.target.vertex, b.target.vertex) &&
|
|
58
|
+
isSameSegment(a.target.segment, b.target.segment) &&
|
|
59
|
+
a.lngLat.lng === b.lngLat.lng &&
|
|
60
|
+
a.lngLat.lat === b.lngLat.lat);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether the new candidate replaces the current best candidate
|
|
64
|
+
*/
|
|
65
|
+
function isBetterCandidate(best, priority, distancePx, preferred) {
|
|
66
|
+
if (best.priority !== priority)
|
|
67
|
+
return priority < best.priority;
|
|
68
|
+
if (best.distancePx !== distancePx)
|
|
69
|
+
return distancePx < best.distancePx;
|
|
70
|
+
// Only on a complete tie does a candidate of the preferred feature overturn the one
|
|
71
|
+
// that arrived first
|
|
72
|
+
return preferred && !best.preferred;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Creates a SnapService
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
export function createSnapService(deps = {}) {
|
|
80
|
+
// kinds is nested, so it is copied (so that the defaults object is not rewritten)
|
|
81
|
+
const options = {
|
|
82
|
+
...DEFAULT_SNAP_OPTIONS,
|
|
83
|
+
...deps.options,
|
|
84
|
+
kinds: resolveSnapKinds(deps.options?.kinds),
|
|
85
|
+
datasets: deps.options?.datasets ?? DEFAULT_SNAP_OPTIONS.datasets,
|
|
86
|
+
guideStepDegrees: resolveGuideStepDegrees(deps.options?.guideStepDegrees),
|
|
87
|
+
};
|
|
88
|
+
const tileSize = deps.tileSize ?? DEFAULT_TILE_SIZE;
|
|
89
|
+
const providers = [];
|
|
90
|
+
let enabled = options.enabled;
|
|
91
|
+
let lastResult = null;
|
|
92
|
+
if (deps.store && deps.spatialIndex) {
|
|
93
|
+
providers.push(...createBuiltInSnapProviders({ store: deps.store, spatialIndex: deps.spatialIndex, snapTargets: deps.snapTargets }, {
|
|
94
|
+
tileSize,
|
|
95
|
+
...deps.guide,
|
|
96
|
+
// Read at every query, so setGuideStep takes effect without rebuilding the provider
|
|
97
|
+
getNorthStepDegrees: () => options.guideStepDegrees,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stores the result and emits an event when it changed
|
|
102
|
+
*/
|
|
103
|
+
function publish(result) {
|
|
104
|
+
const changed = !isSameResult(lastResult, result);
|
|
105
|
+
lastResult = result;
|
|
106
|
+
if (changed) {
|
|
107
|
+
deps.eventEmitter?.emit('snap.change', result);
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Evaluates a single candidate and updates best
|
|
113
|
+
*
|
|
114
|
+
* They are compared by the priority of the kind first and then by distance, and only
|
|
115
|
+
* when the distances tie as well does the candidate matching preferFeature
|
|
116
|
+
* (preferred) win. Otherwise the one that arrived first is kept.
|
|
117
|
+
*/
|
|
118
|
+
function evaluate(best, coordinate, target, cursor, perPixel, preferred) {
|
|
119
|
+
const distancePx = distanceInPixels(coordinate, cursor, perPixel);
|
|
120
|
+
if (distancePx > options.tolerancePx)
|
|
121
|
+
return best;
|
|
122
|
+
const priority = SNAP_KIND_PRIORITY[target.kind];
|
|
123
|
+
if (best && !isBetterCandidate(best, priority, distancePx, preferred)) {
|
|
124
|
+
return best;
|
|
125
|
+
}
|
|
126
|
+
return { coordinate, target, priority, distancePx, preferred };
|
|
127
|
+
}
|
|
128
|
+
/** How far a longitude moves to reach its copy nearest to the cursor (0 in most cases) */
|
|
129
|
+
function turnToCursor(lng, cursorLng) {
|
|
130
|
+
return nearestLongitude(lng, cursorLng) - lng;
|
|
131
|
+
}
|
|
132
|
+
/** A coordinate moved along the longitude (the same array when it does not move) */
|
|
133
|
+
function moveBy(coordinate, turn) {
|
|
134
|
+
return turn === 0 ? coordinate : [coordinate[0] + turn, coordinate[1]];
|
|
135
|
+
}
|
|
136
|
+
function resolve(lngLat, point, ctx) {
|
|
137
|
+
if (!enabled || isDisabledByModifier(ctx.modifiers, options.disableKey)) {
|
|
138
|
+
return publish({ lngLat });
|
|
139
|
+
}
|
|
140
|
+
const perPixel = degreesPerPixel(lngLat.lat, ctx.zoom, tileSize);
|
|
141
|
+
const toleranceLngDeg = perPixel.lng * options.tolerancePx;
|
|
142
|
+
const toleranceLatDeg = perPixel.lat * options.tolerancePx;
|
|
143
|
+
const cursor = [lngLat.lng, lngLat.lat];
|
|
144
|
+
// The cursor on each copy of the world its tolerance reaches. The features are stored in
|
|
145
|
+
// [-180, 180], while the cursor comes in the unwrapped longitude of the view (above 180 on
|
|
146
|
+
// the copy east of the antimeridian, where the rendering draws the stored features a second
|
|
147
|
+
// time). The candidates are looked up around the cursor brought into [-180, 180], and also
|
|
148
|
+
// on the neighbouring copy when the tolerance runs past ±180. Each candidate is then taken
|
|
149
|
+
// on its copy nearest to the cursor (a segment moves by the turn of its start), so it is
|
|
150
|
+
// evaluated and returned in the frame of the cursor; a candidate already in that frame (a
|
|
151
|
+
// guide drawn from the tentative) does not move. Away from the antimeridian this is the
|
|
152
|
+
// cursor alone, and nothing moves.
|
|
153
|
+
const stored = wrapLongitude(lngLat.lng);
|
|
154
|
+
const copies = [stored];
|
|
155
|
+
if (stored + toleranceLngDeg > 180)
|
|
156
|
+
copies.push(stored - 360);
|
|
157
|
+
if (stored - toleranceLngDeg < -180)
|
|
158
|
+
copies.push(stored + 360);
|
|
159
|
+
let best = null;
|
|
160
|
+
for (const copyLng of copies) {
|
|
161
|
+
const copyLngLat = copyLng === lngLat.lng ? lngLat : { lng: copyLng, lat: lngLat.lat };
|
|
162
|
+
const bbox = {
|
|
163
|
+
minX: copyLng - toleranceLngDeg,
|
|
164
|
+
minY: lngLat.lat - toleranceLatDeg,
|
|
165
|
+
maxX: copyLng + toleranceLngDeg,
|
|
166
|
+
maxY: lngLat.lat + toleranceLatDeg,
|
|
167
|
+
};
|
|
168
|
+
const providerCtx = {
|
|
169
|
+
...ctx,
|
|
170
|
+
lngLat: copyLngLat,
|
|
171
|
+
point,
|
|
172
|
+
tolerancePx: options.tolerancePx,
|
|
173
|
+
toleranceLngDeg,
|
|
174
|
+
toleranceLatDeg,
|
|
175
|
+
};
|
|
176
|
+
for (const provider of providers) {
|
|
177
|
+
let candidates;
|
|
178
|
+
try {
|
|
179
|
+
candidates = provider.candidates(bbox, providerCtx);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
// An exception from one provider does not stop snapping as a whole
|
|
183
|
+
console.error(`Error in snap provider "${provider.name}":`, error);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
for (const candidate of candidates) {
|
|
187
|
+
// Candidates of a disabled kind are not evaluated
|
|
188
|
+
if (!options.kinds[candidate.kind])
|
|
189
|
+
continue;
|
|
190
|
+
let coordinate;
|
|
191
|
+
if (isSegmentCandidate(candidate)) {
|
|
192
|
+
const turn = turnToCursor(candidate.start[0], lngLat.lng);
|
|
193
|
+
coordinate = nearestPointOnSegment(cursor, moveBy(candidate.start, turn), moveBy(candidate.end, turn), perPixel);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
coordinate = moveBy(candidate.coordinate, turnToCursor(candidate.coordinate[0], lngLat.lng));
|
|
197
|
+
}
|
|
198
|
+
// The target keeps the stored coordinates (it names the geometry that was snapped to)
|
|
199
|
+
const target = { kind: candidate.kind };
|
|
200
|
+
if (candidate.featureId !== undefined)
|
|
201
|
+
target.featureId = candidate.featureId;
|
|
202
|
+
if (candidate.datasetId !== undefined)
|
|
203
|
+
target.datasetId = candidate.datasetId;
|
|
204
|
+
if (candidate.description !== undefined)
|
|
205
|
+
target.description = candidate.description;
|
|
206
|
+
if (isSegmentCandidate(candidate)) {
|
|
207
|
+
const segment = { start: candidate.start, end: candidate.end };
|
|
208
|
+
if (candidate.startRef !== undefined)
|
|
209
|
+
segment.startRef = candidate.startRef;
|
|
210
|
+
if (candidate.endRef !== undefined)
|
|
211
|
+
segment.endRef = candidate.endRef;
|
|
212
|
+
target.segment = segment;
|
|
213
|
+
}
|
|
214
|
+
else if (candidate.vertex !== undefined) {
|
|
215
|
+
target.vertex = candidate.vertex;
|
|
216
|
+
}
|
|
217
|
+
// Whether it matches the "preferred feature" used as the tie-break on a tie
|
|
218
|
+
// (two unspecified datasetIds also count as a match)
|
|
219
|
+
const preferred = ctx.preferFeature !== undefined &&
|
|
220
|
+
candidate.featureId === ctx.preferFeature.featureId &&
|
|
221
|
+
candidate.datasetId === ctx.preferFeature.datasetId;
|
|
222
|
+
best = evaluate(best, coordinate, target, cursor, perPixel, preferred);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (!best) {
|
|
227
|
+
return publish({ lngLat });
|
|
228
|
+
}
|
|
229
|
+
return publish({
|
|
230
|
+
lngLat: { lng: best.coordinate[0], lat: best.coordinate[1] },
|
|
231
|
+
target: best.target,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
resolve,
|
|
236
|
+
register(provider) {
|
|
237
|
+
providers.push(provider);
|
|
238
|
+
return () => {
|
|
239
|
+
const index = providers.indexOf(provider);
|
|
240
|
+
if (index >= 0)
|
|
241
|
+
providers.splice(index, 1);
|
|
242
|
+
};
|
|
243
|
+
},
|
|
244
|
+
setEnabled(value) {
|
|
245
|
+
enabled = value;
|
|
246
|
+
},
|
|
247
|
+
isEnabled() {
|
|
248
|
+
return enabled;
|
|
249
|
+
},
|
|
250
|
+
setKindEnabled(kind, value) {
|
|
251
|
+
options.kinds[kind] = value;
|
|
252
|
+
},
|
|
253
|
+
isKindEnabled(kind) {
|
|
254
|
+
return options.kinds[kind];
|
|
255
|
+
},
|
|
256
|
+
setDatasetsEnabled(value) {
|
|
257
|
+
options.datasets = value;
|
|
258
|
+
},
|
|
259
|
+
isDatasetsEnabled() {
|
|
260
|
+
return options.datasets;
|
|
261
|
+
},
|
|
262
|
+
setGuideStep(degrees) {
|
|
263
|
+
options.guideStepDegrees = resolveGuideStepDegrees(degrees);
|
|
264
|
+
},
|
|
265
|
+
getResult() {
|
|
266
|
+
return lastResult;
|
|
267
|
+
},
|
|
268
|
+
getOptions() {
|
|
269
|
+
return { ...options, enabled, kinds: { ...options.kinds } };
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
}
|