@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,122 @@
|
|
|
1
|
+
import type { Coordinate, Feature, VertexRef } from '../../store/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The set of handles to display
|
|
4
|
+
*
|
|
5
|
+
* It holds no coordinates. Because the set can be reused as is even after the vertices
|
|
6
|
+
* move, the number of handles does not change while dragging.
|
|
7
|
+
*/
|
|
8
|
+
export interface VisibleHandleSet {
|
|
9
|
+
/** Vertices to display (same VertexRef semantics as computeVertexHandles) */
|
|
10
|
+
vertexRefs: VertexRef[];
|
|
11
|
+
/** Midpoints to display (same VertexRef semantics as computeMidpointHandles) */
|
|
12
|
+
midpointRefs: VertexRef[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Viewport used for the pre-filtering of the thinning
|
|
16
|
+
*/
|
|
17
|
+
export interface ThinningViewport {
|
|
18
|
+
/** lngLat rectangle. When null, pre-filtering is skipped (all vertices are candidates) */
|
|
19
|
+
bounds: {
|
|
20
|
+
minLng: number;
|
|
21
|
+
minLat: number;
|
|
22
|
+
maxLng: number;
|
|
23
|
+
maxLat: number;
|
|
24
|
+
} | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Counts the total number of handles (vertices + midpoints) without enumerating them all
|
|
28
|
+
*
|
|
29
|
+
* It matches computeVertexHandles(feature).length +
|
|
30
|
+
* computeMidpointHandles(feature).length exactly. Because it is used to decide whether the
|
|
31
|
+
* thinning kicks in and whether the cache is invalidated, it only scans the number of rings
|
|
32
|
+
* and parts.
|
|
33
|
+
*/
|
|
34
|
+
export declare function countPotentialHandles(feature: Feature): number;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the handles of this feature are thinned
|
|
37
|
+
*/
|
|
38
|
+
export declare function shouldThinHandles(feature: Feature): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Computes the set of handles to display (pure function)
|
|
41
|
+
*
|
|
42
|
+
* Vertices are chosen with a greedy algorithm that takes only those whose screen distance
|
|
43
|
+
* from the previously adopted vertex is at least MIN_HANDLE_SPACING_PX. Midpoints are
|
|
44
|
+
* emitted only when both end vertices have been adopted and the screen length of the edge
|
|
45
|
+
* is at least MIDPOINT_MIN_EDGE_PX.
|
|
46
|
+
*
|
|
47
|
+
* @param project Function that projects a longitude/latitude to screen coordinates
|
|
48
|
+
* @param viewport Rectangle for pre-filtering (off-screen vertices are not even projected)
|
|
49
|
+
*/
|
|
50
|
+
export declare function computeVisibleHandleSet(feature: Feature, project: (coord: Coordinate) => {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
}, viewport: ThinningViewport): VisibleHandleSet;
|
|
54
|
+
/**
|
|
55
|
+
* Returns the set with the vertex references it does not contain added on the vertex side
|
|
56
|
+
*
|
|
57
|
+
* A rendering-only supplement that prevents a recomputation from hiding the selected or
|
|
58
|
+
* in-operation vertices and producing "it disappeared even though I selected it". The hit
|
|
59
|
+
* testing side does not apply this supplement (the principle that only what is visible can
|
|
60
|
+
* be grabbed is not bent for a single supplemented point; a selected vertex is being
|
|
61
|
+
* dragged, so it need not be grabbed again, which makes this a harmless simplification).
|
|
62
|
+
*/
|
|
63
|
+
export declare function includeRequiredVertexRefs(set: VisibleHandleSet, required: readonly VertexRef[]): VisibleHandleSet;
|
|
64
|
+
/**
|
|
65
|
+
* Looks up the coordinate of a vertex handle
|
|
66
|
+
*
|
|
67
|
+
* index is the vertex number excluding the closing point, but it matches the number counted
|
|
68
|
+
* from the head of the raw coordinate sequence (the closing point only ever sits at the
|
|
69
|
+
* end), so it can be used as an index as is.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveVertexCoordinate(feature: Feature, ref: VertexRef): Coordinate | null;
|
|
72
|
+
/**
|
|
73
|
+
* Looks up the coordinate of a midpoint handle
|
|
74
|
+
*
|
|
75
|
+
* The midpoint of edge i is the midpoint on the Mercator plane of the raw coordinates i and
|
|
76
|
+
* i+1, the point halfway along the edge as drawn (the same formula as computeMidpointHandles;
|
|
77
|
+
* `mercatorMidpoint`). For the last edge of a closed ring no wrap-around is needed either,
|
|
78
|
+
* because the trailing closing point has the same coordinate as the first.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveMidpointCoordinate(feature: Feature, ref: VertexRef): Coordinate | null;
|
|
81
|
+
/**
|
|
82
|
+
* Cache of the thinned sets
|
|
83
|
+
*
|
|
84
|
+
* Rendering (selection-ui-drawer) and hit testing (handle-test) have to look at the same
|
|
85
|
+
* set. One cache belongs to one draw instance (it is part of the SelectionScope that both the
|
|
86
|
+
* CustomLayer and the modes receive), so two instances holding a feature with the same id
|
|
87
|
+
* (a duplicated document, for instance) never share a set or a refresh timer.
|
|
88
|
+
*/
|
|
89
|
+
export declare class HandleThinningCache {
|
|
90
|
+
private entries;
|
|
91
|
+
private refreshTimer;
|
|
92
|
+
/**
|
|
93
|
+
* Gets the set from the rendering path (building it if there is none)
|
|
94
|
+
*
|
|
95
|
+
* While the camera is moving the stale set is returned, and it is rebuilt once the camera
|
|
96
|
+
* has been still for THINNING_REFRESH_DEBOUNCE_MS. Only when the vertex count changes is
|
|
97
|
+
* it rebuilt immediately.
|
|
98
|
+
*
|
|
99
|
+
* @param now Current time (passed by the caller for testability)
|
|
100
|
+
* @param compute Function that computes the set
|
|
101
|
+
* @param onNeedsRefresh Hook that triggers a redraw after the camera settles, called when
|
|
102
|
+
* a stale set was returned
|
|
103
|
+
*/
|
|
104
|
+
ensureSet(feature: Feature, cameraSig: string, now: number, compute: () => VisibleHandleSet, onNeedsRefresh?: () => void): VisibleHandleSet;
|
|
105
|
+
/**
|
|
106
|
+
* Gets "the set currently displayed" from the hit testing path
|
|
107
|
+
*
|
|
108
|
+
* The camera signature is not consulted. The stale set used while moving is precisely the
|
|
109
|
+
* one being displayed, and matching it is the source of truth for hit testing. For a
|
|
110
|
+
* feature that is not thinned it returns null, and the caller tests by full enumeration
|
|
111
|
+
* as before.
|
|
112
|
+
*/
|
|
113
|
+
getDisplayedSet(feature: Feature): VisibleHandleSet | null;
|
|
114
|
+
/**
|
|
115
|
+
* Discards the cache (all entries when featureId is omitted)
|
|
116
|
+
*/
|
|
117
|
+
clear(featureId?: string): void;
|
|
118
|
+
/** Stores an entry (discarding the oldest one when the upper bound is exceeded) */
|
|
119
|
+
private store;
|
|
120
|
+
/** Re-arms the timer that triggers a redraw (only one is held at a time) */
|
|
121
|
+
private scheduleRefresh;
|
|
122
|
+
}
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Screen-density thinning of the editing handles
|
|
5
|
+
*
|
|
6
|
+
* When a LineString / Polygon (including the Multi types) with thousands to tens of
|
|
7
|
+
* thousands of vertices is selected, the vertex handles and midpoint handles are thinned by
|
|
8
|
+
* screen density to build "the set of vertex references to display". Only the display is
|
|
9
|
+
* thinned; the doc (the coordinate sequence) is never touched.
|
|
10
|
+
*
|
|
11
|
+
* What is visible is the source of truth for what can be manipulated, so hit testing
|
|
12
|
+
* (handle-test.ts) also covers only the set built here. Grabbing a place with no handle
|
|
13
|
+
* still moves the feature itself as before, so moving a dense line as a whole still works.
|
|
14
|
+
*/
|
|
15
|
+
import { HANDLE_THINNING_THRESHOLD, MIDPOINT_MIN_EDGE_PX, MIN_HANDLE_SPACING_PX, THINNING_REFRESH_DEBOUNCE_MS, } from '../../shared/config/selection.js';
|
|
16
|
+
import { mercatorMidpoint } from '../../shared/math/globe-subdivision.js';
|
|
17
|
+
import { supportsVertexEditing } from '../../shared/utils/coordinates.js';
|
|
18
|
+
import { isSameVertexRef } from '../../shared/utils/vertex-ref.js';
|
|
19
|
+
/**
|
|
20
|
+
* Decomposes a feature into scan units
|
|
21
|
+
*
|
|
22
|
+
* They are ordered so that the scan order of the vertices is exactly the same as in
|
|
23
|
+
* computeVertexHandles and the scan order of the edges exactly the same as in
|
|
24
|
+
* computeMidpointHandles.
|
|
25
|
+
*/
|
|
26
|
+
function collectHandleRuns(feature) {
|
|
27
|
+
const runs = [];
|
|
28
|
+
if (feature.type === 'LineString') {
|
|
29
|
+
pushLineRun(runs, feature.coordinates);
|
|
30
|
+
}
|
|
31
|
+
else if (feature.type === 'Polygon') {
|
|
32
|
+
pushPolygonRuns(runs, feature.coordinates);
|
|
33
|
+
}
|
|
34
|
+
else if (feature.type === 'MultiPoint') {
|
|
35
|
+
// Splitting a MultiPoint per part would adopt every point and defeat the thinning, so
|
|
36
|
+
// all parts are scanned as a single sequence
|
|
37
|
+
const points = feature.coordinates;
|
|
38
|
+
runs.push({
|
|
39
|
+
coords: points,
|
|
40
|
+
vertexCount: points.length,
|
|
41
|
+
hasEdges: false,
|
|
42
|
+
forceLast: false,
|
|
43
|
+
makeRef: (index) => ({ part: index, ring: 0, index: 0 }),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (feature.type === 'MultiLineString') {
|
|
47
|
+
const parts = feature.coordinates;
|
|
48
|
+
for (let part = 0; part < parts.length; part++) {
|
|
49
|
+
pushLineRun(runs, parts[part], part);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (feature.type === 'MultiPolygon') {
|
|
53
|
+
const parts = feature.coordinates;
|
|
54
|
+
for (let part = 0; part < parts.length; part++) {
|
|
55
|
+
pushPolygonRuns(runs, parts[part], part);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return runs;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Adds a line (a single coordinate sequence) as a scan unit
|
|
62
|
+
*/
|
|
63
|
+
function pushLineRun(runs, coords, part) {
|
|
64
|
+
runs.push({
|
|
65
|
+
coords,
|
|
66
|
+
vertexCount: coords.length,
|
|
67
|
+
hasEdges: true,
|
|
68
|
+
forceLast: true,
|
|
69
|
+
makeRef: (index) => (part === undefined ? { ring: 0, index } : { part, ring: 0, index }),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Adds a polygon (an array of rings) as scan units
|
|
74
|
+
*/
|
|
75
|
+
function pushPolygonRuns(runs, rings, part) {
|
|
76
|
+
for (let ring = 0; ring < rings.length; ring++) {
|
|
77
|
+
const coords = rings[ring];
|
|
78
|
+
if (coords.length === 0)
|
|
79
|
+
continue;
|
|
80
|
+
runs.push({
|
|
81
|
+
coords,
|
|
82
|
+
vertexCount: countRingVertices(coords),
|
|
83
|
+
hasEdges: true,
|
|
84
|
+
// A closed ring has no endpoints, and in an open ring the edges also end at the last
|
|
85
|
+
// vertex, so nothing is force-adopted
|
|
86
|
+
forceLast: false,
|
|
87
|
+
makeRef: (index) => (part === undefined ? { ring, index } : { part, ring, index }),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Number of vertex handles of a ring (the vertex count excluding the closing point)
|
|
93
|
+
*
|
|
94
|
+
* The closing-point test is identical to collectPolygonVertexHandles (the first and the
|
|
95
|
+
* last coordinates match).
|
|
96
|
+
*/
|
|
97
|
+
function countRingVertices(ring) {
|
|
98
|
+
if (ring.length === 0)
|
|
99
|
+
return 0;
|
|
100
|
+
const isClosed = ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
|
|
101
|
+
return isClosed ? ring.length - 1 : ring.length;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Counts the total number of handles (vertices + midpoints) without enumerating them all
|
|
105
|
+
*
|
|
106
|
+
* It matches computeVertexHandles(feature).length +
|
|
107
|
+
* computeMidpointHandles(feature).length exactly. Because it is used to decide whether the
|
|
108
|
+
* thinning kicks in and whether the cache is invalidated, it only scans the number of rings
|
|
109
|
+
* and parts.
|
|
110
|
+
*/
|
|
111
|
+
export function countPotentialHandles(feature) {
|
|
112
|
+
if (feature.type === 'Point')
|
|
113
|
+
return 1;
|
|
114
|
+
if (feature.type === 'LineString') {
|
|
115
|
+
return countLineHandles(feature.coordinates.length);
|
|
116
|
+
}
|
|
117
|
+
if (feature.type === 'Polygon') {
|
|
118
|
+
return countPolygonHandles(feature.coordinates);
|
|
119
|
+
}
|
|
120
|
+
if (feature.type === 'MultiPoint') {
|
|
121
|
+
// Each coordinate is the vertex handle of one part. There are no edges
|
|
122
|
+
return feature.coordinates.length;
|
|
123
|
+
}
|
|
124
|
+
if (feature.type === 'MultiLineString') {
|
|
125
|
+
let total = 0;
|
|
126
|
+
for (const part of feature.coordinates) {
|
|
127
|
+
total += countLineHandles(part.length);
|
|
128
|
+
}
|
|
129
|
+
return total;
|
|
130
|
+
}
|
|
131
|
+
if (feature.type === 'MultiPolygon') {
|
|
132
|
+
let total = 0;
|
|
133
|
+
for (const part of feature.coordinates) {
|
|
134
|
+
total += countPolygonHandles(part);
|
|
135
|
+
}
|
|
136
|
+
return total;
|
|
137
|
+
}
|
|
138
|
+
// Circle / Freehand / Image / custom features have no vertex handles
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
/** Number of handles of a single line (n vertices + n-1 edges) */
|
|
142
|
+
function countLineHandles(length) {
|
|
143
|
+
return length + Math.max(0, length - 1);
|
|
144
|
+
}
|
|
145
|
+
/** Number of handles of a single polygon (the sum of vertices + edges over the rings) */
|
|
146
|
+
function countPolygonHandles(rings) {
|
|
147
|
+
let total = 0;
|
|
148
|
+
for (const ring of rings) {
|
|
149
|
+
if (ring.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
total += countRingVertices(ring) + Math.max(0, ring.length - 1);
|
|
152
|
+
}
|
|
153
|
+
return total;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Whether the handles of this feature are thinned
|
|
157
|
+
*/
|
|
158
|
+
export function shouldThinHandles(feature) {
|
|
159
|
+
return (supportsVertexEditing(feature.type) &&
|
|
160
|
+
countPotentialHandles(feature) > HANDLE_THINNING_THRESHOLD);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Whether the coordinate falls inside the viewport rectangle (always true if bounds is null)
|
|
164
|
+
*/
|
|
165
|
+
function isInBounds(coord, bounds) {
|
|
166
|
+
if (!bounds)
|
|
167
|
+
return true;
|
|
168
|
+
return (coord[0] >= bounds.minLng &&
|
|
169
|
+
coord[0] <= bounds.maxLng &&
|
|
170
|
+
coord[1] >= bounds.minLat &&
|
|
171
|
+
coord[1] <= bounds.maxLat);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Computes the set of handles to display (pure function)
|
|
175
|
+
*
|
|
176
|
+
* Vertices are chosen with a greedy algorithm that takes only those whose screen distance
|
|
177
|
+
* from the previously adopted vertex is at least MIN_HANDLE_SPACING_PX. Midpoints are
|
|
178
|
+
* emitted only when both end vertices have been adopted and the screen length of the edge
|
|
179
|
+
* is at least MIDPOINT_MIN_EDGE_PX.
|
|
180
|
+
*
|
|
181
|
+
* @param project Function that projects a longitude/latitude to screen coordinates
|
|
182
|
+
* @param viewport Rectangle for pre-filtering (off-screen vertices are not even projected)
|
|
183
|
+
*/
|
|
184
|
+
export function computeVisibleHandleSet(feature, project, viewport) {
|
|
185
|
+
const vertexRefs = [];
|
|
186
|
+
const midpointRefs = [];
|
|
187
|
+
const minSpacingSq = MIN_HANDLE_SPACING_PX * MIN_HANDLE_SPACING_PX;
|
|
188
|
+
const minEdgeSq = MIDPOINT_MIN_EDGE_PX * MIDPOINT_MIN_EDGE_PX;
|
|
189
|
+
for (const run of collectHandleRuns(feature)) {
|
|
190
|
+
// Screen positions of the adopted vertices (kept so the midpoint test need not reproject)
|
|
191
|
+
const adopted = new Map();
|
|
192
|
+
let last = null;
|
|
193
|
+
for (let i = 0; i < run.vertexCount; i++) {
|
|
194
|
+
// Off-screen vertices are skipped without being projected (and "the previously
|
|
195
|
+
// adopted point" is not updated either)
|
|
196
|
+
if (!isInBounds(run.coords[i], viewport.bounds))
|
|
197
|
+
continue;
|
|
198
|
+
const screen = project(run.coords[i]);
|
|
199
|
+
const isLastVertex = run.forceLast && i === run.vertexCount - 1;
|
|
200
|
+
if (last !== null && !isLastVertex && distanceSq(screen, last) < minSpacingSq) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
vertexRefs.push(run.makeRef(i));
|
|
204
|
+
adopted.set(i, screen);
|
|
205
|
+
last = screen;
|
|
206
|
+
}
|
|
207
|
+
if (!run.hasEdges)
|
|
208
|
+
continue;
|
|
209
|
+
// The edges are enumerated as in computeMidpointHandles (i = 0..len-2 over the raw
|
|
210
|
+
// coordinates)
|
|
211
|
+
for (let i = 0; i < run.coords.length - 1; i++) {
|
|
212
|
+
const start = adopted.get(i);
|
|
213
|
+
// The last edge of a closed ring wraps back to vertex 0, not to the closing point
|
|
214
|
+
const endIndex = i + 1 < run.vertexCount ? i + 1 : 0;
|
|
215
|
+
const end = adopted.get(endIndex);
|
|
216
|
+
if (!start || !end)
|
|
217
|
+
continue;
|
|
218
|
+
if (distanceSq(start, end) < minEdgeSq)
|
|
219
|
+
continue;
|
|
220
|
+
midpointRefs.push(run.makeRef(i));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return { vertexRefs, midpointRefs };
|
|
224
|
+
}
|
|
225
|
+
/** The square of the screen distance between two points */
|
|
226
|
+
function distanceSq(a, b) {
|
|
227
|
+
const dx = a.x - b.x;
|
|
228
|
+
const dy = a.y - b.y;
|
|
229
|
+
return dx * dx + dy * dy;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Returns the set with the vertex references it does not contain added on the vertex side
|
|
233
|
+
*
|
|
234
|
+
* A rendering-only supplement that prevents a recomputation from hiding the selected or
|
|
235
|
+
* in-operation vertices and producing "it disappeared even though I selected it". The hit
|
|
236
|
+
* testing side does not apply this supplement (the principle that only what is visible can
|
|
237
|
+
* be grabbed is not bent for a single supplemented point; a selected vertex is being
|
|
238
|
+
* dragged, so it need not be grabbed again, which makes this a harmless simplification).
|
|
239
|
+
*/
|
|
240
|
+
export function includeRequiredVertexRefs(set, required) {
|
|
241
|
+
if (required.length === 0)
|
|
242
|
+
return set;
|
|
243
|
+
const missing = required.filter((ref) => !set.vertexRefs.some((r) => isSameVertexRef(r, ref)));
|
|
244
|
+
if (missing.length === 0)
|
|
245
|
+
return set;
|
|
246
|
+
return {
|
|
247
|
+
vertexRefs: [...set.vertexRefs, ...missing],
|
|
248
|
+
midpointRefs: set.midpointRefs,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Extracts the raw coordinate sequence (one line / one ring) the vertex reference belongs to
|
|
253
|
+
*/
|
|
254
|
+
function getRefCoords(feature, ref) {
|
|
255
|
+
const part = ref.part ?? 0;
|
|
256
|
+
if (feature.type === 'Point') {
|
|
257
|
+
return [feature.coordinates];
|
|
258
|
+
}
|
|
259
|
+
if (feature.type === 'LineString') {
|
|
260
|
+
return feature.coordinates;
|
|
261
|
+
}
|
|
262
|
+
if (feature.type === 'Polygon') {
|
|
263
|
+
return feature.coordinates[ref.ring] ?? null;
|
|
264
|
+
}
|
|
265
|
+
if (feature.type === 'MultiPoint') {
|
|
266
|
+
const point = feature.coordinates[part];
|
|
267
|
+
return point ? [point] : null;
|
|
268
|
+
}
|
|
269
|
+
if (feature.type === 'MultiLineString') {
|
|
270
|
+
return feature.coordinates[part] ?? null;
|
|
271
|
+
}
|
|
272
|
+
if (feature.type === 'MultiPolygon') {
|
|
273
|
+
return feature.coordinates[part]?.[ref.ring] ?? null;
|
|
274
|
+
}
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Looks up the coordinate of a vertex handle
|
|
279
|
+
*
|
|
280
|
+
* index is the vertex number excluding the closing point, but it matches the number counted
|
|
281
|
+
* from the head of the raw coordinate sequence (the closing point only ever sits at the
|
|
282
|
+
* end), so it can be used as an index as is.
|
|
283
|
+
*/
|
|
284
|
+
export function resolveVertexCoordinate(feature, ref) {
|
|
285
|
+
const coords = getRefCoords(feature, ref);
|
|
286
|
+
return coords?.[ref.index] ?? null;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Looks up the coordinate of a midpoint handle
|
|
290
|
+
*
|
|
291
|
+
* The midpoint of edge i is the midpoint on the Mercator plane of the raw coordinates i and
|
|
292
|
+
* i+1, the point halfway along the edge as drawn (the same formula as computeMidpointHandles;
|
|
293
|
+
* `mercatorMidpoint`). For the last edge of a closed ring no wrap-around is needed either,
|
|
294
|
+
* because the trailing closing point has the same coordinate as the first.
|
|
295
|
+
*/
|
|
296
|
+
export function resolveMidpointCoordinate(feature, ref) {
|
|
297
|
+
const coords = getRefCoords(feature, ref);
|
|
298
|
+
const start = coords?.[ref.index];
|
|
299
|
+
const end = coords?.[ref.index + 1];
|
|
300
|
+
if (!start || !end)
|
|
301
|
+
return null;
|
|
302
|
+
return mercatorMidpoint(start, end);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Upper bound on the number of cache entries (the selection is effectively single, so 4 is
|
|
306
|
+
* enough)
|
|
307
|
+
*/
|
|
308
|
+
const MAX_CACHE_ENTRIES = 4;
|
|
309
|
+
/** Slack of the timer that triggers a redraw (fires reliably after the debounce expires) */
|
|
310
|
+
const REFRESH_TIMER_MARGIN_MS = 20;
|
|
311
|
+
/**
|
|
312
|
+
* Cache of the thinned sets
|
|
313
|
+
*
|
|
314
|
+
* Rendering (selection-ui-drawer) and hit testing (handle-test) have to look at the same
|
|
315
|
+
* set. One cache belongs to one draw instance (it is part of the SelectionScope that both the
|
|
316
|
+
* CustomLayer and the modes receive), so two instances holding a feature with the same id
|
|
317
|
+
* (a duplicated document, for instance) never share a set or a refresh timer.
|
|
318
|
+
*/
|
|
319
|
+
export class HandleThinningCache {
|
|
320
|
+
constructor() {
|
|
321
|
+
Object.defineProperty(this, "entries", {
|
|
322
|
+
enumerable: true,
|
|
323
|
+
configurable: true,
|
|
324
|
+
writable: true,
|
|
325
|
+
value: new Map()
|
|
326
|
+
});
|
|
327
|
+
Object.defineProperty(this, "refreshTimer", {
|
|
328
|
+
enumerable: true,
|
|
329
|
+
configurable: true,
|
|
330
|
+
writable: true,
|
|
331
|
+
value: null
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Gets the set from the rendering path (building it if there is none)
|
|
336
|
+
*
|
|
337
|
+
* While the camera is moving the stale set is returned, and it is rebuilt once the camera
|
|
338
|
+
* has been still for THINNING_REFRESH_DEBOUNCE_MS. Only when the vertex count changes is
|
|
339
|
+
* it rebuilt immediately.
|
|
340
|
+
*
|
|
341
|
+
* @param now Current time (passed by the caller for testability)
|
|
342
|
+
* @param compute Function that computes the set
|
|
343
|
+
* @param onNeedsRefresh Hook that triggers a redraw after the camera settles, called when
|
|
344
|
+
* a stale set was returned
|
|
345
|
+
*/
|
|
346
|
+
ensureSet(feature, cameraSig, now, compute, onNeedsRefresh) {
|
|
347
|
+
const handleCount = countPotentialHandles(feature);
|
|
348
|
+
const entry = this.entries.get(feature.id);
|
|
349
|
+
// No entry / the vertex count changed -> rebuild immediately
|
|
350
|
+
if (!entry || entry.handleCount !== handleCount) {
|
|
351
|
+
const set = compute();
|
|
352
|
+
this.store(feature.id, { handleCount, cameraSig, set });
|
|
353
|
+
return set;
|
|
354
|
+
}
|
|
355
|
+
if (entry.cameraSig === cameraSig) {
|
|
356
|
+
entry.pendingSig = undefined;
|
|
357
|
+
entry.pendingSince = undefined;
|
|
358
|
+
return entry.set;
|
|
359
|
+
}
|
|
360
|
+
if (entry.pendingSig !== cameraSig) {
|
|
361
|
+
// A new camera position was seen. The debounce is counted from here
|
|
362
|
+
entry.pendingSig = cameraSig;
|
|
363
|
+
entry.pendingSince = now;
|
|
364
|
+
}
|
|
365
|
+
else if (now - (entry.pendingSince ?? now) >= THINNING_REFRESH_DEBOUNCE_MS) {
|
|
366
|
+
const set = compute();
|
|
367
|
+
entry.set = set;
|
|
368
|
+
entry.cameraSig = cameraSig;
|
|
369
|
+
entry.pendingSig = undefined;
|
|
370
|
+
entry.pendingSince = undefined;
|
|
371
|
+
return set;
|
|
372
|
+
}
|
|
373
|
+
// Return the stale set. The timer that triggers a redraw is re-armed so that the
|
|
374
|
+
// recomputation runs even if no rendering frame arrives after the camera settles
|
|
375
|
+
this.scheduleRefresh(onNeedsRefresh);
|
|
376
|
+
return entry.set;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Gets "the set currently displayed" from the hit testing path
|
|
380
|
+
*
|
|
381
|
+
* The camera signature is not consulted. The stale set used while moving is precisely the
|
|
382
|
+
* one being displayed, and matching it is the source of truth for hit testing. For a
|
|
383
|
+
* feature that is not thinned it returns null, and the caller tests by full enumeration
|
|
384
|
+
* as before.
|
|
385
|
+
*/
|
|
386
|
+
getDisplayedSet(feature) {
|
|
387
|
+
const entry = this.entries.get(feature.id);
|
|
388
|
+
if (!entry)
|
|
389
|
+
return null;
|
|
390
|
+
if (entry.handleCount !== countPotentialHandles(feature))
|
|
391
|
+
return null;
|
|
392
|
+
return entry.set;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Discards the cache (all entries when featureId is omitted)
|
|
396
|
+
*/
|
|
397
|
+
clear(featureId) {
|
|
398
|
+
if (featureId === undefined) {
|
|
399
|
+
this.entries.clear();
|
|
400
|
+
if (this.refreshTimer !== null) {
|
|
401
|
+
clearTimeout(this.refreshTimer);
|
|
402
|
+
this.refreshTimer = null;
|
|
403
|
+
}
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
this.entries.delete(featureId);
|
|
407
|
+
}
|
|
408
|
+
/** Stores an entry (discarding the oldest one when the upper bound is exceeded) */
|
|
409
|
+
store(featureId, entry) {
|
|
410
|
+
this.entries.delete(featureId);
|
|
411
|
+
while (this.entries.size >= MAX_CACHE_ENTRIES) {
|
|
412
|
+
const oldest = this.entries.keys().next();
|
|
413
|
+
if (oldest.done)
|
|
414
|
+
break;
|
|
415
|
+
this.entries.delete(oldest.value);
|
|
416
|
+
}
|
|
417
|
+
this.entries.set(featureId, entry);
|
|
418
|
+
}
|
|
419
|
+
/** Re-arms the timer that triggers a redraw (only one is held at a time) */
|
|
420
|
+
scheduleRefresh(onNeedsRefresh) {
|
|
421
|
+
if (!onNeedsRefresh)
|
|
422
|
+
return;
|
|
423
|
+
if (this.refreshTimer !== null)
|
|
424
|
+
clearTimeout(this.refreshTimer);
|
|
425
|
+
this.refreshTimer = setTimeout(() => {
|
|
426
|
+
this.refreshTimer = null;
|
|
427
|
+
onNeedsRefresh();
|
|
428
|
+
}, THINNING_REFRESH_DEBOUNCE_MS + REFRESH_TIMER_MARGIN_MS);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HandleType } from '../../shared/config/constants.js';
|
|
2
|
+
import type { Coordinate, Feature, VertexRef } from '../../store/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A handle of the selection UI: its kind and its position.
|
|
5
|
+
*/
|
|
6
|
+
export interface HandleInfo {
|
|
7
|
+
/** The kind of handle (a resize corner, a vertex, a midpoint, a rotation handle...) */
|
|
8
|
+
type: HandleType;
|
|
9
|
+
/** The position of the handle, `[lng, lat]` in degrees */
|
|
10
|
+
position: Coordinate;
|
|
11
|
+
/** Vertex reference for vertex/midpoint handles (part number + ring number + vertex index) */
|
|
12
|
+
vertexRef?: VertexRef;
|
|
13
|
+
}
|
|
14
|
+
export { supportsVertexEditing } from '../../shared/utils/coordinates.js';
|
|
15
|
+
/**
|
|
16
|
+
* Computes the position of the radius handle for a Circle
|
|
17
|
+
*
|
|
18
|
+
* The handle is laid out with the same geodesic direct problem as the circle's outline, so it
|
|
19
|
+
* sits on the outline at any latitude and radius.
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeCircleRadiusHandle(feature: Feature): HandleInfo | null;
|
|
22
|
+
/**
|
|
23
|
+
* Computes the position of the center marker for a Circle
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeCircleCenterHandle(feature: Feature): HandleInfo | null;
|