@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,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BoxSelectionStrategy
|
|
3
|
+
*
|
|
4
|
+
* Intersection test strategy interface for box selection.
|
|
5
|
+
* Like HitTestStrategy, it defines the test logic per Feature type.
|
|
6
|
+
* Tests for custom types can be added through CustomFeatureHandler.
|
|
7
|
+
*/
|
|
8
|
+
import type { BoundingBox, Feature, FeatureType } from '../../store/types.js';
|
|
9
|
+
/**
|
|
10
|
+
* The test of one feature type against the rectangle of a box selection in select mode, as
|
|
11
|
+
* registered through the `boxSelection` of a `CustomFeatureHandler`. A box that crosses the
|
|
12
|
+
* ±180 degree meridian is tested as two rectangles.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import type { BoxSelectionStrategy } from '@sakuzu/maplibre-gl-draw';
|
|
17
|
+
*
|
|
18
|
+
* const markerBoxSelection: BoxSelectionStrategy = {
|
|
19
|
+
* featureType: 'Marker',
|
|
20
|
+
* intersects(feature, rect) {
|
|
21
|
+
* const [lng, lat] = feature.coordinates as [number, number];
|
|
22
|
+
* return lng >= rect.minX && lng <= rect.maxX && lat >= rect.minY && lat <= rect.maxY;
|
|
23
|
+
* },
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface BoxSelectionStrategy {
|
|
28
|
+
/** The target feature type */
|
|
29
|
+
readonly featureType: FeatureType;
|
|
30
|
+
/**
|
|
31
|
+
* Tests whether the Feature intersects the selection box
|
|
32
|
+
*
|
|
33
|
+
* @param feature The feature to test
|
|
34
|
+
* @param rect The selection box in degrees
|
|
35
|
+
* @returns `true` if it intersects (the feature is then selected)
|
|
36
|
+
*/
|
|
37
|
+
intersects(feature: Feature, rect: BoundingBox): boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The registry of {@link BoxSelectionStrategy} by feature type; one strategy per type.
|
|
41
|
+
*/
|
|
42
|
+
export declare class BoxSelectionStrategyRegistry {
|
|
43
|
+
private strategies;
|
|
44
|
+
/**
|
|
45
|
+
* Registers a strategy
|
|
46
|
+
*
|
|
47
|
+
* @returns a function that cancels the registration and puts back the strategy it replaced
|
|
48
|
+
* (it does nothing once another strategy has been registered for the type)
|
|
49
|
+
*/
|
|
50
|
+
register(strategy: BoxSelectionStrategy): () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Returns the strategy of a type, or `undefined` when none is registered
|
|
53
|
+
*/
|
|
54
|
+
get(featureType: FeatureType): BoxSelectionStrategy | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Returns every registered strategy, in registration order
|
|
57
|
+
*/
|
|
58
|
+
getAll(): BoxSelectionStrategy[];
|
|
59
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { registerRestoring } from './strategies/base.js';
|
|
4
|
+
/**
|
|
5
|
+
* The registry of {@link BoxSelectionStrategy} by feature type; one strategy per type.
|
|
6
|
+
*/
|
|
7
|
+
export class BoxSelectionStrategyRegistry {
|
|
8
|
+
constructor() {
|
|
9
|
+
Object.defineProperty(this, "strategies", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: new Map()
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Registers a strategy
|
|
18
|
+
*
|
|
19
|
+
* @returns a function that cancels the registration and puts back the strategy it replaced
|
|
20
|
+
* (it does nothing once another strategy has been registered for the type)
|
|
21
|
+
*/
|
|
22
|
+
register(strategy) {
|
|
23
|
+
return registerRestoring(this.strategies, strategy.featureType, strategy);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns the strategy of a type, or `undefined` when none is registered
|
|
27
|
+
*/
|
|
28
|
+
get(featureType) {
|
|
29
|
+
return this.strategies.get(featureType);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns every registered strategy, in registration order
|
|
33
|
+
*/
|
|
34
|
+
getAll() {
|
|
35
|
+
return Array.from(this.strategies.values());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape hit testing tests on the globe
|
|
3
|
+
*
|
|
4
|
+
* The strategies test in longitude and latitude and take an edge as the straight line between
|
|
5
|
+
* its vertices in degrees. On the globe an edge is drawn along the straight line of the
|
|
6
|
+
* Mercator plane carried onto the sphere (`view/globe-subdivision.ts`), which leaves the
|
|
7
|
+
* straight line in degrees on a long edge that is not a parallel or a meridian. So on the globe
|
|
8
|
+
* the lines and the rings are cut along the Mercator plane before they are tested, with the
|
|
9
|
+
* line cell of the rendering: between two close points the two straight lines agree, and what
|
|
10
|
+
* can be clicked is what is drawn.
|
|
11
|
+
*/
|
|
12
|
+
import type { Map as MapLibreMap } from 'maplibre-gl';
|
|
13
|
+
import type { Feature } from '../../store/types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Reshapes a feature into the shape it is drawn with, for the precise test (the feature itself
|
|
16
|
+
* when the shape is the same)
|
|
17
|
+
*/
|
|
18
|
+
export type DrawnShapeResolver = (feature: Feature) => Feature;
|
|
19
|
+
/**
|
|
20
|
+
* The line cell of the globe for hit testing, in Mercator world units (0 on a flat map)
|
|
21
|
+
*
|
|
22
|
+
* The rendering cuts while maplibre draws the globe. A map set to the globe projection is cut
|
|
23
|
+
* here at every zoom: past its switch to Mercator the cut only adds points on the straight
|
|
24
|
+
* lines already drawn.
|
|
25
|
+
*/
|
|
26
|
+
export declare function globeHitTestGrid(map: MapLibreMap): number;
|
|
27
|
+
/**
|
|
28
|
+
* The feature with its lines and rings cut along the Mercator plane into pieces of at most
|
|
29
|
+
* `grid` (the feature itself when nothing is cut)
|
|
30
|
+
*
|
|
31
|
+
* LineString, Freehand, Polygon, MultiLineString and MultiPolygon are cut. The other types
|
|
32
|
+
* keep their shape: a point has no edge, and a circle and an image are tested by their own
|
|
33
|
+
* geometry.
|
|
34
|
+
*
|
|
35
|
+
* @param feature The feature to test
|
|
36
|
+
* @param grid The longest piece, in Mercator world units (0 cuts nothing)
|
|
37
|
+
*/
|
|
38
|
+
export declare function shapeOnGlobe(feature: Feature, grid: number): Feature;
|
|
39
|
+
/**
|
|
40
|
+
* A resolver that cuts on the globe of `map`, keeping the last cut of each feature
|
|
41
|
+
*
|
|
42
|
+
* Hover tests the same features on every move of the pointer, so a feature object that was
|
|
43
|
+
* already cut with the same cell is not cut again. Features are replaced, not changed in
|
|
44
|
+
* place, when their coordinates change, so the object is the key.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createGlobeShapeResolver(map: MapLibreMap): DrawnShapeResolver;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { densifyOnMercatorPlane, globeSubdivisionGrid, } from '../../shared/math/globe-subdivision.js';
|
|
4
|
+
import { isGlobeProjection } from '../../shared/utils/map.js';
|
|
5
|
+
/** The most points the cut adds to one path (a guard against a runaway) */
|
|
6
|
+
const MAX_POINTS = 65536;
|
|
7
|
+
/**
|
|
8
|
+
* The line cell of the globe for hit testing, in Mercator world units (0 on a flat map)
|
|
9
|
+
*
|
|
10
|
+
* The rendering cuts while maplibre draws the globe. A map set to the globe projection is cut
|
|
11
|
+
* here at every zoom: past its switch to Mercator the cut only adds points on the straight
|
|
12
|
+
* lines already drawn.
|
|
13
|
+
*/
|
|
14
|
+
export function globeHitTestGrid(map) {
|
|
15
|
+
return isGlobeProjection(map) ? globeSubdivisionGrid(map.getZoom(), 'line') : 0;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The feature with its lines and rings cut along the Mercator plane into pieces of at most
|
|
19
|
+
* `grid` (the feature itself when nothing is cut)
|
|
20
|
+
*
|
|
21
|
+
* LineString, Freehand, Polygon, MultiLineString and MultiPolygon are cut. The other types
|
|
22
|
+
* keep their shape: a point has no edge, and a circle and an image are tested by their own
|
|
23
|
+
* geometry.
|
|
24
|
+
*
|
|
25
|
+
* @param feature The feature to test
|
|
26
|
+
* @param grid The longest piece, in Mercator world units (0 cuts nothing)
|
|
27
|
+
*/
|
|
28
|
+
export function shapeOnGlobe(feature, grid) {
|
|
29
|
+
if (!(grid > 0))
|
|
30
|
+
return feature;
|
|
31
|
+
const cut = (path) => densifyOnMercatorPlane(path, grid, MAX_POINTS);
|
|
32
|
+
let coordinates;
|
|
33
|
+
switch (feature.type) {
|
|
34
|
+
case 'LineString':
|
|
35
|
+
case 'Freehand':
|
|
36
|
+
coordinates = cut(feature.coordinates);
|
|
37
|
+
break;
|
|
38
|
+
case 'Polygon':
|
|
39
|
+
case 'MultiLineString':
|
|
40
|
+
coordinates = feature.coordinates.map(cut);
|
|
41
|
+
break;
|
|
42
|
+
case 'MultiPolygon':
|
|
43
|
+
coordinates = feature.coordinates.map((rings) => rings.map(cut));
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
return feature;
|
|
47
|
+
}
|
|
48
|
+
return { ...feature, coordinates };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A resolver that cuts on the globe of `map`, keeping the last cut of each feature
|
|
52
|
+
*
|
|
53
|
+
* Hover tests the same features on every move of the pointer, so a feature object that was
|
|
54
|
+
* already cut with the same cell is not cut again. Features are replaced, not changed in
|
|
55
|
+
* place, when their coordinates change, so the object is the key.
|
|
56
|
+
*/
|
|
57
|
+
export function createGlobeShapeResolver(map) {
|
|
58
|
+
const cache = new WeakMap();
|
|
59
|
+
return (feature) => {
|
|
60
|
+
const grid = globeHitTestGrid(map);
|
|
61
|
+
if (!(grid > 0))
|
|
62
|
+
return feature;
|
|
63
|
+
const hit = cache.get(feature);
|
|
64
|
+
if (hit && hit.grid === grid)
|
|
65
|
+
return hit.shape;
|
|
66
|
+
const shape = shapeOnGlobe(feature, grid);
|
|
67
|
+
cache.set(feature, { grid, shape });
|
|
68
|
+
return shape;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hit Test module
|
|
3
|
+
*/
|
|
4
|
+
export type { OBB, ScreenPoint } from '../../shared/math/index.js';
|
|
5
|
+
export { createOBB, distanceToOBB, getOBBAABB, getOBBCorners, pointInOBB, } from '../../shared/math/index.js';
|
|
6
|
+
export { createCoreBoxSelectionStrategies, ImageBoxSelectionStrategy, LineStringBoxSelectionStrategy, MultiLineStringBoxSelectionStrategy, MultiPointBoxSelectionStrategy, MultiPolygonBoxSelectionStrategy, PointBoxSelectionStrategy, PolygonBoxSelectionStrategy, } from './box-strategies.js';
|
|
7
|
+
export type { BoxSelectionStrategy } from './box-strategy.js';
|
|
8
|
+
export { BoxSelectionStrategyRegistry } from './box-strategy.js';
|
|
9
|
+
export type { HitTestService, UnprojectFunction } from './service.js';
|
|
10
|
+
export { HitTestServiceImpl } from './service.js';
|
|
11
|
+
export type { HitTestOptions, HitTestResult, HitTestStrategy, VertexHit, } from './strategies/index.js';
|
|
12
|
+
export { CircleHitTestStrategy, DEFAULT_HIT_TEST_OPTIONS, HitTestStrategyRegistry, ImageHitTestStrategy, LineHitTestStrategy, MultiLineStringHitTestStrategy, MultiPointHitTestStrategy, MultiPolygonHitTestStrategy, PointHitTestStrategy, PolygonHitTestStrategy, } from './strategies/index.js';
|
|
13
|
+
export type { HitTestTopmost, TopHit, TopmostHitTestDeps, TopmostHitTestOptions, } from './topmost.js';
|
|
14
|
+
export { createTopmostHitTester } from './topmost.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
export { createOBB, distanceToOBB, getOBBAABB, getOBBCorners, pointInOBB, } from '../../shared/math/index.js';
|
|
4
|
+
// Box selection strategies
|
|
5
|
+
export { createCoreBoxSelectionStrategies, ImageBoxSelectionStrategy, LineStringBoxSelectionStrategy, MultiLineStringBoxSelectionStrategy, MultiPointBoxSelectionStrategy, MultiPolygonBoxSelectionStrategy, PointBoxSelectionStrategy, PolygonBoxSelectionStrategy, } from './box-strategies.js';
|
|
6
|
+
export { BoxSelectionStrategyRegistry } from './box-strategy.js';
|
|
7
|
+
export { HitTestServiceImpl } from './service.js';
|
|
8
|
+
export { CircleHitTestStrategy, DEFAULT_HIT_TEST_OPTIONS, HitTestStrategyRegistry, ImageHitTestStrategy, LineHitTestStrategy, MultiLineStringHitTestStrategy, MultiPointHitTestStrategy, MultiPolygonHitTestStrategy, PointHitTestStrategy, PolygonHitTestStrategy, } from './strategies/index.js';
|
|
9
|
+
export { createTopmostHitTester } from './topmost.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local frame of hit testing
|
|
3
|
+
*
|
|
4
|
+
* Hit testing decides "within clickTolerance screen pixels of the click". Coordinates are
|
|
5
|
+
* longitude / latitude, so that decision is made in a frame where one unit is the same
|
|
6
|
+
* screen length in every direction: the Web Mercator plane around the click. Near a
|
|
7
|
+
* latitude φ a latitude difference is 1 / cos φ times longer on screen than the same
|
|
8
|
+
* longitude difference, so latitude differences are divided by cos φ and every distance
|
|
9
|
+
* comes out in degrees of longitude at the click latitude.
|
|
10
|
+
*
|
|
11
|
+
* The tolerance is expressed in the same unit. It is the ground length of clickTolerance
|
|
12
|
+
* pixels along the screen x axis, measured with unproject, so it does not depend on the
|
|
13
|
+
* bearing (the length of a displacement does not change when the map is turned) and follows
|
|
14
|
+
* the local scale under pitch (the screen x axis is never foreshortened).
|
|
15
|
+
*
|
|
16
|
+
* This is the contract every HitTestStrategy receives as `toleranceLngLat`: degrees of
|
|
17
|
+
* longitude at the click latitude. A latitude tolerance is `toleranceLngLat * cos φ`.
|
|
18
|
+
*/
|
|
19
|
+
import type { ScreenPoint } from '../../shared/math/index.js';
|
|
20
|
+
import type { Coordinate } from '../../store/types.js';
|
|
21
|
+
/** Converts a screen point into longitude / latitude */
|
|
22
|
+
type Unproject = (point: ScreenPoint) => {
|
|
23
|
+
lng: number;
|
|
24
|
+
lat: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* cos φ of a latitude: how much shorter a latitude difference is than on screen, relative
|
|
28
|
+
* to the same longitude difference
|
|
29
|
+
*/
|
|
30
|
+
export declare function latitudeScale(latitude: number): number;
|
|
31
|
+
/**
|
|
32
|
+
* The click on the copies of the world whose stored features it can reach
|
|
33
|
+
*
|
|
34
|
+
* The features are stored with longitudes in [-180, 180], while the click unprojects to the
|
|
35
|
+
* unwrapped longitude of the view (above 180 on the copy east of the antimeridian, which the
|
|
36
|
+
* rendering draws as a second copy of the stored features). The click is therefore brought
|
|
37
|
+
* into [-180, 180], where it meets the stored coordinates of the copy drawn under it. When its
|
|
38
|
+
* reach runs past ±180, the click is also given on the neighbouring copy, so a feature just
|
|
39
|
+
* across the line is found too. Away from the antimeridian this is the click alone, unchanged.
|
|
40
|
+
*
|
|
41
|
+
* The first step is the rule InputRouter applies to every event before a mode sees it
|
|
42
|
+
* (`toStoredCopy`), so a click routed through it arrives here already in [-180, 180]; the
|
|
43
|
+
* wrapping stays for the callers that hit test a raw pointer position.
|
|
44
|
+
*
|
|
45
|
+
* @param coordinate The click (unwrapped longitude)
|
|
46
|
+
* @param reach How far the test reaches from the click (degrees of longitude)
|
|
47
|
+
* @returns The click on each copy to test, the stored copy first
|
|
48
|
+
*/
|
|
49
|
+
export declare function clickCopies(coordinate: Coordinate, reach: number): Coordinate[];
|
|
50
|
+
/**
|
|
51
|
+
* The click tolerance in degrees of longitude at the click latitude
|
|
52
|
+
*
|
|
53
|
+
* It measures the ground length of `tolerancePx` pixels along the screen x axis, so turning
|
|
54
|
+
* the map does not change it.
|
|
55
|
+
*/
|
|
56
|
+
export declare function toleranceDegrees(unproject: Unproject, point: ScreenPoint, tolerancePx: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* The distance between two points in the local frame (degrees of longitude)
|
|
59
|
+
*
|
|
60
|
+
* @param latScale latitudeScale of the click latitude
|
|
61
|
+
*/
|
|
62
|
+
export declare function localDistance(a: Coordinate, b: Coordinate, latScale: number): number;
|
|
63
|
+
/**
|
|
64
|
+
* The distance from a point to a segment in the local frame (degrees of longitude)
|
|
65
|
+
*
|
|
66
|
+
* @param latScale latitudeScale of the click latitude
|
|
67
|
+
*/
|
|
68
|
+
export declare function localPointToSegmentDistance(point: Coordinate, start: Coordinate, end: Coordinate, latScale: number): number;
|
|
69
|
+
/**
|
|
70
|
+
* The shortest distance from a point to a polyline in the local frame (degrees of longitude)
|
|
71
|
+
*
|
|
72
|
+
* An array with fewer than two vertices has no segment and is infinitely far.
|
|
73
|
+
*
|
|
74
|
+
* @param latScale latitudeScale of the click latitude
|
|
75
|
+
*/
|
|
76
|
+
export declare function localPointToPolylineDistance(point: Coordinate, coords: Coordinate[], latScale: number): number;
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { wrapLongitude } from '../../shared/math/longitude.js';
|
|
4
|
+
/** Lower bound of cos φ (guards against the poles, where Web Mercator diverges) */
|
|
5
|
+
const MIN_LATITUDE_SCALE = 1e-6;
|
|
6
|
+
/**
|
|
7
|
+
* cos φ of a latitude: how much shorter a latitude difference is than on screen, relative
|
|
8
|
+
* to the same longitude difference
|
|
9
|
+
*/
|
|
10
|
+
export function latitudeScale(latitude) {
|
|
11
|
+
return Math.max(Math.cos((latitude * Math.PI) / 180), MIN_LATITUDE_SCALE);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Wraps a longitude difference into [-180, 180)
|
|
15
|
+
*/
|
|
16
|
+
function wrapLngDelta(delta) {
|
|
17
|
+
return ((((delta + 180) % 360) + 360) % 360) - 180;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The click on the copies of the world whose stored features it can reach
|
|
21
|
+
*
|
|
22
|
+
* The features are stored with longitudes in [-180, 180], while the click unprojects to the
|
|
23
|
+
* unwrapped longitude of the view (above 180 on the copy east of the antimeridian, which the
|
|
24
|
+
* rendering draws as a second copy of the stored features). The click is therefore brought
|
|
25
|
+
* into [-180, 180], where it meets the stored coordinates of the copy drawn under it. When its
|
|
26
|
+
* reach runs past ±180, the click is also given on the neighbouring copy, so a feature just
|
|
27
|
+
* across the line is found too. Away from the antimeridian this is the click alone, unchanged.
|
|
28
|
+
*
|
|
29
|
+
* The first step is the rule InputRouter applies to every event before a mode sees it
|
|
30
|
+
* (`toStoredCopy`), so a click routed through it arrives here already in [-180, 180]; the
|
|
31
|
+
* wrapping stays for the callers that hit test a raw pointer position.
|
|
32
|
+
*
|
|
33
|
+
* @param coordinate The click (unwrapped longitude)
|
|
34
|
+
* @param reach How far the test reaches from the click (degrees of longitude)
|
|
35
|
+
* @returns The click on each copy to test, the stored copy first
|
|
36
|
+
*/
|
|
37
|
+
export function clickCopies(coordinate, reach) {
|
|
38
|
+
const lng = wrapLongitude(coordinate[0]);
|
|
39
|
+
const lat = coordinate[1];
|
|
40
|
+
const copies = [lng === coordinate[0] ? coordinate : [lng, lat]];
|
|
41
|
+
if (lng + reach > 180)
|
|
42
|
+
copies.push([lng - 360, lat]);
|
|
43
|
+
if (lng - reach < -180)
|
|
44
|
+
copies.push([lng + 360, lat]);
|
|
45
|
+
return copies;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The click tolerance in degrees of longitude at the click latitude
|
|
49
|
+
*
|
|
50
|
+
* It measures the ground length of `tolerancePx` pixels along the screen x axis, so turning
|
|
51
|
+
* the map does not change it.
|
|
52
|
+
*/
|
|
53
|
+
export function toleranceDegrees(unproject, point, tolerancePx) {
|
|
54
|
+
if (!(tolerancePx > 0))
|
|
55
|
+
return 0;
|
|
56
|
+
const origin = unproject(point);
|
|
57
|
+
const offset = unproject({ x: point.x + tolerancePx, y: point.y });
|
|
58
|
+
const dLng = wrapLngDelta(offset.lng - origin.lng);
|
|
59
|
+
const dLat = (offset.lat - origin.lat) / latitudeScale(origin.lat);
|
|
60
|
+
return Math.hypot(dLng, dLat);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The distance between two points in the local frame (degrees of longitude)
|
|
64
|
+
*
|
|
65
|
+
* @param latScale latitudeScale of the click latitude
|
|
66
|
+
*/
|
|
67
|
+
export function localDistance(a, b, latScale) {
|
|
68
|
+
const dx = b[0] - a[0];
|
|
69
|
+
const dy = (b[1] - a[1]) / latScale;
|
|
70
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The distance from a point to a segment in the local frame (degrees of longitude)
|
|
74
|
+
*
|
|
75
|
+
* @param latScale latitudeScale of the click latitude
|
|
76
|
+
*/
|
|
77
|
+
export function localPointToSegmentDistance(point, start, end, latScale) {
|
|
78
|
+
const px = point[0];
|
|
79
|
+
const py = point[1] / latScale;
|
|
80
|
+
const ax = start[0];
|
|
81
|
+
const ay = start[1] / latScale;
|
|
82
|
+
const dx = end[0] - ax;
|
|
83
|
+
const dy = end[1] / latScale - ay;
|
|
84
|
+
const lengthSquared = dx * dx + dy * dy;
|
|
85
|
+
// The same arithmetic as shared/math pointToSegmentDistance, so that a latScale of 1
|
|
86
|
+
// gives bit-identical results
|
|
87
|
+
if (lengthSquared === 0)
|
|
88
|
+
return planarDistance(px, py, ax, ay);
|
|
89
|
+
const t = Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / lengthSquared));
|
|
90
|
+
return planarDistance(px, py, ax + t * dx, ay + t * dy);
|
|
91
|
+
}
|
|
92
|
+
function planarDistance(x1, y1, x2, y2) {
|
|
93
|
+
const dx = x2 - x1;
|
|
94
|
+
const dy = y2 - y1;
|
|
95
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The shortest distance from a point to a polyline in the local frame (degrees of longitude)
|
|
99
|
+
*
|
|
100
|
+
* An array with fewer than two vertices has no segment and is infinitely far.
|
|
101
|
+
*
|
|
102
|
+
* @param latScale latitudeScale of the click latitude
|
|
103
|
+
*/
|
|
104
|
+
export function localPointToPolylineDistance(point, coords, latScale) {
|
|
105
|
+
let min = Number.POSITIVE_INFINITY;
|
|
106
|
+
for (let i = 0; i < coords.length - 1; i++) {
|
|
107
|
+
const distance = localPointToSegmentDistance(point, coords[i], coords[i + 1], latScale);
|
|
108
|
+
if (distance < min)
|
|
109
|
+
min = distance;
|
|
110
|
+
}
|
|
111
|
+
return min;
|
|
112
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distance queries of hit testing through the segment grid index
|
|
3
|
+
*
|
|
4
|
+
* The grid itself (shared/math/segment-grid.ts) is a plain index over a coordinate array.
|
|
5
|
+
* The distances here are measured in the local frame of hit testing (local-frame.ts).
|
|
6
|
+
*/
|
|
7
|
+
import { type SegmentGrid } from '../../shared/math/segment-grid.js';
|
|
8
|
+
import type { Coordinate } from '../../store/types.js';
|
|
9
|
+
export type { SegmentGrid } from '../../shared/math/segment-grid.js';
|
|
10
|
+
export { buildSegmentGrid, getSegmentGrid, querySegmentIndicesInBBox, SEGMENT_INDEX_THRESHOLD, } from '../../shared/math/segment-grid.js';
|
|
11
|
+
/**
|
|
12
|
+
* Finds the shortest distance within the tolerance through the index
|
|
13
|
+
*
|
|
14
|
+
* The distance is measured in the local frame of hit testing (local-frame.ts): degrees of
|
|
15
|
+
* longitude, with latitude differences divided by latScale. A latScale of 1 is plain degree
|
|
16
|
+
* space.
|
|
17
|
+
*
|
|
18
|
+
* @param latScale latitudeScale of the click latitude
|
|
19
|
+
* @returns The distance if within the tolerance, null if outside
|
|
20
|
+
*/
|
|
21
|
+
export declare function queryDistanceWithin(grid: SegmentGrid, coords: Coordinate[], point: Coordinate, tolerance: number, latScale?: number): number | null;
|
|
22
|
+
/**
|
|
23
|
+
* The shortest distance to a polyline (or a ring) within the tolerance
|
|
24
|
+
*
|
|
25
|
+
* When the vertex count is below the threshold it scans everything, and at or above it
|
|
26
|
+
* uses the index. Both go through localPointToSegmentDistance, so the distance values match
|
|
27
|
+
* exactly.
|
|
28
|
+
*
|
|
29
|
+
* @param latScale latitudeScale of the click latitude (1 is plain degree space)
|
|
30
|
+
* @returns The distance if within the tolerance, null if outside
|
|
31
|
+
*/
|
|
32
|
+
export declare function polylineDistanceWithin(coords: Coordinate[], point: Coordinate, tolerance: number, latScale?: number): number | null;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Distance queries of hit testing through the segment grid index
|
|
5
|
+
*
|
|
6
|
+
* The grid itself (shared/math/segment-grid.ts) is a plain index over a coordinate array.
|
|
7
|
+
* The distances here are measured in the local frame of hit testing (local-frame.ts).
|
|
8
|
+
*/
|
|
9
|
+
import { cellIndex, getSegmentGrid, nextGeneration, SEGMENT_INDEX_THRESHOLD, } from '../../shared/math/segment-grid.js';
|
|
10
|
+
import { localPointToPolylineDistance, localPointToSegmentDistance } from './local-frame.js';
|
|
11
|
+
export { buildSegmentGrid, getSegmentGrid, querySegmentIndicesInBBox, SEGMENT_INDEX_THRESHOLD, } from '../../shared/math/segment-grid.js';
|
|
12
|
+
/**
|
|
13
|
+
* Finds the shortest distance within the tolerance through the index
|
|
14
|
+
*
|
|
15
|
+
* The distance is measured in the local frame of hit testing (local-frame.ts): degrees of
|
|
16
|
+
* longitude, with latitude differences divided by latScale. A latScale of 1 is plain degree
|
|
17
|
+
* space.
|
|
18
|
+
*
|
|
19
|
+
* @param latScale latitudeScale of the click latitude
|
|
20
|
+
* @returns The distance if within the tolerance, null if outside
|
|
21
|
+
*/
|
|
22
|
+
export function queryDistanceWithin(grid, coords, point, tolerance, latScale = 1) {
|
|
23
|
+
if (grid.segmentCount === 0)
|
|
24
|
+
return null;
|
|
25
|
+
const [px, py] = point;
|
|
26
|
+
// A latitude difference within the tolerance is at most tolerance * latScale
|
|
27
|
+
const queryMinX = px - tolerance;
|
|
28
|
+
const queryMinY = py - tolerance * latScale;
|
|
29
|
+
const queryMaxX = px + tolerance;
|
|
30
|
+
const queryMaxY = py + tolerance * latScale;
|
|
31
|
+
// If the tolerance box does not intersect the bbox, there is no candidate
|
|
32
|
+
if (queryMaxX < grid.minX ||
|
|
33
|
+
queryMinX > grid.maxX ||
|
|
34
|
+
queryMaxY < grid.minY ||
|
|
35
|
+
queryMinY > grid.maxY) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const col0 = cellIndex(queryMinX - grid.minX, grid.cellW, grid.cols);
|
|
39
|
+
const col1 = cellIndex(queryMaxX - grid.minX, grid.cellW, grid.cols);
|
|
40
|
+
const row0 = cellIndex(queryMinY - grid.minY, grid.cellH, grid.rows);
|
|
41
|
+
const row1 = cellIndex(queryMaxY - grid.minY, grid.cellH, grid.rows);
|
|
42
|
+
const stamp = nextGeneration(grid);
|
|
43
|
+
let minDistance = Number.POSITIVE_INFINITY;
|
|
44
|
+
for (let row = row0; row <= row1; row++) {
|
|
45
|
+
const rowOffset = row * grid.cols;
|
|
46
|
+
for (let col = col0; col <= col1; col++) {
|
|
47
|
+
const cell = grid.cells[rowOffset + col];
|
|
48
|
+
if (!cell)
|
|
49
|
+
continue;
|
|
50
|
+
for (const i of cell) {
|
|
51
|
+
// A segment is registered in several cells, so compute it only once per query
|
|
52
|
+
if (grid.visited[i] === stamp)
|
|
53
|
+
continue;
|
|
54
|
+
grid.visited[i] = stamp;
|
|
55
|
+
const distance = localPointToSegmentDistance(point, coords[i], coords[i + 1], latScale);
|
|
56
|
+
if (distance < minDistance)
|
|
57
|
+
minDistance = distance;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return minDistance <= tolerance ? minDistance : null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The shortest distance to a polyline (or a ring) within the tolerance
|
|
65
|
+
*
|
|
66
|
+
* When the vertex count is below the threshold it scans everything, and at or above it
|
|
67
|
+
* uses the index. Both go through localPointToSegmentDistance, so the distance values match
|
|
68
|
+
* exactly.
|
|
69
|
+
*
|
|
70
|
+
* @param latScale latitudeScale of the click latitude (1 is plain degree space)
|
|
71
|
+
* @returns The distance if within the tolerance, null if outside
|
|
72
|
+
*/
|
|
73
|
+
export function polylineDistanceWithin(coords, point, tolerance, latScale = 1) {
|
|
74
|
+
if (coords.length < SEGMENT_INDEX_THRESHOLD) {
|
|
75
|
+
const distance = localPointToPolylineDistance(point, coords, latScale);
|
|
76
|
+
return distance <= tolerance ? distance : null;
|
|
77
|
+
}
|
|
78
|
+
return queryDistanceWithin(getSegmentGrid(coords), coords, point, tolerance, latScale);
|
|
79
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HitTestService
|
|
3
|
+
*
|
|
4
|
+
* The service that integrates the two-stage hit testing.
|
|
5
|
+
* 1. Narrowing down the candidates with the SpatialIndex (rbush)
|
|
6
|
+
* 2. The precise test with a HitTestStrategy
|
|
7
|
+
*/
|
|
8
|
+
import type { ScreenPoint } from '../../shared/math/index.js';
|
|
9
|
+
import type { Coordinate, Feature } from '../../store/types.js';
|
|
10
|
+
import type { DrawnShapeResolver } from './globe-shape.js';
|
|
11
|
+
import type { HitTestOptions, HitTestResult, HitTestStrategy } from './strategies/base.js';
|
|
12
|
+
/**
|
|
13
|
+
* Converts a position in CSS px relative to the map container into degrees, as
|
|
14
|
+
* `map.unproject` does.
|
|
15
|
+
*/
|
|
16
|
+
export type UnprojectFunction = (point: ScreenPoint) => {
|
|
17
|
+
lng: number;
|
|
18
|
+
lat: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* The injection point that maps the anchor of a symbol to screen coordinates (terrain
|
|
22
|
+
* aware)
|
|
23
|
+
*
|
|
24
|
+
* Points are drawn without a depth test, so they are visible even when they are behind the
|
|
25
|
+
* terrain. When one of those is clicked, the path "click -> terrain-aware unproject ->
|
|
26
|
+
* longitude/latitude -> spatial index" can never hit it in principle, because the line of
|
|
27
|
+
* sight lands on the terrain surface in front (even on a slope that is not occluded the
|
|
28
|
+
* landing point is displaced, which shrinks the effective radius).
|
|
29
|
+
*
|
|
30
|
+
* Therefore symbols alone take the path "project the anchor of each candidate to screen
|
|
31
|
+
* coordinates with the same projection as the rendering, and compare it directly with the
|
|
32
|
+
* screen coordinates of the click". The implementation is the anchor projection of the
|
|
33
|
+
* view layer (`view/terrain/anchor.ts`), which is identical to the one the rendering uses.
|
|
34
|
+
*
|
|
35
|
+
* While `project` returns null (the terrain is disabled, or no frame has been established
|
|
36
|
+
* yet) the conventional path is used as before. Hit testing without terrain does not
|
|
37
|
+
* change by a single byte.
|
|
38
|
+
*/
|
|
39
|
+
export interface AnchorScreenProjector {
|
|
40
|
+
project(coord: Coordinate): ScreenPoint | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The two-stage hit test of the features of the Store: candidates from the spatial index,
|
|
44
|
+
* then the precise test of each type's {@link HitTestStrategy}.
|
|
45
|
+
*
|
|
46
|
+
* Extensions receive it through their context. The tolerance is the click tolerance of the
|
|
47
|
+
* draw instance (6 px by default).
|
|
48
|
+
*/
|
|
49
|
+
export interface HitTestService {
|
|
50
|
+
/**
|
|
51
|
+
* Returns the frontmost feature that is hit, walking `orderedFeatures` from the end
|
|
52
|
+
*
|
|
53
|
+
* @param screenPoint The position in CSS px relative to the map container
|
|
54
|
+
* @param unproject Converts screen positions into degrees
|
|
55
|
+
* @param orderedFeatures The candidates in display order (the last is in front)
|
|
56
|
+
* @returns The hit, or `null` when nothing is hit
|
|
57
|
+
*/
|
|
58
|
+
hitTest(screenPoint: ScreenPoint, unproject: UnprojectFunction, orderedFeatures: Feature[]): HitTestResult | null;
|
|
59
|
+
/**
|
|
60
|
+
* Returns every feature that is hit, sorted by distance (the closest first)
|
|
61
|
+
*
|
|
62
|
+
* @param screenPoint The position in CSS px relative to the map container
|
|
63
|
+
* @param unproject Converts screen positions into degrees
|
|
64
|
+
* @param orderedFeatures The candidates in display order
|
|
65
|
+
* @returns The hits. An empty array when nothing is hit
|
|
66
|
+
*/
|
|
67
|
+
hitTestAll(screenPoint: ScreenPoint, unproject: UnprojectFunction, orderedFeatures: Feature[]): HitTestResult[];
|
|
68
|
+
/**
|
|
69
|
+
* Tests one feature with the strategy of its type
|
|
70
|
+
*
|
|
71
|
+
* @param feature The feature to test
|
|
72
|
+
* @param coordinate The position `[lng, lat]` in degrees
|
|
73
|
+
* @param toleranceLngLat The tolerance in degrees of longitude at that latitude
|
|
74
|
+
* @returns `true` when it is hit. `false` when no strategy is registered for its type
|
|
75
|
+
*/
|
|
76
|
+
hitTestFeature(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Updates the tile size in px of the map (the Image hit test converts pixel sizes with it)
|
|
79
|
+
*/
|
|
80
|
+
setTileSize?(tileSize: number): void;
|
|
81
|
+
/**
|
|
82
|
+
* Registers a custom hit testing strategy (for dynamic registration)
|
|
83
|
+
*
|
|
84
|
+
* @returns a function that cancels the registration (see HitTestStrategyRegistry.register)
|
|
85
|
+
*/
|
|
86
|
+
registerStrategy?(strategy: HitTestStrategy): () => void;
|
|
87
|
+
/**
|
|
88
|
+
* Registers, per feature type, the extra reach (in CSS pixels) for narrowing down the
|
|
89
|
+
* candidates
|
|
90
|
+
*
|
|
91
|
+
* The first stage narrows down the candidates with a radius equivalent to clickTolerance,
|
|
92
|
+
* so a type whose per-type strategy tests a wider area than that (icons and the like)
|
|
93
|
+
* would drop out of the candidates before it ever reaches the precise test. Widening the
|
|
94
|
+
* search radius by the registered distance lets such a type reach the second stage
|
|
95
|
+
* regardless of the state or the zoom.
|
|
96
|
+
*
|
|
97
|
+
* Only the candidate set widens; the semantics of a hit are decided by the strategy as
|
|
98
|
+
* before.
|
|
99
|
+
*
|
|
100
|
+
* @returns a function that cancels the registration (it does not remove a later
|
|
101
|
+
* registration of the same type)
|
|
102
|
+
*/
|
|
103
|
+
registerCandidateReach?(type: string, reachPx: number | (() => number)): () => void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The options of HitTestServiceImpl
|
|
107
|
+
*/
|
|
108
|
+
export interface HitTestServiceImplOptions extends Partial<HitTestOptions> {
|
|
109
|
+
/** The tile size (taken from transform.tileSize of MapLibre) */
|
|
110
|
+
tileSize?: number;
|
|
111
|
+
/** The injection point that maps the anchor of a symbol to screen coordinates (terrain
|
|
112
|
+
* aware; when omitted only the conventional path is used) */
|
|
113
|
+
anchorScreen?: AnchorScreenProjector;
|
|
114
|
+
/**
|
|
115
|
+
* Reshapes a feature into the shape it is drawn with before the precise test (on the globe,
|
|
116
|
+
* its edges cut along the Mercator plane; `globe-shape.ts`). When omitted the stored shape
|
|
117
|
+
* is tested
|
|
118
|
+
*/
|
|
119
|
+
drawnShape?: DrawnShapeResolver;
|
|
120
|
+
}
|