@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,333 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { clickCopies, toleranceDegrees } from './local-frame.js';
|
|
4
|
+
import { DEFAULT_HIT_TEST_OPTIONS, HitTestStrategyRegistry } from './strategies/base.js';
|
|
5
|
+
import { CircleHitTestStrategy } from './strategies/circle.js';
|
|
6
|
+
import { ImageHitTestStrategy } from './strategies/image.js';
|
|
7
|
+
import { LineHitTestStrategy } from './strategies/line.js';
|
|
8
|
+
import { MultiLineStringHitTestStrategy, MultiPointHitTestStrategy, MultiPolygonHitTestStrategy, } from './strategies/multi.js';
|
|
9
|
+
import { PointHitTestStrategy } from './strategies/point.js';
|
|
10
|
+
import { PolygonHitTestStrategy } from './strategies/polygon.js';
|
|
11
|
+
import { createVisibilityLookup } from './visibility-lookup.js';
|
|
12
|
+
/**
|
|
13
|
+
* The types tested in screen space (the symbols drawn without a depth test)
|
|
14
|
+
*
|
|
15
|
+
* Polygons, lines, circles and images are draped onto the ground surface and are occluded
|
|
16
|
+
* correctly by depth, so the longitude/latitude path remains the correct one for them.
|
|
17
|
+
*/
|
|
18
|
+
const SCREEN_SPACE_TYPES = new Set(['Point', 'MultiPoint']);
|
|
19
|
+
/**
|
|
20
|
+
* The HitTestService implementation
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export class HitTestServiceImpl {
|
|
25
|
+
constructor(store, spatialIndex, options = {}) {
|
|
26
|
+
Object.defineProperty(this, "spatialIndex", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "store", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "registry", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: void 0
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(this, "options", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true,
|
|
48
|
+
value: void 0
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(this, "imageStrategy", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true,
|
|
54
|
+
value: void 0
|
|
55
|
+
});
|
|
56
|
+
/** The extra reach (in CSS pixels) for narrowing down the candidates, per feature type */
|
|
57
|
+
Object.defineProperty(this, "candidateReach", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: new Map()
|
|
62
|
+
});
|
|
63
|
+
/** The anchor projection of the symbols (terrain aware; without it only the conventional
|
|
64
|
+
* path is used) */
|
|
65
|
+
Object.defineProperty(this, "anchorScreen", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: void 0
|
|
70
|
+
});
|
|
71
|
+
/** The shape a feature is drawn with (the stored shape when there is no resolver) */
|
|
72
|
+
Object.defineProperty(this, "drawnShape", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: void 0
|
|
77
|
+
});
|
|
78
|
+
this.store = store;
|
|
79
|
+
this.spatialIndex = spatialIndex;
|
|
80
|
+
this.anchorScreen = options.anchorScreen ?? null;
|
|
81
|
+
this.drawnShape = options.drawnShape ?? ((feature) => feature);
|
|
82
|
+
this.options = { ...DEFAULT_HIT_TEST_OPTIONS, ...options };
|
|
83
|
+
const tileSize = options.tileSize ?? 512;
|
|
84
|
+
// Register the default strategies
|
|
85
|
+
this.registry = new HitTestStrategyRegistry();
|
|
86
|
+
this.registry.register(new PointHitTestStrategy());
|
|
87
|
+
this.registry.register(new LineHitTestStrategy());
|
|
88
|
+
this.registry.register(new PolygonHitTestStrategy());
|
|
89
|
+
this.registry.register(new CircleHitTestStrategy());
|
|
90
|
+
// The Multi geometries (a hit if any part is hit / the distance is the minimum over the
|
|
91
|
+
// parts)
|
|
92
|
+
this.registry.register(new MultiPointHitTestStrategy());
|
|
93
|
+
this.registry.register(new MultiLineStringHitTestStrategy());
|
|
94
|
+
this.registry.register(new MultiPolygonHitTestStrategy());
|
|
95
|
+
// Freehand uses the same strategy as LineString
|
|
96
|
+
const freehandStrategy = new LineHitTestStrategy();
|
|
97
|
+
// Create a wrapper with geometryType changed to Freehand
|
|
98
|
+
this.registry.register({
|
|
99
|
+
geometryType: 'Freehand',
|
|
100
|
+
test: freehandStrategy.test.bind(freehandStrategy),
|
|
101
|
+
distance: freehandStrategy.distance.bind(freehandStrategy),
|
|
102
|
+
testDistance: freehandStrategy.testDistance.bind(freehandStrategy),
|
|
103
|
+
});
|
|
104
|
+
// The Image strategy (it depends on the zoom level and the tile size)
|
|
105
|
+
this.imageStrategy = new ImageHitTestStrategy(tileSize);
|
|
106
|
+
this.registry.register(this.imageStrategy);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Updates the tile size
|
|
110
|
+
*/
|
|
111
|
+
setTileSize(tileSize) {
|
|
112
|
+
this.imageStrategy.setTileSize(tileSize);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Registers a custom strategy
|
|
116
|
+
*/
|
|
117
|
+
registerStrategy(strategy) {
|
|
118
|
+
return this.registry.register(strategy);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Registers the extra reach for narrowing down the candidates
|
|
122
|
+
*
|
|
123
|
+
* A type whose value changes with the zoom or with settings is registered as a function
|
|
124
|
+
* (it is evaluated on every query).
|
|
125
|
+
*/
|
|
126
|
+
registerCandidateReach(type, reachPx) {
|
|
127
|
+
this.candidateReach.set(type, reachPx);
|
|
128
|
+
return () => {
|
|
129
|
+
if (this.candidateReach.get(type) === reachPx)
|
|
130
|
+
this.candidateReach.delete(type);
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The maximum of the registered extra reaches (in CSS pixels)
|
|
135
|
+
*
|
|
136
|
+
* Widening the candidate set is cheap (the precise test of the second stage drops the
|
|
137
|
+
* extras), so the search is not split per type and is done once with the single maximum.
|
|
138
|
+
*/
|
|
139
|
+
maxCandidateReachPx() {
|
|
140
|
+
let max = 0;
|
|
141
|
+
for (const reach of this.candidateReach.values()) {
|
|
142
|
+
const value = typeof reach === 'function' ? reach() : reach;
|
|
143
|
+
if (Number.isFinite(value) && value > max)
|
|
144
|
+
max = value;
|
|
145
|
+
}
|
|
146
|
+
return max;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Widens the radius of the candidate search (degrees of longitude) by the extra reach
|
|
150
|
+
*
|
|
151
|
+
* The degrees per pixel are obtained by dividing the already computed toleranceLngLat by
|
|
152
|
+
* clickTolerance (so no additional call to unproject is made). Only when clickTolerance is
|
|
153
|
+
* 0 is one pixel measured directly.
|
|
154
|
+
*
|
|
155
|
+
* The radius is a square box in degrees. A latitude reach needs only radius * cos φ
|
|
156
|
+
* (local-frame.ts), so the box never misses a candidate.
|
|
157
|
+
*/
|
|
158
|
+
expandSearchRadius(toleranceLngLat, tolerancePx, screenPoint, unproject) {
|
|
159
|
+
const reachPx = this.maxCandidateReachPx();
|
|
160
|
+
if (reachPx <= 0)
|
|
161
|
+
return toleranceLngLat;
|
|
162
|
+
const degPerPx = tolerancePx > 0 ? toleranceLngLat / tolerancePx : toleranceDegrees(unproject, screenPoint, 1);
|
|
163
|
+
return toleranceLngLat + reachPx * degPerPx;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns the frontmost hit in the visual stacking order
|
|
167
|
+
*
|
|
168
|
+
* The arbitration walks the indices of orderedFeatures in descending order (from the
|
|
169
|
+
* front) and takes the first feature that satisfies test(). The distance is not used (the
|
|
170
|
+
* visual stacking order is the only order: a point on top of a polygon wins, and a
|
|
171
|
+
* polygon in front occludes a point behind it).
|
|
172
|
+
*/
|
|
173
|
+
hitTest(screenPoint, unproject, orderedFeatures) {
|
|
174
|
+
const results = this.hitTestAll(screenPoint, unproject, orderedFeatures);
|
|
175
|
+
if (results.length === 0)
|
|
176
|
+
return null;
|
|
177
|
+
if (results.length === 1)
|
|
178
|
+
return results[0];
|
|
179
|
+
const byId = new Map(results.map((r) => [r.feature.id, r]));
|
|
180
|
+
for (let i = orderedFeatures.length - 1; i >= 0; i--) {
|
|
181
|
+
const result = byId.get(orderedFeatures[i].id);
|
|
182
|
+
if (result)
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
// The candidates are narrowed down from orderedFeatures, so this is never reached
|
|
186
|
+
// (a safety net)
|
|
187
|
+
return results[0];
|
|
188
|
+
}
|
|
189
|
+
hitTestAll(screenPoint, unproject, orderedFeatures) {
|
|
190
|
+
const lngLat = unproject(screenPoint);
|
|
191
|
+
const coordinate = [lngLat.lng, lngLat.lat];
|
|
192
|
+
// The tolerance is a screen length. It is converted into degrees of longitude at the
|
|
193
|
+
// click latitude by measuring the ground length of clickTolerance pixels, so it does not
|
|
194
|
+
// depend on the bearing (see local-frame.ts)
|
|
195
|
+
const tolerance = this.options.clickTolerance;
|
|
196
|
+
const toleranceLngLat = toleranceDegrees(unproject, screenPoint, tolerance);
|
|
197
|
+
// Stage 1: narrow down the candidates with the spatial index.
|
|
198
|
+
// The search radius is widened by the registered extra reach
|
|
199
|
+
// (registerCandidateReach). Unlike the approach of baking the appearance into the bbox
|
|
200
|
+
// of the index, this does not depend on the state or the zoom. The tolerance passed to
|
|
201
|
+
// the second stage is toleranceLngLat as before (only the candidate set widens; the
|
|
202
|
+
// semantics of a hit are decided by the strategy).
|
|
203
|
+
const searchRadius = this.expandSearchRadius(toleranceLngLat, tolerance, screenPoint, unproject);
|
|
204
|
+
// The click on each copy of the world it can reach (the stored copy alone away from the
|
|
205
|
+
// antimeridian; local-frame.ts)
|
|
206
|
+
const copies = clickCopies(coordinate, searchRadius);
|
|
207
|
+
const candidatesByCopy = copies.map((copy) => new Set(this.spatialIndex.findNear(copy, searchRadius)));
|
|
208
|
+
const isCandidate = (id) => candidatesByCopy.some((set) => set.has(id));
|
|
209
|
+
// Filter down to the visible features only.
|
|
210
|
+
// A lock forbids interaction, not selection, so nothing is excluded here for it
|
|
211
|
+
// (a locked feature can still be selected, and moving / transforming / deleting it is
|
|
212
|
+
// rejected on the interaction side).
|
|
213
|
+
// Hidden features (visible=false on the feature / layer / group) are not drawn, so they
|
|
214
|
+
// are excluded from the selection targets.
|
|
215
|
+
// Layers and groups are looked up only once per container (not once per feature).
|
|
216
|
+
const selectable = createVisibilityLookup(this.store);
|
|
217
|
+
const visibleCandidates = orderedFeatures.filter((f) => {
|
|
218
|
+
if (!isCandidate(f.id))
|
|
219
|
+
return false;
|
|
220
|
+
return selectable(f);
|
|
221
|
+
});
|
|
222
|
+
// Symbols (points) are tested in screen space. This works only while the terrain is
|
|
223
|
+
// enabled; when it is disabled null is returned and the conventional path is used as
|
|
224
|
+
// before.
|
|
225
|
+
const degPerPx = tolerance > 0 ? toleranceLngLat / tolerance : 0;
|
|
226
|
+
const screen = this.hitTestAnchorsInScreenSpace(screenPoint, orderedFeatures, tolerance, degPerPx, selectable);
|
|
227
|
+
// Stage 2: the precise test
|
|
228
|
+
const results = screen ? [...screen.results] : [];
|
|
229
|
+
for (const feature of visibleCandidates) {
|
|
230
|
+
// Types already tested in screen space are not sent down the longitude/latitude path
|
|
231
|
+
// (they would be added twice)
|
|
232
|
+
if (screen?.handledTypes.has(feature.type))
|
|
233
|
+
continue;
|
|
234
|
+
const strategy = this.registry.get(feature.type);
|
|
235
|
+
if (!strategy)
|
|
236
|
+
continue;
|
|
237
|
+
// The feature is tested against the click on each copy it is a candidate of, and the
|
|
238
|
+
// nearest hit counts. It is tested in the shape it is drawn with (the result keeps the
|
|
239
|
+
// stored feature)
|
|
240
|
+
const shape = this.drawnShape(feature);
|
|
241
|
+
let best = null;
|
|
242
|
+
for (let i = 0; i < copies.length; i++) {
|
|
243
|
+
if (!candidatesByCopy[i].has(feature.id))
|
|
244
|
+
continue;
|
|
245
|
+
const copy = copies[i];
|
|
246
|
+
let distance = null;
|
|
247
|
+
// A strategy that has testDistance finishes the test and the distance computation in
|
|
248
|
+
// a single scan
|
|
249
|
+
if (strategy.testDistance) {
|
|
250
|
+
distance = strategy.testDistance(shape, copy, toleranceLngLat);
|
|
251
|
+
}
|
|
252
|
+
else if (strategy.test(shape, copy, toleranceLngLat)) {
|
|
253
|
+
distance = strategy.distance(shape, copy);
|
|
254
|
+
}
|
|
255
|
+
if (distance !== null && (best === null || distance < best))
|
|
256
|
+
best = distance;
|
|
257
|
+
}
|
|
258
|
+
if (best !== null)
|
|
259
|
+
results.push({ feature, distance: best });
|
|
260
|
+
}
|
|
261
|
+
// Sort by distance
|
|
262
|
+
results.sort((a, b) => a.distance - b.distance);
|
|
263
|
+
return results;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Tests the anchors of the symbols in screen coordinates
|
|
267
|
+
*
|
|
268
|
+
* The candidates are the points that fall within the field of view. Occluded points are
|
|
269
|
+
* candidates too (they are drawn without a depth test and are actually visible). The
|
|
270
|
+
* spatial index is not used: as long as the longitude/latitude obtained by unprojecting
|
|
271
|
+
* the click point lands on the terrain surface in front, nearness in longitude/latitude
|
|
272
|
+
* does not agree with nearness on screen.
|
|
273
|
+
*
|
|
274
|
+
* The distance is converted back into a longitude difference so that it can be lined up
|
|
275
|
+
* with the other results (it is multiplied by the longitude difference per screen pixel).
|
|
276
|
+
* The meaning of the ordering does not change.
|
|
277
|
+
*
|
|
278
|
+
* @returns null when the anchor projection is unusable (it falls back to the conventional
|
|
279
|
+
* path)
|
|
280
|
+
*/
|
|
281
|
+
hitTestAnchorsInScreenSpace(screenPoint, orderedFeatures, tolerancePx, degPerPx, selectable) {
|
|
282
|
+
const projector = this.anchorScreen;
|
|
283
|
+
if (!projector)
|
|
284
|
+
return null;
|
|
285
|
+
const results = [];
|
|
286
|
+
let usable = false;
|
|
287
|
+
for (const feature of orderedFeatures) {
|
|
288
|
+
if (!SCREEN_SPACE_TYPES.has(feature.type))
|
|
289
|
+
continue;
|
|
290
|
+
if (!selectable(feature))
|
|
291
|
+
continue;
|
|
292
|
+
const reachPx = tolerancePx + this.candidateReachPx(feature.type);
|
|
293
|
+
const parts = feature.type === 'MultiPoint'
|
|
294
|
+
? feature.coordinates
|
|
295
|
+
: [feature.coordinates];
|
|
296
|
+
let nearest = Number.POSITIVE_INFINITY;
|
|
297
|
+
for (const coord of parts) {
|
|
298
|
+
const point = projector.project(coord);
|
|
299
|
+
// null means the anchor projection is unusable (the terrain is disabled, or the
|
|
300
|
+
// point is behind the camera). In the former case nothing at all is projected, so
|
|
301
|
+
// this whole path is not used.
|
|
302
|
+
if (!point)
|
|
303
|
+
continue;
|
|
304
|
+
usable = true;
|
|
305
|
+
const distance = Math.hypot(point.x - screenPoint.x, point.y - screenPoint.y);
|
|
306
|
+
if (distance < nearest)
|
|
307
|
+
nearest = distance;
|
|
308
|
+
}
|
|
309
|
+
if (nearest <= reachPx) {
|
|
310
|
+
results.push({ feature, distance: nearest * degPerPx });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (!usable)
|
|
314
|
+
return null;
|
|
315
|
+
return { results, handledTypes: SCREEN_SPACE_TYPES };
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* The extra reach registered for a type (in CSS pixels)
|
|
319
|
+
*/
|
|
320
|
+
candidateReachPx(type) {
|
|
321
|
+
const reach = this.candidateReach.get(type);
|
|
322
|
+
if (reach === undefined)
|
|
323
|
+
return 0;
|
|
324
|
+
const value = typeof reach === 'function' ? reach() : reach;
|
|
325
|
+
return Number.isFinite(value) && value > 0 ? value : 0;
|
|
326
|
+
}
|
|
327
|
+
hitTestFeature(feature, coordinate, toleranceLngLat) {
|
|
328
|
+
const strategy = this.registry.get(feature.type);
|
|
329
|
+
if (!strategy)
|
|
330
|
+
return false;
|
|
331
|
+
return strategy.test(this.drawnShape(feature), coordinate, toleranceLngLat);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HitTestStrategy
|
|
3
|
+
*
|
|
4
|
+
* Interface for the precise test logic of each geometry type.
|
|
5
|
+
*/
|
|
6
|
+
import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
|
|
7
|
+
/**
|
|
8
|
+
* A vertex handle or a midpoint handle that was hit.
|
|
9
|
+
*/
|
|
10
|
+
export interface VertexHit {
|
|
11
|
+
/** The id of the feature the handle belongs to */
|
|
12
|
+
featureId: string;
|
|
13
|
+
/** The index of the vertex in its ring or line (for a midpoint, the vertex before it) */
|
|
14
|
+
vertexIndex: number;
|
|
15
|
+
/** The index of the ring for a Polygon (0 = the outer ring) */
|
|
16
|
+
ringIndex?: number;
|
|
17
|
+
/** The position of the handle, `[lng, lat]` in degrees */
|
|
18
|
+
coordinate: Coordinate;
|
|
19
|
+
/** Whether it is a vertex or the midpoint of an edge */
|
|
20
|
+
type: 'vertex' | 'midpoint';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A feature hit by a click, with its distance from the click.
|
|
24
|
+
*/
|
|
25
|
+
export interface HitTestResult {
|
|
26
|
+
/** The feature that was hit */
|
|
27
|
+
feature: Feature;
|
|
28
|
+
/**
|
|
29
|
+
* The distance from the click to the feature, in degrees of longitude at the click latitude
|
|
30
|
+
* (see {@link HitTestStrategy})
|
|
31
|
+
*/
|
|
32
|
+
distance: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The hit tolerances, in screen px.
|
|
36
|
+
*/
|
|
37
|
+
export interface HitTestOptions {
|
|
38
|
+
/** Tolerance for the click test (pixels) */
|
|
39
|
+
clickTolerance: number;
|
|
40
|
+
/** Tolerance for vertex handles (pixels) */
|
|
41
|
+
vertexTolerance: number;
|
|
42
|
+
/** Tolerance for midpoint handles (pixels) */
|
|
43
|
+
midpointTolerance: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Default hit test options
|
|
47
|
+
*
|
|
48
|
+
* The only default of the click tolerance: the `clickTolerance` option of a draw instance
|
|
49
|
+
* falls back to it too.
|
|
50
|
+
*/
|
|
51
|
+
export declare const DEFAULT_HIT_TEST_OPTIONS: HitTestOptions;
|
|
52
|
+
/**
|
|
53
|
+
* The precise hit test of one feature type, as registered through the `hitTest` of a
|
|
54
|
+
* `CustomFeatureHandler`.
|
|
55
|
+
*
|
|
56
|
+
* The library first narrows the candidates with its spatial index and then calls `test` on
|
|
57
|
+
* each candidate from the front; the first that returns `true` receives the click. The
|
|
58
|
+
* tolerance is the click tolerance (a screen length) expressed in degrees of longitude
|
|
59
|
+
* at the click latitude. It does not depend on the bearing. To compare a latitude
|
|
60
|
+
* difference, divide it by cos φ of the click latitude (or multiply the tolerance by cos φ):
|
|
61
|
+
* one degree of latitude is 1 / cos φ times longer on screen than one degree of longitude.
|
|
62
|
+
* Distances are returned in the same unit.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import type { HitTestStrategy } from '@sakuzu/maplibre-gl-draw';
|
|
67
|
+
*
|
|
68
|
+
* // A marker type hit within the tolerance around its single position
|
|
69
|
+
* const markerHitTest: HitTestStrategy = {
|
|
70
|
+
* geometryType: 'Marker',
|
|
71
|
+
* test(feature, [lng, lat], tolerance) {
|
|
72
|
+
* return this.distance(feature, [lng, lat]) <= tolerance;
|
|
73
|
+
* },
|
|
74
|
+
* distance(feature, [lng, lat]) {
|
|
75
|
+
* const [x, y] = feature.coordinates as [number, number];
|
|
76
|
+
* const cos = Math.cos((lat * Math.PI) / 180);
|
|
77
|
+
* return Math.hypot(x - lng, (y - lat) / cos);
|
|
78
|
+
* },
|
|
79
|
+
* };
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export interface HitTestStrategy {
|
|
83
|
+
/** The feature type this strategy tests; a registration replaces the one for the type */
|
|
84
|
+
readonly geometryType: FeatureType;
|
|
85
|
+
/**
|
|
86
|
+
* Tests whether the feature was hit
|
|
87
|
+
*
|
|
88
|
+
* @param feature The feature to test
|
|
89
|
+
* @param coordinate The click coordinate [lng, lat]
|
|
90
|
+
* @param toleranceLngLat The tolerance (degrees of longitude at the click latitude)
|
|
91
|
+
* @returns true if it was hit
|
|
92
|
+
*/
|
|
93
|
+
test(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Computes the distance to the center or the nearest point of the feature
|
|
96
|
+
*
|
|
97
|
+
* @param feature The target feature
|
|
98
|
+
* @param coordinate The reference coordinate [lng, lat]
|
|
99
|
+
* @returns The distance (degrees of longitude at the reference latitude)
|
|
100
|
+
*/
|
|
101
|
+
distance(feature: Feature, coordinate: Coordinate): number;
|
|
102
|
+
/**
|
|
103
|
+
* Performs the hit test and the distance computation in a single scan
|
|
104
|
+
*
|
|
105
|
+
* When it is equivalent to test() returning true, it returns the same distance as
|
|
106
|
+
* distance(). Outside the tolerance it returns null. Strategies without an
|
|
107
|
+
* implementation are substituted by test() + distance().
|
|
108
|
+
*
|
|
109
|
+
* @param feature The feature to test
|
|
110
|
+
* @param coordinate The click coordinate [lng, lat]
|
|
111
|
+
* @param toleranceLngLat The tolerance (degrees of longitude at the click latitude)
|
|
112
|
+
* @returns The distance (same unit) if within the tolerance, null if outside
|
|
113
|
+
*/
|
|
114
|
+
testDistance?(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): number | null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Hit testing strategy registry
|
|
118
|
+
*/
|
|
119
|
+
export declare class HitTestStrategyRegistry {
|
|
120
|
+
private strategies;
|
|
121
|
+
/**
|
|
122
|
+
* Registers a strategy
|
|
123
|
+
*
|
|
124
|
+
* @returns a function that cancels the registration and puts back the strategy it replaced
|
|
125
|
+
* (it does nothing once another strategy has been registered for the type)
|
|
126
|
+
*/
|
|
127
|
+
register(strategy: HitTestStrategy): () => void;
|
|
128
|
+
/**
|
|
129
|
+
* Gets a strategy
|
|
130
|
+
*/
|
|
131
|
+
get(geometryType: FeatureType): HitTestStrategy | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Gets all registered strategies
|
|
134
|
+
*/
|
|
135
|
+
getAll(): HitTestStrategy[];
|
|
136
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Default hit test options
|
|
5
|
+
*
|
|
6
|
+
* The only default of the click tolerance: the `clickTolerance` option of a draw instance
|
|
7
|
+
* falls back to it too.
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_HIT_TEST_OPTIONS = {
|
|
10
|
+
clickTolerance: 6,
|
|
11
|
+
vertexTolerance: 8,
|
|
12
|
+
midpointTolerance: 6,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Hit testing strategy registry
|
|
16
|
+
*/
|
|
17
|
+
export class HitTestStrategyRegistry {
|
|
18
|
+
constructor() {
|
|
19
|
+
Object.defineProperty(this, "strategies", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: new Map()
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Registers a strategy
|
|
28
|
+
*
|
|
29
|
+
* @returns a function that cancels the registration and puts back the strategy it replaced
|
|
30
|
+
* (it does nothing once another strategy has been registered for the type)
|
|
31
|
+
*/
|
|
32
|
+
register(strategy) {
|
|
33
|
+
return registerRestoring(this.strategies, strategy.geometryType, strategy);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Gets a strategy
|
|
37
|
+
*/
|
|
38
|
+
get(geometryType) {
|
|
39
|
+
return this.strategies.get(geometryType);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets all registered strategies
|
|
43
|
+
*/
|
|
44
|
+
getAll() {
|
|
45
|
+
return Array.from(this.strategies.values());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Sets a value in a registry keyed by type, and returns the function that cancels it: the
|
|
50
|
+
* value it replaced comes back (a built-in strategy overridden by an extension, for example).
|
|
51
|
+
* Cancelling after another value has been set for the key does nothing.
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export function registerRestoring(registry, key, value) {
|
|
56
|
+
const replaced = registry.get(key);
|
|
57
|
+
registry.set(key, value);
|
|
58
|
+
return () => {
|
|
59
|
+
if (registry.get(key) !== value)
|
|
60
|
+
return;
|
|
61
|
+
if (replaced === undefined)
|
|
62
|
+
registry.delete(key);
|
|
63
|
+
else
|
|
64
|
+
registry.set(key, replaced);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
|
|
2
|
+
import type { HitTestStrategy } from './base.js';
|
|
3
|
+
/**
|
|
4
|
+
* Hit testing strategy for the Circle type
|
|
5
|
+
*/
|
|
6
|
+
export declare class CircleHitTestStrategy implements HitTestStrategy {
|
|
7
|
+
readonly geometryType: FeatureType;
|
|
8
|
+
test(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
|
|
9
|
+
distance(feature: Feature, coordinate: Coordinate): number;
|
|
10
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* CircleHitTestStrategy
|
|
5
|
+
*
|
|
6
|
+
* Hit testing strategy for Circle features.
|
|
7
|
+
* It tests whether the distance from the center is within the radius.
|
|
8
|
+
*/
|
|
9
|
+
import { haversineDistanceMeters, metersToLng } from '../../../shared/math/index.js';
|
|
10
|
+
import { getCircleRadius } from '../../../shared/utils/property.js';
|
|
11
|
+
/**
|
|
12
|
+
* Hit testing strategy for the Circle type
|
|
13
|
+
*/
|
|
14
|
+
export class CircleHitTestStrategy {
|
|
15
|
+
constructor() {
|
|
16
|
+
Object.defineProperty(this, "geometryType", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: 'Circle'
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
test(feature, coordinate, toleranceLngLat) {
|
|
24
|
+
const center = feature.coordinates;
|
|
25
|
+
const radiusMeters = getCircleRadius(feature);
|
|
26
|
+
if (radiusMeters === undefined || radiusMeters <= 0) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// Compute the distance from the center (meters)
|
|
30
|
+
const distanceMeters = haversineDistanceMeters(coordinate, center);
|
|
31
|
+
// Convert the tolerance to meters
|
|
32
|
+
// toleranceLngLat is a longitude difference, so convert it using the latitude
|
|
33
|
+
const toleranceMeters = Math.abs(metersToLng(1, center[1])) > 0
|
|
34
|
+
? (toleranceLngLat / metersToLng(1, center[1])) * 1
|
|
35
|
+
: 0;
|
|
36
|
+
// Simplified tolerance computation, taking the pixel tolerance into account
|
|
37
|
+
// The actual tolerance is roughly 10-20 meters (it depends on the zoom level)
|
|
38
|
+
const effectiveTolerance = Math.max(toleranceMeters, 10);
|
|
39
|
+
return distanceMeters <= radiusMeters + effectiveTolerance;
|
|
40
|
+
}
|
|
41
|
+
distance(feature, coordinate) {
|
|
42
|
+
const center = feature.coordinates;
|
|
43
|
+
const radiusMeters = getCircleRadius(feature);
|
|
44
|
+
if (radiusMeters === undefined || radiusMeters <= 0) {
|
|
45
|
+
return Number.POSITIVE_INFINITY;
|
|
46
|
+
}
|
|
47
|
+
// Distance from the center (meters)
|
|
48
|
+
const distanceMeters = haversineDistanceMeters(coordinate, center);
|
|
49
|
+
// Return the distance from the boundary of the circle
|
|
50
|
+
// Negative inside (the closer to the boundary, the closer to 0), positive outside
|
|
51
|
+
const distanceFromEdge = distanceMeters - radiusMeters;
|
|
52
|
+
// For hit testing, return the absolute distance from the boundary
|
|
53
|
+
// Inside it is the distance to the boundary, and outside it is also the distance to it
|
|
54
|
+
return Math.abs(distanceFromEdge);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Coordinate, Feature } from '../../../store/types.js';
|
|
2
|
+
import type { HitTestStrategy } from './base.js';
|
|
3
|
+
/**
|
|
4
|
+
* ImageHitTestStrategy
|
|
5
|
+
*/
|
|
6
|
+
export declare class ImageHitTestStrategy implements HitTestStrategy {
|
|
7
|
+
readonly geometryType: "Image";
|
|
8
|
+
private tileSize;
|
|
9
|
+
constructor(tileSize?: number);
|
|
10
|
+
/**
|
|
11
|
+
* Updates the tile size
|
|
12
|
+
*/
|
|
13
|
+
setTileSize(tileSize: number): void;
|
|
14
|
+
test(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
|
|
15
|
+
distance(feature: Feature, coordinate: Coordinate): number;
|
|
16
|
+
/**
|
|
17
|
+
* Computes the dimensions (in degrees) and the rotation of an image feature
|
|
18
|
+
*
|
|
19
|
+
* It uses the same size computation logic as ImageRenderer
|
|
20
|
+
*/
|
|
21
|
+
private computeDims;
|
|
22
|
+
}
|