@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,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subdivision step per terrain tile (the index)
|
|
3
|
+
*
|
|
4
|
+
* MapLibre's terrain is "a polyline surface stretched over a fixed grid per tile". The grid
|
|
5
|
+
* spacing is the tile's Mercator width / terrain.meshSize, and in a pitched view coarser-zoom
|
|
6
|
+
* tiles are used the farther away the view is, so it varies from place to place.
|
|
7
|
+
*
|
|
8
|
+
* Unless our own subdivision matches that grid exactly, the fill drops out whichever way it
|
|
9
|
+
* deviates.
|
|
10
|
+
*
|
|
11
|
+
* - When our step is finer than the tile's actual mesh, in concave terrain (valley floors)
|
|
12
|
+
* MapLibre's coarse chord crosses above the true terrain while our own nodes drop all the
|
|
13
|
+
* way to the DEM value, so the polygon sinks below the chord and is carved away by depth
|
|
14
|
+
* (dendritic dropouts)
|
|
15
|
+
* - When it is coarser, in convex terrain (ridges) our own chord dives below the ridge and is
|
|
16
|
+
* carved away
|
|
17
|
+
*
|
|
18
|
+
* It is not "finer is safer" but "only an exact match is safe".
|
|
19
|
+
*
|
|
20
|
+
* The index is held in cells whose side length is that of the finest tile. A coarse tile spans
|
|
21
|
+
* several cells, but the finest tile's side length is an integer multiple of a coarse tile's
|
|
22
|
+
* mesh spacing, so a cell boundary always lies on one of that tile's mesh lines. In other
|
|
23
|
+
* words, cutting at cell boundaries only adds nodes; it never creates a seam (a T-junction).
|
|
24
|
+
*/
|
|
25
|
+
import type { RenderableTerrainTile } from './detect.js';
|
|
26
|
+
import type { MercatorRect, TessellationTiling } from './tessellation.js';
|
|
27
|
+
/**
|
|
28
|
+
* Builds the index of subdivision steps from the terrain tiles being drawn
|
|
29
|
+
*
|
|
30
|
+
* @param tiles The terrain tiles MapLibre is drawing
|
|
31
|
+
* @param meshSize The number of subdivisions of one tile (terrain.meshSize; 128 by default)
|
|
32
|
+
* @param region The range that may be subdivided (the index covers all of it)
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildTessellationTiling(tiles: readonly RenderableTerrainTile[], meshSize: number, region: MercatorRect | null): TessellationTiling | null;
|
|
35
|
+
/**
|
|
36
|
+
* Fingerprint of the tile configuration covering a given rectangle
|
|
37
|
+
*
|
|
38
|
+
* This is the key for deciding "whether the subdivision of that range is still correct". With
|
|
39
|
+
* the same fingerprint there is no need to subdivide again; with a different one there is. It
|
|
40
|
+
* includes the following three things.
|
|
41
|
+
*
|
|
42
|
+
* - The base step (which changes when the zoom changes) and the step of each index cell that
|
|
43
|
+
* overlaps the rectangle (the tile zoom configuration itself). Both are written as absolute
|
|
44
|
+
* values
|
|
45
|
+
* - The coarsening factor (the power of 2 applied to the step)
|
|
46
|
+
* - Whether the rectangle sticks out of the range that may be subdivided (the part that sticks
|
|
47
|
+
* out is not subdivided, so once the range moves and "ground that has not been subdivided
|
|
48
|
+
* yet" comes in, it has to be subdivided again)
|
|
49
|
+
*
|
|
50
|
+
* Moving the camera changes the zoom of the tiles used for the distance. Even when the
|
|
51
|
+
* geometry is correct, a polygon left "subdivided with the step of the old configuration"
|
|
52
|
+
* makes the old chord disagree with the new mesh, producing spotty breakthroughs and seams on
|
|
53
|
+
* ridges and in valleys. This is what is behind the observation that it looks clean right
|
|
54
|
+
* after a reload but falls apart once you pan or zoom to the spot.
|
|
55
|
+
*/
|
|
56
|
+
export declare function tilingSignature(tiling: TessellationTiling | null, region: MercatorRect | null, coarsen: number, baseGrid: number, x0: number, y0: number, x1: number, y1: number): string;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/** Upper bound on the number of cells in the index (no index is built for a wider view) */
|
|
4
|
+
const MAX_TILING_CELLS = 4096;
|
|
5
|
+
/**
|
|
6
|
+
* Builds the index of subdivision steps from the terrain tiles being drawn
|
|
7
|
+
*
|
|
8
|
+
* @param tiles The terrain tiles MapLibre is drawing
|
|
9
|
+
* @param meshSize The number of subdivisions of one tile (terrain.meshSize; 128 by default)
|
|
10
|
+
* @param region The range that may be subdivided (the index covers all of it)
|
|
11
|
+
*/
|
|
12
|
+
export function buildTessellationTiling(tiles, meshSize, region) {
|
|
13
|
+
if (tiles.length === 0 || !(meshSize > 0))
|
|
14
|
+
return null;
|
|
15
|
+
let maxZoom = 0;
|
|
16
|
+
for (const tile of tiles) {
|
|
17
|
+
if (tile.z > maxZoom)
|
|
18
|
+
maxZoom = tile.z;
|
|
19
|
+
}
|
|
20
|
+
const cell = 1 / 2 ** maxZoom;
|
|
21
|
+
if (!(cell > 0))
|
|
22
|
+
return null;
|
|
23
|
+
// The index covers all of "the range that may be subdivided". A cell with no tile gets a
|
|
24
|
+
// step of 0, and that area is emitted as is without being subdivided (outside the range the
|
|
25
|
+
// elevation is clamped to the edge value, so there is no point in subdividing).
|
|
26
|
+
//
|
|
27
|
+
// The index must not be trimmed to the bounding box of the tiles. Doing so drops the part of
|
|
28
|
+
// the range that falls outside the index, and the fill of that ground disappears entirely
|
|
29
|
+
// (hit while implementing this).
|
|
30
|
+
let minX;
|
|
31
|
+
let minY;
|
|
32
|
+
let maxX;
|
|
33
|
+
let maxY;
|
|
34
|
+
if (region) {
|
|
35
|
+
minX = region.x0;
|
|
36
|
+
minY = region.y0;
|
|
37
|
+
maxX = region.x1;
|
|
38
|
+
maxY = region.y1;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
minX = Number.POSITIVE_INFINITY;
|
|
42
|
+
minY = Number.POSITIVE_INFINITY;
|
|
43
|
+
maxX = Number.NEGATIVE_INFINITY;
|
|
44
|
+
maxY = Number.NEGATIVE_INFINITY;
|
|
45
|
+
for (const tile of tiles) {
|
|
46
|
+
const size = 1 / 2 ** tile.z;
|
|
47
|
+
const x0 = tile.x * size;
|
|
48
|
+
const y0 = tile.y * size;
|
|
49
|
+
if (x0 < minX)
|
|
50
|
+
minX = x0;
|
|
51
|
+
if (y0 < minY)
|
|
52
|
+
minY = y0;
|
|
53
|
+
if (x0 + size > maxX)
|
|
54
|
+
maxX = x0 + size;
|
|
55
|
+
if (y0 + size > maxY)
|
|
56
|
+
maxY = y0 + size;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (!(maxX > minX) || !(maxY > minY))
|
|
60
|
+
return null;
|
|
61
|
+
const x0 = Math.floor(minX / cell) * cell;
|
|
62
|
+
const y0 = Math.floor(minY / cell) * cell;
|
|
63
|
+
const cols = Math.ceil((maxX - x0) / cell);
|
|
64
|
+
const rows = Math.ceil((maxY - y0) / cell);
|
|
65
|
+
if (cols <= 0 || rows <= 0)
|
|
66
|
+
return null;
|
|
67
|
+
// When there are too many cells (an unexpectedly wide spread) no index is built. Without an
|
|
68
|
+
// index the subdivision falls back to a single step as before (a picture is still produced)
|
|
69
|
+
if (cols * rows > MAX_TILING_CELLS)
|
|
70
|
+
return null;
|
|
71
|
+
const grids = new Float64Array(cols * rows);
|
|
72
|
+
// Coarse tiles are placed first and finer tiles overwrite them (same as how the atlas is
|
|
73
|
+
// baked)
|
|
74
|
+
const ordered = [...tiles].sort((a, b) => a.z - b.z);
|
|
75
|
+
for (const tile of ordered) {
|
|
76
|
+
const size = 1 / 2 ** tile.z;
|
|
77
|
+
const grid = size / meshSize;
|
|
78
|
+
const tx0 = tile.x * size;
|
|
79
|
+
const ty0 = tile.y * size;
|
|
80
|
+
const ix0 = Math.max(0, Math.floor((tx0 - x0) / cell));
|
|
81
|
+
const iy0 = Math.max(0, Math.floor((ty0 - y0) / cell));
|
|
82
|
+
const ix1 = Math.min(cols - 1, Math.ceil((tx0 + size - x0) / cell) - 1);
|
|
83
|
+
const iy1 = Math.min(rows - 1, Math.ceil((ty0 + size - y0) / cell) - 1);
|
|
84
|
+
for (let iy = iy0; iy <= iy1; iy++) {
|
|
85
|
+
for (let ix = ix0; ix <= ix1; ix++) {
|
|
86
|
+
grids[iy * cols + ix] = grid;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
rect: { x0, y0, x1: x0 + cols * cell, y1: y0 + rows * cell },
|
|
92
|
+
cell,
|
|
93
|
+
cols,
|
|
94
|
+
rows,
|
|
95
|
+
grids,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Fingerprint of the tile configuration covering a given rectangle
|
|
100
|
+
*
|
|
101
|
+
* This is the key for deciding "whether the subdivision of that range is still correct". With
|
|
102
|
+
* the same fingerprint there is no need to subdivide again; with a different one there is. It
|
|
103
|
+
* includes the following three things.
|
|
104
|
+
*
|
|
105
|
+
* - The base step (which changes when the zoom changes) and the step of each index cell that
|
|
106
|
+
* overlaps the rectangle (the tile zoom configuration itself). Both are written as absolute
|
|
107
|
+
* values
|
|
108
|
+
* - The coarsening factor (the power of 2 applied to the step)
|
|
109
|
+
* - Whether the rectangle sticks out of the range that may be subdivided (the part that sticks
|
|
110
|
+
* out is not subdivided, so once the range moves and "ground that has not been subdivided
|
|
111
|
+
* yet" comes in, it has to be subdivided again)
|
|
112
|
+
*
|
|
113
|
+
* Moving the camera changes the zoom of the tiles used for the distance. Even when the
|
|
114
|
+
* geometry is correct, a polygon left "subdivided with the step of the old configuration"
|
|
115
|
+
* makes the old chord disagree with the new mesh, producing spotty breakthroughs and seams on
|
|
116
|
+
* ridges and in valleys. This is what is behind the observation that it looks clean right
|
|
117
|
+
* after a reload but falls apart once you pan or zoom to the spot.
|
|
118
|
+
*/
|
|
119
|
+
export function tilingSignature(tiling, region, coarsen, baseGrid, x0, y0, x1, y1) {
|
|
120
|
+
// The step is 1/(2^z * meshSize), so its log2 is always an integer. It is written as an
|
|
121
|
+
// absolute value.
|
|
122
|
+
//
|
|
123
|
+
// This must not be written as "the difference from the finest tile in the view". Moving the
|
|
124
|
+
// zoom by one level moves both the tile's z and the finest z together, so the difference
|
|
125
|
+
// stays the same and it is judged "unchanged" even though the step actually changed by a
|
|
126
|
+
// factor of 2. A chunk left with the old step is never subdivided again, and streaky
|
|
127
|
+
// breakthroughs remain on ridges and in valleys.
|
|
128
|
+
const exponent = (grid) => (grid > 0 ? String(Math.round(Math.log2(grid))) : '-');
|
|
129
|
+
// The step itself is part of the key too (so that a zoom change is caught even on the path
|
|
130
|
+
// without an index)
|
|
131
|
+
const parts = [`${exponent(baseGrid)}:${coarsen}`];
|
|
132
|
+
if (!tiling)
|
|
133
|
+
return parts.join('|');
|
|
134
|
+
const inside = !region || (x0 >= region.x0 && x1 <= region.x1 && y0 >= region.y0 && y1 <= region.y1);
|
|
135
|
+
parts.push(inside ? 'i' : 'o');
|
|
136
|
+
if (!inside && region) {
|
|
137
|
+
// Something straddling the range also depends on the range itself (the cut changes)
|
|
138
|
+
parts.push(`${region.x0},${region.y0},${region.x1},${region.y1}`);
|
|
139
|
+
}
|
|
140
|
+
const ix0 = Math.max(0, Math.floor((x0 - tiling.rect.x0) / tiling.cell));
|
|
141
|
+
const ix1 = Math.min(tiling.cols - 1, Math.floor((x1 - tiling.rect.x0) / tiling.cell));
|
|
142
|
+
const iy0 = Math.max(0, Math.floor((y0 - tiling.rect.y0) / tiling.cell));
|
|
143
|
+
const iy1 = Math.min(tiling.rows - 1, Math.floor((y1 - tiling.rect.y0) / tiling.cell));
|
|
144
|
+
if (ix1 < ix0 || iy1 < iy0)
|
|
145
|
+
return parts.join('|');
|
|
146
|
+
// The step of each cell. The origin of the index is rounded to the finest tile's boundary,
|
|
147
|
+
// so the same ground always falls into the same cell (the indices do not shift when the
|
|
148
|
+
// range moves)
|
|
149
|
+
for (let iy = iy0; iy <= iy1; iy++) {
|
|
150
|
+
for (let ix = ix0; ix <= ix1; ix++) {
|
|
151
|
+
parts.push(exponent(tiling.grids[iy * tiling.cols + ix]));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return parts.join('|');
|
|
155
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How maplibre lays out a DEM tile, reads it on the GPU and measures elevations (the one copy
|
|
3
|
+
* the engine keeps)
|
|
4
|
+
*
|
|
5
|
+
* A custom layer does not receive the `TERRAIN3D` part of maplibre's vertex prelude
|
|
6
|
+
* (maplibre-coupling.md, item 2), so the engine reads maplibre's DEM textures with its own
|
|
7
|
+
* shaders: the drape (`drape/shared.ts`, `drape/edge-constrain.ts`) and the DEM atlas
|
|
8
|
+
* (`dem-atlas.ts`). Whatever those shaders must assume about the upstream layout is written
|
|
9
|
+
* here and nowhere else, so an upstream change is one edit.
|
|
10
|
+
*
|
|
11
|
+
* Copied from maplibre-gl-js 6.11.1:
|
|
12
|
+
*
|
|
13
|
+
* - `src/data/dem_data.ts`, `DEMData`: the texture of a DEM tile is `dim + 4` texels on a
|
|
14
|
+
* side, the `dim` pixels of the tile behind a border of 2 texels on every side
|
|
15
|
+
* (`dim = data.height - 4` at line 54, `_idx` at line 140). `backfillBorder` (line 157) fills
|
|
16
|
+
* the border from the neighbouring tiles, and until a neighbour arrives it repeats the edge
|
|
17
|
+
* pixels (line 83).
|
|
18
|
+
* - `src/shaders/glsl/_prelude.vertex.glsl`, `ele` and `get_elevation` (lines 137 to 169): a
|
|
19
|
+
* tile position is mapped by `u_terrain_matrix` into the unit square of the DEM tile and the
|
|
20
|
+
* texel coordinate is `uv * u_terrain_dim + 1.5` (DEM pixel i describes the cell centred at
|
|
21
|
+
* `(i + 0.5) / dim` and sits at texel `i + 2`). The four texels around it are fetched with
|
|
22
|
+
* `texelFetch`, clamped to the texture, decoded with `u_terrain_unpack` and interpolated
|
|
23
|
+
* bilinearly by hand (an encoded DEM cannot be interpolated by the sampler), then multiplied
|
|
24
|
+
* by `u_terrain_exaggeration`.
|
|
25
|
+
* - `src/geo/lng_lat.ts`, `earthRadius = 6371008.8` (line 8), and
|
|
26
|
+
* `src/geo/mercator_coordinate.ts`, `circumferenceAtLatitude` (line 14): the sphere an
|
|
27
|
+
* elevation in meters is turned into Mercator units on (`mercatorZfromAltitude`), which is
|
|
28
|
+
* how maplibre scales its terrain mesh and `map.project`. It is not the WGS84 equator the
|
|
29
|
+
* geometry of the engine measures distances on; the 0.1 % between them is a pixel at the
|
|
30
|
+
* top of a high, exaggerated mountain.
|
|
31
|
+
* - `src/render/terrain.ts`, `getElevationSampler` (line 324, `DEM_CELL_CENTER_OFFSET = -0.5`
|
|
32
|
+
* at line 60): the CPU sampler places the pixels the same way, and it is what
|
|
33
|
+
* `map.queryTerrainElevation` returns where the terrain is drawn. The engine's CPU side reads
|
|
34
|
+
* that function (`ground.ts`) and copies nothing of it.
|
|
35
|
+
*
|
|
36
|
+
* Up to maplibre 6.7 the border was one texel and the offset `+ 1.0` (the pixels sat on the
|
|
37
|
+
* cell corners); 6.8.0 and 6.9.1 changed both (the move to the cell centres is
|
|
38
|
+
* maplibre-gl-js#8420). The end-to-end test `src/e2e/terrain.e2e.test.ts` compares what
|
|
39
|
+
* these shaders read with `map.queryTerrainElevation`, and the projection of the anchors
|
|
40
|
+
* (which uses the sphere through `metrics.ts`) with `map.project`, on a known DEM, and fails
|
|
41
|
+
* when they part.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* The circumference of the sphere maplibre turns elevations into Mercator units on (meters),
|
|
45
|
+
* `2 * PI * earthRadius`
|
|
46
|
+
*/
|
|
47
|
+
export declare const UPSTREAM_EARTH_CIRCUMFERENCE_METERS: number;
|
|
48
|
+
/** The border around the pixels of a DEM tile, in texels on each side */
|
|
49
|
+
export declare const DEM_BORDER_TEXELS = 2;
|
|
50
|
+
/**
|
|
51
|
+
* What is added to `uv * dim` to get the texel coordinate of a position (the border, less half
|
|
52
|
+
* a texel because pixels are centred on their cells)
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEM_TEXEL_OFFSET: number;
|
|
55
|
+
/**
|
|
56
|
+
* The texel coordinate of a position of the DEM tile (the same formula as `get_elevation`)
|
|
57
|
+
*
|
|
58
|
+
* @param uv The position in the unit square of the DEM tile
|
|
59
|
+
* @param dim The number of pixels of the DEM tile on a side (`u_terrain_dim`)
|
|
60
|
+
*/
|
|
61
|
+
export declare function demTexelCoord(uv: number, dim: number): number;
|
|
62
|
+
/**
|
|
63
|
+
* The texel coordinate of the last texel of a DEM texture (the far end of the border)
|
|
64
|
+
*
|
|
65
|
+
* A bilinear sample needs the texel at `floor(coord) + 1`, so real data is read only for
|
|
66
|
+
* texel coordinates in `[0, demLastTexel(dim)]`; beyond it the clamp repeats the last texel.
|
|
67
|
+
*
|
|
68
|
+
* @param dim The number of pixels of the DEM tile on a side
|
|
69
|
+
*/
|
|
70
|
+
export declare function demLastTexel(dim: number): number;
|
|
71
|
+
/**
|
|
72
|
+
* The GLSL of the upstream DEM layout, for both shader stages
|
|
73
|
+
*
|
|
74
|
+
* - `upstream_dem_coord(uv, dim)`: the texel coordinate of a position ({@link demTexelCoord})
|
|
75
|
+
* - `upstream_dem_last_texel(dim)`: {@link demLastTexel}
|
|
76
|
+
* - `upstream_dem_bilinear(dem, unpack, coord)`: the elevation at a texel coordinate, in
|
|
77
|
+
* meters before the exaggeration (the body of `get_elevation`)
|
|
78
|
+
*
|
|
79
|
+
* The functions take the texture and its unpack vector as arguments, so the drape can also
|
|
80
|
+
* read the DEM of a neighbouring tile with them (`edge-constrain.ts`).
|
|
81
|
+
*/
|
|
82
|
+
export declare const UPSTREAM_DEM_GLSL: string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* How maplibre lays out a DEM tile, reads it on the GPU and measures elevations (the one copy
|
|
5
|
+
* the engine keeps)
|
|
6
|
+
*
|
|
7
|
+
* A custom layer does not receive the `TERRAIN3D` part of maplibre's vertex prelude
|
|
8
|
+
* (maplibre-coupling.md, item 2), so the engine reads maplibre's DEM textures with its own
|
|
9
|
+
* shaders: the drape (`drape/shared.ts`, `drape/edge-constrain.ts`) and the DEM atlas
|
|
10
|
+
* (`dem-atlas.ts`). Whatever those shaders must assume about the upstream layout is written
|
|
11
|
+
* here and nowhere else, so an upstream change is one edit.
|
|
12
|
+
*
|
|
13
|
+
* Copied from maplibre-gl-js 6.11.1:
|
|
14
|
+
*
|
|
15
|
+
* - `src/data/dem_data.ts`, `DEMData`: the texture of a DEM tile is `dim + 4` texels on a
|
|
16
|
+
* side, the `dim` pixels of the tile behind a border of 2 texels on every side
|
|
17
|
+
* (`dim = data.height - 4` at line 54, `_idx` at line 140). `backfillBorder` (line 157) fills
|
|
18
|
+
* the border from the neighbouring tiles, and until a neighbour arrives it repeats the edge
|
|
19
|
+
* pixels (line 83).
|
|
20
|
+
* - `src/shaders/glsl/_prelude.vertex.glsl`, `ele` and `get_elevation` (lines 137 to 169): a
|
|
21
|
+
* tile position is mapped by `u_terrain_matrix` into the unit square of the DEM tile and the
|
|
22
|
+
* texel coordinate is `uv * u_terrain_dim + 1.5` (DEM pixel i describes the cell centred at
|
|
23
|
+
* `(i + 0.5) / dim` and sits at texel `i + 2`). The four texels around it are fetched with
|
|
24
|
+
* `texelFetch`, clamped to the texture, decoded with `u_terrain_unpack` and interpolated
|
|
25
|
+
* bilinearly by hand (an encoded DEM cannot be interpolated by the sampler), then multiplied
|
|
26
|
+
* by `u_terrain_exaggeration`.
|
|
27
|
+
* - `src/geo/lng_lat.ts`, `earthRadius = 6371008.8` (line 8), and
|
|
28
|
+
* `src/geo/mercator_coordinate.ts`, `circumferenceAtLatitude` (line 14): the sphere an
|
|
29
|
+
* elevation in meters is turned into Mercator units on (`mercatorZfromAltitude`), which is
|
|
30
|
+
* how maplibre scales its terrain mesh and `map.project`. It is not the WGS84 equator the
|
|
31
|
+
* geometry of the engine measures distances on; the 0.1 % between them is a pixel at the
|
|
32
|
+
* top of a high, exaggerated mountain.
|
|
33
|
+
* - `src/render/terrain.ts`, `getElevationSampler` (line 324, `DEM_CELL_CENTER_OFFSET = -0.5`
|
|
34
|
+
* at line 60): the CPU sampler places the pixels the same way, and it is what
|
|
35
|
+
* `map.queryTerrainElevation` returns where the terrain is drawn. The engine's CPU side reads
|
|
36
|
+
* that function (`ground.ts`) and copies nothing of it.
|
|
37
|
+
*
|
|
38
|
+
* Up to maplibre 6.7 the border was one texel and the offset `+ 1.0` (the pixels sat on the
|
|
39
|
+
* cell corners); 6.8.0 and 6.9.1 changed both (the move to the cell centres is
|
|
40
|
+
* maplibre-gl-js#8420). The end-to-end test `src/e2e/terrain.e2e.test.ts` compares what
|
|
41
|
+
* these shaders read with `map.queryTerrainElevation`, and the projection of the anchors
|
|
42
|
+
* (which uses the sphere through `metrics.ts`) with `map.project`, on a known DEM, and fails
|
|
43
|
+
* when they part.
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* The circumference of the sphere maplibre turns elevations into Mercator units on (meters),
|
|
47
|
+
* `2 * PI * earthRadius`
|
|
48
|
+
*/
|
|
49
|
+
export const UPSTREAM_EARTH_CIRCUMFERENCE_METERS = 2 * Math.PI * 6371008.8;
|
|
50
|
+
/** The border around the pixels of a DEM tile, in texels on each side */
|
|
51
|
+
export const DEM_BORDER_TEXELS = 2;
|
|
52
|
+
/**
|
|
53
|
+
* What is added to `uv * dim` to get the texel coordinate of a position (the border, less half
|
|
54
|
+
* a texel because pixels are centred on their cells)
|
|
55
|
+
*/
|
|
56
|
+
export const DEM_TEXEL_OFFSET = DEM_BORDER_TEXELS - 0.5;
|
|
57
|
+
/**
|
|
58
|
+
* The texel coordinate of a position of the DEM tile (the same formula as `get_elevation`)
|
|
59
|
+
*
|
|
60
|
+
* @param uv The position in the unit square of the DEM tile
|
|
61
|
+
* @param dim The number of pixels of the DEM tile on a side (`u_terrain_dim`)
|
|
62
|
+
*/
|
|
63
|
+
export function demTexelCoord(uv, dim) {
|
|
64
|
+
return uv * dim + DEM_TEXEL_OFFSET;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The texel coordinate of the last texel of a DEM texture (the far end of the border)
|
|
68
|
+
*
|
|
69
|
+
* A bilinear sample needs the texel at `floor(coord) + 1`, so real data is read only for
|
|
70
|
+
* texel coordinates in `[0, demLastTexel(dim)]`; beyond it the clamp repeats the last texel.
|
|
71
|
+
*
|
|
72
|
+
* @param dim The number of pixels of the DEM tile on a side
|
|
73
|
+
*/
|
|
74
|
+
export function demLastTexel(dim) {
|
|
75
|
+
return dim + 2 * DEM_BORDER_TEXELS - 1;
|
|
76
|
+
}
|
|
77
|
+
/** A number as a GLSL float literal */
|
|
78
|
+
function glslFloat(value) {
|
|
79
|
+
return Number.isInteger(value) ? `${value}.0` : `${value}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The GLSL of the upstream DEM layout, for both shader stages
|
|
83
|
+
*
|
|
84
|
+
* - `upstream_dem_coord(uv, dim)`: the texel coordinate of a position ({@link demTexelCoord})
|
|
85
|
+
* - `upstream_dem_last_texel(dim)`: {@link demLastTexel}
|
|
86
|
+
* - `upstream_dem_bilinear(dem, unpack, coord)`: the elevation at a texel coordinate, in
|
|
87
|
+
* meters before the exaggeration (the body of `get_elevation`)
|
|
88
|
+
*
|
|
89
|
+
* The functions take the texture and its unpack vector as arguments, so the drape can also
|
|
90
|
+
* read the DEM of a neighbouring tile with them (`edge-constrain.ts`).
|
|
91
|
+
*/
|
|
92
|
+
export const UPSTREAM_DEM_GLSL = `
|
|
93
|
+
vec2 upstream_dem_coord(vec2 uv, float dim) {
|
|
94
|
+
return uv * dim + ${glslFloat(DEM_TEXEL_OFFSET)};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
float upstream_dem_last_texel(float dim) {
|
|
98
|
+
return dim + ${glslFloat(2 * DEM_BORDER_TEXELS - 1)};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
float upstream_dem_ele(sampler2D dem, vec4 unpack, ivec2 pos) {
|
|
102
|
+
vec4 rgb = (texelFetch(dem, pos, 0) * 255.0) * unpack;
|
|
103
|
+
return rgb.r + rgb.g + rgb.b - unpack.a;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
float upstream_dem_bilinear(sampler2D dem, vec4 unpack, vec2 coord) {
|
|
107
|
+
vec2 f = fract(coord);
|
|
108
|
+
ivec2 c = ivec2(floor(coord));
|
|
109
|
+
ivec2 hi = textureSize(dem, 0) - 1;
|
|
110
|
+
float tl = upstream_dem_ele(dem, unpack, clamp(c, ivec2(0), hi));
|
|
111
|
+
float tr = upstream_dem_ele(dem, unpack, clamp(c + ivec2(1, 0), ivec2(0), hi));
|
|
112
|
+
float bl = upstream_dem_ele(dem, unpack, clamp(c + ivec2(0, 1), ivec2(0), hi));
|
|
113
|
+
float br = upstream_dem_ele(dem, unpack, clamp(c + ivec2(1, 1), ivec2(0), hi));
|
|
114
|
+
return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
|
|
115
|
+
}
|
|
116
|
+
`;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension point for the auxiliary handles
|
|
3
|
+
*
|
|
4
|
+
* A general-purpose hook for showing and grabbing handles on the selected feature that are
|
|
5
|
+
* "neither a vertex nor a resize handle". All core holds is the hit testing and the drag
|
|
6
|
+
* delegation; drawing the handles is the responsibility of the registering side (the plugin
|
|
7
|
+
* of an extension implementation). core knows nothing at all about the meaning of a handle
|
|
8
|
+
* (it only carries the position and the identifier).
|
|
9
|
+
*
|
|
10
|
+
* There are two ways to emit handles: those bound to the selected feature (getHandles) and
|
|
11
|
+
* those that can always be emitted regardless of the selection (getGlobalHandles). The
|
|
12
|
+
* latter is an entry point provided for "interaction state that does not fit the concept of
|
|
13
|
+
* a selection" (such as a focus held by an extension implementation), and hit testing, drag
|
|
14
|
+
* delegation and the cursor all go through exactly the same machinery as the former.
|
|
15
|
+
*
|
|
16
|
+
* One registry belongs to one draw instance (it is part of the SelectionScope), so the handles
|
|
17
|
+
* of a second draw instance on the same page never appear in, or take the drags of, the first.
|
|
18
|
+
*/
|
|
19
|
+
import type { DragNormalizedEvent } from '../../dispatcher/types.js';
|
|
20
|
+
import type { LngLat, ScreenPoint } from '../../shared/math/index.js';
|
|
21
|
+
import type { Coordinate, Feature } from '../../store/types.js';
|
|
22
|
+
/**
|
|
23
|
+
* One auxiliary handle returned by an {@link AuxiliaryHandleProvider}.
|
|
24
|
+
*/
|
|
25
|
+
export interface AuxiliaryHandle {
|
|
26
|
+
/** Identifier unique within the provider */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Position of the handle, `[lng, lat]` in degrees */
|
|
29
|
+
position: Coordinate;
|
|
30
|
+
/** Cursor on hover (when omitted, 'pointer') */
|
|
31
|
+
cursor?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The context passed to {@link AuxiliaryHandleProvider.getHandles}: the tested point, the
|
|
35
|
+
* coordinate transforms and the zoom.
|
|
36
|
+
*
|
|
37
|
+
* A minimal structure holding only the point being hit tested (screen px), the coordinate
|
|
38
|
+
* transform and the zoom. The point is passed as is so that dynamic handles which appear
|
|
39
|
+
* only near the cursor (edge affordances and the like) can be expressed. The coordinate
|
|
40
|
+
* transform follows the same convention as the CoordinateTransform used by the existing
|
|
41
|
+
* handle hit testing (geographic coordinates [lng, lat] <-> screen px).
|
|
42
|
+
*/
|
|
43
|
+
export interface AuxiliaryHandleContext {
|
|
44
|
+
/** The point being hit tested (screen px) */
|
|
45
|
+
point: ScreenPoint;
|
|
46
|
+
/** Geographic coordinates -> screen px */
|
|
47
|
+
project(lngLat: Coordinate): ScreenPoint;
|
|
48
|
+
/** Screen px -> geographic coordinates */
|
|
49
|
+
unproject(point: ScreenPoint): LngLat;
|
|
50
|
+
/** Current zoom level */
|
|
51
|
+
zoom: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Which auxiliary handle of which provider was grabbed, and on which feature.
|
|
55
|
+
*/
|
|
56
|
+
export interface AuxiliaryHandleHit {
|
|
57
|
+
/** The id of the provider that returned the handle */
|
|
58
|
+
providerId: string;
|
|
59
|
+
/** The id of the handle within the provider */
|
|
60
|
+
handleId: string;
|
|
61
|
+
/**
|
|
62
|
+
* ID of the feature the handle sat on.
|
|
63
|
+
*
|
|
64
|
+
* A selection-independent handle (getGlobalHandles) has no feature, so it becomes an
|
|
65
|
+
* empty string (when `global` is true).
|
|
66
|
+
*/
|
|
67
|
+
featureId: string;
|
|
68
|
+
/** Whether it came from a selection-independent handle (getGlobalHandles) */
|
|
69
|
+
global?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A source of handles on the selected feature that are neither vertices nor resize handles,
|
|
73
|
+
* and the receiver of their drags.
|
|
74
|
+
*
|
|
75
|
+
* Register one with `draw.registerAuxiliaryHandleProvider(provider)`. The library hit tests
|
|
76
|
+
* the handles and delegates their drags; drawing them is the provider's job (with an overlay
|
|
77
|
+
* renderer, for example).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* import type { AuxiliaryHandleProvider } from '@sakuzu/maplibre-gl-draw';
|
|
82
|
+
*
|
|
83
|
+
* // A handle 20 px above the first vertex of the selected line, which logs its drag
|
|
84
|
+
* const labelHandle: AuxiliaryHandleProvider = {
|
|
85
|
+
* id: 'label-handle',
|
|
86
|
+
* getHandles(feature, ctx) {
|
|
87
|
+
* if (feature.type !== 'LineString') return [];
|
|
88
|
+
* const first = (feature.coordinates as [number, number][])[0];
|
|
89
|
+
* const p = ctx.project(first);
|
|
90
|
+
* const { lng, lat } = ctx.unproject({ x: p.x, y: p.y - 20 });
|
|
91
|
+
* return [{ id: 'label', position: [lng, lat], cursor: 'move' }];
|
|
92
|
+
* },
|
|
93
|
+
* onHandleDragStart: () => true,
|
|
94
|
+
* onHandleDragMove: (event) => console.log(event.lngLat),
|
|
95
|
+
* onHandleDragEnd: () => {},
|
|
96
|
+
* };
|
|
97
|
+
*
|
|
98
|
+
* const unregister = draw.registerAuxiliaryHandleProvider(labelHandle);
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export interface AuxiliaryHandleProvider {
|
|
102
|
+
/** Identifier unique within the registry (re-registering with the same id overwrites) */
|
|
103
|
+
id: string;
|
|
104
|
+
/**
|
|
105
|
+
* Returns the list of auxiliary handles for the feature in a single selection.
|
|
106
|
+
* It is called on every hit test, so heavy computation must be avoided.
|
|
107
|
+
*/
|
|
108
|
+
getHandles(feature: Feature, context: AuxiliaryHandleContext): AuxiliaryHandle[];
|
|
109
|
+
/**
|
|
110
|
+
* Returns the list of selection-independent handles (optional).
|
|
111
|
+
*
|
|
112
|
+
* They can always be emitted, whether the selection is empty or something else is
|
|
113
|
+
* selected. When core has finished testing against the selected feature (getHandles) and
|
|
114
|
+
* nothing was hit, it goes on to ask this one. Hit testing, drag delegation and the
|
|
115
|
+
* handling of the cursor all go through exactly the same machinery as the handles of
|
|
116
|
+
* getHandles.
|
|
117
|
+
*
|
|
118
|
+
* When one is grabbed, the AuxiliaryHandleHit has an empty featureId and global set to
|
|
119
|
+
* true (because there is no feature it sits on).
|
|
120
|
+
*
|
|
121
|
+
* It is called on every hit test, so heavy computation must be avoided.
|
|
122
|
+
*/
|
|
123
|
+
getGlobalHandles?(context: AuxiliaryHandleContext): AuxiliaryHandle[];
|
|
124
|
+
/**
|
|
125
|
+
* Drag delegation. When it returns true, core stops dragPan and routes the subsequent
|
|
126
|
+
* move / end to the same provider. When false, core does not start a drag.
|
|
127
|
+
*/
|
|
128
|
+
onHandleDragStart(hit: AuxiliaryHandleHit, event: DragNormalizedEvent): boolean;
|
|
129
|
+
/** Called for each move of a drag this provider accepted */
|
|
130
|
+
onHandleDragMove(event: DragNormalizedEvent): void;
|
|
131
|
+
/** Called at the end of a drag this provider accepted */
|
|
132
|
+
onHandleDragEnd(event: DragNormalizedEvent): void;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The registered providers of auxiliary handles of one draw instance
|
|
136
|
+
*/
|
|
137
|
+
export interface AuxiliaryHandleRegistry {
|
|
138
|
+
/**
|
|
139
|
+
* Registers a provider (re-registering with the same id overwrites)
|
|
140
|
+
*
|
|
141
|
+
* @returns A function that cancels the registration (calling it after a re-registration
|
|
142
|
+
* with the same id does not remove the provider that came in later)
|
|
143
|
+
*/
|
|
144
|
+
register(provider: AuxiliaryHandleProvider): () => void;
|
|
145
|
+
/** Gets a registered provider by id */
|
|
146
|
+
get(id: string): AuxiliaryHandleProvider | undefined;
|
|
147
|
+
/** Enumerates the registered providers (in registration order) */
|
|
148
|
+
list(): AuxiliaryHandleProvider[];
|
|
149
|
+
/** Cancels every registration (called when the draw instance is destroyed) */
|
|
150
|
+
clear(): void;
|
|
151
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Creates the registry of auxiliary handle providers of one draw instance
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export function createAuxiliaryHandleRegistry() {
|
|
9
|
+
const providers = new Map();
|
|
10
|
+
return {
|
|
11
|
+
register(provider) {
|
|
12
|
+
providers.set(provider.id, provider);
|
|
13
|
+
return () => {
|
|
14
|
+
if (providers.get(provider.id) === provider)
|
|
15
|
+
providers.delete(provider.id);
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
get: (id) => providers.get(id),
|
|
19
|
+
list: () => [...providers.values()],
|
|
20
|
+
clear: () => providers.clear(),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computing the selection bounding box
|
|
3
|
+
*
|
|
4
|
+
* Computes the bounding box in geographic coordinates uniformly for every feature type.
|
|
5
|
+
* Used by hit testing.
|
|
6
|
+
*
|
|
7
|
+
* The basic policy (see docs/internals/architecture.md):
|
|
8
|
+
* - Data and computation are in geographic coordinates
|
|
9
|
+
* - Hit testing unprojects the click position and decides in geographic coordinates
|
|
10
|
+
* - Only rendering converts into screen coordinates
|
|
11
|
+
*/
|
|
12
|
+
import type { SelectionUIConfig } from '../../shared/config/selection.js';
|
|
13
|
+
import type { CoordinateTransform } from '../../shared/math/index.js';
|
|
14
|
+
import type { Coordinate, Feature } from '../../store/types.js';
|
|
15
|
+
import { type BoundingBoxCoords, type SelectionExtensionRegistry } from './selection-ui/index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Compute the bounding box with a margin of a feature in geographic coordinates
|
|
18
|
+
*
|
|
19
|
+
* Supports every feature type:
|
|
20
|
+
* - Point: the icon size + the margin are computed in screen coordinates and converted
|
|
21
|
+
* into geographic coordinates
|
|
22
|
+
* - LineString/Polygon: the margin is applied by applyMarginToBoundingBox
|
|
23
|
+
*
|
|
24
|
+
* @param feature The target feature
|
|
25
|
+
* @param transform The coordinate transform
|
|
26
|
+
* @param config The selection UI configuration
|
|
27
|
+
* @returns The bounding box with a margin in geographic coordinates, or null when it
|
|
28
|
+
* cannot be computed
|
|
29
|
+
*/
|
|
30
|
+
export declare function computeFeatureGeoBoundingBox(feature: Feature, transform: CoordinateTransform, config: SelectionUIConfig, extensions?: SelectionExtensionRegistry): BoundingBoxCoords | null;
|
|
31
|
+
/**
|
|
32
|
+
* Compute the combined geographic bounding box of several features (with a margin)
|
|
33
|
+
*
|
|
34
|
+
* @param features The array of target features
|
|
35
|
+
* @param transform The coordinate transform
|
|
36
|
+
* @param config The selection UI configuration
|
|
37
|
+
* @param extensions The draw instance's extension points (custom bounding boxes and point
|
|
38
|
+
* frame extents)
|
|
39
|
+
* @returns The bounding box with a margin in geographic coordinates, or null when it
|
|
40
|
+
* cannot be computed
|
|
41
|
+
*/
|
|
42
|
+
export declare function computeCombinedGeoBoundingBox(features: Feature[], transform: CoordinateTransform, config: SelectionUIConfig, extensions?: SelectionExtensionRegistry): BoundingBoxCoords | null;
|
|
43
|
+
/**
|
|
44
|
+
* Decide whether a point in geographic coordinates is inside a convex quadrilateral
|
|
45
|
+
*
|
|
46
|
+
* Uses the cross product method. It decides whether the point is inside the convex
|
|
47
|
+
* quadrilateral enclosed by the 4 corners.
|
|
48
|
+
*
|
|
49
|
+
* @param lngLat The geographic coordinate to test [lng, lat]
|
|
50
|
+
* @param bbox The bounding box in geographic coordinates
|
|
51
|
+
* @returns true when the point is inside the bbox
|
|
52
|
+
*/
|
|
53
|
+
export declare function isPointInGeoBoundingBox(lngLat: Coordinate, bbox: BoundingBoxCoords): boolean;
|