@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,891 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { DEFAULT_FEATURE_STYLE_CONFIG } from '../shared/config/feature-style.js';
|
|
4
|
+
import { sanitizeDrawFactors } from '../view/renderers/draw-factors.js';
|
|
5
|
+
import { TerrainContext } from '../view/terrain/context.js';
|
|
6
|
+
import { DisplayChunkSet } from './chunk-set.js';
|
|
7
|
+
import { ColumnarSource } from './columnar/source.js';
|
|
8
|
+
import { DisplayProviderLoader } from './provider.js';
|
|
9
|
+
import { drawSelectionHighlight, hitTestDisplayFeatures, sameFeatureIds, } from './selection.js';
|
|
10
|
+
import { FeatureArraySource } from './source.js';
|
|
11
|
+
import { DisplayFeatureStyler } from './style.js';
|
|
12
|
+
import { CollisionThinningState, pointMarkerRadiusPx } from './thinning.js';
|
|
13
|
+
import { normalizeDisplayFeature } from './types.js';
|
|
14
|
+
// The importers of these moved names keep their path (the definitions live in the parts)
|
|
15
|
+
export { needsRetessellation } from './chunk-set.js';
|
|
16
|
+
/**
|
|
17
|
+
* Implementation of a dataset
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export class DatasetImpl {
|
|
22
|
+
constructor(options, deps) {
|
|
23
|
+
Object.defineProperty(this, "id", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "interactive", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
/** The current side. It is rewritten by the reordering of the manager */
|
|
36
|
+
Object.defineProperty(this, "currentOrder", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
42
|
+
/** Whether it is shown. While it is false, neither rendering nor hit testing happens */
|
|
43
|
+
Object.defineProperty(this, "isVisible", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true,
|
|
47
|
+
value: true
|
|
48
|
+
});
|
|
49
|
+
/** The contents (the rows, their chunks and their spatial index) */
|
|
50
|
+
Object.defineProperty(this, "source", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true,
|
|
54
|
+
value: new FeatureArraySource([])
|
|
55
|
+
});
|
|
56
|
+
Object.defineProperty(this, "styler", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: void 0
|
|
61
|
+
});
|
|
62
|
+
/** Zoom-dependent drawing factors (no factors when not set) */
|
|
63
|
+
Object.defineProperty(this, "zoomScale", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: null
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* Whether the polygons and lines are handed to the analytic drape (decided per frame by the
|
|
71
|
+
* rendering side)
|
|
72
|
+
*
|
|
73
|
+
* While they are handed over, the solid polygons and lines are not pushed onto the retained
|
|
74
|
+
* batches. This is so that the same thing is not drawn twice and so that the whole cost of the
|
|
75
|
+
* subdivision that matches the terrain mesh is skipped.
|
|
76
|
+
*/
|
|
77
|
+
Object.defineProperty(this, "drapedFills", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true,
|
|
80
|
+
writable: true,
|
|
81
|
+
value: false
|
|
82
|
+
});
|
|
83
|
+
/** The terrain used when the draw target provides none (inactive: draws flat) */
|
|
84
|
+
Object.defineProperty(this, "flatTerrain", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
value: new TerrainContext()
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* The revision that triggers rebuilding the index of the drape
|
|
92
|
+
*
|
|
93
|
+
* It advances only when the contents, the style or the visibility changed. It does not advance
|
|
94
|
+
* on a zoom, on the view or on the thinning (the drape draws no point; if it advanced on a
|
|
95
|
+
* pan or a zoom band, the index would be rebuilt on every gesture).
|
|
96
|
+
*/
|
|
97
|
+
Object.defineProperty(this, "contentRevision", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
configurable: true,
|
|
100
|
+
writable: true,
|
|
101
|
+
value: 0
|
|
102
|
+
});
|
|
103
|
+
/** Advances whenever the drawn rows change (`getDrawnRowsRevision`) */
|
|
104
|
+
Object.defineProperty(this, "drawnRowsRevision", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: 0
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* The zoom of the most recent frame drawn (the zoom the sizes are drawn with; null before the
|
|
112
|
+
* first frame). The band of the thinning is decided from it
|
|
113
|
+
*/
|
|
114
|
+
Object.defineProperty(this, "frameZoom", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: null
|
|
119
|
+
});
|
|
120
|
+
/** Whether this dataset was drawn in the most recent frame */
|
|
121
|
+
Object.defineProperty(this, "drawnInFrame", {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
configurable: true,
|
|
124
|
+
writable: true,
|
|
125
|
+
value: false
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Revision number of the style
|
|
129
|
+
*
|
|
130
|
+
* The footprint of the thinning is decided by the style (the rule, the base style, the zoom
|
|
131
|
+
* factors), so the winners are picked again once it advances. It is part of the cache key.
|
|
132
|
+
*/
|
|
133
|
+
Object.defineProperty(this, "styleRevision", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
configurable: true,
|
|
136
|
+
writable: true,
|
|
137
|
+
value: 0
|
|
138
|
+
});
|
|
139
|
+
/** The retained chunks */
|
|
140
|
+
Object.defineProperty(this, "chunks", {
|
|
141
|
+
enumerable: true,
|
|
142
|
+
configurable: true,
|
|
143
|
+
writable: true,
|
|
144
|
+
value: void 0
|
|
145
|
+
});
|
|
146
|
+
/** The collision thinning */
|
|
147
|
+
Object.defineProperty(this, "thinning", {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
configurable: true,
|
|
150
|
+
writable: true,
|
|
151
|
+
value: void 0
|
|
152
|
+
});
|
|
153
|
+
/** The loading through the provider (null without a provider) */
|
|
154
|
+
Object.defineProperty(this, "loader", {
|
|
155
|
+
enumerable: true,
|
|
156
|
+
configurable: true,
|
|
157
|
+
writable: true,
|
|
158
|
+
value: void 0
|
|
159
|
+
});
|
|
160
|
+
Object.defineProperty(this, "listeners", {
|
|
161
|
+
enumerable: true,
|
|
162
|
+
configurable: true,
|
|
163
|
+
writable: true,
|
|
164
|
+
value: new Map()
|
|
165
|
+
});
|
|
166
|
+
/** The features of the selected rows (in draw order; only the ids that exist are held) */
|
|
167
|
+
Object.defineProperty(this, "selected", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
writable: true,
|
|
171
|
+
value: []
|
|
172
|
+
});
|
|
173
|
+
Object.defineProperty(this, "removed", {
|
|
174
|
+
enumerable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
writable: true,
|
|
177
|
+
value: false
|
|
178
|
+
});
|
|
179
|
+
/** Whether the 'change' of a band followed by a frame is waiting to be sent */
|
|
180
|
+
Object.defineProperty(this, "thinningNoticePending", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: false
|
|
185
|
+
});
|
|
186
|
+
/** Cancels the waiting picking of the winners of the nearby bands (null = nothing waits) */
|
|
187
|
+
Object.defineProperty(this, "cancelPrefetch", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
configurable: true,
|
|
190
|
+
writable: true,
|
|
191
|
+
value: null
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(this, "deps", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
configurable: true,
|
|
196
|
+
writable: true,
|
|
197
|
+
value: void 0
|
|
198
|
+
});
|
|
199
|
+
/** Predicate that picks out the points drawn by an external renderer (null when not injected) */
|
|
200
|
+
Object.defineProperty(this, "externalPointRender", {
|
|
201
|
+
enumerable: true,
|
|
202
|
+
configurable: true,
|
|
203
|
+
writable: true,
|
|
204
|
+
value: void 0
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* Whether it is a point drawn by an external renderer (core does not draw it)
|
|
208
|
+
*
|
|
209
|
+
* The three paths (retained, immediate, selection) look only at this one. Scattering the test
|
|
210
|
+
* across each path would produce a disagreement such as "the circle comes back only when it is
|
|
211
|
+
* selected" the moment one of them is forgotten. The line that puts `MultiPoint` out of scope
|
|
212
|
+
* is also closed in here (when one feature has several points far apart, the unit to delegate
|
|
213
|
+
* to the external renderer is undefined; it is the same line as the collision thinning).
|
|
214
|
+
*/
|
|
215
|
+
Object.defineProperty(this, "isExternallyRenderedPoint", {
|
|
216
|
+
enumerable: true,
|
|
217
|
+
configurable: true,
|
|
218
|
+
writable: true,
|
|
219
|
+
value: (feature) => feature.type === 'Point' && this.externalPointRender?.(feature) === true
|
|
220
|
+
});
|
|
221
|
+
const given = [options.features, options.columnar, options.provider].filter((input) => input !== undefined);
|
|
222
|
+
if (given.length > 1) {
|
|
223
|
+
throw new Error(`Dataset "${options.id}": only one of features, columnar and provider can be given`);
|
|
224
|
+
}
|
|
225
|
+
if (options.prepared && !options.columnar) {
|
|
226
|
+
throw new Error(`Dataset "${options.id}": prepared is given without columnar`);
|
|
227
|
+
}
|
|
228
|
+
this.id = options.id;
|
|
229
|
+
this.currentOrder = options.order ?? 'below-store';
|
|
230
|
+
this.interactive = options.interactive ?? false;
|
|
231
|
+
this.styler = new DisplayFeatureStyler(options.styleRule, options.baseStyle);
|
|
232
|
+
this.zoomScale = options.zoomScale ?? null;
|
|
233
|
+
this.externalPointRender = options.externalPointRender ?? null;
|
|
234
|
+
this.deps = deps;
|
|
235
|
+
this.chunks = new DisplayChunkSet({
|
|
236
|
+
collector: (rows, collect, drawn) => this.source.collector(rows, this.collectContext(collect, drawn)),
|
|
237
|
+
drawnRows: () => this.thinning.mask,
|
|
238
|
+
// Not passed when it is not injected (the path without a predicate is as before)
|
|
239
|
+
externalPointFilter: () => this.externalPointRender ? this.isExternallyRenderedPoint : undefined,
|
|
240
|
+
drapedFills: () => this.drapedFills,
|
|
241
|
+
requestRepaint: () => this.deps.requestRepaint(),
|
|
242
|
+
onInvalidateAll: () => {
|
|
243
|
+
this.contentRevision++;
|
|
244
|
+
},
|
|
245
|
+
pixelRatio: deps.pixelRatio,
|
|
246
|
+
triangulationScheduler: deps.triangulationScheduler,
|
|
247
|
+
buildBudgetMs: deps.timeSlicing === false ? Number.POSITIVE_INFINITY : undefined,
|
|
248
|
+
});
|
|
249
|
+
this.thinning = new CollisionThinningState({
|
|
250
|
+
rows: () => this.source,
|
|
251
|
+
featuresGeneration: () => this.chunks.generation,
|
|
252
|
+
styleRevision: () => this.styleRevision,
|
|
253
|
+
footprintPx: (band, marginPx) => {
|
|
254
|
+
const defaults = this.pointDefaults();
|
|
255
|
+
const scale = sanitizeDrawFactors(this.zoomScale?.(band)).scale;
|
|
256
|
+
const baseStyle = this.styler.base;
|
|
257
|
+
return (styleRadius) => pointMarkerRadiusPx(styleRadius, baseStyle, defaults, scale) + marginPx;
|
|
258
|
+
},
|
|
259
|
+
}, options.collisionThinning);
|
|
260
|
+
this.loader = options.provider
|
|
261
|
+
? new DisplayProviderLoader(options.provider, {
|
|
262
|
+
id: this.id,
|
|
263
|
+
debounceMs: deps.providerDebounceMs,
|
|
264
|
+
apply: (features) => {
|
|
265
|
+
this.applySource(new FeatureArraySource(features));
|
|
266
|
+
this.deps.requestRepaint();
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
: null;
|
|
270
|
+
if (options.features) {
|
|
271
|
+
this.setFeatures(options.features);
|
|
272
|
+
}
|
|
273
|
+
else if (options.columnar) {
|
|
274
|
+
this.setColumnar(options.columnar, options.prepared);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** Draw order (the current side) */
|
|
278
|
+
get order() {
|
|
279
|
+
return this.currentOrder;
|
|
280
|
+
}
|
|
281
|
+
/** Whether it is shown */
|
|
282
|
+
get visible() {
|
|
283
|
+
return this.isVisible;
|
|
284
|
+
}
|
|
285
|
+
/** Whether it has a provider */
|
|
286
|
+
get hasProvider() {
|
|
287
|
+
return this.loader !== null;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Whether it needs to know about the changes of the displayed range (moveend): only to call
|
|
291
|
+
* its provider (the band of the thinning follows the frames drawn)
|
|
292
|
+
*/
|
|
293
|
+
get needsViewportUpdates() {
|
|
294
|
+
return this.loader !== null;
|
|
295
|
+
}
|
|
296
|
+
/** Whether it has been removed */
|
|
297
|
+
get isRemoved() {
|
|
298
|
+
return this.removed;
|
|
299
|
+
}
|
|
300
|
+
// === Public API ===
|
|
301
|
+
setVisible(visible) {
|
|
302
|
+
if (this.isVisible === visible)
|
|
303
|
+
return;
|
|
304
|
+
this.isVisible = visible;
|
|
305
|
+
this.contentRevision++;
|
|
306
|
+
// The retained batches are not discarded, so showing it again draws at once without a rebuild
|
|
307
|
+
this.emit('change', { reason: 'visibility' });
|
|
308
|
+
this.deps.requestRepaint();
|
|
309
|
+
}
|
|
310
|
+
setFeatures(features) {
|
|
311
|
+
this.applySource(new FeatureArraySource(features.map(normalizeDisplayFeature)));
|
|
312
|
+
this.deps.requestRepaint();
|
|
313
|
+
}
|
|
314
|
+
setColumnar(input, prepared) {
|
|
315
|
+
this.applySource(new ColumnarSource(input, prepared));
|
|
316
|
+
this.deps.requestRepaint();
|
|
317
|
+
}
|
|
318
|
+
setStyleRule(rule) {
|
|
319
|
+
this.styler.setRule(rule);
|
|
320
|
+
// The colors change, so the retained batches of every chunk are rebuilt
|
|
321
|
+
this.restyle();
|
|
322
|
+
}
|
|
323
|
+
setBaseStyle(style) {
|
|
324
|
+
this.styler.setBase(style);
|
|
325
|
+
// The appearance changes, so the retained batches of every chunk are rebuilt
|
|
326
|
+
this.restyle();
|
|
327
|
+
}
|
|
328
|
+
setExternalPointRender(predicate) {
|
|
329
|
+
this.externalPointRender = predicate ?? null;
|
|
330
|
+
// "Which points are not drawn" is baked into the retained batches, so as much is discarded as
|
|
331
|
+
// in setStyleRule / setBaseStyle. Without discarding it, the picture of the external renderer
|
|
332
|
+
// would be laid over the old circles that remain (or the points would stay gone even after
|
|
333
|
+
// the predicate is removed)
|
|
334
|
+
this.styler.clear();
|
|
335
|
+
this.restyle();
|
|
336
|
+
}
|
|
337
|
+
setZoomScale(zoomScale) {
|
|
338
|
+
// The factors are only multiplied in at draw time, so the retained batches are untouched
|
|
339
|
+
this.zoomScale = zoomScale;
|
|
340
|
+
// The footprint of the thinning does change with the factors, so the winners are picked
|
|
341
|
+
// again (the next draw rebuilds the points when they changed)
|
|
342
|
+
this.styleRevision++;
|
|
343
|
+
this.syncThinning('change');
|
|
344
|
+
this.schedulePrefetch();
|
|
345
|
+
this.deps.requestRepaint();
|
|
346
|
+
}
|
|
347
|
+
getZoomScale() {
|
|
348
|
+
return this.zoomScale;
|
|
349
|
+
}
|
|
350
|
+
getBaseStyle() {
|
|
351
|
+
return this.styler.base;
|
|
352
|
+
}
|
|
353
|
+
getFeatures() {
|
|
354
|
+
return this.source.features();
|
|
355
|
+
}
|
|
356
|
+
setSelectedIds(ids) {
|
|
357
|
+
// Keep the draw order and drop the ids that do not exist
|
|
358
|
+
const rows = ids.length === 0 ? [] : this.source.rowsOfIds(new Set(ids));
|
|
359
|
+
const next = rows.map((row) => this.source.featureAt(row));
|
|
360
|
+
if (sameFeatureIds(this.selected, next))
|
|
361
|
+
return;
|
|
362
|
+
this.selected = next;
|
|
363
|
+
this.emit('change', { reason: 'selection' });
|
|
364
|
+
this.deps.requestRepaint();
|
|
365
|
+
}
|
|
366
|
+
getSelectedIds() {
|
|
367
|
+
return this.selected.map((feature) => feature.id);
|
|
368
|
+
}
|
|
369
|
+
setCollisionThinning(options) {
|
|
370
|
+
const result = this.thinning.setOptions(options, this.thinningZoom());
|
|
371
|
+
if (!result)
|
|
372
|
+
return;
|
|
373
|
+
// The next draw rebuilds the points only when the drawn rows changed
|
|
374
|
+
if (result.drawnChanged)
|
|
375
|
+
this.drawnRowsChanged('change');
|
|
376
|
+
this.schedulePrefetch();
|
|
377
|
+
}
|
|
378
|
+
getCollisionThinning() {
|
|
379
|
+
return this.thinning.options;
|
|
380
|
+
}
|
|
381
|
+
getVisibleFeatureIds() {
|
|
382
|
+
return this.thinning.drawable;
|
|
383
|
+
}
|
|
384
|
+
getThinningStats() {
|
|
385
|
+
return this.thinning.stats(this.source.length);
|
|
386
|
+
}
|
|
387
|
+
getDrawnRowsRevision() {
|
|
388
|
+
return this.drawnRowsRevision;
|
|
389
|
+
}
|
|
390
|
+
findRow(id) {
|
|
391
|
+
const row = this.source.rowOfId(id);
|
|
392
|
+
return row >= 0 ? row : null;
|
|
393
|
+
}
|
|
394
|
+
invalidateProviderCache() {
|
|
395
|
+
if (!this.loader || this.removed)
|
|
396
|
+
return;
|
|
397
|
+
const { bounds, zoom } = this.deps.getViewportState();
|
|
398
|
+
this.loader.invalidate(bounds, zoom);
|
|
399
|
+
}
|
|
400
|
+
on(event, handler) {
|
|
401
|
+
let set = this.listeners.get(event);
|
|
402
|
+
if (!set) {
|
|
403
|
+
set = new Set();
|
|
404
|
+
this.listeners.set(event, set);
|
|
405
|
+
}
|
|
406
|
+
set.add(handler);
|
|
407
|
+
return () => this.off(event, handler);
|
|
408
|
+
}
|
|
409
|
+
off(event, handler) {
|
|
410
|
+
this.listeners.get(event)?.delete(handler);
|
|
411
|
+
}
|
|
412
|
+
remove() {
|
|
413
|
+
if (this.removed)
|
|
414
|
+
return;
|
|
415
|
+
this.removed = true;
|
|
416
|
+
this.dispose();
|
|
417
|
+
this.deps.onRemove(this.id);
|
|
418
|
+
this.deps.requestRepaint();
|
|
419
|
+
}
|
|
420
|
+
// === Internal API (called from the manager) ===
|
|
421
|
+
/**
|
|
422
|
+
* Rewrites the side (the path of the reordering)
|
|
423
|
+
*
|
|
424
|
+
* Only where it is drawn changes, so neither the retained batches, nor the visibility, nor the
|
|
425
|
+
* state of the provider is touched. The repaint is requested by the manager.
|
|
426
|
+
*/
|
|
427
|
+
setOrder(order) {
|
|
428
|
+
this.currentOrder = order;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Fires an event
|
|
432
|
+
*
|
|
433
|
+
* click / hover are called only when interactive. change is called regardless of interactive
|
|
434
|
+
* when the contents, the style or the visibility changed.
|
|
435
|
+
*/
|
|
436
|
+
emit(event, payload) {
|
|
437
|
+
const set = this.listeners.get(event);
|
|
438
|
+
if (!set)
|
|
439
|
+
return;
|
|
440
|
+
// An exception in one handler is isolated so that it does not drag in the others or the
|
|
441
|
+
// rendering path
|
|
442
|
+
for (const handler of [...set]) {
|
|
443
|
+
try {
|
|
444
|
+
handler(payload);
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
console.error(`Error in Dataset "${this.id}" listener for "${event}":`, error);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
// === Hand-off with the analytic drape ===
|
|
452
|
+
/**
|
|
453
|
+
* The revision that triggers rebuilding the index of the drape
|
|
454
|
+
*
|
|
455
|
+
* It advances only when the contents, the style, the thinning or the visibility changed.
|
|
456
|
+
*/
|
|
457
|
+
get drapeRevision() {
|
|
458
|
+
return this.contentRevision;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* The features handed to the analytic drape (with the rule colors applied, in draw order)
|
|
462
|
+
*
|
|
463
|
+
* The drape draws polygons and lines, and the thinning removes only points, so the drawn rows
|
|
464
|
+
* play no part here (a change of the zoom band does not rebuild the index of the drape). They
|
|
465
|
+
* are not narrowed by the view either. Narrowing them would change the order of the elements
|
|
466
|
+
* whenever the view moves and force the tile index to be rebuilt (the narrowing is done with
|
|
467
|
+
* the bounding box of each tile; `view/terrain/drape/binning.ts`).
|
|
468
|
+
*/
|
|
469
|
+
drapeFeatures() {
|
|
470
|
+
if (!this.isVisible)
|
|
471
|
+
return [];
|
|
472
|
+
const source = this.source;
|
|
473
|
+
// A table of points has nothing for it (and its rows are not built into features for
|
|
474
|
+
// nothing)
|
|
475
|
+
if (source instanceof ColumnarSource && source.table.onlyPoints)
|
|
476
|
+
return [];
|
|
477
|
+
const features = [];
|
|
478
|
+
for (let row = 0; row < source.length; row++) {
|
|
479
|
+
const type = source.typeOf(row);
|
|
480
|
+
if (type === null || type === 'Point' || type === 'MultiPoint')
|
|
481
|
+
continue;
|
|
482
|
+
features.push(source.featureAt(row));
|
|
483
|
+
}
|
|
484
|
+
return this.styler.prepareAll(features);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Reports whether the polygons and lines are handed to the analytic drape (decided per frame by
|
|
488
|
+
* the rendering side)
|
|
489
|
+
*
|
|
490
|
+
* A chunk whose way of handing over changed is re-baked the next time things settle. The
|
|
491
|
+
* previous version keeps being drawn until then, so the picture never disappears at the switch.
|
|
492
|
+
*/
|
|
493
|
+
setDrapedFills(draped) {
|
|
494
|
+
this.drapedFills = draped;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Zoom-dependent drawing factors (passed to the uniforms of the analytic drape)
|
|
498
|
+
*
|
|
499
|
+
* They are the same values that the retained batch path passes to `drawChunkBatches`.
|
|
500
|
+
*/
|
|
501
|
+
drapeFactors(zoom) {
|
|
502
|
+
return sanitizeDrawFactors(this.zoomScale?.(zoom));
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Returns the features inside the viewport in draw order (with the rule colors and the base
|
|
506
|
+
* style applied)
|
|
507
|
+
*/
|
|
508
|
+
collectVisible(bounds) {
|
|
509
|
+
return this.styler.prepareAll(this.featuresOf(this.source.index.search(bounds)));
|
|
510
|
+
}
|
|
511
|
+
collectDrawnRows(bounds) {
|
|
512
|
+
const source = this.source;
|
|
513
|
+
const thinning = this.thinning;
|
|
514
|
+
// The index holds only the rows with a geometry. `skip` is a hidden feature (a table has no
|
|
515
|
+
// hidden rows)
|
|
516
|
+
return source.index.searchWhere(bounds, (row) => thinning.isDrawnRow(row) && source.thinningRole(row) !== 'skip');
|
|
517
|
+
}
|
|
518
|
+
getRowFeature(row) {
|
|
519
|
+
if (!this.hasRow(row))
|
|
520
|
+
return null;
|
|
521
|
+
return this.styler.prepareIfStyled(this.source.featureAt(row));
|
|
522
|
+
}
|
|
523
|
+
getRowId(row) {
|
|
524
|
+
return this.hasRow(row) ? this.source.idOf(row) : null;
|
|
525
|
+
}
|
|
526
|
+
getRowType(row) {
|
|
527
|
+
return this.hasRow(row) ? this.source.typeOf(row) : null;
|
|
528
|
+
}
|
|
529
|
+
getRowBounds(row) {
|
|
530
|
+
if (!this.hasRow(row) || !this.source.hasGeometry(row))
|
|
531
|
+
return null;
|
|
532
|
+
const bounds = this.source.bounds;
|
|
533
|
+
const at = row * 4;
|
|
534
|
+
return { minX: bounds[at], minY: bounds[at + 1], maxX: bounds[at + 2], maxY: bounds[at + 3] };
|
|
535
|
+
}
|
|
536
|
+
getRowPoint(row) {
|
|
537
|
+
if (this.getRowType(row) !== 'Point')
|
|
538
|
+
return null;
|
|
539
|
+
const point = this.source.pointOf(row);
|
|
540
|
+
return [point[0], point[1]];
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Whether the most recent draw left a chunk unbuilt
|
|
544
|
+
*
|
|
545
|
+
* It turns false at the first frame that leaves nothing unbuilt (a measurement reads it to know
|
|
546
|
+
* when everything in view is drawn).
|
|
547
|
+
*/
|
|
548
|
+
get hasPendingBuild() {
|
|
549
|
+
return this.chunks.hasPendingBuild;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Whether work remains that will change what this dataset draws without the host doing
|
|
553
|
+
* anything: a chunk the most recent frame left unbuilt (only when it drew this dataset), or
|
|
554
|
+
* a call of the provider waiting for its debounce or its response. A hidden dataset draws
|
|
555
|
+
* nothing, so it has none
|
|
556
|
+
*/
|
|
557
|
+
get hasPendingWork() {
|
|
558
|
+
if (!this.isVisible)
|
|
559
|
+
return false;
|
|
560
|
+
return this.loader?.busy === true || (this.drawnInFrame && this.chunks.hasPendingBuild);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* The start of a frame (called by the manager before anything is drawn)
|
|
564
|
+
*
|
|
565
|
+
* The frame decides the zoom band of the thinning, once, from the zoom it draws with, before
|
|
566
|
+
* any layer draws: every layer of the frame that reads the drawn rows then reads the rows this
|
|
567
|
+
* frame draws. A hidden dataset only records the zoom (its rows follow once it is drawn).
|
|
568
|
+
*
|
|
569
|
+
* @param zoom The zoom the frame draws with
|
|
570
|
+
*/
|
|
571
|
+
beginFrame(zoom) {
|
|
572
|
+
this.frameZoom = zoom;
|
|
573
|
+
this.drawnInFrame = false;
|
|
574
|
+
if (this.isVisible && !this.removed)
|
|
575
|
+
this.syncThinning('frame');
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Draws the chunks that intersect the viewport
|
|
579
|
+
*
|
|
580
|
+
* In retained mode it only draws the retained batches of the chunks that intersect (building
|
|
581
|
+
* them the first time when necessary; `DisplayChunkSet.draw`). In an environment where the
|
|
582
|
+
* retained-mode renderers are not available, features are narrowed one at a time with the
|
|
583
|
+
* spatial index and fed to the batches, as before.
|
|
584
|
+
*
|
|
585
|
+
* Nothing happens while it is hidden. The retained batches are kept, so showing it again takes
|
|
586
|
+
* effect without a build in between.
|
|
587
|
+
*
|
|
588
|
+
* The zoom-dependent factors are evaluated once per frame and the same values are passed to
|
|
589
|
+
* every batch of that frame. At a zoom where the opacity becomes 0, the drawing itself is
|
|
590
|
+
* skipped.
|
|
591
|
+
*/
|
|
592
|
+
draw(target, projectionData, zoom, bounds) {
|
|
593
|
+
if (!this.isVisible)
|
|
594
|
+
return;
|
|
595
|
+
// The rows follow the band of the zoom drawn (the manager normally did it at the start of
|
|
596
|
+
// the frame, with the same zoom, and this finds nothing to do)
|
|
597
|
+
this.frameZoom = zoom;
|
|
598
|
+
this.syncThinning('frame');
|
|
599
|
+
const factors = sanitizeDrawFactors(this.zoomScale?.(zoom));
|
|
600
|
+
// Completely transparent means there is nothing to draw (the immediate path is skipped too)
|
|
601
|
+
if (factors.opacity <= 0)
|
|
602
|
+
return;
|
|
603
|
+
this.drawnInFrame = true;
|
|
604
|
+
// The terrain state of the draw instance this dataset is drawn into
|
|
605
|
+
const terrain = target.getTerrain?.() ?? this.flatTerrain;
|
|
606
|
+
const renderers = target.getRetainedRenderers?.();
|
|
607
|
+
if (renderers) {
|
|
608
|
+
this.chunks.draw({ target, renderers, terrain, projectionData, zoom, bounds, factors });
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
this.drawImmediate(target, projectionData, zoom, bounds);
|
|
612
|
+
}
|
|
613
|
+
drawSelectionHighlight({
|
|
614
|
+
target,
|
|
615
|
+
projectionData,
|
|
616
|
+
zoom,
|
|
617
|
+
bounds,
|
|
618
|
+
selected: this.selected,
|
|
619
|
+
styles: this.chunks.retainedRenderers?.styles,
|
|
620
|
+
terrain,
|
|
621
|
+
datasetId: this.id,
|
|
622
|
+
drapedFills: this.drapedFills,
|
|
623
|
+
prepare: (feature) => this.styler.prepareIfStyled(feature),
|
|
624
|
+
isExternalPoint: this.isExternallyRenderedPoint,
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Returns the frontmost hit (`hitTestDisplayFeatures`)
|
|
629
|
+
*
|
|
630
|
+
* While it is hidden it always misses (what is not visible cannot be grabbed).
|
|
631
|
+
*/
|
|
632
|
+
hitTest(coordinate, toleranceLngLat, test) {
|
|
633
|
+
return this.hitTestRow(coordinate, toleranceLngLat, test)?.feature ?? null;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Returns the frontmost hit with its row (`hitTestDisplayFeatures`)
|
|
637
|
+
*
|
|
638
|
+
* The feature carries the rule colors and the base style. While it is hidden it always misses.
|
|
639
|
+
*/
|
|
640
|
+
hitTestRow(coordinate, toleranceLngLat, test) {
|
|
641
|
+
if (!this.isVisible)
|
|
642
|
+
return null;
|
|
643
|
+
// The hit radius of a point changes with the zoom, so it is computed from the current zoom on
|
|
644
|
+
// every test
|
|
645
|
+
const zoom = this.deps.getZoom();
|
|
646
|
+
const source = this.source;
|
|
647
|
+
const hit = hitTestDisplayFeatures({
|
|
648
|
+
coordinate,
|
|
649
|
+
toleranceLngLat,
|
|
650
|
+
test,
|
|
651
|
+
zoom,
|
|
652
|
+
scale: sanitizeDrawFactors(this.zoomScale?.(zoom)).scale,
|
|
653
|
+
baseStyle: this.styler.base,
|
|
654
|
+
pointDefaults: this.pointDefaults(),
|
|
655
|
+
maxStylePointRadius: source.maxStylePointRadius,
|
|
656
|
+
search: (bounds) => source.index.search(bounds),
|
|
657
|
+
featureAt: (row) => source.featureAt(row),
|
|
658
|
+
isDrawn: (row) => this.thinning.isDrawnRow(row),
|
|
659
|
+
});
|
|
660
|
+
return hit ? { feature: this.styler.prepareIfStyled(hit.feature), row: hit.row } : null;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Schedules the call of the provider according to the changes of the displayed range
|
|
664
|
+
*
|
|
665
|
+
* The range is handled through a key rounded to a zoom stage plus tile coordinates. Nothing
|
|
666
|
+
* happens when it equals the key already applied; when it is in the cache it is applied at
|
|
667
|
+
* once; otherwise the call is debounced. While a fetch is in flight, the previous result keeps
|
|
668
|
+
* being shown.
|
|
669
|
+
*/
|
|
670
|
+
scheduleProviderUpdate(bounds, zoom) {
|
|
671
|
+
if (!this.loader || this.removed)
|
|
672
|
+
return;
|
|
673
|
+
this.loader.schedule(bounds, zoom);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Releases the resources (timers, index, subscriptions)
|
|
677
|
+
*
|
|
678
|
+
* After it is disposed, a response in flight is not applied either (the path called directly
|
|
679
|
+
* from the destroy of the manager is treated the same way).
|
|
680
|
+
*/
|
|
681
|
+
dispose() {
|
|
682
|
+
this.cancelPrefetch?.();
|
|
683
|
+
this.cancelPrefetch = null;
|
|
684
|
+
this.removed = true;
|
|
685
|
+
this.loader?.dispose();
|
|
686
|
+
this.chunks.dispose();
|
|
687
|
+
this.source = new FeatureArraySource([]);
|
|
688
|
+
this.selected = [];
|
|
689
|
+
this.thinning.clear();
|
|
690
|
+
this.styler.clear();
|
|
691
|
+
this.listeners.clear();
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Releases only the GPU resources of retained mode
|
|
695
|
+
*
|
|
696
|
+
* It is called when the rendering layer is disposed (onRemove). The dataset itself stays
|
|
697
|
+
* alive and the chunks are built again on the next draw once the layer is recreated.
|
|
698
|
+
*/
|
|
699
|
+
disposeRetained() {
|
|
700
|
+
this.chunks.releaseRetained();
|
|
701
|
+
}
|
|
702
|
+
// === Internals ===
|
|
703
|
+
/**
|
|
704
|
+
* Default style of a point (the default of core when not injected)
|
|
705
|
+
*/
|
|
706
|
+
pointDefaults() {
|
|
707
|
+
return this.deps.pointStyle ?? DEFAULT_FEATURE_STYLE_CONFIG.point.point;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Draws in immediate mode (the path for an environment without the retained-mode renderers)
|
|
711
|
+
*
|
|
712
|
+
* The frame of the batch is started without passing a layer. The rules have already been
|
|
713
|
+
* evaluated here, so the rule evaluation of the rendering side (FeatureDrawer) is not used.
|
|
714
|
+
*/
|
|
715
|
+
drawImmediate(target, projectionData, zoom, bounds) {
|
|
716
|
+
const rows = this.source.index.search(bounds).filter((row) => this.thinning.isDrawnRow(row));
|
|
717
|
+
let visible = this.styler.prepareAll(this.featuresOf(rows));
|
|
718
|
+
// A point drawn by an external renderer is not drawn by core (without a predicate it passes
|
|
719
|
+
// straight through)
|
|
720
|
+
if (this.externalPointRender) {
|
|
721
|
+
visible = visible.filter((feature) => !this.isExternallyRenderedPoint(feature));
|
|
722
|
+
}
|
|
723
|
+
if (visible.length === 0)
|
|
724
|
+
return;
|
|
725
|
+
target.beginFrame(projectionData, zoom);
|
|
726
|
+
for (const feature of visible) {
|
|
727
|
+
target.processFeature(feature, false);
|
|
728
|
+
}
|
|
729
|
+
target.endFrame();
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Applies new contents (the chunks, the index and the caches come with them)
|
|
733
|
+
*
|
|
734
|
+
* The only triggers for rebuilding the retained batches are this path (setFeatures,
|
|
735
|
+
* setColumnar and applying a provider result) and setStyleRule / setBaseStyle.
|
|
736
|
+
*/
|
|
737
|
+
applySource(source) {
|
|
738
|
+
this.source = source;
|
|
739
|
+
this.styler.clear();
|
|
740
|
+
// An id that disappeared in the replacement is dropped from the selection (an id that
|
|
741
|
+
// remained points at the row of the new contents)
|
|
742
|
+
if (this.selected.length > 0) {
|
|
743
|
+
const selectedIds = new Set(this.selected.map((feature) => feature.id));
|
|
744
|
+
this.selected = source.rowsOfIds(selectedIds).map((row) => source.featureAt(row));
|
|
745
|
+
}
|
|
746
|
+
this.chunks.replace(source.chunks);
|
|
747
|
+
// The winners are picked again together with the replacement (it is done before emit so that
|
|
748
|
+
// a host receiving change does not read the old set). The rows themselves are new
|
|
749
|
+
this.syncDrawnRows();
|
|
750
|
+
this.drawnRowsRevision++;
|
|
751
|
+
this.schedulePrefetch();
|
|
752
|
+
this.emit('change', { reason: 'features' });
|
|
753
|
+
}
|
|
754
|
+
/** Whether a number is a row of the current contents */
|
|
755
|
+
hasRow(row) {
|
|
756
|
+
return Number.isInteger(row) && row >= 0 && row < this.source.length;
|
|
757
|
+
}
|
|
758
|
+
/** The features of rows (without the rule colors) */
|
|
759
|
+
featuresOf(rows) {
|
|
760
|
+
const features = new Array(rows.length);
|
|
761
|
+
for (let i = 0; i < rows.length; i++)
|
|
762
|
+
features[i] = this.source.featureAt(rows[i]);
|
|
763
|
+
return features;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* What the source needs to collect the rows of a chunk
|
|
767
|
+
*
|
|
768
|
+
* @param drawn The rows to collect (a build reads the mask of the moment it starts, never a
|
|
769
|
+
* later one, so the chunk knows exactly which rows its points were built with)
|
|
770
|
+
*/
|
|
771
|
+
collectContext(options, drawn) {
|
|
772
|
+
return {
|
|
773
|
+
...options,
|
|
774
|
+
styler: this.styler,
|
|
775
|
+
isDrawn: drawn === null ? () => true : (row) => drawn[row] === 1,
|
|
776
|
+
styleKey: this.styleRevision,
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
/** The appearance changed: pick the winners again, rebuild every chunk and tell the listeners */
|
|
780
|
+
restyle() {
|
|
781
|
+
this.styleRevision++;
|
|
782
|
+
// The chunks are rebuilt anyway; the change of the drawn rows is part of this change
|
|
783
|
+
if (this.syncDrawnRows())
|
|
784
|
+
this.drawnRowsRevision++;
|
|
785
|
+
this.schedulePrefetch();
|
|
786
|
+
this.chunks.invalidateAll();
|
|
787
|
+
this.emit('change', { reason: 'style' });
|
|
788
|
+
this.deps.requestRepaint();
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* The zoom the band of the thinning is decided from: the zoom of the most recent frame (the
|
|
792
|
+
* zoom the frame draws with; the zoom of the map before the first frame), lowered by the drop
|
|
793
|
+
* of the pitch correction
|
|
794
|
+
*
|
|
795
|
+
* One zoom decides the band. The zoom of the map itself is not read again: the elevation
|
|
796
|
+
* settlement of the terrain changes it without changing the picture, and the band would flip
|
|
797
|
+
* while nothing moved.
|
|
798
|
+
*/
|
|
799
|
+
thinningZoom() {
|
|
800
|
+
return (this.frameZoom ?? this.deps.getZoom()) - this.deps.getPitchZoomDrop();
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Brings the drawn rows up to the band of the zoom (`CollisionThinningState.sync`)
|
|
804
|
+
*
|
|
805
|
+
* @param cause `frame` for a frame about to draw, `change` for a change made by the host
|
|
806
|
+
*/
|
|
807
|
+
syncThinning(cause) {
|
|
808
|
+
if (this.syncDrawnRows())
|
|
809
|
+
this.drawnRowsChanged(cause);
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* `CollisionThinningState.sync` with the zoom of `thinningZoom` (nothing is measured while the
|
|
813
|
+
* thinning is off)
|
|
814
|
+
*
|
|
815
|
+
* @returns Whether the drawn rows changed
|
|
816
|
+
*/
|
|
817
|
+
syncDrawnRows() {
|
|
818
|
+
if (!this.thinning.enabled && !this.thinning.active)
|
|
819
|
+
return false;
|
|
820
|
+
return this.thinning.sync(this.thinningZoom());
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* The drawn rows changed through the thinning (the only place that handles it)
|
|
824
|
+
*
|
|
825
|
+
* Nothing is discarded: the draw rebuilds the point part of each chunk it draws before it
|
|
826
|
+
* draws it (`DisplayChunkSet.draw`). The drawn rows, the hit testing and the queries switch
|
|
827
|
+
* together, and the `change` event (`thinning`) is sent:
|
|
828
|
+
*
|
|
829
|
+
* - `frame`: the frame that picked them draws them; the event is sent after that frame, so a
|
|
830
|
+
* listener never runs in the middle of drawing and reads the rows that are on screen
|
|
831
|
+
* - `change`: a change made by the host (the settings, the zoom factors); the event is sent at
|
|
832
|
+
* once, like the other events of a change, and the next frame draws them
|
|
833
|
+
*/
|
|
834
|
+
drawnRowsChanged(cause) {
|
|
835
|
+
this.drawnRowsRevision++;
|
|
836
|
+
this.schedulePrefetch();
|
|
837
|
+
if (cause === 'change') {
|
|
838
|
+
this.emit('change', { reason: 'thinning' });
|
|
839
|
+
this.deps.requestRepaint();
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
if (this.thinningNoticePending)
|
|
843
|
+
return;
|
|
844
|
+
this.thinningNoticePending = true;
|
|
845
|
+
queueMicrotask(() => {
|
|
846
|
+
this.thinningNoticePending = false;
|
|
847
|
+
if (!this.removed)
|
|
848
|
+
this.emit('change', { reason: 'thinning' });
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Picks the winners of the bands near the current one while the page is idle, in slices that
|
|
853
|
+
* end with the idle period (`CollisionThinningState.prefetch`)
|
|
854
|
+
*/
|
|
855
|
+
schedulePrefetch() {
|
|
856
|
+
if (this.cancelPrefetch || this.removed || !this.thinning.enabled)
|
|
857
|
+
return;
|
|
858
|
+
this.cancelPrefetch = whenIdle((deadline) => {
|
|
859
|
+
this.cancelPrefetch = null;
|
|
860
|
+
if (this.removed)
|
|
861
|
+
return;
|
|
862
|
+
if (this.thinning.prefetch(deadline, idleNow))
|
|
863
|
+
this.schedulePrefetch();
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* The time given to one idle task where `requestIdleCallback` is missing (ms): a slice that
|
|
869
|
+
* does not blow a frame
|
|
870
|
+
*/
|
|
871
|
+
const IDLE_FALLBACK_BUDGET_MS = 8;
|
|
872
|
+
/** How long to wait for an idle period where `requestIdleCallback` is missing (ms) */
|
|
873
|
+
const IDLE_FALLBACK_MS = 100;
|
|
874
|
+
/** The clock the idle deadlines are measured with */
|
|
875
|
+
function idleNow() {
|
|
876
|
+
return typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Runs `task` when the page is idle, with the time at which the idle period ends (a timer and a
|
|
880
|
+
* fixed budget where `requestIdleCallback` is missing)
|
|
881
|
+
*
|
|
882
|
+
* @returns Cancels it
|
|
883
|
+
*/
|
|
884
|
+
function whenIdle(task) {
|
|
885
|
+
if (typeof globalThis.requestIdleCallback === 'function') {
|
|
886
|
+
const handle = globalThis.requestIdleCallback((idle) => task(idleNow() + idle.timeRemaining()));
|
|
887
|
+
return () => globalThis.cancelIdleCallback(handle);
|
|
888
|
+
}
|
|
889
|
+
const handle = setTimeout(() => task(idleNow() + IDLE_FALLBACK_BUDGET_MS), IDLE_FALLBACK_MS);
|
|
890
|
+
return () => clearTimeout(handle);
|
|
891
|
+
}
|