@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,149 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { applyMarginToBoundingBox } from '../../shared/math/index.js';
|
|
4
|
+
import { computeBoundingBox, hasZeroArea, resolvePointFrameExtentWith, } from './selection-ui/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Compute the bounding box with a margin of a feature in geographic coordinates
|
|
7
|
+
*
|
|
8
|
+
* Supports every feature type:
|
|
9
|
+
* - Point: the icon size + the margin are computed in screen coordinates and converted
|
|
10
|
+
* into geographic coordinates
|
|
11
|
+
* - LineString/Polygon: the margin is applied by applyMarginToBoundingBox
|
|
12
|
+
*
|
|
13
|
+
* @param feature The target feature
|
|
14
|
+
* @param transform The coordinate transform
|
|
15
|
+
* @param config The selection UI configuration
|
|
16
|
+
* @returns The bounding box with a margin in geographic coordinates, or null when it
|
|
17
|
+
* cannot be computed
|
|
18
|
+
*/
|
|
19
|
+
export function computeFeatureGeoBoundingBox(feature, transform, config, extensions) {
|
|
20
|
+
const margin = config.boundingBox.margin;
|
|
21
|
+
// Compute the bbox for the selection UI (the draw instance's custom types included)
|
|
22
|
+
const selectionBbox = computeBoundingBox(feature, extensions);
|
|
23
|
+
if (!selectionBbox)
|
|
24
|
+
return null;
|
|
25
|
+
// Zero area (a single-coordinate feature such as Point) is expanded in pixels on screen
|
|
26
|
+
if (hasZeroArea(selectionBbox)) {
|
|
27
|
+
return computeSingleCoordGeoBoundingBox(feature, selectionBbox.center, transform, margin, extensions);
|
|
28
|
+
}
|
|
29
|
+
// A bbox that has a size is expanded by the margin
|
|
30
|
+
const marginedBbox = applyMarginToBoundingBox(selectionBbox, margin, transform);
|
|
31
|
+
return {
|
|
32
|
+
...marginedBbox,
|
|
33
|
+
center: selectionBbox.center,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute the combined geographic bounding box of several features (with a margin)
|
|
38
|
+
*
|
|
39
|
+
* @param features The array of target features
|
|
40
|
+
* @param transform The coordinate transform
|
|
41
|
+
* @param config The selection UI configuration
|
|
42
|
+
* @param extensions The draw instance's extension points (custom bounding boxes and point
|
|
43
|
+
* frame extents)
|
|
44
|
+
* @returns The bounding box with a margin in geographic coordinates, or null when it
|
|
45
|
+
* cannot be computed
|
|
46
|
+
*/
|
|
47
|
+
export function computeCombinedGeoBoundingBox(features, transform, config, extensions) {
|
|
48
|
+
if (features.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
// For a single feature the OBB is returned as is
|
|
51
|
+
if (features.length === 1) {
|
|
52
|
+
return computeFeatureGeoBoundingBox(features[0], transform, config, extensions);
|
|
53
|
+
}
|
|
54
|
+
// For several features, an AABB containing all the vertices is computed
|
|
55
|
+
let minLng = Number.POSITIVE_INFINITY;
|
|
56
|
+
let maxLng = Number.NEGATIVE_INFINITY;
|
|
57
|
+
let minLat = Number.POSITIVE_INFINITY;
|
|
58
|
+
let maxLat = Number.NEGATIVE_INFINITY;
|
|
59
|
+
for (const feature of features) {
|
|
60
|
+
const bbox = computeFeatureGeoBoundingBox(feature, transform, config, extensions);
|
|
61
|
+
if (!bbox)
|
|
62
|
+
continue;
|
|
63
|
+
// Update the min/max of the 4 corners
|
|
64
|
+
const corners = [bbox.topLeft, bbox.topRight, bbox.bottomRight, bbox.bottomLeft];
|
|
65
|
+
for (const corner of corners) {
|
|
66
|
+
minLng = Math.min(minLng, corner[0]);
|
|
67
|
+
maxLng = Math.max(maxLng, corner[0]);
|
|
68
|
+
minLat = Math.min(minLat, corner[1]);
|
|
69
|
+
maxLat = Math.max(maxLat, corner[1]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!Number.isFinite(minLng))
|
|
73
|
+
return null;
|
|
74
|
+
return {
|
|
75
|
+
topLeft: [minLng, maxLat],
|
|
76
|
+
topRight: [maxLng, maxLat],
|
|
77
|
+
bottomRight: [maxLng, minLat],
|
|
78
|
+
bottomLeft: [minLng, minLat],
|
|
79
|
+
center: [(minLng + maxLng) / 2, (minLat + maxLat) / 2],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Compute the bounding box with a margin of a single-coordinate feature in geographic coordinates
|
|
84
|
+
*
|
|
85
|
+
* The extent of the frame of a point (registrable per type; 12px square when unregistered)
|
|
86
|
+
* plus the margin is computed in screen coordinates and converted into geographic ones.
|
|
87
|
+
* The coordinate received is the center of the bbox (since features other than Point can
|
|
88
|
+
* also be zero-area, e.g. a MultiPoint with a single point; coordinates must not be
|
|
89
|
+
* treated as a Coordinate).
|
|
90
|
+
*/
|
|
91
|
+
function computeSingleCoordGeoBoundingBox(feature, coord, transform, margin, extensions) {
|
|
92
|
+
const center = transform.project(coord);
|
|
93
|
+
// The half width and half height of the frame of the point + the margin
|
|
94
|
+
const extent = extensions
|
|
95
|
+
? extensions.resolvePointFrameExtent(feature)
|
|
96
|
+
: resolvePointFrameExtentWith(undefined, feature);
|
|
97
|
+
const halfWidth = extent.halfWidth + margin;
|
|
98
|
+
const halfHeight = extent.halfHeight + margin;
|
|
99
|
+
// Convert the 4 corners in screen coordinates into geographic coordinates
|
|
100
|
+
const topLeft = transform.unproject({ x: center.x - halfWidth, y: center.y - halfHeight });
|
|
101
|
+
const topRight = transform.unproject({ x: center.x + halfWidth, y: center.y - halfHeight });
|
|
102
|
+
const bottomRight = transform.unproject({ x: center.x + halfWidth, y: center.y + halfHeight });
|
|
103
|
+
const bottomLeft = transform.unproject({ x: center.x - halfWidth, y: center.y + halfHeight });
|
|
104
|
+
return {
|
|
105
|
+
topLeft: [topLeft.lng, topLeft.lat],
|
|
106
|
+
topRight: [topRight.lng, topRight.lat],
|
|
107
|
+
bottomRight: [bottomRight.lng, bottomRight.lat],
|
|
108
|
+
bottomLeft: [bottomLeft.lng, bottomLeft.lat],
|
|
109
|
+
center: coord,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Decide whether a point in geographic coordinates is inside a convex quadrilateral
|
|
114
|
+
*
|
|
115
|
+
* Uses the cross product method. It decides whether the point is inside the convex
|
|
116
|
+
* quadrilateral enclosed by the 4 corners.
|
|
117
|
+
*
|
|
118
|
+
* @param lngLat The geographic coordinate to test [lng, lat]
|
|
119
|
+
* @param bbox The bounding box in geographic coordinates
|
|
120
|
+
* @returns true when the point is inside the bbox
|
|
121
|
+
*/
|
|
122
|
+
export function isPointInGeoBoundingBox(lngLat, bbox) {
|
|
123
|
+
// Inside test for a convex quadrilateral (the cross product method)
|
|
124
|
+
const corners = [bbox.topLeft, bbox.topRight, bbox.bottomRight, bbox.bottomLeft];
|
|
125
|
+
// For each edge, decide which side the point is on
|
|
126
|
+
// If it is on the same side for every edge, it is inside
|
|
127
|
+
let sign = null;
|
|
128
|
+
for (let i = 0; i < 4; i++) {
|
|
129
|
+
const p1 = corners[i];
|
|
130
|
+
const p2 = corners[(i + 1) % 4];
|
|
131
|
+
// The edge vector
|
|
132
|
+
const edgeX = p2[0] - p1[0];
|
|
133
|
+
const edgeY = p2[1] - p1[1];
|
|
134
|
+
// The vector to the point
|
|
135
|
+
const toPointX = lngLat[0] - p1[0];
|
|
136
|
+
const toPointY = lngLat[1] - p1[1];
|
|
137
|
+
// The cross product (2D)
|
|
138
|
+
const cross = edgeX * toPointY - edgeY * toPointX;
|
|
139
|
+
if (sign === null) {
|
|
140
|
+
sign = cross >= 0 ? 1 : -1;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
if ((cross >= 0 ? 1 : -1) !== sign) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DEFAULT_BOX_SELECTION_STYLE_CONFIG } from '../../shared/config/rendering.js';
|
|
4
|
+
import { FillShaderManager } from '../renderers/polygon/fill.js';
|
|
5
|
+
import { StrokeRenderer } from '../renderers/stroke.js';
|
|
6
|
+
/**
|
|
7
|
+
* BoxSelectionRenderer
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export class BoxSelectionRenderer {
|
|
12
|
+
constructor(map, gl, styleConfig, pixelRatio) {
|
|
13
|
+
Object.defineProperty(this, "strokeRenderer", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: void 0
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "fillShaderManager", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "styleConfig", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: void 0
|
|
30
|
+
});
|
|
31
|
+
// The rubber band is a rectangle on the screen, so it is never given elevation: its
|
|
32
|
+
// renderers are built without the draw instance's terrain (they draw flat)
|
|
33
|
+
this.strokeRenderer = new StrokeRenderer(map, gl, pixelRatio);
|
|
34
|
+
this.fillShaderManager = new FillShaderManager(gl);
|
|
35
|
+
this.styleConfig = styleConfig ?? DEFAULT_BOX_SELECTION_STYLE_CONFIG;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Make sure the shader exists
|
|
39
|
+
*/
|
|
40
|
+
ensureShader(shaderData) {
|
|
41
|
+
this.strokeRenderer.ensureShader(shaderData);
|
|
42
|
+
this.fillShaderManager.ensureShader(shaderData);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Set the offset uniforms
|
|
46
|
+
*/
|
|
47
|
+
setOffsetUniforms(uniforms) {
|
|
48
|
+
this.strokeRenderer.setOffsetUniforms(uniforms);
|
|
49
|
+
this.fillShaderManager.setOffsetUniforms(uniforms);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Draw the box selection UI
|
|
53
|
+
*/
|
|
54
|
+
draw(boxSelection, projectionData, zoom) {
|
|
55
|
+
const { startPoint, endPoint } = boxSelection;
|
|
56
|
+
// Compute the 4 vertices of the rectangle (a closed ring)
|
|
57
|
+
const ring = [
|
|
58
|
+
[startPoint[0], startPoint[1]],
|
|
59
|
+
[endPoint[0], startPoint[1]],
|
|
60
|
+
[endPoint[0], endPoint[1]],
|
|
61
|
+
[startPoint[0], endPoint[1]],
|
|
62
|
+
[startPoint[0], startPoint[1]], // closing it
|
|
63
|
+
];
|
|
64
|
+
// Draw the fill
|
|
65
|
+
this.fillShaderManager.drawPolygon(ring, this.styleConfig.fillColor, projectionData, zoom);
|
|
66
|
+
// Draw the frame (a dotted line)
|
|
67
|
+
const strokeStyle = {
|
|
68
|
+
width: this.styleConfig.strokeWidth,
|
|
69
|
+
color: this.styleConfig.strokeColor,
|
|
70
|
+
opacity: this.styleConfig.strokeOpacity,
|
|
71
|
+
lineStyle: 'dashed',
|
|
72
|
+
dashArray: this.styleConfig.dashArray,
|
|
73
|
+
};
|
|
74
|
+
this.strokeRenderer.draw(ring, strokeStyle, { widthUnit: 'pixels', closed: true }, zoom, projectionData);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Dispose of the resources
|
|
78
|
+
*/
|
|
79
|
+
dispose() {
|
|
80
|
+
this.strokeRenderer.dispose();
|
|
81
|
+
this.fillShaderManager.dispose();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { applyMarginToBoundingBox } from '../../shared/math/index.js';
|
|
4
|
+
import { nearestLongitude } from '../../shared/math/longitude.js';
|
|
5
|
+
import { computeCombinedGeoBoundingBox, isPointInGeoBoundingBox } from './bounds.js';
|
|
6
|
+
import { resolveMidpointCoordinate, resolveVertexCoordinate } from './handle-thinning.js';
|
|
7
|
+
import { computeCircleRadiusHandle, computeMidpointHandles, computeResizeHandles, computeRotateHandle, computeVertexHandles, supportsVertexEditing, } from './handles.js';
|
|
8
|
+
import { computeBoundingBox, computeCombinedBoundingBox, hasZeroArea, } from './selection-ui/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* A transform that projects every longitude on the copy of the world nearest to the pointer
|
|
11
|
+
*
|
|
12
|
+
* The handles are tested around the pointer. Across the antimeridian the feature on the other
|
|
13
|
+
* side of the line is drawn as a second copy, moved by 360 degrees, while its coordinates stay
|
|
14
|
+
* stored in [-180, 180] and the pointer unprojects to the unwrapped longitude of the view. The
|
|
15
|
+
* copy nearest to the pointer is the copy drawn there, so a handle is projected on it. Away from
|
|
16
|
+
* the antimeridian no longitude moves (nearestLongitude leaves anything within 180 degrees).
|
|
17
|
+
*/
|
|
18
|
+
function alignToPointer(transform, screenPoint) {
|
|
19
|
+
const reference = transform.unproject(screenPoint).lng;
|
|
20
|
+
return {
|
|
21
|
+
project: (lngLat) => transform.project([nearestLongitude(lngLat[0], reference), lngLat[1]]),
|
|
22
|
+
unproject: (point) => transform.unproject(point),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Determines, in screen coordinates, whether the point is inside the handle's rectangle
|
|
27
|
+
*
|
|
28
|
+
* Builds a rectangle from the handle's center position and radius (size/2), and determines
|
|
29
|
+
* whether the click position is inside that rectangle.
|
|
30
|
+
*/
|
|
31
|
+
function isPointInHandleRect(screenPoint, handleScreenPos, halfSize) {
|
|
32
|
+
return (screenPoint.x >= handleScreenPos.x - halfSize &&
|
|
33
|
+
screenPoint.x <= handleScreenPos.x + halfSize &&
|
|
34
|
+
screenPoint.y >= handleScreenPos.y - halfSize &&
|
|
35
|
+
screenPoint.y <= handleScreenPos.y + halfSize);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Hit test for the rotate handle
|
|
39
|
+
*/
|
|
40
|
+
function hitTestRotateHandle(marginedBbox, config, zoom, params) {
|
|
41
|
+
const handle = computeRotateHandle(marginedBbox, config.rotateHandle.distance, zoom);
|
|
42
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
43
|
+
const halfSize = config.rotateHandle.point.size / 2;
|
|
44
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
45
|
+
return { type: 'rotate' };
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Hit test for the resize handles
|
|
51
|
+
*
|
|
52
|
+
* @param marginedBbox Bounding box after the margin is applied
|
|
53
|
+
* @param config Configuration of the selection UI
|
|
54
|
+
* @param params Hit test parameters
|
|
55
|
+
* @param getAdditionalHandles Callback that computes the additional handles (it receives
|
|
56
|
+
* the bbox after the margin is applied)
|
|
57
|
+
*/
|
|
58
|
+
function hitTestResizeHandles(marginedBbox, config, params, getAdditionalHandles) {
|
|
59
|
+
const additionalHandles = getAdditionalHandles?.(marginedBbox);
|
|
60
|
+
const handles = computeResizeHandles(marginedBbox, additionalHandles);
|
|
61
|
+
const halfSize = config.resizeHandle.point.size / 2;
|
|
62
|
+
for (const handle of handles) {
|
|
63
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
64
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
65
|
+
return {
|
|
66
|
+
type: 'resize',
|
|
67
|
+
handle: handle.type,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/** Extra margin added to the pointer rectangle used for pre-filtering (pixels) */
|
|
74
|
+
const POINTER_BOUNDS_MARGIN_PX = 2;
|
|
75
|
+
/**
|
|
76
|
+
* Computes the longitude/latitude rectangle around the pointer
|
|
77
|
+
*
|
|
78
|
+
* Unprojects the four corners of the screen rectangle centered on the press point and
|
|
79
|
+
* builds their bounding box. Hit testing while thinning uses it to discard vertices outside
|
|
80
|
+
* this rectangle without projecting them. When it crosses longitude +/-180, pre-filtering
|
|
81
|
+
* is given up (null).
|
|
82
|
+
*/
|
|
83
|
+
function computePointerBounds(params, halfSize) {
|
|
84
|
+
const size = halfSize + POINTER_BOUNDS_MARGIN_PX;
|
|
85
|
+
const { x, y } = params.screenPoint;
|
|
86
|
+
const corners = [
|
|
87
|
+
params.transform.unproject({ x: x - size, y: y - size }),
|
|
88
|
+
params.transform.unproject({ x: x + size, y: y - size }),
|
|
89
|
+
params.transform.unproject({ x: x - size, y: y + size }),
|
|
90
|
+
params.transform.unproject({ x: x + size, y: y + size }),
|
|
91
|
+
];
|
|
92
|
+
let minLng = Number.POSITIVE_INFINITY;
|
|
93
|
+
let minLat = Number.POSITIVE_INFINITY;
|
|
94
|
+
let maxLng = Number.NEGATIVE_INFINITY;
|
|
95
|
+
let maxLat = Number.NEGATIVE_INFINITY;
|
|
96
|
+
for (const corner of corners) {
|
|
97
|
+
minLng = Math.min(minLng, corner.lng);
|
|
98
|
+
maxLng = Math.max(maxLng, corner.lng);
|
|
99
|
+
minLat = Math.min(minLat, corner.lat);
|
|
100
|
+
maxLat = Math.max(maxLat, corner.lat);
|
|
101
|
+
}
|
|
102
|
+
// A large longitude difference despite a tiny screen rectangle means the date line was
|
|
103
|
+
// crossed
|
|
104
|
+
if (maxLng - minLng > 180)
|
|
105
|
+
return null;
|
|
106
|
+
return { minLng, minLat, maxLng, maxLat };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether the coordinate falls inside the pre-filter rectangle (always true if it is null)
|
|
110
|
+
*/
|
|
111
|
+
function isInPointerBounds(coord, bounds) {
|
|
112
|
+
if (!bounds)
|
|
113
|
+
return true;
|
|
114
|
+
// The rectangle is in the unwrapped longitudes of the pointer (alignToPointer)
|
|
115
|
+
const lng = nearestLongitude(coord[0], (bounds.minLng + bounds.maxLng) / 2);
|
|
116
|
+
return (lng >= bounds.minLng &&
|
|
117
|
+
lng <= bounds.maxLng &&
|
|
118
|
+
coord[1] >= bounds.minLat &&
|
|
119
|
+
coord[1] <= bounds.maxLat);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Hit test against the set of handles currently displayed
|
|
123
|
+
*
|
|
124
|
+
* The path used while thinning. Candidates are narrowed by the pointer rectangle before
|
|
125
|
+
* being projected, so it stays cheap however large the set is. The test itself is the same
|
|
126
|
+
* as in the full-enumeration path (isPointInHandleRect).
|
|
127
|
+
*/
|
|
128
|
+
function hitTestVisibleRefs(feature, refs, resolve, halfSize, params) {
|
|
129
|
+
const bounds = computePointerBounds(params, halfSize);
|
|
130
|
+
for (const ref of refs) {
|
|
131
|
+
const position = resolve(feature, ref);
|
|
132
|
+
if (!position)
|
|
133
|
+
continue;
|
|
134
|
+
if (!isInPointerBounds(position, bounds))
|
|
135
|
+
continue;
|
|
136
|
+
const handleScreenPos = params.transform.project(position);
|
|
137
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
138
|
+
// Do not hand out the reference stored in the cache as is (the caller keeps it)
|
|
139
|
+
return { ...ref };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Hit test for the vertex handles
|
|
146
|
+
*
|
|
147
|
+
* For a Polygon all rings (outer ring + inner rings) are covered, and for the Multi types
|
|
148
|
+
* the vertices of all parts. Because it uses the same computeVertexHandles as the
|
|
149
|
+
* rendering, every vertex that shows a handle can always be grabbed.
|
|
150
|
+
*
|
|
151
|
+
* While thinning, only the displayed set is covered. Circles that are not visible cannot be
|
|
152
|
+
* grabbed, but in exchange everything that can be grabbed is visible.
|
|
153
|
+
*/
|
|
154
|
+
function hitTestVertexHandles(feature, config, params) {
|
|
155
|
+
const halfSize = config.vertexHandle.point.size / 2;
|
|
156
|
+
const displayed = params.scope.thinning.getDisplayedSet(feature);
|
|
157
|
+
if (displayed) {
|
|
158
|
+
const vertexRef = hitTestVisibleRefs(feature, displayed.vertexRefs, resolveVertexCoordinate, halfSize, params);
|
|
159
|
+
return vertexRef ? { type: 'vertex', vertexRef, featureId: feature.id } : null;
|
|
160
|
+
}
|
|
161
|
+
const handles = computeVertexHandles(feature);
|
|
162
|
+
for (const handle of handles) {
|
|
163
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
164
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
165
|
+
return {
|
|
166
|
+
type: 'vertex',
|
|
167
|
+
vertexRef: handle.vertexRef,
|
|
168
|
+
featureId: feature.id,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Hit test for the midpoint handles
|
|
176
|
+
*
|
|
177
|
+
* For a Polygon all rings (outer ring + inner rings) are covered, and for the Multi types
|
|
178
|
+
* the edges of all parts. While thinning, only the displayed midpoints are covered.
|
|
179
|
+
*/
|
|
180
|
+
function hitTestMidpointHandles(feature, config, params) {
|
|
181
|
+
const halfSize = config.midpointHandle.point.size / 2;
|
|
182
|
+
const displayed = params.scope.thinning.getDisplayedSet(feature);
|
|
183
|
+
if (displayed) {
|
|
184
|
+
const vertexRef = hitTestVisibleRefs(feature, displayed.midpointRefs, resolveMidpointCoordinate, halfSize, params);
|
|
185
|
+
return vertexRef ? { type: 'midpoint', vertexRef, featureId: feature.id } : null;
|
|
186
|
+
}
|
|
187
|
+
const handles = computeMidpointHandles(feature);
|
|
188
|
+
for (const handle of handles) {
|
|
189
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
190
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
191
|
+
return {
|
|
192
|
+
type: 'midpoint',
|
|
193
|
+
vertexRef: handle.vertexRef,
|
|
194
|
+
featureId: feature.id,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Hit test for the radius handle of a Circle
|
|
202
|
+
*/
|
|
203
|
+
function hitTestCircleRadiusHandle(feature, config, params) {
|
|
204
|
+
const handle = computeCircleRadiusHandle(feature);
|
|
205
|
+
if (!handle)
|
|
206
|
+
return null;
|
|
207
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
208
|
+
const halfSize = config.radiusHandle.point.size / 2;
|
|
209
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
210
|
+
return { type: 'radius', featureId: feature.id };
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Hit test for the auxiliary handles (provided by an extension implementation)
|
|
216
|
+
*
|
|
217
|
+
* Enumerating the handles is left to the callback (the aggregation of the providers), while
|
|
218
|
+
* the test is done with the same screen-px rectangle as the existing handles. To keep the
|
|
219
|
+
* grab feel uniform, the test size is the same as for the vertex handles (rendering is the
|
|
220
|
+
* provider's responsibility, so core knows only the positions).
|
|
221
|
+
*/
|
|
222
|
+
function hitTestAuxiliaryHandles(feature, config, zoom, params, getAuxiliaryHandles) {
|
|
223
|
+
const context = {
|
|
224
|
+
point: params.screenPoint,
|
|
225
|
+
project: (lngLat) => params.transform.project(lngLat),
|
|
226
|
+
unproject: (point) => params.transform.unproject(point),
|
|
227
|
+
zoom,
|
|
228
|
+
};
|
|
229
|
+
const halfSize = config.vertexHandle.point.size / 2;
|
|
230
|
+
for (const { providerId, handle } of getAuxiliaryHandles(context)) {
|
|
231
|
+
const handleScreenPos = params.transform.project(handle.position);
|
|
232
|
+
if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
|
|
233
|
+
return {
|
|
234
|
+
type: 'auxiliary',
|
|
235
|
+
featureId: feature.id,
|
|
236
|
+
auxiliary: { providerId, handleId: handle.id, featureId: feature.id },
|
|
237
|
+
cursor: handle.cursor,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Hit test for the selection-independent auxiliary handles
|
|
245
|
+
*
|
|
246
|
+
* It can be called even when the selection is empty (hitTestHandles assumes a selection, so
|
|
247
|
+
* this is a separate entry point). The test size, the handling of the cursor and the shape
|
|
248
|
+
* of the returned HandleHitResult are identical to the auxiliary handles of the selection,
|
|
249
|
+
* and drag delegation goes through the same auxiliary path. The only difference is that
|
|
250
|
+
* "there is no feature it sits on", which is expressed by global / an empty featureId on
|
|
251
|
+
* the hit.
|
|
252
|
+
*
|
|
253
|
+
* @param getGlobalHandles Callback that enumerates the handles (when omitted, no test is
|
|
254
|
+
* performed)
|
|
255
|
+
*
|
|
256
|
+
* @internal
|
|
257
|
+
*/
|
|
258
|
+
export function hitTestGlobalAuxiliaryHandles(screenPoint, transform, config, zoom, getGlobalHandles) {
|
|
259
|
+
if (!getGlobalHandles)
|
|
260
|
+
return null;
|
|
261
|
+
transform = alignToPointer(transform, screenPoint);
|
|
262
|
+
const context = {
|
|
263
|
+
point: screenPoint,
|
|
264
|
+
project: (lngLat) => transform.project(lngLat),
|
|
265
|
+
unproject: (point) => transform.unproject(point),
|
|
266
|
+
zoom,
|
|
267
|
+
};
|
|
268
|
+
const halfSize = config.vertexHandle.point.size / 2;
|
|
269
|
+
for (const { providerId, handle } of getGlobalHandles(context)) {
|
|
270
|
+
const handleScreenPos = transform.project(handle.position);
|
|
271
|
+
if (isPointInHandleRect(screenPoint, handleScreenPos, halfSize)) {
|
|
272
|
+
return {
|
|
273
|
+
type: 'auxiliary',
|
|
274
|
+
auxiliary: { providerId, handleId: handle.id, featureId: '', global: true },
|
|
275
|
+
cursor: handle.cursor,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Hit test against all handles
|
|
283
|
+
*
|
|
284
|
+
* Priority order:
|
|
285
|
+
* 1. Rotate handle
|
|
286
|
+
* 2. Resize handles (the four corners + the additional handles)
|
|
287
|
+
* 3. Auxiliary handles (provided by an extension implementation; single selection only)
|
|
288
|
+
* 4. Vertex handles
|
|
289
|
+
* 5. Midpoint handles
|
|
290
|
+
* 6. Inside of the bounding box (move)
|
|
291
|
+
*
|
|
292
|
+
* @param screenPoint Screen coordinates
|
|
293
|
+
* @param features The selected features
|
|
294
|
+
* @param transform Coordinate transform
|
|
295
|
+
* @param config Configuration of the selection UI
|
|
296
|
+
* @param zoom Zoom level
|
|
297
|
+
* @param scope The selection scope of the draw instance (extension points of the custom
|
|
298
|
+
* types and the thinned handle sets that are displayed)
|
|
299
|
+
* @param getAdditionalResizeHandles Callback that computes the additional handles (it
|
|
300
|
+
* receives the bbox after the margin is applied)
|
|
301
|
+
* @param getAuxiliaryHandles Callback that enumerates the auxiliary handles (when omitted,
|
|
302
|
+
* the auxiliary handles are not tested)
|
|
303
|
+
*
|
|
304
|
+
* @internal
|
|
305
|
+
*/
|
|
306
|
+
export function hitTestHandles(screenPoint, features, transform, config, zoom, scope, getAdditionalResizeHandles, getAuxiliaryHandles) {
|
|
307
|
+
if (features.length === 0) {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
transform = alignToPointer(transform, screenPoint);
|
|
311
|
+
// Compute the bbox with the margin in geographic coordinates (for the move test)
|
|
312
|
+
const geoBbox = computeCombinedGeoBoundingBox(features, transform, config, scope.extensions);
|
|
313
|
+
if (!geoBbox) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
// Compute the bbox without the margin (for computing the handle positions)
|
|
317
|
+
const rawBbox = computeCombinedBoundingBox(features, scope.extensions);
|
|
318
|
+
if (!rawBbox) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
// The bbox after the margin is applied (for computing the handle positions)
|
|
322
|
+
const margin = config.boundingBox.margin;
|
|
323
|
+
const marginedBbox = {
|
|
324
|
+
...applyMarginToBoundingBox(rawBbox, margin, transform),
|
|
325
|
+
center: rawBbox.center,
|
|
326
|
+
};
|
|
327
|
+
const params = {
|
|
328
|
+
screenPoint,
|
|
329
|
+
transform,
|
|
330
|
+
scope,
|
|
331
|
+
};
|
|
332
|
+
// When only single-coordinate features (Point and the like) are selected, skip the rotate
|
|
333
|
+
// and resize handles
|
|
334
|
+
const singleFeatureBbox = features.length === 1 ? computeBoundingBox(features[0], scope.extensions) : null;
|
|
335
|
+
const isPointOnly = singleFeatureBbox !== null && hasZeroArea(singleFeatureBbox);
|
|
336
|
+
// A Circle has no rotate handle; it has a radius handle instead
|
|
337
|
+
const isCircle = features.length === 1 && features[0].type === 'Circle';
|
|
338
|
+
if (!isPointOnly) {
|
|
339
|
+
// For a Circle: the radius handle (in place of the rotate handle)
|
|
340
|
+
if (isCircle) {
|
|
341
|
+
const radiusHit = hitTestCircleRadiusHandle(features[0], config, params);
|
|
342
|
+
if (radiusHit)
|
|
343
|
+
return radiusHit;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
// 1. Rotate handle (anything other than a Circle)
|
|
347
|
+
const rotateHit = hitTestRotateHandle(marginedBbox, config, zoom, params);
|
|
348
|
+
if (rotateHit)
|
|
349
|
+
return rotateHit;
|
|
350
|
+
}
|
|
351
|
+
// 2. Resize handles (including the additional handles)
|
|
352
|
+
const resizeHit = hitTestResizeHandles(marginedBbox, config, params, getAdditionalResizeHandles);
|
|
353
|
+
if (resizeHit)
|
|
354
|
+
return resizeHit;
|
|
355
|
+
}
|
|
356
|
+
// 3. Auxiliary handles (single selection only; the same restriction as the existing
|
|
357
|
+
// additional handles). They are taken after resize and before vertex. When they
|
|
358
|
+
// overlap a vertex or a midpoint, the auxiliary handle wins (it is enough to move it
|
|
359
|
+
// aside and then grab the vertex).
|
|
360
|
+
if (features.length === 1 && getAuxiliaryHandles) {
|
|
361
|
+
const auxiliaryHit = hitTestAuxiliaryHandles(features[0], config, zoom, params, getAuxiliaryHandles);
|
|
362
|
+
if (auxiliaryHit)
|
|
363
|
+
return auxiliaryHit;
|
|
364
|
+
}
|
|
365
|
+
// 4. Vertex handles (single selection only)
|
|
366
|
+
if (features.length === 1) {
|
|
367
|
+
const feature = features[0];
|
|
368
|
+
// Point, Text, Image, Circle and Freehand have no vertex handles (move only)
|
|
369
|
+
// Freehand does not support vertex editing (because it is a free curve)
|
|
370
|
+
if (supportsVertexEditing(feature.type)) {
|
|
371
|
+
const vertexHit = hitTestVertexHandles(feature, config, params);
|
|
372
|
+
if (vertexHit)
|
|
373
|
+
return vertexHit;
|
|
374
|
+
// 5. Midpoint handles (a MultiPoint has no edges, so the result is empty)
|
|
375
|
+
const midpointHit = hitTestMidpointHandles(feature, config, params);
|
|
376
|
+
if (midpointHit)
|
|
377
|
+
return midpointHit;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// 6. Inside of the bounding box (move)
|
|
381
|
+
// Convert the click position to geographic coordinates and test it
|
|
382
|
+
const geoLngLat = transform.unproject(screenPoint);
|
|
383
|
+
const geoPoint = [geoLngLat.lng, geoLngLat.lat];
|
|
384
|
+
if (isPointInGeoBoundingBox(geoPoint, geoBbox)) {
|
|
385
|
+
return { type: 'move' };
|
|
386
|
+
}
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Gets the cursor that corresponds to the handle type
|
|
391
|
+
*
|
|
392
|
+
* @internal
|
|
393
|
+
*/
|
|
394
|
+
export function getCursorForHandle(hitResult) {
|
|
395
|
+
if (!hitResult)
|
|
396
|
+
return 'default';
|
|
397
|
+
switch (hitResult.type) {
|
|
398
|
+
case 'rotate':
|
|
399
|
+
return 'grab';
|
|
400
|
+
case 'resize': {
|
|
401
|
+
// The resize cursor that matches the handle position
|
|
402
|
+
switch (hitResult.handle) {
|
|
403
|
+
case 'resize-nw':
|
|
404
|
+
return 'nw-resize';
|
|
405
|
+
case 'resize-n':
|
|
406
|
+
return 'n-resize';
|
|
407
|
+
case 'resize-ne':
|
|
408
|
+
return 'ne-resize';
|
|
409
|
+
case 'resize-e':
|
|
410
|
+
return 'e-resize';
|
|
411
|
+
case 'resize-se':
|
|
412
|
+
return 'se-resize';
|
|
413
|
+
case 'resize-s':
|
|
414
|
+
return 's-resize';
|
|
415
|
+
case 'resize-sw':
|
|
416
|
+
return 'sw-resize';
|
|
417
|
+
case 'resize-w':
|
|
418
|
+
return 'w-resize';
|
|
419
|
+
default:
|
|
420
|
+
return 'default';
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
case 'vertex':
|
|
424
|
+
return 'pointer';
|
|
425
|
+
case 'midpoint':
|
|
426
|
+
return 'crosshair';
|
|
427
|
+
case 'move':
|
|
428
|
+
return 'move';
|
|
429
|
+
case 'radius':
|
|
430
|
+
return 'pointer';
|
|
431
|
+
case 'auxiliary':
|
|
432
|
+
// The cursor specified by the auxiliary handle; if unset, 'pointer' as for vertices
|
|
433
|
+
return hitResult.cursor ?? 'pointer';
|
|
434
|
+
default:
|
|
435
|
+
return 'default';
|
|
436
|
+
}
|
|
437
|
+
}
|