@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,621 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { getDashPattern, getMetersPerPixel, RENDERING_DEFAULTS } from '../../shared/math/index.js';
|
|
4
|
+
import { resolveContentPixelRatio, resolvePixelRatio } from '../../shared/utils/pixel-ratio.js';
|
|
5
|
+
import { getSurfaceTessellationStep } from '../globe-subdivision.js';
|
|
6
|
+
import { calculateLngLatOffset, createProgram, getProjectionTransitionUniform, OFFSET_MODE_GLSL, } from '../shaders/helpers.js';
|
|
7
|
+
import { ProjectionUniformManager } from '../shaders/projection.js';
|
|
8
|
+
import { anchorElevationMeters } from '../terrain/anchor.js';
|
|
9
|
+
import { TerrainContext } from '../terrain/context.js';
|
|
10
|
+
import { densifyPath } from '../terrain/tessellation.js';
|
|
11
|
+
import { screenPixelDistance } from './line/line-geometry.js';
|
|
12
|
+
/** Sentinel meaning that there is no per-vertex elevation (the same convention as the shader) */
|
|
13
|
+
const NO_ELEVATION = -1.0e6;
|
|
14
|
+
/**
|
|
15
|
+
* The upper limit on subdivision points that may be inserted when draping the
|
|
16
|
+
* outline of the selection UI onto the terrain
|
|
17
|
+
*
|
|
18
|
+
* A selection box has only 4 edges, but selecting a wide feature makes one edge
|
|
19
|
+
* hundreds of kilometers long. The step is the node spacing of the terrain mesh,
|
|
20
|
+
* so without an upper limit the number of points diverges.
|
|
21
|
+
*/
|
|
22
|
+
const UI_DENSIFY_MAX_POINTS = 4096;
|
|
23
|
+
// The structure of the vertex data: lng, lat, prevLng, prevLat, nextLng, nextLat, side, distance
|
|
24
|
+
const FLOATS_PER_VERTEX = 9;
|
|
25
|
+
const STRIDE = FLOATS_PER_VERTEX * 4; // 36 bytes
|
|
26
|
+
/**
|
|
27
|
+
* The cumulative distance of every vertex of a path, in CSS px at `zoom` (for dashes)
|
|
28
|
+
*
|
|
29
|
+
* The fragment shader compares it with the dash pattern, which is also in CSS px, so a dash
|
|
30
|
+
* keeps its length on screen at any zoom and latitude (the same rule as the SDF line
|
|
31
|
+
* renderer: the distance is measured on the 512 px Web Mercator world).
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export function strokeDashDistances(coords, zoom) {
|
|
36
|
+
const distances = [];
|
|
37
|
+
let cumulative = 0;
|
|
38
|
+
for (let i = 0; i < coords.length; i++) {
|
|
39
|
+
if (i > 0)
|
|
40
|
+
cumulative += screenPixelDistance(coords[i - 1], coords[i], zoom);
|
|
41
|
+
distances.push(cumulative);
|
|
42
|
+
}
|
|
43
|
+
return distances;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* StrokeRenderer
|
|
47
|
+
*/
|
|
48
|
+
export class StrokeRenderer {
|
|
49
|
+
constructor(map, gl, pixelRatio, terrain = new TerrainContext()) {
|
|
50
|
+
Object.defineProperty(this, "map", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true,
|
|
54
|
+
value: void 0
|
|
55
|
+
});
|
|
56
|
+
Object.defineProperty(this, "gl", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: void 0
|
|
61
|
+
});
|
|
62
|
+
/** The injected rendering ratio (when not injected, it is read from window each time) */
|
|
63
|
+
Object.defineProperty(this, "pixelRatio", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: void 0
|
|
68
|
+
});
|
|
69
|
+
/** The terrain state of the draw instance this renderer belongs to */
|
|
70
|
+
Object.defineProperty(this, "terrain", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true,
|
|
73
|
+
writable: true,
|
|
74
|
+
value: void 0
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(this, "program", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
writable: true,
|
|
80
|
+
value: null
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(this, "variantName", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
configurable: true,
|
|
85
|
+
writable: true,
|
|
86
|
+
value: ''
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(this, "projectionUniformManager", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
configurable: true,
|
|
91
|
+
writable: true,
|
|
92
|
+
value: void 0
|
|
93
|
+
});
|
|
94
|
+
// Uniform locations (specific to this renderer)
|
|
95
|
+
Object.defineProperty(this, "colorLoc", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: null
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(this, "dashArrayLoc", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
configurable: true,
|
|
104
|
+
writable: true,
|
|
105
|
+
value: null
|
|
106
|
+
});
|
|
107
|
+
Object.defineProperty(this, "dashEnabledLoc", {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
configurable: true,
|
|
110
|
+
writable: true,
|
|
111
|
+
value: null
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(this, "widthLoc", {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
configurable: true,
|
|
116
|
+
writable: true,
|
|
117
|
+
value: null
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(this, "viewportLoc", {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
configurable: true,
|
|
122
|
+
writable: true,
|
|
123
|
+
value: null
|
|
124
|
+
});
|
|
125
|
+
Object.defineProperty(this, "miterLimitLoc", {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
configurable: true,
|
|
128
|
+
writable: true,
|
|
129
|
+
value: null
|
|
130
|
+
});
|
|
131
|
+
Object.defineProperty(this, "explicitElevationLoc", {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
writable: true,
|
|
135
|
+
value: null
|
|
136
|
+
});
|
|
137
|
+
// Holds the uniforms for offset mode
|
|
138
|
+
Object.defineProperty(this, "offsetUniforms", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
configurable: true,
|
|
141
|
+
writable: true,
|
|
142
|
+
value: null
|
|
143
|
+
});
|
|
144
|
+
// The VAO and vertex buffer reused across draws (the attributes are set up only once,
|
|
145
|
+
// at construction)
|
|
146
|
+
Object.defineProperty(this, "vao", {
|
|
147
|
+
enumerable: true,
|
|
148
|
+
configurable: true,
|
|
149
|
+
writable: true,
|
|
150
|
+
value: null
|
|
151
|
+
});
|
|
152
|
+
Object.defineProperty(this, "vertexBuffer", {
|
|
153
|
+
enumerable: true,
|
|
154
|
+
configurable: true,
|
|
155
|
+
writable: true,
|
|
156
|
+
value: null
|
|
157
|
+
});
|
|
158
|
+
this.map = map;
|
|
159
|
+
this.gl = gl;
|
|
160
|
+
this.pixelRatio = pixelRatio;
|
|
161
|
+
this.terrain = terrain;
|
|
162
|
+
this.projectionUniformManager = new ProjectionUniformManager(gl, { surface: true, terrain });
|
|
163
|
+
this.vertexBuffer = gl.createBuffer();
|
|
164
|
+
this.vao = gl.createVertexArray();
|
|
165
|
+
this.setupVAO();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Set up the vertex attributes on the VAO
|
|
169
|
+
*
|
|
170
|
+
* The structure of the vertex data: lng, lat, prevLng, prevLat, nextLng, nextLat, side, distance
|
|
171
|
+
* (8 floats = 32 bytes)
|
|
172
|
+
*/
|
|
173
|
+
setupVAO() {
|
|
174
|
+
const gl = this.gl;
|
|
175
|
+
gl.bindVertexArray(this.vao);
|
|
176
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
177
|
+
gl.enableVertexAttribArray(0);
|
|
178
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, STRIDE, 0); // a_pos
|
|
179
|
+
gl.enableVertexAttribArray(1);
|
|
180
|
+
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, STRIDE, 8); // a_prev
|
|
181
|
+
gl.enableVertexAttribArray(2);
|
|
182
|
+
gl.vertexAttribPointer(2, 2, gl.FLOAT, false, STRIDE, 16); // a_next
|
|
183
|
+
gl.enableVertexAttribArray(3);
|
|
184
|
+
gl.vertexAttribPointer(3, 1, gl.FLOAT, false, STRIDE, 24); // a_side
|
|
185
|
+
gl.enableVertexAttribArray(4);
|
|
186
|
+
gl.vertexAttribPointer(4, 1, gl.FLOAT, false, STRIDE, 28); // a_distance
|
|
187
|
+
gl.enableVertexAttribArray(5);
|
|
188
|
+
gl.vertexAttribPointer(5, 1, gl.FLOAT, false, STRIDE, 32); // a_elevation_m
|
|
189
|
+
gl.bindVertexArray(null);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Make sure the shader exists (recreating it when necessary)
|
|
193
|
+
*/
|
|
194
|
+
ensureShader(shaderData) {
|
|
195
|
+
if (this.variantName !== shaderData.variantName) {
|
|
196
|
+
if (this.program) {
|
|
197
|
+
this.gl.deleteProgram(this.program);
|
|
198
|
+
}
|
|
199
|
+
this.program = this.createShaderProgram(shaderData.vertexShaderPrelude, shaderData.define);
|
|
200
|
+
this.variantName = shaderData.variantName;
|
|
201
|
+
// Get the uniform locations specific to this renderer
|
|
202
|
+
this.colorLoc = this.gl.getUniformLocation(this.program, 'u_color');
|
|
203
|
+
this.dashArrayLoc = this.gl.getUniformLocation(this.program, 'u_dashArray');
|
|
204
|
+
this.dashEnabledLoc = this.gl.getUniformLocation(this.program, 'u_dashEnabled');
|
|
205
|
+
this.widthLoc = this.gl.getUniformLocation(this.program, 'u_width');
|
|
206
|
+
this.viewportLoc = this.gl.getUniformLocation(this.program, 'u_viewport');
|
|
207
|
+
this.miterLimitLoc = this.gl.getUniformLocation(this.program, 'u_miter_limit');
|
|
208
|
+
this.explicitElevationLoc = this.gl.getUniformLocation(this.program, 'u_explicit_elevation_m');
|
|
209
|
+
// Get the projection-related uniform locations (shared implementation)
|
|
210
|
+
this.projectionUniformManager.getLocations(this.program);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Set the uniforms for offset mode
|
|
215
|
+
*/
|
|
216
|
+
setOffsetUniforms(uniforms) {
|
|
217
|
+
this.offsetUniforms = uniforms;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create the shader program (offset mode)
|
|
221
|
+
*
|
|
222
|
+
* The same HHAA scheme as SDFLineRenderer:
|
|
223
|
+
* 1. Project the current, previous and next vertices into clip space
|
|
224
|
+
* 2. Compute the direction vectors in screen space and derive the normals
|
|
225
|
+
* 3. Miter computation
|
|
226
|
+
* 4. Apply the offset in screen space
|
|
227
|
+
* 5. Antialiasing in the fragment shader
|
|
228
|
+
*/
|
|
229
|
+
createShaderProgram(prelude, define) {
|
|
230
|
+
const projTransitionUniform = getProjectionTransitionUniform(prelude);
|
|
231
|
+
const vertexSource = `#version 300 es
|
|
232
|
+
${prelude}
|
|
233
|
+
${define}
|
|
234
|
+
${projTransitionUniform}${OFFSET_MODE_GLSL}
|
|
235
|
+
|
|
236
|
+
// Vertex attributes
|
|
237
|
+
// The current vertex (relative coordinates: dLng, dLat - the offset from the center)
|
|
238
|
+
layout(location = 0) in vec2 a_pos;
|
|
239
|
+
layout(location = 1) in vec2 a_prev; // The previous vertex (relative coordinates: dLng, dLat)
|
|
240
|
+
layout(location = 2) in vec2 a_next; // The next vertex (relative coordinates: dLng, dLat)
|
|
241
|
+
layout(location = 3) in float a_side; // +1 (left side) or -1 (right side)
|
|
242
|
+
layout(location = 4) in float a_distance;
|
|
243
|
+
// The elevation (in meters) to place this vertex on. Below the sentinel, the ground
|
|
244
|
+
// elevation is used
|
|
245
|
+
layout(location = 5) in float a_elevation_m;
|
|
246
|
+
|
|
247
|
+
uniform float u_width; // The line width (in pixels)
|
|
248
|
+
uniform vec2 u_viewport; // The viewport size
|
|
249
|
+
uniform float u_miter_limit; // The miter limit
|
|
250
|
+
// The explicit elevation (in meters). When negative, the ground elevation is looked up from the DEM
|
|
251
|
+
uniform float u_explicit_elevation_m;
|
|
252
|
+
|
|
253
|
+
out float v_dist; // The signed distance from the line center (in pixels)
|
|
254
|
+
out float v_width; // Half of the line width (in pixels)
|
|
255
|
+
out float v_distance; // The cumulative distance (for dashes)
|
|
256
|
+
|
|
257
|
+
// Project relative coordinates into clip space in offset mode (using the offset already
|
|
258
|
+
// computed on the CPU side)
|
|
259
|
+
vec4 projectOffset(vec2 offset) {
|
|
260
|
+
return project_position_to_clipspace_from_offset(offset, u_projection_matrix);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Convert clip space coordinates into screen space (pixels)
|
|
264
|
+
vec2 clipToScreen(vec4 clip) {
|
|
265
|
+
// Convert to NDC (perspective division) and then to screen coordinates
|
|
266
|
+
vec2 ndc = clip.xy / clip.w;
|
|
267
|
+
return (ndc * 0.5 + 0.5) * u_viewport;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Convert a screen space offset into a clip space offset
|
|
271
|
+
vec2 screenToClipOffset(vec2 screenOffset, float w) {
|
|
272
|
+
return screenOffset * 2.0 / u_viewport * w;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
void main() {
|
|
276
|
+
// When an explicit elevation is given, place the vertex at that height rather
|
|
277
|
+
// than using the DEM. A "single plate enclosing the feature", such as a selection
|
|
278
|
+
// box, twists in space if a different height is picked up for each vertex
|
|
279
|
+
// (view/ui/selection-ui-drawer.ts)
|
|
280
|
+
if (a_elevation_m > -1.0e5) {
|
|
281
|
+
// The per-vertex elevation (the value the CPU obtained from the ground). It is the
|
|
282
|
+
// same value as in hit testing, so the drawn line and the position that can be
|
|
283
|
+
// grabbed match structurally
|
|
284
|
+
g_anchor_elevation_m = a_elevation_m;
|
|
285
|
+
g_anchor_elevation_on = 1.0;
|
|
286
|
+
} else if (u_explicit_elevation_m > -1.0e5) {
|
|
287
|
+
g_anchor_elevation_m = u_explicit_elevation_m;
|
|
288
|
+
g_anchor_elevation_on = 1.0;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Offset mode: project the current, previous and next vertices into clip space
|
|
292
|
+
// (using the relative coordinates already computed on the CPU side)
|
|
293
|
+
vec4 currentClip = projectOffset(a_pos);
|
|
294
|
+
vec4 prevClip = projectOffset(a_prev);
|
|
295
|
+
vec4 nextClip = projectOffset(a_next);
|
|
296
|
+
|
|
297
|
+
// Convert into screen space
|
|
298
|
+
vec2 currentScreen = clipToScreen(currentClip);
|
|
299
|
+
vec2 prevScreen = clipToScreen(prevClip);
|
|
300
|
+
vec2 nextScreen = clipToScreen(nextClip);
|
|
301
|
+
|
|
302
|
+
// Determine whether the previous and next vertices are the same (start/end point)
|
|
303
|
+
bool hasPrev = distance(a_pos, a_prev) > 0.0000001;
|
|
304
|
+
bool hasNext = distance(a_pos, a_next) > 0.0000001;
|
|
305
|
+
|
|
306
|
+
vec2 normal;
|
|
307
|
+
float miterScale = 1.0;
|
|
308
|
+
|
|
309
|
+
if (!hasPrev && hasNext) {
|
|
310
|
+
// Start point: only the normal of the next segment
|
|
311
|
+
vec2 dir = normalize(nextScreen - currentScreen);
|
|
312
|
+
normal = vec2(-dir.y, dir.x);
|
|
313
|
+
} else if (hasPrev && !hasNext) {
|
|
314
|
+
// End point: only the normal of the previous segment
|
|
315
|
+
vec2 dir = normalize(currentScreen - prevScreen);
|
|
316
|
+
normal = vec2(-dir.y, dir.x);
|
|
317
|
+
} else if (hasPrev && hasNext) {
|
|
318
|
+
// Intermediate point: miter join
|
|
319
|
+
vec2 dir1 = normalize(currentScreen - prevScreen);
|
|
320
|
+
vec2 dir2 = normalize(nextScreen - currentScreen);
|
|
321
|
+
|
|
322
|
+
vec2 normal1 = vec2(-dir1.y, dir1.x);
|
|
323
|
+
vec2 normal2 = vec2(-dir2.y, dir2.x);
|
|
324
|
+
|
|
325
|
+
// The miter normal (the average of the two normals, normalized)
|
|
326
|
+
vec2 avgNormal = normal1 + normal2;
|
|
327
|
+
float avgLen = length(avgNormal);
|
|
328
|
+
|
|
329
|
+
if (avgLen > 0.001) {
|
|
330
|
+
normal = avgNormal / avgLen;
|
|
331
|
+
float cosHalf = dot(normal, normal1);
|
|
332
|
+
if (cosHalf > 0.001) {
|
|
333
|
+
miterScale = 1.0 / cosHalf;
|
|
334
|
+
// Bevel once the miter limit is exceeded
|
|
335
|
+
if (miterScale > u_miter_limit) {
|
|
336
|
+
miterScale = 1.0;
|
|
337
|
+
normal = normal1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
// A 180 degree turn back
|
|
342
|
+
normal = normal1;
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
// A single point (fallback)
|
|
346
|
+
normal = vec2(0.0, 1.0);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// HHAA: expand by w+1 so that partially covered pixels are included as well
|
|
350
|
+
float halfWidth = u_width / 2.0;
|
|
351
|
+
float expandedHalfWidth = halfWidth + 1.0;
|
|
352
|
+
|
|
353
|
+
// The offset in screen space
|
|
354
|
+
vec2 screenOffset = normal * a_side * expandedHalfWidth * miterScale;
|
|
355
|
+
|
|
356
|
+
// Convert into an offset in clip space
|
|
357
|
+
vec2 clipOffset = screenToClipOffset(screenOffset, currentClip.w);
|
|
358
|
+
|
|
359
|
+
// The final position
|
|
360
|
+
gl_Position = currentClip + vec4(clipOffset, 0.0, 0.0);
|
|
361
|
+
|
|
362
|
+
// The values passed to the fragment shader
|
|
363
|
+
v_dist = a_side * expandedHalfWidth; // The signed distance (in pixels)
|
|
364
|
+
v_width = halfWidth; // Half of the line width (in pixels)
|
|
365
|
+
v_distance = a_distance;
|
|
366
|
+
}`;
|
|
367
|
+
const fragmentSource = `#version 300 es
|
|
368
|
+
precision highp float;
|
|
369
|
+
|
|
370
|
+
uniform vec4 u_color;
|
|
371
|
+
uniform vec4 u_dashArray; // [dashLength, gapLength, patternLength, 0]
|
|
372
|
+
uniform float u_dashEnabled;
|
|
373
|
+
|
|
374
|
+
in float v_dist; // The signed distance from the line center (in pixels)
|
|
375
|
+
in float v_width; // Half of the line width (in pixels)
|
|
376
|
+
in float v_distance; // The cumulative distance
|
|
377
|
+
|
|
378
|
+
out vec4 fragColor;
|
|
379
|
+
|
|
380
|
+
// HHAA: compute the intersection of the pixel and the half plane
|
|
381
|
+
float pixelLine(float x) {
|
|
382
|
+
return clamp(x + 0.5, 0.0, 1.0);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
void main() {
|
|
386
|
+
// The dash pattern
|
|
387
|
+
if (u_dashEnabled > 0.5) {
|
|
388
|
+
float patternLength = u_dashArray.z;
|
|
389
|
+
if (patternLength > 0.0) {
|
|
390
|
+
float pos = mod(v_distance, patternLength);
|
|
391
|
+
if (pos > u_dashArray.x) {
|
|
392
|
+
discard;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// HHAA: compute the coverage as the difference of two half planes
|
|
398
|
+
float d = v_dist;
|
|
399
|
+
float w = v_width;
|
|
400
|
+
|
|
401
|
+
float left = pixelLine(d - w);
|
|
402
|
+
float right = pixelLine(d + w);
|
|
403
|
+
float coverage = right - left;
|
|
404
|
+
|
|
405
|
+
fragColor = u_color * coverage;
|
|
406
|
+
}`;
|
|
407
|
+
return createProgram(this.gl, vertexSource, fragmentSource);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Set the projection uniforms (supports offset mode and globe mode)
|
|
411
|
+
* @param projectionData MapLibre's ProjectionData
|
|
412
|
+
* @param zoom The current zoom level (used to switch offset mode)
|
|
413
|
+
*/
|
|
414
|
+
setProjectionUniforms(projectionData, zoom) {
|
|
415
|
+
this.projectionUniformManager.setUniforms(projectionData, zoom, this.offsetUniforms);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Convert the width into pixels
|
|
419
|
+
* When widthUnit is meters, it is converted into pixels based on the zoom level and the latitude
|
|
420
|
+
* On high-DPI displays it is converted into physical pixels, taking devicePixelRatio into account
|
|
421
|
+
*/
|
|
422
|
+
getWidthInPixels(width, widthUnit, zoom, centerLat) {
|
|
423
|
+
if (widthUnit === 'pixels') {
|
|
424
|
+
// Convert CSS pixels into physical pixels (fixed in screen pixels, so renderScale
|
|
425
|
+
// is included)
|
|
426
|
+
return width * resolvePixelRatio(this.pixelRatio);
|
|
427
|
+
}
|
|
428
|
+
// Meter units: convert into pixels
|
|
429
|
+
const tileSize = this.map.transform?.tileSize ?? 512;
|
|
430
|
+
const metersPerPixel = getMetersPerPixel(centerLat, zoom, tileSize);
|
|
431
|
+
// Meter units are converted into physical pixels as well. But a ground dimension
|
|
432
|
+
// already scales with the camera zoom (metersPerPixel moves with the zoom), so
|
|
433
|
+
// renderScale is not multiplied in (see "the two ratios" in
|
|
434
|
+
// shared/utils/pixel-ratio.ts).
|
|
435
|
+
return (width / metersPerPixel) * resolveContentPixelRatio(this.pixelRatio);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Generate the vertex data of a line (triangle strip)
|
|
439
|
+
* Each vertex carries the information of the previous and next vertices
|
|
440
|
+
*/
|
|
441
|
+
generateVertices(lngLatCoords, closed, distances) {
|
|
442
|
+
if (lngLatCoords.length < 2)
|
|
443
|
+
return [];
|
|
444
|
+
const vertices = [];
|
|
445
|
+
const n = lngLatCoords.length;
|
|
446
|
+
for (let i = 0; i < n; i++) {
|
|
447
|
+
const current = lngLatCoords[i];
|
|
448
|
+
const prev = i > 0 ? lngLatCoords[i - 1] : closed ? lngLatCoords[n - 2] : current;
|
|
449
|
+
const next = i < n - 1 ? lngLatCoords[i + 1] : closed ? lngLatCoords[1] : current;
|
|
450
|
+
// The cumulative distance (for the dash pattern, CSS px)
|
|
451
|
+
const cumulativeDistance = distances[i];
|
|
452
|
+
// The vertex on the left side (side = +1)
|
|
453
|
+
vertices.push({
|
|
454
|
+
lng: current.lng,
|
|
455
|
+
lat: current.lat,
|
|
456
|
+
prevLng: prev.lng,
|
|
457
|
+
prevLat: prev.lat,
|
|
458
|
+
nextLng: next.lng,
|
|
459
|
+
nextLat: next.lat,
|
|
460
|
+
side: 1,
|
|
461
|
+
distance: cumulativeDistance,
|
|
462
|
+
});
|
|
463
|
+
// The vertex on the right side (side = -1)
|
|
464
|
+
vertices.push({
|
|
465
|
+
lng: current.lng,
|
|
466
|
+
lat: current.lat,
|
|
467
|
+
prevLng: prev.lng,
|
|
468
|
+
prevLat: prev.lat,
|
|
469
|
+
nextLng: next.lng,
|
|
470
|
+
nextLat: next.lat,
|
|
471
|
+
side: -1,
|
|
472
|
+
distance: cumulativeDistance,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
return vertices;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Draw a line
|
|
479
|
+
*/
|
|
480
|
+
draw(coords, style, options, zoom, projectionData) {
|
|
481
|
+
if (!this.program || coords.length < 2 || !projectionData)
|
|
482
|
+
return;
|
|
483
|
+
const gl = this.gl;
|
|
484
|
+
// On terrain a long edge sinks into valleys, so subdivision points are inserted
|
|
485
|
+
// on a grid. The outlines of the selection box and the handles pass through here
|
|
486
|
+
// too, so they sit at the same elevation as the feature itself. On the globe the same
|
|
487
|
+
// points keep an edge on the path the features are drawn along instead of a chord through
|
|
488
|
+
// the sphere (globe-subdivision.ts).
|
|
489
|
+
// On a flat map without terrain, null is returned and the coordinates are used as they are.
|
|
490
|
+
//
|
|
491
|
+
// This is the one place where the step is not limited to the tessellation region
|
|
492
|
+
// (the intersection of the DEM atlas and the view). If it were, an edge leaving the
|
|
493
|
+
// region would become "a single straight line whose elevation was only sampled at its
|
|
494
|
+
// two ends", and in a tilted view the box would cut diagonally through the terrain and
|
|
495
|
+
// look like a box stretching to a completely different place. This renderer draws only
|
|
496
|
+
// the outlines of selection boxes and handles, which have few edges, so the cost is
|
|
497
|
+
// bounded by an upper limit on the number of points rather than by a region.
|
|
498
|
+
const terrainStep = getSurfaceTessellationStep(this.terrain, 'line');
|
|
499
|
+
const path = terrainStep
|
|
500
|
+
? densifyPath(coords, {
|
|
501
|
+
...terrainStep,
|
|
502
|
+
region: null,
|
|
503
|
+
maxPoints: Math.min(terrainStep.maxPoints, UI_DENSIFY_MAX_POINTS),
|
|
504
|
+
})
|
|
505
|
+
: coords;
|
|
506
|
+
// Convert the WGS84 coordinates into the LngLatCoord form (the Mercator conversion
|
|
507
|
+
// is done in the shader)
|
|
508
|
+
const lngLatCoords = path.map(([lng, lat]) => ({ lng, lat }));
|
|
509
|
+
// Compute the center latitude (for the pixel conversion in the case of meter units)
|
|
510
|
+
const centerLat = coords.reduce((sum, [, lat]) => sum + lat, 0) / coords.length;
|
|
511
|
+
// Convert the line width into pixels
|
|
512
|
+
const widthPixels = this.getWidthInPixels(style.width, options.widthUnit, zoom, centerLat);
|
|
513
|
+
// When following the ground is requested, look up the elevation on the CPU for each
|
|
514
|
+
// point of the path. It comes from the same function as hit testing (anchor
|
|
515
|
+
// projection), so the drawn line and the position that can be grabbed match
|
|
516
|
+
// structurally. Placing it on a single height (elevationMeters) makes only the
|
|
517
|
+
// rendering shift in a tilted view, so it can no longer be grabbed
|
|
518
|
+
const elevations = options.followTerrain
|
|
519
|
+
? new Map(path.map(([lng, lat]) => [
|
|
520
|
+
`${lng},${lat}`,
|
|
521
|
+
anchorElevationMeters(this.terrain, lng, lat),
|
|
522
|
+
]))
|
|
523
|
+
: null;
|
|
524
|
+
const vertices = this.generateVertices(lngLatCoords, options.closed, strokeDashDistances(path, zoom));
|
|
525
|
+
if (vertices.length < 4)
|
|
526
|
+
return;
|
|
527
|
+
// Compute the relative coordinates on the CPU side (offset mode)
|
|
528
|
+
const centerLngLat = this.offsetUniforms?.centerLngLat ?? [0, 0];
|
|
529
|
+
const vertexData = new Float32Array(vertices.length * FLOATS_PER_VERTEX);
|
|
530
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
531
|
+
const base = i * FLOATS_PER_VERTEX;
|
|
532
|
+
// Compute the coordinates relative to the center coordinate (computed at 64-bit
|
|
533
|
+
// precision and then stored as Float32)
|
|
534
|
+
const posOffset = calculateLngLatOffset([vertices[i].lng, vertices[i].lat], centerLngLat);
|
|
535
|
+
const prevOffset = calculateLngLatOffset([vertices[i].prevLng, vertices[i].prevLat], centerLngLat);
|
|
536
|
+
const nextOffset = calculateLngLatOffset([vertices[i].nextLng, vertices[i].nextLat], centerLngLat);
|
|
537
|
+
vertexData[base + 0] = posOffset[0];
|
|
538
|
+
vertexData[base + 1] = posOffset[1];
|
|
539
|
+
vertexData[base + 2] = prevOffset[0];
|
|
540
|
+
vertexData[base + 3] = prevOffset[1];
|
|
541
|
+
vertexData[base + 4] = nextOffset[0];
|
|
542
|
+
vertexData[base + 5] = nextOffset[1];
|
|
543
|
+
vertexData[base + 6] = vertices[i].side;
|
|
544
|
+
vertexData[base + 7] = vertices[i].distance;
|
|
545
|
+
vertexData[base + 8] = elevations
|
|
546
|
+
? (elevations.get(`${vertices[i].lng},${vertices[i].lat}`) ?? NO_ELEVATION)
|
|
547
|
+
: NO_ELEVATION;
|
|
548
|
+
}
|
|
549
|
+
// Transfer the vertex data (the VAO and the vertex buffer are reused)
|
|
550
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
551
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.DYNAMIC_DRAW);
|
|
552
|
+
gl.bindVertexArray(this.vao);
|
|
553
|
+
gl.useProgram(this.program);
|
|
554
|
+
this.setProjectionUniforms(projectionData, zoom);
|
|
555
|
+
// Set the viewport size and the line width
|
|
556
|
+
if (this.viewportLoc) {
|
|
557
|
+
gl.uniform2f(this.viewportLoc, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
|
558
|
+
}
|
|
559
|
+
if (this.widthLoc) {
|
|
560
|
+
gl.uniform1f(this.widthLoc, widthPixels);
|
|
561
|
+
}
|
|
562
|
+
if (this.miterLimitLoc) {
|
|
563
|
+
gl.uniform1f(this.miterLimitLoc, RENDERING_DEFAULTS.MITER_LIMIT);
|
|
564
|
+
}
|
|
565
|
+
if (this.explicitElevationLoc) {
|
|
566
|
+
// The sentinel meaning that there is no explicit elevation. A depth that cannot exist is used
|
|
567
|
+
gl.uniform1f(this.explicitElevationLoc, options.elevationMeters ?? -1.0e6);
|
|
568
|
+
}
|
|
569
|
+
const color = [style.color[0], style.color[1], style.color[2], style.color[3] * style.opacity];
|
|
570
|
+
if (this.colorLoc) {
|
|
571
|
+
gl.uniform4fv(this.colorLoc, color);
|
|
572
|
+
}
|
|
573
|
+
const dashPattern = style.dashArray ?? getDashPattern(style.lineStyle);
|
|
574
|
+
const isDashed = style.lineStyle !== 'solid' && dashPattern.length >= 2;
|
|
575
|
+
if (this.dashEnabledLoc) {
|
|
576
|
+
gl.uniform1f(this.dashEnabledLoc, isDashed ? 1.0 : 0.0);
|
|
577
|
+
}
|
|
578
|
+
if (isDashed && this.dashArrayLoc) {
|
|
579
|
+
const dashLength = dashPattern[0];
|
|
580
|
+
const gapLength = dashPattern[1];
|
|
581
|
+
const patternLength = dashLength + gapLength;
|
|
582
|
+
gl.uniform4fv(this.dashArrayLoc, [dashLength, gapLength, patternLength, 0]);
|
|
583
|
+
}
|
|
584
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length);
|
|
585
|
+
gl.bindVertexArray(null);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Draw a closed path (such as the outer ring of a polygon)
|
|
589
|
+
*/
|
|
590
|
+
drawClosed(coords, style, options, zoom, projectionData) {
|
|
591
|
+
if (coords.length < 3)
|
|
592
|
+
return;
|
|
593
|
+
// When the first and last points are the same, remove the duplicate
|
|
594
|
+
let closedCoords = coords;
|
|
595
|
+
const first = coords[0];
|
|
596
|
+
const last = coords[coords.length - 1];
|
|
597
|
+
if (first[0] === last[0] && first[1] === last[1]) {
|
|
598
|
+
closedCoords = coords.slice(0, -1);
|
|
599
|
+
}
|
|
600
|
+
// Draw it as a closed path
|
|
601
|
+
const loopCoords = [...closedCoords, closedCoords[0]];
|
|
602
|
+
this.draw(loopCoords, style, { ...options, closed: true }, zoom, projectionData);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Dispose of the resources
|
|
606
|
+
*/
|
|
607
|
+
dispose() {
|
|
608
|
+
if (this.program) {
|
|
609
|
+
this.gl.deleteProgram(this.program);
|
|
610
|
+
this.program = null;
|
|
611
|
+
}
|
|
612
|
+
if (this.vao) {
|
|
613
|
+
this.gl.deleteVertexArray(this.vao);
|
|
614
|
+
this.vao = null;
|
|
615
|
+
}
|
|
616
|
+
if (this.vertexBuffer) {
|
|
617
|
+
this.gl.deleteBuffer(this.vertexBuffer);
|
|
618
|
+
this.vertexBuffer = null;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Serial number of the render frame
|
|
5
|
+
*
|
|
6
|
+
* Uniforms are per-program residual state, so a value that does not change
|
|
7
|
+
* within a frame only needs to be written once. Retained-mode rendering
|
|
8
|
+
* rewrites the same projection matrix and the same camera-related values for
|
|
9
|
+
* every chunk (batch), and once there are hundreds of visible chunks this
|
|
10
|
+
* re-setting alone eats up the frame's CPU budget.
|
|
11
|
+
*
|
|
12
|
+
* Each renderer remembers "the value it wrote last time" and skips the gl call
|
|
13
|
+
* when it is unchanged, but to avoid missing an update should the
|
|
14
|
+
* ProjectionData handed over by MapLibre ever change to a design where the
|
|
15
|
+
* same reference is kept and only its contents are rewritten, the memo is
|
|
16
|
+
* always invalidated when the frame changes over. This serial number is the
|
|
17
|
+
* basis for that.
|
|
18
|
+
*
|
|
19
|
+
* The number is advanced by one at the entry point of the custom layer's
|
|
20
|
+
* render. Sharing the number across multiple maps is fine (an advance caused
|
|
21
|
+
* by another map's render only errs on the side of "rewriting more than
|
|
22
|
+
* necessary", and correctness is not harmed).
|
|
23
|
+
*/
|
|
24
|
+
/** The current frame number */
|
|
25
|
+
let renderFrame = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Declares the start of a frame (invalidates the memoization of uniforms)
|
|
28
|
+
*/
|
|
29
|
+
export function beginRenderFrame() {
|
|
30
|
+
renderFrame++;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns the current frame number
|
|
34
|
+
*/
|
|
35
|
+
export function getRenderFrame() {
|
|
36
|
+
return renderFrame;
|
|
37
|
+
}
|