@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,509 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { resolvePixelRatio } from '../../shared/utils/pixel-ratio.js';
|
|
4
|
+
import { updateGlobeSubdivision } from '../globe-subdivision.js';
|
|
5
|
+
import { beginRenderFrame } from '../shaders/frame.js';
|
|
6
|
+
import { installAnchorProjector, uninstallAnchorProjector } from '../terrain/anchor.js';
|
|
7
|
+
import { releaseTerrainContext, } from '../terrain/context.js';
|
|
8
|
+
import { getCameraMercator } from '../terrain/detect.js';
|
|
9
|
+
import { setQuadDrapeFrame, setTerrainCameraMoving, setTerrainRenderState, } from '../terrain/state.js';
|
|
10
|
+
import { DisplayListCache } from './display-list.js';
|
|
11
|
+
import { DrapePlanner } from './drape-planner.js';
|
|
12
|
+
import { renderForeground, renderSegment } from './frame-render.js';
|
|
13
|
+
import { buildFrameState, StyleZoom } from './frame-state.js';
|
|
14
|
+
import { createRenderScope } from './render-scope.js';
|
|
15
|
+
import { disposeRenderers, initRenderers } from './renderers.js';
|
|
16
|
+
import { SlotManager } from './slot-manager.js';
|
|
17
|
+
import { renderSlotLayerId } from './slots.js';
|
|
18
|
+
import { StoreRetainedCache } from './store-retained.js';
|
|
19
|
+
import { isOpacityOnlyLayersChange } from './store-retained-invalidation.js';
|
|
20
|
+
import { TerrainResolver } from './terrain-resolver.js';
|
|
21
|
+
/**
|
|
22
|
+
* Factory function of the CustomLayerInterface
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export function createCustomLayer(deps) {
|
|
27
|
+
const { map, store, spatialIndex, featureStyle, selectionConfig, renderingConfig, customFeatureHandlers, datasets, pixelRatio, } = deps;
|
|
28
|
+
// The providers of companion drawing are dedicated to this instance
|
|
29
|
+
const featureCompanions = deps.featureCompanions;
|
|
30
|
+
// Map of the custom feature handlers
|
|
31
|
+
const customRenderers = new Map();
|
|
32
|
+
if (customFeatureHandlers) {
|
|
33
|
+
for (const handler of customFeatureHandlers) {
|
|
34
|
+
customRenderers.set(handler.type, handler.renderer);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const engine = {
|
|
38
|
+
gl: null,
|
|
39
|
+
mapInstance: null,
|
|
40
|
+
renderers: null,
|
|
41
|
+
storeRetainedCache: null,
|
|
42
|
+
builtPixelRatio: null,
|
|
43
|
+
unsubscribeStore: null,
|
|
44
|
+
unwatchContextLoss: null,
|
|
45
|
+
frame: null,
|
|
46
|
+
preparedTerrainState: null,
|
|
47
|
+
};
|
|
48
|
+
/** The ordered list of the features to display (the immediate path; follows the Store) */
|
|
49
|
+
const displayList = new DisplayListCache(store);
|
|
50
|
+
const dynamicOverlayRenderers = [];
|
|
51
|
+
/**
|
|
52
|
+
* Terrain state of this draw instance
|
|
53
|
+
*
|
|
54
|
+
* The frame state, the generation counters, the frame of the anchor projection and the
|
|
55
|
+
* subdivision cache are all held here. It used to be module-global, and the screen, the
|
|
56
|
+
* thumbnails, the previews and the print overwrote each other's state every frame.
|
|
57
|
+
* It is part of the render scope, together with the caches of triangulation and style
|
|
58
|
+
* evaluation that are keyed by feature id (another instance holding the same ids never reads
|
|
59
|
+
* them). The renderers receive the parts they need at construction.
|
|
60
|
+
*/
|
|
61
|
+
const renderScope = createRenderScope(deps.selectionScope);
|
|
62
|
+
const terrainContext = renderScope.terrain;
|
|
63
|
+
const terrainResolver = new TerrainResolver(map, terrainContext);
|
|
64
|
+
const drape = new DrapePlanner({
|
|
65
|
+
map,
|
|
66
|
+
store,
|
|
67
|
+
terrain: terrainContext,
|
|
68
|
+
datasets,
|
|
69
|
+
timeSlicing: renderingConfig.timeSlicing,
|
|
70
|
+
});
|
|
71
|
+
const styleZoom = new StyleZoom();
|
|
72
|
+
const slots = new SlotManager({
|
|
73
|
+
map,
|
|
74
|
+
getLayerOrder: () => store.getLayerOrder(),
|
|
75
|
+
isExternalEntry: deps.isExternalEntry,
|
|
76
|
+
onSlotsChange: deps.onSlotsChange,
|
|
77
|
+
createSlotLayer: makeSlotLayer,
|
|
78
|
+
});
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Creation and disposal of the engine (built when the first slot goes onto the map, torn down
|
|
81
|
+
// when the last slot is removed)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
function engineAdd(mapInstance, glContext) {
|
|
84
|
+
if (!slots.attach())
|
|
85
|
+
return;
|
|
86
|
+
engine.gl = glContext;
|
|
87
|
+
engine.mapInstance = mapInstance;
|
|
88
|
+
// Insert the anchor projection into the hit testing side. It only takes effect in the frames
|
|
89
|
+
// where the terrain is active (it returns null until setAnchorFrame is called), and on a map
|
|
90
|
+
// without terrain the project of MapLibre is used as before.
|
|
91
|
+
installAnchorProjector(mapInstance, terrainContext);
|
|
92
|
+
// Subscribe to the Store changes to invalidate the earcut, style rule and retained batch
|
|
93
|
+
// caches
|
|
94
|
+
// Changes made while the layer was off the map were not seen
|
|
95
|
+
displayList.invalidate();
|
|
96
|
+
engine.unsubscribeStore = store.subscribe((changes) => {
|
|
97
|
+
engine.storeRetainedCache?.applyChanges(changes);
|
|
98
|
+
displayList.applyChanges(changes);
|
|
99
|
+
// The binning of the analytic drape is rebuilt only on a change of the geometry, the style,
|
|
100
|
+
// the membership or the order. Rebuilding it indiscriminately on changes such as
|
|
101
|
+
// selection / editing / tentative / mode would run the dataset (about 10 ms) and the
|
|
102
|
+
// binning on every interaction and make the map stutter (measured; the exclusion test of
|
|
103
|
+
// the dataset depends only on the type and the style, so the collected result does not
|
|
104
|
+
// change even without looking at them). The opacity of a layer is a factor of its drape
|
|
105
|
+
// source, written every frame, so a change of the opacity alone keeps the binning.
|
|
106
|
+
const affectsDrape = changes.features !== undefined ||
|
|
107
|
+
(changes.layers !== undefined && !isOpacityOnlyLayersChange(changes.layers)) ||
|
|
108
|
+
changes.groups !== undefined ||
|
|
109
|
+
changes.layerReorder !== undefined ||
|
|
110
|
+
changes.groupReorder !== undefined;
|
|
111
|
+
if (affectsDrape)
|
|
112
|
+
drape.invalidate();
|
|
113
|
+
if (changes.features?.updated) {
|
|
114
|
+
for (const { id } of changes.features.updated) {
|
|
115
|
+
renderScope.earcut.delete(id);
|
|
116
|
+
renderScope.styleRules.delete(id);
|
|
117
|
+
terrainContext.fillCache.delete(id);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (changes.features?.deleted) {
|
|
121
|
+
for (const feature of changes.features.deleted) {
|
|
122
|
+
renderScope.earcut.delete(feature.id);
|
|
123
|
+
renderScope.styleRules.delete(feature.id);
|
|
124
|
+
terrainContext.fillCache.delete(feature.id);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// When the style rule of a layer changes, the evaluation results of every feature that
|
|
128
|
+
// belongs to that layer go stale. There is no reverse lookup of the membership, so the
|
|
129
|
+
// whole cache is discarded (changing a rule is a rare operation).
|
|
130
|
+
if (changes.layers?.updated) {
|
|
131
|
+
for (const { layer, previous } of changes.layers.updated) {
|
|
132
|
+
if (layer.styleRule !== previous.styleRule) {
|
|
133
|
+
renderScope.styleRules.clear();
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// When the stacking order changes, the slots follow it (a layer added, removed or
|
|
139
|
+
// reordered; a dataset joining the order also goes through setLayerOrder
|
|
140
|
+
// and arrives here)
|
|
141
|
+
if (changes.layers !== undefined)
|
|
142
|
+
slots.sync();
|
|
143
|
+
});
|
|
144
|
+
watchContextLoss(mapInstance);
|
|
145
|
+
// Build the GPU side (skipped while the context is lost; the restore builds it then)
|
|
146
|
+
buildGpuResources();
|
|
147
|
+
// If the stacking order changed before it was added, the number of slots is matched here
|
|
148
|
+
slots.sync();
|
|
149
|
+
}
|
|
150
|
+
function engineRemove() {
|
|
151
|
+
if (!slots.detach())
|
|
152
|
+
return;
|
|
153
|
+
if (engine.unsubscribeStore) {
|
|
154
|
+
engine.unsubscribeStore();
|
|
155
|
+
engine.unsubscribeStore = null;
|
|
156
|
+
}
|
|
157
|
+
engine.unwatchContextLoss?.();
|
|
158
|
+
engine.unwatchContextLoss = null;
|
|
159
|
+
releaseGpuResources();
|
|
160
|
+
// The overlay renderers stay registered. maplibre removes the custom layers when it swaps
|
|
161
|
+
// the style or loses the WebGL context, and the host adds them back afterwards; the overlays
|
|
162
|
+
// then receive onAdd again from buildGpuResources (they were registered once, by a plugin or
|
|
163
|
+
// at creation, and nobody registers them a second time).
|
|
164
|
+
engine.mapInstance = null;
|
|
165
|
+
renderScope.earcut.clear();
|
|
166
|
+
renderScope.styleRules.clear();
|
|
167
|
+
// Release the terrain state of this instance
|
|
168
|
+
releaseTerrainContext(terrainContext);
|
|
169
|
+
// Remove the inserted anchor projection (hit testing goes back to the project of MapLibre)
|
|
170
|
+
if (map)
|
|
171
|
+
uninstallAnchorProjector(map);
|
|
172
|
+
}
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// GPU resources (every buffer, texture, program, vertex array and framebuffer)
|
|
175
|
+
//
|
|
176
|
+
// Everything that lives in the WebGL context is created by buildGpuResources and dropped by
|
|
177
|
+
// releaseGpuResources, and nothing else holds a GL object across frames. A lost context
|
|
178
|
+
// invalidates every GL object at once, so this pair is also what the context loss and the
|
|
179
|
+
// restore run (docs/internals/rendering.md, "GPU resources and WebGL context loss"). The CPU-side
|
|
180
|
+
// state (the Store subscription, the caches of triangulation and style evaluation, the
|
|
181
|
+
// drape index of the elements) is kept.
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
/**
|
|
184
|
+
* Creates the GPU resources of the engine
|
|
185
|
+
*
|
|
186
|
+
* It does nothing when they already exist or when the context is lost (the restore calls it
|
|
187
|
+
* again).
|
|
188
|
+
*/
|
|
189
|
+
function buildGpuResources() {
|
|
190
|
+
const { gl, mapInstance } = engine;
|
|
191
|
+
if (engine.renderers || !gl || !mapInstance || gl.isContextLost())
|
|
192
|
+
return;
|
|
193
|
+
engine.renderers = initRenderers({
|
|
194
|
+
gl,
|
|
195
|
+
map: mapInstance,
|
|
196
|
+
store,
|
|
197
|
+
spatialIndex,
|
|
198
|
+
featureStyle,
|
|
199
|
+
selectionConfig,
|
|
200
|
+
renderingConfig,
|
|
201
|
+
customFeatureHandlers,
|
|
202
|
+
pixelRatio,
|
|
203
|
+
scope: renderScope,
|
|
204
|
+
onImageError: deps.onImageError,
|
|
205
|
+
});
|
|
206
|
+
if (renderingConfig.storeRetained !== false) {
|
|
207
|
+
engine.storeRetainedCache = new StoreRetainedCache(store, {
|
|
208
|
+
terrain: terrainContext,
|
|
209
|
+
extensions: renderScope.selection.extensions,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// Initialize the custom renderers and the overlay renderers (an overlay added before the
|
|
213
|
+
// engine existed receives its onAdd here)
|
|
214
|
+
for (const renderer of customRenderers.values()) {
|
|
215
|
+
renderer.onAdd(gl, mapInstance);
|
|
216
|
+
}
|
|
217
|
+
for (const renderer of dynamicOverlayRenderers) {
|
|
218
|
+
renderer.onAdd(gl, mapInstance);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Drops the GPU resources of the engine
|
|
223
|
+
*
|
|
224
|
+
* The delete calls are harmless on a lost context (WebGL ignores them), so the same path serves
|
|
225
|
+
* the removal from the map and the context loss.
|
|
226
|
+
*/
|
|
227
|
+
function releaseGpuResources() {
|
|
228
|
+
engine.frame = null;
|
|
229
|
+
engine.preparedTerrainState = null;
|
|
230
|
+
const r = engine.renderers;
|
|
231
|
+
if (!r)
|
|
232
|
+
return;
|
|
233
|
+
for (const renderer of customRenderers.values()) {
|
|
234
|
+
renderer.onRemove();
|
|
235
|
+
}
|
|
236
|
+
for (const renderer of dynamicOverlayRenderers) {
|
|
237
|
+
renderer.onRemove();
|
|
238
|
+
}
|
|
239
|
+
// Release the retained-mode GPU resources held by the datasets (the
|
|
240
|
+
// datasets themselves are kept and built again once the layer is recreated)
|
|
241
|
+
datasets?.disposeRetained();
|
|
242
|
+
// Release the retained batches of the Store rendering too (before disposing the renderers)
|
|
243
|
+
engine.storeRetainedCache?.dispose(r.batchManager.getRetainedRenderers());
|
|
244
|
+
engine.storeRetainedCache = null;
|
|
245
|
+
engine.builtPixelRatio = null;
|
|
246
|
+
// The DEM atlas, the drape renderers, and the plan and the index that point into the pack
|
|
247
|
+
// uploaded to the drape renderer (the next frame collects and uploads again)
|
|
248
|
+
terrainResolver.releaseGpu();
|
|
249
|
+
drape.releaseGpu();
|
|
250
|
+
setQuadDrapeFrame(terrainContext, null);
|
|
251
|
+
disposeRenderers(r);
|
|
252
|
+
engine.renderers = null;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Follows the loss and the restore of the WebGL context of the map
|
|
256
|
+
*
|
|
257
|
+
* These are events of the GL context, not input, so they are subscribed here and not in the
|
|
258
|
+
* InputNormalizer. maplibre 6.6 itself removes every custom layer when the context is lost
|
|
259
|
+
* (onRemove runs, and this listener goes with it) and does not add them back; the host adds
|
|
260
|
+
* them again after the restore (attachSlotLayers follows `styledata`), and onAdd builds
|
|
261
|
+
* everything again. The listener covers the other shape, where the layer stays on the map
|
|
262
|
+
* through the loss: the GPU side is dropped on the loss and built again on the restore
|
|
263
|
+
* (docs/internals/maplibre-coupling.md, item 23).
|
|
264
|
+
*/
|
|
265
|
+
function watchContextLoss(mapInstance) {
|
|
266
|
+
const canvas = mapInstance.getCanvas?.();
|
|
267
|
+
if (!canvas)
|
|
268
|
+
return;
|
|
269
|
+
const onLost = () => {
|
|
270
|
+
releaseGpuResources();
|
|
271
|
+
};
|
|
272
|
+
const onRestored = () => {
|
|
273
|
+
if (slots.addedCount === 0)
|
|
274
|
+
return;
|
|
275
|
+
buildGpuResources();
|
|
276
|
+
mapInstance.triggerRepaint?.();
|
|
277
|
+
};
|
|
278
|
+
canvas.addEventListener('webglcontextlost', onLost, false);
|
|
279
|
+
canvas.addEventListener('webglcontextrestored', onRestored, false);
|
|
280
|
+
engine.unwatchContextLoss = () => {
|
|
281
|
+
canvas.removeEventListener('webglcontextlost', onLost, false);
|
|
282
|
+
canvas.removeEventListener('webglcontextrestored', onRestored, false);
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// ---------------------------------------------------------------------------
|
|
286
|
+
// Preparation of the frame (done once by the first slot)
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
function beginFrame(renderOptions) {
|
|
289
|
+
const { gl, renderers: r } = engine;
|
|
290
|
+
if (!gl || !r)
|
|
291
|
+
return null;
|
|
292
|
+
// Declare the switch to a new frame (this invalidates the memoized uniforms held by each
|
|
293
|
+
// renderer; see shaders/frame.ts)
|
|
294
|
+
beginRenderFrame();
|
|
295
|
+
// While the camera is moving, the re-baking of the retained batches is deferred (read by
|
|
296
|
+
// display/chunk-set.ts)
|
|
297
|
+
setTerrainCameraMoving(terrainContext, map?.isMoving?.() === true || map?.isZooming?.() === true);
|
|
298
|
+
// The zoom that the rendering reads is the style zoom (a value that absorbs the steps of the
|
|
299
|
+
// elevation settlement; frame-state.ts). The position of the camera (the altitude in meters)
|
|
300
|
+
// tells a settlement from a jump of the camera
|
|
301
|
+
const rawZoom = map?.getZoom() ?? 14;
|
|
302
|
+
const cameraBusy = map?.isMoving?.() === true || map?.isZooming?.() === true;
|
|
303
|
+
const zoom = styleZoom.update(rawZoom, cameraBusy, getCameraMercator(map, 1));
|
|
304
|
+
// The datasets decide the rows they draw from the zoom of this frame, before anything of it
|
|
305
|
+
// is drawn (the drape plan below and every layer of the frame read the same rows)
|
|
306
|
+
datasets?.beginFrame(zoom);
|
|
307
|
+
// Detection of the terrain and establishing the frame state
|
|
308
|
+
//
|
|
309
|
+
// INACTIVE is put in place when there is no terrain. The u_terrain_on of the shaders becomes
|
|
310
|
+
// 0 and the vertex computation is exactly the same as before the terrain was introduced (zero
|
|
311
|
+
// regression). This is looked at every frame (setTerrain / removeTerrain emit no event).
|
|
312
|
+
//
|
|
313
|
+
// It is normally resolved in prerender, before maplibre starts the main pass, because baking
|
|
314
|
+
// the DEM atlas renders into a framebuffer of its own; switching framebuffers in the middle
|
|
315
|
+
// of the main pass makes a tiled GPU store and reload the whole frame
|
|
316
|
+
const terrainState = engine.preparedTerrainState ?? terrainResolver.resolve(gl);
|
|
317
|
+
engine.preparedTerrainState = null;
|
|
318
|
+
setTerrainRenderState(terrainContext, terrainState);
|
|
319
|
+
// The cells the globe cuts the geometry into (none on a flat map; globe-subdivision.ts)
|
|
320
|
+
updateGlobeSubdivision(terrainContext, renderOptions.defaultProjectionData.projectionTransition ?? 0, rawZoom);
|
|
321
|
+
// Follow the changes of the rendering pixel ratio (moving to another display, or
|
|
322
|
+
// draw.setRenderScale()). The widths of the already baked retained batches no longer match
|
|
323
|
+
// when the ratio changes, so they are discarded.
|
|
324
|
+
const dpr = resolvePixelRatio(pixelRatio);
|
|
325
|
+
if (engine.builtPixelRatio !== dpr) {
|
|
326
|
+
if (engine.builtPixelRatio !== null)
|
|
327
|
+
engine.storeRetainedCache?.invalidateAll();
|
|
328
|
+
engine.builtPixelRatio = dpr;
|
|
329
|
+
}
|
|
330
|
+
return buildFrameState({
|
|
331
|
+
gl,
|
|
332
|
+
renderers: r,
|
|
333
|
+
map,
|
|
334
|
+
store,
|
|
335
|
+
terrainContext,
|
|
336
|
+
displayList,
|
|
337
|
+
drape,
|
|
338
|
+
renderOptions,
|
|
339
|
+
zoom,
|
|
340
|
+
rawZoom,
|
|
341
|
+
dpr,
|
|
342
|
+
terrainState,
|
|
343
|
+
retainedAvailable: engine.storeRetainedCache !== null,
|
|
344
|
+
overlayRenderers: dynamicOverlayRenderers,
|
|
345
|
+
segments: slots.segments,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// render of a slot (maplibre calls it per slot)
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
function renderSlot(index, renderOptions) {
|
|
352
|
+
const { gl, renderers: r } = engine;
|
|
353
|
+
// Nothing is drawn while the GPU side is missing (a lost context, before the restore)
|
|
354
|
+
if (!gl || !r || gl.isContextLost())
|
|
355
|
+
return;
|
|
356
|
+
// The slots are called in the order of the list (ascending index). An index that goes back
|
|
357
|
+
// means a new frame. A frame where the last slot never arrived (right after slots were added
|
|
358
|
+
// or removed, for example) is closed here as well
|
|
359
|
+
if (engine.frame === null || index <= engine.frame.lastIndex) {
|
|
360
|
+
engine.frame = beginFrame(renderOptions);
|
|
361
|
+
}
|
|
362
|
+
const frame = engine.frame;
|
|
363
|
+
if (!frame)
|
|
364
|
+
return;
|
|
365
|
+
// Right after slots are removed, the render of a removed slot never arrives (it has been
|
|
366
|
+
// removed from the map), but to be safe nothing outside the segments is drawn
|
|
367
|
+
if (index >= frame.segments.length)
|
|
368
|
+
return;
|
|
369
|
+
const renderDeps = {
|
|
370
|
+
gl,
|
|
371
|
+
renderers: r,
|
|
372
|
+
map,
|
|
373
|
+
store,
|
|
374
|
+
terrainContext,
|
|
375
|
+
drape,
|
|
376
|
+
customRenderers,
|
|
377
|
+
featureCompanions,
|
|
378
|
+
datasets,
|
|
379
|
+
storeRetainedCache: engine.storeRetainedCache,
|
|
380
|
+
selectionScope: renderScope.selection,
|
|
381
|
+
};
|
|
382
|
+
renderSegment(renderDeps, frame, index);
|
|
383
|
+
frame.lastIndex = index;
|
|
384
|
+
if (index === frame.segments.length - 1) {
|
|
385
|
+
renderForeground(renderDeps, frame);
|
|
386
|
+
engine.frame = null;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/** Creates the CustomLayer of the slot at `index` (the first one is customLayer itself) */
|
|
390
|
+
function makeSlotLayer(index) {
|
|
391
|
+
return {
|
|
392
|
+
id: renderSlotLayerId(index),
|
|
393
|
+
type: 'custom',
|
|
394
|
+
renderingMode: '3d',
|
|
395
|
+
onAdd(mapInstance, glContext) {
|
|
396
|
+
engineAdd(mapInstance, glContext);
|
|
397
|
+
},
|
|
398
|
+
render(_gl, renderOptions) {
|
|
399
|
+
renderSlot(index, renderOptions);
|
|
400
|
+
},
|
|
401
|
+
onRemove() {
|
|
402
|
+
engineRemove();
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/** Whether a feature renderer is still registered for some type */
|
|
407
|
+
function isRegisteredRenderer(renderer) {
|
|
408
|
+
for (const registered of customRenderers.values()) {
|
|
409
|
+
if (registered === renderer)
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
const customLayer = {
|
|
415
|
+
id: renderSlotLayerId(0),
|
|
416
|
+
type: 'custom',
|
|
417
|
+
renderingMode: '3d',
|
|
418
|
+
onAdd(mapInstance, glContext) {
|
|
419
|
+
engineAdd(mapInstance, glContext);
|
|
420
|
+
},
|
|
421
|
+
// The offscreen pass of maplibre, before the main pass of the frame. Only the first slot
|
|
422
|
+
// prepares here: the terrain state of the frame, which bakes the DEM atlas into its own
|
|
423
|
+
// framebuffer when the terrain changed (maplibre resets its GL state after it; see
|
|
424
|
+
// maplibre-coupling.md, "prerender")
|
|
425
|
+
prerender() {
|
|
426
|
+
const { gl } = engine;
|
|
427
|
+
if (!gl || !engine.renderers || gl.isContextLost())
|
|
428
|
+
return;
|
|
429
|
+
engine.preparedTerrainState = terrainResolver.resolve(gl);
|
|
430
|
+
},
|
|
431
|
+
// The first argument also accepts WebGL1, to match the declaration of CustomRenderMethod
|
|
432
|
+
// (what is used is the WebGL2 context received in onAdd, so the body does not change).
|
|
433
|
+
render(_gl, renderOptions) {
|
|
434
|
+
renderSlot(0, renderOptions);
|
|
435
|
+
},
|
|
436
|
+
onRemove() {
|
|
437
|
+
engineRemove();
|
|
438
|
+
},
|
|
439
|
+
addOverlayRenderer(renderer) {
|
|
440
|
+
dynamicOverlayRenderers.push(renderer);
|
|
441
|
+
// An element involved in the rendering was added, so the prepared retained batches are
|
|
442
|
+
// rebuilt
|
|
443
|
+
engine.storeRetainedCache?.invalidateAll();
|
|
444
|
+
// Only while the GPU side exists (otherwise buildGpuResources calls onAdd)
|
|
445
|
+
if (engine.renderers && engine.gl && engine.mapInstance) {
|
|
446
|
+
renderer.onAdd(engine.gl, engine.mapInstance);
|
|
447
|
+
}
|
|
448
|
+
return () => customLayer.removeOverlayRenderer(renderer);
|
|
449
|
+
},
|
|
450
|
+
removeOverlayRenderer(renderer) {
|
|
451
|
+
const index = dynamicOverlayRenderers.indexOf(renderer);
|
|
452
|
+
if (index === -1)
|
|
453
|
+
return;
|
|
454
|
+
dynamicOverlayRenderers.splice(index, 1);
|
|
455
|
+
engine.storeRetainedCache?.invalidateAll();
|
|
456
|
+
// Its GPU resources exist only while the engine does
|
|
457
|
+
if (engine.renderers && engine.gl)
|
|
458
|
+
renderer.onRemove();
|
|
459
|
+
engine.mapInstance?.triggerRepaint();
|
|
460
|
+
},
|
|
461
|
+
registerFeatureRenderer(type, renderer) {
|
|
462
|
+
const replaced = customRenderers.get(type);
|
|
463
|
+
customRenderers.set(type, renderer);
|
|
464
|
+
// Adding a custom type changes the classification of the features (whether they can be
|
|
465
|
+
// retained)
|
|
466
|
+
engine.storeRetainedCache?.invalidateAll();
|
|
467
|
+
// Only while the GPU side exists (otherwise buildGpuResources calls onAdd)
|
|
468
|
+
if (engine.renderers && engine.gl && engine.mapInstance) {
|
|
469
|
+
// A renderer can serve several types: it is released only when no type uses it
|
|
470
|
+
if (replaced && !isRegisteredRenderer(replaced))
|
|
471
|
+
replaced.onRemove();
|
|
472
|
+
renderer.onAdd(engine.gl, engine.mapInstance);
|
|
473
|
+
}
|
|
474
|
+
return () => {
|
|
475
|
+
if (customRenderers.get(type) !== renderer)
|
|
476
|
+
return;
|
|
477
|
+
customRenderers.delete(type);
|
|
478
|
+
engine.storeRetainedCache?.invalidateAll();
|
|
479
|
+
if (engine.renderers && engine.gl && !isRegisteredRenderer(renderer))
|
|
480
|
+
renderer.onRemove();
|
|
481
|
+
engine.mapInstance?.triggerRepaint();
|
|
482
|
+
};
|
|
483
|
+
},
|
|
484
|
+
getRenderSlots() {
|
|
485
|
+
return slots.getRenderSlots();
|
|
486
|
+
},
|
|
487
|
+
getSlotLayers() {
|
|
488
|
+
return slots.getSlotLayers();
|
|
489
|
+
},
|
|
490
|
+
getTerrainContext() {
|
|
491
|
+
return terrainContext;
|
|
492
|
+
},
|
|
493
|
+
hasPendingWork() {
|
|
494
|
+
if (drape.hasPendingWork)
|
|
495
|
+
return true;
|
|
496
|
+
if (datasets?.hasPendingWork())
|
|
497
|
+
return true;
|
|
498
|
+
for (const renderer of dynamicOverlayRenderers) {
|
|
499
|
+
if (renderer.hasPendingWork?.())
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
return false;
|
|
503
|
+
},
|
|
504
|
+
};
|
|
505
|
+
// The first slot is customLayer itself. When there are separators, the following slots are
|
|
506
|
+
// prepared here (the host adds them to the map in order from the first)
|
|
507
|
+
slots.init(customLayer);
|
|
508
|
+
return customLayer;
|
|
509
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch the depth test and record the new state
|
|
3
|
+
*/
|
|
4
|
+
export declare function setDepthTestEnabled(gl: WebGL2RenderingContext, enabled: boolean): void;
|
|
5
|
+
/**
|
|
6
|
+
* The recorded state of the depth test of a context (false when nothing was recorded yet)
|
|
7
|
+
*/
|
|
8
|
+
export declare function isDepthTestEnabled(gl: WebGL2RenderingContext): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Sync back to the actual GL state (once at the start of a frame)
|
|
11
|
+
*
|
|
12
|
+
* This is the only place that asks GL. It happens once per frame, so the cost is negligible.
|
|
13
|
+
*/
|
|
14
|
+
export declare function syncDepthTestEnabled(gl: WebGL2RenderingContext): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Remembering the state of the depth test
|
|
5
|
+
*
|
|
6
|
+
* Symbols (point billboards and SDF glyphs) must not be clipped by the depth of the terrain, so
|
|
7
|
+
* the depth test is disabled while they are drawn and then restored
|
|
8
|
+
* (`renderers/point/billboard-depth.ts`). That "restored" value must not be obtained by asking
|
|
9
|
+
* `gl.isEnabled` every time. A WebGL state query synchronously round-trips to the GPU process, so
|
|
10
|
+
* on a map with thousands of labels it becomes thousands of round-trips in a single frame and
|
|
11
|
+
* rendering stalls for tens of seconds.
|
|
12
|
+
*
|
|
13
|
+
* Only CustomLayer and the analysis drape switch the depth test. The side that switches it records
|
|
14
|
+
* the value here, and the symbol side reads that record. The record belongs to the WebGL context
|
|
15
|
+
* whose state it mirrors (one entry per context), so two maps never read each other's value, and
|
|
16
|
+
* two draw instances on one map share the context's true state. CustomLayer also reads the actual
|
|
17
|
+
* state once at the start of a frame and syncs to it.
|
|
18
|
+
*/
|
|
19
|
+
/** The recorded depth test state of each WebGL context */
|
|
20
|
+
const depthTestState = new WeakMap();
|
|
21
|
+
/**
|
|
22
|
+
* Switch the depth test and record the new state
|
|
23
|
+
*/
|
|
24
|
+
export function setDepthTestEnabled(gl, enabled) {
|
|
25
|
+
if (enabled)
|
|
26
|
+
gl.enable(gl.DEPTH_TEST);
|
|
27
|
+
else
|
|
28
|
+
gl.disable(gl.DEPTH_TEST);
|
|
29
|
+
depthTestState.set(gl, enabled);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The recorded state of the depth test of a context (false when nothing was recorded yet)
|
|
33
|
+
*/
|
|
34
|
+
export function isDepthTestEnabled(gl) {
|
|
35
|
+
return depthTestState.get(gl) === true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sync back to the actual GL state (once at the start of a frame)
|
|
39
|
+
*
|
|
40
|
+
* This is the only place that asks GL. It happens once per frame, so the cost is negligible.
|
|
41
|
+
*/
|
|
42
|
+
export function syncDepthTestEnabled(gl) {
|
|
43
|
+
depthTestState.set(gl, gl.isEnabled(gl.DEPTH_TEST));
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* The display list of the immediate path
|
|
5
|
+
*
|
|
6
|
+
* The immediate path draws the features in view in draw order every frame. Building that list
|
|
7
|
+
* from the Store each frame (the ordered list, the local visibility, then the viewport) walks
|
|
8
|
+
* every feature and allocates arrays of that size, which costs milliseconds on a store of 100k
|
|
9
|
+
* features even when a handful are on screen.
|
|
10
|
+
*
|
|
11
|
+
* The ordered list of the features to display depends only on the Store, so it is kept here and
|
|
12
|
+
* rebuilt only after a change that can alter it. The features in view are then taken from the
|
|
13
|
+
* spatial index (the ids inside the view) and put in draw order by their rank in the list, which
|
|
14
|
+
* costs in proportion to what is on screen rather than to the whole store.
|
|
15
|
+
*/
|
|
16
|
+
import { getDisplayFeatures } from '../../store/local-visibility.js';
|
|
17
|
+
/**
|
|
18
|
+
* Above this share of the list, the ids in view are taken by walking the list (sorting that
|
|
19
|
+
* many ranks would cost more than one pass over the list)
|
|
20
|
+
*/
|
|
21
|
+
const SORT_SHARE_LIMIT = 0.25;
|
|
22
|
+
/**
|
|
23
|
+
* The ordered list of the features to display, rebuilt only when the Store changes it
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export class DisplayListCache {
|
|
28
|
+
constructor(store) {
|
|
29
|
+
Object.defineProperty(this, "store", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "list", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: null
|
|
40
|
+
});
|
|
41
|
+
/** featureId → position in the list (built when first needed) */
|
|
42
|
+
Object.defineProperty(this, "rank", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: null
|
|
47
|
+
});
|
|
48
|
+
this.store = store;
|
|
49
|
+
}
|
|
50
|
+
/** The features to display, in draw order (the same list as getDisplayFeatures) */
|
|
51
|
+
features() {
|
|
52
|
+
if (!this.list)
|
|
53
|
+
this.list = getDisplayFeatures(this.store);
|
|
54
|
+
return this.list;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The features among `ids` that are displayed, in draw order
|
|
58
|
+
*
|
|
59
|
+
* @param ids The ids to keep (the features inside the view)
|
|
60
|
+
*/
|
|
61
|
+
inOrder(ids) {
|
|
62
|
+
const list = this.features();
|
|
63
|
+
if (ids.size > list.length * SORT_SHARE_LIMIT) {
|
|
64
|
+
return list.filter((feature) => ids.has(feature.id));
|
|
65
|
+
}
|
|
66
|
+
const rank = this.rankOf(list);
|
|
67
|
+
const positions = new Int32Array(ids.size);
|
|
68
|
+
let count = 0;
|
|
69
|
+
for (const id of ids) {
|
|
70
|
+
const position = rank.get(id);
|
|
71
|
+
if (position !== undefined)
|
|
72
|
+
positions[count++] = position;
|
|
73
|
+
}
|
|
74
|
+
const sorted = positions.subarray(0, count).sort();
|
|
75
|
+
const result = new Array(count);
|
|
76
|
+
for (let i = 0; i < count; i++)
|
|
77
|
+
result[i] = list[sorted[i]];
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Follows a change of the Store
|
|
82
|
+
*
|
|
83
|
+
* The list depends on the features (their visibility and membership), the layers, the groups,
|
|
84
|
+
* their order and the local visibility (reported as a change of the UI state). A change of the
|
|
85
|
+
* selection alone, for example, keeps it.
|
|
86
|
+
*/
|
|
87
|
+
applyChanges(changes) {
|
|
88
|
+
if (changes.features !== undefined ||
|
|
89
|
+
changes.layers !== undefined ||
|
|
90
|
+
changes.groups !== undefined ||
|
|
91
|
+
changes.layerReorder !== undefined ||
|
|
92
|
+
changes.groupReorder !== undefined ||
|
|
93
|
+
changes.uiStateChanged === true) {
|
|
94
|
+
this.invalidate();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Forgets the list (the next use rebuilds it) */
|
|
98
|
+
invalidate() {
|
|
99
|
+
this.list = null;
|
|
100
|
+
this.rank = null;
|
|
101
|
+
}
|
|
102
|
+
rankOf(list) {
|
|
103
|
+
if (!this.rank) {
|
|
104
|
+
const rank = new Map();
|
|
105
|
+
for (let i = 0; i < list.length; i++)
|
|
106
|
+
rank.set(list[i].id, i);
|
|
107
|
+
this.rank = rank;
|
|
108
|
+
}
|
|
109
|
+
return this.rank;
|
|
110
|
+
}
|
|
111
|
+
}
|