@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,611 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only AND MIT
|
|
3
|
+
/**
|
|
4
|
+
* Shader helpers
|
|
5
|
+
*
|
|
6
|
+
* Utilities for creating and managing WebGL2 shaders
|
|
7
|
+
* Performs the WGS84 -> Mercator -> clip coordinate conversion on the GPU
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Converts WGS84 coordinates to Mercator coordinates (high precision
|
|
11
|
+
* computation on the CPU side)
|
|
12
|
+
*/
|
|
13
|
+
export function lngLatToMercator(lng, lat) {
|
|
14
|
+
const x = (lng + 180) / 360;
|
|
15
|
+
const latRad = (lat * Math.PI) / 180;
|
|
16
|
+
const y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2;
|
|
17
|
+
return [x, y];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The precision every sampler of the engine is read with
|
|
21
|
+
*
|
|
22
|
+
* GLSL ES 3.00 gives `sampler2D` no default precision other than lowp, in both stages, and a
|
|
23
|
+
* texture lookup returns the precision of its sampler. The engine reads coordinates (RGBA32F
|
|
24
|
+
* textures) and 24-bit fixed-point elevations through samplers, which lowp would quantize on
|
|
25
|
+
* GPUs that honour it, so every program declares highp for them. `createProgram` inserts the
|
|
26
|
+
* statement into both stages, so no shader source can leave it out.
|
|
27
|
+
*/
|
|
28
|
+
export const SAMPLER_PRECISION_GLSL = 'precision highp sampler2D;';
|
|
29
|
+
/** The version directive every shader of the engine starts with */
|
|
30
|
+
const VERSION_DIRECTIVE = /^#version 300 es[^\n]*\n/;
|
|
31
|
+
/**
|
|
32
|
+
* Gives a shader source the engine's sampler precision
|
|
33
|
+
*
|
|
34
|
+
* The statement goes right after the `#version 300 es` line (the directive must stay first).
|
|
35
|
+
* A source without that directive is returned unchanged. Repeating the statement in the source
|
|
36
|
+
* itself is harmless.
|
|
37
|
+
*/
|
|
38
|
+
export function withSamplerPrecision(source) {
|
|
39
|
+
const match = VERSION_DIRECTIVE.exec(source);
|
|
40
|
+
if (!match)
|
|
41
|
+
return source;
|
|
42
|
+
return `${match[0]}${SAMPLER_PRECISION_GLSL}\n${source.slice(match[0].length)}`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compiles and links a WebGL2 program from a vertex and a fragment shader source.
|
|
46
|
+
*
|
|
47
|
+
* Every program of the engine is compiled here, so the rules that apply to all of them live
|
|
48
|
+
* here: both stages are given highp samplers (`withSamplerPrecision`).
|
|
49
|
+
*
|
|
50
|
+
* @param gl The WebGL2 context
|
|
51
|
+
* @param vertexSource The vertex shader source, starting with `#version 300 es`
|
|
52
|
+
* @param fragmentSource The fragment shader source, starting with `#version 300 es`
|
|
53
|
+
* @returns The linked program
|
|
54
|
+
* @throws Error with the info log when a shader fails to compile or the program fails to link
|
|
55
|
+
*/
|
|
56
|
+
export function createProgram(gl, vertexSource, fragmentSource) {
|
|
57
|
+
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
58
|
+
gl.shaderSource(vertexShader, withSamplerPrecision(vertexSource));
|
|
59
|
+
gl.compileShader(vertexShader);
|
|
60
|
+
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
|
61
|
+
throw new Error(`Vertex shader error: ${gl.getShaderInfoLog(vertexShader)}`);
|
|
62
|
+
}
|
|
63
|
+
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
64
|
+
gl.shaderSource(fragmentShader, withSamplerPrecision(fragmentSource));
|
|
65
|
+
gl.compileShader(fragmentShader);
|
|
66
|
+
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
|
67
|
+
throw new Error(`Fragment shader error: ${gl.getShaderInfoLog(fragmentShader)}`);
|
|
68
|
+
}
|
|
69
|
+
const program = gl.createProgram();
|
|
70
|
+
gl.attachShader(program, vertexShader);
|
|
71
|
+
gl.attachShader(program, fragmentShader);
|
|
72
|
+
gl.linkProgram(program);
|
|
73
|
+
gl.deleteShader(vertexShader);
|
|
74
|
+
gl.deleteShader(fragmentShader);
|
|
75
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
76
|
+
throw new Error(`Program link error: ${gl.getProgramInfoLog(program)}`);
|
|
77
|
+
}
|
|
78
|
+
return program;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns the declaration of `u_projection_transition` when a maplibre prelude lacks it.
|
|
82
|
+
*
|
|
83
|
+
* MapLibre's globe mode prelude defines u_projection_transition, but the
|
|
84
|
+
* Mercator mode does not. This function inspects the prelude and returns the
|
|
85
|
+
* uniform declaration only when it is needed.
|
|
86
|
+
*
|
|
87
|
+
* @param prelude MapLibre's vertexShaderPrelude
|
|
88
|
+
* @returns The uniform declaration (when needed) or an empty string
|
|
89
|
+
*/
|
|
90
|
+
export function getProjectionTransitionUniform(prelude) {
|
|
91
|
+
return prelude.includes('u_projection_transition')
|
|
92
|
+
? ''
|
|
93
|
+
: 'uniform float u_projection_transition;\n';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* GLSL that reads the elevation (meters) from the DEM atlas
|
|
97
|
+
*
|
|
98
|
+
* Used by both the vertex shader (which lifts the vertices) and the fragment
|
|
99
|
+
* shader (which applies shading to the polygon fill; `terrain-shade.ts`).
|
|
100
|
+
* Because they share the same way of taking samples, the elevation the vertex
|
|
101
|
+
* picks up and the elevation the shading reads are always from the same
|
|
102
|
+
* surface.
|
|
103
|
+
*
|
|
104
|
+
* The uniforms end up declared in both stages, but declarations with the same
|
|
105
|
+
* name and type are bundled into one uniform, so the value only needs to be
|
|
106
|
+
* written once.
|
|
107
|
+
*/
|
|
108
|
+
export const DEM_SAMPLE_GLSL = `
|
|
109
|
+
uniform float u_terrain_on;
|
|
110
|
+
uniform sampler2D u_dem_atlas;
|
|
111
|
+
// xy = the atlas origin (relative to the Mercator coordinates of the viewport center),
|
|
112
|
+
// zw = 1/width, 1/height
|
|
113
|
+
uniform vec4 u_dem_atlas_rect;
|
|
114
|
+
uniform vec2 u_dem_atlas_size;
|
|
115
|
+
// x = the meters -> Mercator z coefficient, y = the lift from the ground surface (meters)
|
|
116
|
+
uniform vec2 u_elevation_params;
|
|
117
|
+
|
|
118
|
+
float dem_decode(vec4 texel) {
|
|
119
|
+
return dot(texel.rgb * 255.0, vec3(65536.0, 256.0, 1.0)) / 16777216.0 * 65536.0 - 32768.0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Reads the elevation (meters) from the atlas with bilinear interpolation
|
|
123
|
+
//
|
|
124
|
+
// Our own subdivision points are placed exactly on the real mesh nodes of the terrain tiles
|
|
125
|
+
// (view/terrain/tiling.ts). At the nodes, the value of the polyline surface MapLibre draws
|
|
126
|
+
// and the bilinear value of the DEM agree, so here it is enough to read the DEM directly.
|
|
127
|
+
// Only the points off the nodes (the vertices of the original feature, the points of its
|
|
128
|
+
// outline) differ between the two, but that difference stays within the sag of a single
|
|
129
|
+
// cell and can be covered by the depth bias.
|
|
130
|
+
float dem_elevation_meters(vec2 mercatorOffset) {
|
|
131
|
+
vec2 uv = clamp((mercatorOffset - u_dem_atlas_rect.xy) * u_dem_atlas_rect.zw, 0.0, 1.0);
|
|
132
|
+
vec2 coord = uv * u_dem_atlas_size - 0.5;
|
|
133
|
+
vec2 f = fract(coord);
|
|
134
|
+
ivec2 c = ivec2(floor(coord));
|
|
135
|
+
ivec2 hi = ivec2(u_dem_atlas_size) - 1;
|
|
136
|
+
float tl = dem_decode(texelFetch(u_dem_atlas, clamp(c, ivec2(0), hi), 0));
|
|
137
|
+
float tr = dem_decode(texelFetch(u_dem_atlas, clamp(c + ivec2(1, 0), ivec2(0), hi), 0));
|
|
138
|
+
float bl = dem_decode(texelFetch(u_dem_atlas, clamp(c + ivec2(0, 1), ivec2(0), hi), 0));
|
|
139
|
+
float br = dem_decode(texelFetch(u_dem_atlas, clamp(c + ivec2(1, 1), ivec2(0), hi), 0));
|
|
140
|
+
return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
/**
|
|
144
|
+
* The GLSL functions that project positions relative to the view center (offset mode), with
|
|
145
|
+
* globe support; include it in a vertex shader after the maplibre prelude.
|
|
146
|
+
*
|
|
147
|
+
* To solve the coordinate precision problem (jitter), it uses the same
|
|
148
|
+
* approach as deck.gl's project module. The projection functions below include
|
|
149
|
+
* a port from deck.gl. See THIRD_PARTY_NOTICES.md for the source and the
|
|
150
|
+
* copyright notice.
|
|
151
|
+
* In globe mode, MapLibre's projectTile() is used.
|
|
152
|
+
*
|
|
153
|
+
* The essential points:
|
|
154
|
+
* 1. Do not add Mercator coordinates inside the shader
|
|
155
|
+
* 2. Handle only relative coordinates (offsets) in the shader
|
|
156
|
+
* 3. Compute the clip coordinates of the center at 64-bit precision on the CPU
|
|
157
|
+
* side and add them at the end
|
|
158
|
+
*
|
|
159
|
+
* The computation flow:
|
|
160
|
+
* 1. position.xyz -= coordinateOrigin // make it relative (Float32 is enough)
|
|
161
|
+
* 2. offset = project_offset(position) // convert degrees -> Mercator units
|
|
162
|
+
* 3. gl_Position = viewProjectionMatrix * offset + projectionCenter
|
|
163
|
+
* ^ projectionCenter is computed at 64-bit precision on the CPU side
|
|
164
|
+
*
|
|
165
|
+
* Globe mode support:
|
|
166
|
+
* - When projectionTransition > 0, MapLibre's projectTile() is used
|
|
167
|
+
* - Globe mode is active at zoom < 12, where the precision problem does not
|
|
168
|
+
* occur
|
|
169
|
+
* - In Mercator mode, the precision problem is solved by offset mode
|
|
170
|
+
*
|
|
171
|
+
* The uniforms used:
|
|
172
|
+
* - u_center_lnglat: the WGS84 coordinates of the viewport center (already
|
|
173
|
+
* rounded to Float32)
|
|
174
|
+
* - u_projection_center: the center coordinates in clip space (computed at
|
|
175
|
+
* 64-bit precision on the CPU side)
|
|
176
|
+
* - u_units_per_degree: the conversion coefficient from degrees to Mercator
|
|
177
|
+
* units (computed on the CPU side)
|
|
178
|
+
* - u_units_per_degree2: the non-linear correction coefficient (corrects the
|
|
179
|
+
* variation due to latitude)
|
|
180
|
+
* - u_projection_transition: defined in MapLibre's prelude (0 = Mercator,
|
|
181
|
+
* 1 = globe)
|
|
182
|
+
*
|
|
183
|
+
* The uniforms for globe mode (defined in MapLibre's prelude):
|
|
184
|
+
* - u_projection_tile_mercator_coords: the Mercator coordinates of the tile
|
|
185
|
+
* - u_projection_clipping_plane: the clipping plane
|
|
186
|
+
* - u_projection_fallback_matrix: the fallback matrix
|
|
187
|
+
*/
|
|
188
|
+
export const OFFSET_MODE_GLSL = `
|
|
189
|
+
#define PI 3.14159265359
|
|
190
|
+
|
|
191
|
+
// The WGS84 coordinates of the viewport center (already rounded to Float32)
|
|
192
|
+
uniform vec2 u_center_lnglat;
|
|
193
|
+
// The Mercator coordinates of the viewport center (Float32)
|
|
194
|
+
uniform vec2 u_center_mercator;
|
|
195
|
+
// The center coordinates in clip space (computed at 64-bit precision on the CPU side)
|
|
196
|
+
uniform vec4 u_projection_center;
|
|
197
|
+
// The conversion coefficient from degrees to Mercator units
|
|
198
|
+
uniform vec3 u_units_per_degree;
|
|
199
|
+
// The non-linear correction coefficient (the variation due to latitude)
|
|
200
|
+
uniform vec3 u_units_per_degree2;
|
|
201
|
+
|
|
202
|
+
// The offset mode flag (1 = offset mode, 0 = the projectTile approach)
|
|
203
|
+
// Offset mode is used to solve the precision problem at high zoom levels (around zoom >= 12)
|
|
204
|
+
// At low zoom levels, or when unset (default 0), projectTile() is used
|
|
205
|
+
// Offset mode computes with coordinates relative to the viewport center, so with data
|
|
206
|
+
// covering a wide area the error grows at vertices far from the center
|
|
207
|
+
uniform float u_use_offset_mode;
|
|
208
|
+
|
|
209
|
+
// The reference coordinates of a retained batch - the linearization center (the camera
|
|
210
|
+
// center). Immediate mode uses (0,0)
|
|
211
|
+
// The vertices of a retained batch are relative to the reference coordinates, so the
|
|
212
|
+
// difference needed to align the linearization center with the camera center is received here
|
|
213
|
+
uniform vec2 u_origin_shift;
|
|
214
|
+
|
|
215
|
+
// Note: u_projection_transition is defined in MapLibre's globe mode prelude
|
|
216
|
+
// It is not defined in Mercator mode, so it must be added dynamically using
|
|
217
|
+
// getProjectionTransitionUniform() (exported from shader-helpers.ts)
|
|
218
|
+
|
|
219
|
+
// ---- terrain -------------------------------------------------------------
|
|
220
|
+
//
|
|
221
|
+
// Only when terrain is enabled (u_terrain_on = 1) is the elevation of the ground surface
|
|
222
|
+
// added to the vertex.
|
|
223
|
+
// When it is 0, the computed result is exactly identical to before terrain was introduced
|
|
224
|
+
// (the guarantee of zero regression).
|
|
225
|
+
//
|
|
226
|
+
// The elevation is looked up from the DEM atlas (view/terrain/dem-atlas.ts). The atlas is
|
|
227
|
+
// RGBA8 with the elevation in meters packed into a 24-bit fixed-point value, and the
|
|
228
|
+
// bilinear interpolation is done by hand (because encoded values cannot be interpolated
|
|
229
|
+
// linearly; the same treatment as MapLibre's terrain prelude).
|
|
230
|
+
//
|
|
231
|
+
// The unit of the amount added to the vertex is always Mercator
|
|
232
|
+
// (the same value as MercatorCoordinate.fromLngLat(lngLat, meters).z).
|
|
233
|
+
// Adding meters directly is wrong.
|
|
234
|
+
` +
|
|
235
|
+
DEM_SAMPLE_GLSL +
|
|
236
|
+
`
|
|
237
|
+
// ---- The explicit elevation of an anchor ----------------------------------
|
|
238
|
+
//
|
|
239
|
+
// UI that is determined by a single point, such as points, vertex handles and midpoint
|
|
240
|
+
// handles, does not look the elevation up from the DEM atlas but receives the value the CPU
|
|
241
|
+
// computed. It therefore goes through exactly the same elevation and the same matrix as hit
|
|
242
|
+
// testing (on the CPU), so the drawn position and the hit region agree structurally
|
|
243
|
+
// (see view/terrain/anchor.ts).
|
|
244
|
+
//
|
|
245
|
+
// The caller assigns to these two before calling project_*. Draws that do not assign
|
|
246
|
+
// (polygons and lines) look the value up from the atlas as before, so the results of the
|
|
247
|
+
// existing paths do not change.
|
|
248
|
+
//
|
|
249
|
+
// The lift (u_elevation_params.y) is not added. That exists for rendering reasons, to avoid
|
|
250
|
+
// Z-fighting with the terrain mesh; anchors are drawn without the depth test so it is not
|
|
251
|
+
// needed, and adding it would put them out of step with the projection on the CPU side.
|
|
252
|
+
float g_anchor_elevation_m = 0.0;
|
|
253
|
+
float g_anchor_elevation_on = 0.0;
|
|
254
|
+
|
|
255
|
+
// The elevation at Mercator coordinates relative to the center (in Mercator units, lift
|
|
256
|
+
// included)
|
|
257
|
+
float terrain_elevation_from_offset(vec2 mercatorOffset) {
|
|
258
|
+
if (u_terrain_on < 0.5) return 0.0;
|
|
259
|
+
if (g_anchor_elevation_on > 0.5) return g_anchor_elevation_m * u_elevation_params.x;
|
|
260
|
+
return (dem_elevation_meters(mercatorOffset) + u_elevation_params.y) * u_elevation_params.x;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// The elevation at absolute Mercator coordinates (in Mercator units, lift included)
|
|
264
|
+
float terrain_elevation_at(vec2 mercator) {
|
|
265
|
+
if (u_terrain_on < 0.5) return 0.0;
|
|
266
|
+
if (g_anchor_elevation_on > 0.5) return g_anchor_elevation_m * u_elevation_params.x;
|
|
267
|
+
return terrain_elevation_from_offset(mercator - u_center_mercator);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Converts WGS84 coordinates to Mercator coordinates (the 0-1 range)
|
|
271
|
+
vec2 lngLatToMercator(vec2 lngLat) {
|
|
272
|
+
float x = (lngLat.x + 180.0) / 360.0;
|
|
273
|
+
float latRad = lngLat.y * PI / 180.0;
|
|
274
|
+
float y = (1.0 - log(tan(latRad) + 1.0 / cos(latRad)) / PI) / 2.0;
|
|
275
|
+
return vec2(x, y);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Converts offset coordinates into the units of the common space (Mercator)
|
|
279
|
+
// A port of deck.gl's project_offset_
|
|
280
|
+
// See THIRD_PARTY_NOTICES.md for the source and the copyright notice
|
|
281
|
+
vec3 project_offset(vec3 offset) {
|
|
282
|
+
float dy = offset.y;
|
|
283
|
+
vec3 unitsPerDegree = u_units_per_degree + u_units_per_degree2 * dy;
|
|
284
|
+
return offset * unitsPerDegree;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Converts WGS84 coordinates to relative coordinates and projects them into clip space
|
|
288
|
+
// (for Mercator mode)
|
|
289
|
+
// A port of deck.gl's project_position + project_common_position_to_clipspace
|
|
290
|
+
// See THIRD_PARTY_NOTICES.md for the source and the copyright notice
|
|
291
|
+
vec4 project_position_mercator(vec2 lngLat, mat4 viewProjectionMatrix) {
|
|
292
|
+
// 1. Compute the coordinates relative to the center (Float32 has enough precision)
|
|
293
|
+
vec2 lngLatOffset = lngLat - u_center_lnglat;
|
|
294
|
+
|
|
295
|
+
// 2. Convert the relative coordinates into the units of the common space
|
|
296
|
+
vec3 mercatorOffset = project_offset(vec3(lngLatOffset, 0.0));
|
|
297
|
+
|
|
298
|
+
// 2.5 Put the terrain elevation into z. u_projection_center is computed at z=0, but the
|
|
299
|
+
// matrix is linear, so composing it by adding only the z term is correct
|
|
300
|
+
mercatorOffset.z = terrain_elevation_from_offset(mercatorOffset.xy);
|
|
301
|
+
|
|
302
|
+
// 3. viewProjectionMatrix * offset + projectionCenter
|
|
303
|
+
// Setting w=0 keeps the fourth column of the matrix (the translation) from having an
|
|
304
|
+
// effect
|
|
305
|
+
// The translation comes only from projectionCenter
|
|
306
|
+
vec4 offset = vec4(mercatorOffset, 0.0);
|
|
307
|
+
return viewProjectionMatrix * offset + u_projection_center;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Projects relative coordinates (already computed on the CPU side) into clip space
|
|
311
|
+
// (for Mercator mode, the high precision version)
|
|
312
|
+
// The offset from the center is computed at 64-bit precision on the CPU side and the result
|
|
313
|
+
// is received here
|
|
314
|
+
// This keeps the precision loss from the conversion to Float32 to a minimum
|
|
315
|
+
// The clip conversion is a port of deck.gl's project_common_position_to_clipspace
|
|
316
|
+
// See THIRD_PARTY_NOTICES.md for the source and the copyright notice
|
|
317
|
+
vec4 project_offset_to_clipspace(vec2 lngLatOffset, mat4 viewProjectionMatrix) {
|
|
318
|
+
// Convert the relative coordinates into the units of the common space
|
|
319
|
+
vec3 mercatorOffset = project_offset(vec3(lngLatOffset, 0.0));
|
|
320
|
+
|
|
321
|
+
// Put the terrain elevation into z (0 when terrain is disabled)
|
|
322
|
+
mercatorOffset.z = terrain_elevation_from_offset(mercatorOffset.xy);
|
|
323
|
+
|
|
324
|
+
// viewProjectionMatrix * offset + projectionCenter
|
|
325
|
+
vec4 offset = vec4(mercatorOffset, 0.0);
|
|
326
|
+
return viewProjectionMatrix * offset + u_projection_center;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Projects WGS84 coordinates into clip space
|
|
330
|
+
// Switches automatically between globe mode, low zoom and high zoom
|
|
331
|
+
// - Globe mode (u_projection_transition > 0): uses MapLibre's projectTile()
|
|
332
|
+
// - Mercator mode with u_use_offset_mode=0: uses projectTile() (for low zoom)
|
|
333
|
+
// - Mercator mode with u_use_offset_mode=1: solves the precision problem with offset mode
|
|
334
|
+
// (for high zoom)
|
|
335
|
+
vec4 project_position_to_clipspace(vec2 lngLat, mat4 viewProjectionMatrix) {
|
|
336
|
+
// In globe mode, use MapLibre's projectTile()
|
|
337
|
+
// u_projection_transition is defined in MapLibre's prelude
|
|
338
|
+
if (u_projection_transition > 0.0) {
|
|
339
|
+
// Convert WGS84 -> Mercator and hand it to projectTile()
|
|
340
|
+
vec2 mercator = lngLatToMercator(lngLat);
|
|
341
|
+
return projectTileWithElevation(mercator, terrain_elevation_at(mercator));
|
|
342
|
+
}
|
|
343
|
+
// Used only when offset mode is enabled
|
|
344
|
+
// It solves the precision problem at high zoom levels, but with data covering a wide
|
|
345
|
+
// area the error grows at vertices far from the center
|
|
346
|
+
if (u_use_offset_mode > 0.5) {
|
|
347
|
+
return project_position_mercator(lngLat, viewProjectionMatrix);
|
|
348
|
+
}
|
|
349
|
+
// Default: use MapLibre's projectTile()
|
|
350
|
+
// It is safe because the precision problem does not occur at low zoom levels
|
|
351
|
+
// (projectTileWithElevation at elevation 0 gives the same result as projectTile)
|
|
352
|
+
vec2 mercator = lngLatToMercator(lngLat);
|
|
353
|
+
return projectTileWithElevation(mercator, terrain_elevation_at(mercator));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Projects relative coordinates (already computed at 64-bit precision on the CPU side) into
|
|
357
|
+
// clip space (the high precision version)
|
|
358
|
+
// The offset from the center is computed at 64-bit precision on the CPU side and the result
|
|
359
|
+
// is received here
|
|
360
|
+
// This makes it possible to draw at the correct position even at high zoom levels
|
|
361
|
+
// - Globe mode: restores the absolute coordinates from relative + center coordinates and
|
|
362
|
+
// uses projectTile()
|
|
363
|
+
// - Mercator mode with u_use_offset_mode=1: high precision drawing with offset mode
|
|
364
|
+
// - Otherwise: restores the absolute coordinates and uses projectTile()
|
|
365
|
+
vec4 project_position_to_clipspace_from_offset(vec2 lngLatOffset, mat4 viewProjectionMatrix) {
|
|
366
|
+
// Add the gap between the reference coordinates and the linearization center exactly
|
|
367
|
+
// once here
|
|
368
|
+
// (adding it inside project_offset_to_clipspace would double-count it)
|
|
369
|
+
vec2 shifted = lngLatOffset + u_origin_shift;
|
|
370
|
+
|
|
371
|
+
// In globe mode, use MapLibre's projectTile()
|
|
372
|
+
if (u_projection_transition > 0.0) {
|
|
373
|
+
// Restore the absolute coordinates from the relative ones (Float32 precision, but
|
|
374
|
+
// acceptable in globe mode)
|
|
375
|
+
vec2 lngLat = shifted + u_center_lnglat;
|
|
376
|
+
vec2 mercator = lngLatToMercator(lngLat);
|
|
377
|
+
return projectTileWithElevation(mercator, terrain_elevation_at(mercator));
|
|
378
|
+
}
|
|
379
|
+
// Used only when offset mode is enabled
|
|
380
|
+
if (u_use_offset_mode > 0.5) {
|
|
381
|
+
return project_offset_to_clipspace(shifted, viewProjectionMatrix);
|
|
382
|
+
}
|
|
383
|
+
// Default: restore the absolute coordinates and use MapLibre's projectTile()
|
|
384
|
+
vec2 lngLat = shifted + u_center_lnglat;
|
|
385
|
+
vec2 mercator = lngLatToMercator(lngLat);
|
|
386
|
+
return projectTileWithElevation(mercator, terrain_elevation_at(mercator));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// The Mercator coordinates relative to the center (used as the sample position of the
|
|
390
|
+
// shading)
|
|
391
|
+
//
|
|
392
|
+
// It is exactly the quantity this vertex uses when looking up the elevation
|
|
393
|
+
// (the argument of terrain_elevation_from_offset). If only the shading were derived a
|
|
394
|
+
// different way, the elevation the vertex picks up and the elevation the fill reads would
|
|
395
|
+
// diverge. The branches are evaluated in the same order as the projection.
|
|
396
|
+
vec2 shade_mercator_offset(vec2 lngLatOffset) {
|
|
397
|
+
vec2 shifted = lngLatOffset + u_origin_shift;
|
|
398
|
+
if (u_projection_transition > 0.0 || u_use_offset_mode <= 0.5) {
|
|
399
|
+
return lngLatToMercator(shifted + u_center_lnglat) - u_center_mercator;
|
|
400
|
+
}
|
|
401
|
+
return project_offset(vec3(shifted, 0.0)).xy;
|
|
402
|
+
}
|
|
403
|
+
`;
|
|
404
|
+
/**
|
|
405
|
+
* Computes the offset-mode uniforms for a view center, to pass to `setOffsetUniforms` of the
|
|
406
|
+
* renderers.
|
|
407
|
+
*
|
|
408
|
+
* The uniforms for globe mode are obtained directly from ProjectionData, so
|
|
409
|
+
* this function performs only the offset computation for the Mercator
|
|
410
|
+
* projection.
|
|
411
|
+
*
|
|
412
|
+
* @param centerLngLat The view center `[lng, lat]` in degrees
|
|
413
|
+
* @param mainMatrix MapLibre's projection matrix (column-major 4x4)
|
|
414
|
+
* @returns The uniform values for offset mode
|
|
415
|
+
*/
|
|
416
|
+
export function calculateOffsetUniforms(centerLngLat, mainMatrix) {
|
|
417
|
+
// 1. Round the center coordinates to Float32 (the same procedure as deck.gl)
|
|
418
|
+
const centerLng = Math.fround(centerLngLat[0]);
|
|
419
|
+
const centerLat = Math.fround(centerLngLat[1]);
|
|
420
|
+
// 2. Compute the Mercator coordinates of the center at 64-bit precision
|
|
421
|
+
const [centerMercX, centerMercY] = lngLatToMercator(centerLng, centerLat);
|
|
422
|
+
// 3. Convert the Mercator coordinates of the center into clip space (matrix computation
|
|
423
|
+
// at 64-bit precision)
|
|
424
|
+
// gl_Position = mainMatrix * [mercX, mercY, 0, 1]
|
|
425
|
+
const m = mainMatrix;
|
|
426
|
+
const projectionCenter = [
|
|
427
|
+
m[0] * centerMercX + m[4] * centerMercY + m[12],
|
|
428
|
+
m[1] * centerMercX + m[5] * centerMercY + m[13],
|
|
429
|
+
m[2] * centerMercX + m[6] * centerMercY + m[14],
|
|
430
|
+
m[3] * centerMercX + m[7] * centerMercY + m[15],
|
|
431
|
+
];
|
|
432
|
+
// 4. Compute the conversion coefficient from degrees to Mercator units
|
|
433
|
+
// The Mercator projection: x = (lng + 180) / 360
|
|
434
|
+
// y = (1 - log(tan(lat) + sec(lat)) / PI) / 2
|
|
435
|
+
// dx/dlng = 1/360
|
|
436
|
+
// dy/dlat = -1 / (360 * cos(lat)) (linear approximation)
|
|
437
|
+
const latRad = (centerLat * Math.PI) / 180;
|
|
438
|
+
const cosLat = Math.cos(latRad);
|
|
439
|
+
const unitsPerDegreeX = 1 / 360;
|
|
440
|
+
const unitsPerDegreeY = -1 / (360 * cosLat);
|
|
441
|
+
// 5. The non-linear correction coefficient (the variation due to latitude)
|
|
442
|
+
// Corresponds to deck.gl's unitsPerDegree2 and corrects the distortion at high latitudes
|
|
443
|
+
//
|
|
444
|
+
// A port of getDistanceScales (highPrecision) from @math.gl/web-mercator:
|
|
445
|
+
// latCosine2 = DEGREES_TO_RADIANS * tan(lat) / cos(lat)
|
|
446
|
+
// unitsPerDegree2Y = (unitsPerDegreeX * latCosine2) / 2
|
|
447
|
+
// See THIRD_PARTY_NOTICES.md for the source and the copyright notice
|
|
448
|
+
//
|
|
449
|
+
// In this project the Y axis is flipped (a tile coordinate system), so the sign is flipped
|
|
450
|
+
const latCosine2 = ((Math.PI / 180) * Math.tan(latRad)) / cosLat;
|
|
451
|
+
const unitsPerDegree2Y = -(unitsPerDegreeX * latCosine2) / 2;
|
|
452
|
+
return {
|
|
453
|
+
centerLngLat: [centerLng, centerLat],
|
|
454
|
+
centerLngLat64: [centerLngLat[0], centerLngLat[1]], // keeps the original 64-bit values
|
|
455
|
+
centerMercator: [centerMercX, centerMercY],
|
|
456
|
+
projectionCenter,
|
|
457
|
+
unitsPerDegree: [unitsPerDegreeX, unitsPerDegreeY, 1],
|
|
458
|
+
unitsPerDegree2: [0, unitsPerDegree2Y, 0],
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* The projection matrix of the copy of the world moved east by `lngShift` degrees
|
|
463
|
+
*
|
|
464
|
+
* A view across the antimeridian draws the stored features a second time, moved by 360
|
|
465
|
+
* degrees. That copy is drawn as a virtual camera: the center moves by -lngShift (so every
|
|
466
|
+
* offset the CPU computes against it comes out shifted, in 64 bits) and the matrix moves by
|
|
467
|
+
* +lngShift (M' = M * T(lngShift / 360) in Mercator units), so the two cancel for the camera
|
|
468
|
+
* and the copy lands next to the stored one. Passing both to `calculateOffsetUniforms` gives
|
|
469
|
+
* the same projection center as the real camera, and the absolute path of the shader
|
|
470
|
+
* (projectTile at low zoom) moves by the same amount through the matrix. It is one formula
|
|
471
|
+
* for the CPU and the GPU.
|
|
472
|
+
*
|
|
473
|
+
* @param matrix The projection matrix (column-major 4x4)
|
|
474
|
+
* @param lngShift The shift in degrees of longitude (a multiple of 360)
|
|
475
|
+
* @returns The translated matrix (64-bit values)
|
|
476
|
+
*/
|
|
477
|
+
export function translateMatrixByLongitude(matrix, lngShift) {
|
|
478
|
+
const out = Array.from({ length: 16 }, (_, i) => matrix[i]);
|
|
479
|
+
const dx = lngShift / 360;
|
|
480
|
+
for (let i = 0; i < 4; i++)
|
|
481
|
+
out[12 + i] = matrix[12 + i] + dx * matrix[i];
|
|
482
|
+
return out;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Returns a position relative to the view center in degrees, computed at 64-bit precision
|
|
486
|
+
* so that it survives Float32.
|
|
487
|
+
*
|
|
488
|
+
* Used to solve the coordinate precision problem at high zoom levels.
|
|
489
|
+
* Converting absolute coordinates to Float32 loses precision, but relative
|
|
490
|
+
* coordinates (small values) keep enough precision even in Float32.
|
|
491
|
+
*
|
|
492
|
+
* @param lngLat The WGS84 coordinates [lng, lat]
|
|
493
|
+
* @param centerLngLat The center coordinates [lng, lat] (64-bit precision)
|
|
494
|
+
* @returns The relative coordinates [dLng, dLat] (Float32 has enough precision)
|
|
495
|
+
*/
|
|
496
|
+
export function calculateLngLatOffset(lngLat, centerLngLat) {
|
|
497
|
+
// The subtraction is done at 64-bit precision, and since the result is a small value the
|
|
498
|
+
// precision is kept even in Float32
|
|
499
|
+
return [lngLat[0] - centerLngLat[0], lngLat[1] - centerLngLat[1]];
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Creates the offset mode coordinate transform (performs the same computation
|
|
503
|
+
* as the shader on the CPU side)
|
|
504
|
+
*
|
|
505
|
+
* The computation flow of the shader:
|
|
506
|
+
* 1. lngLatOffset = lngLat - u_center_lnglat
|
|
507
|
+
* 2. mercatorOffset = project_offset(lngLatOffset)
|
|
508
|
+
* = lngLatOffset * (u_units_per_degree + u_units_per_degree2 * lngLatOffset.y)
|
|
509
|
+
* 3. clipPos = viewProjectionMatrix * vec4(mercatorOffset, 0) + u_projection_center
|
|
510
|
+
* 4. ndc = clipPos.xy / clipPos.w
|
|
511
|
+
* 5. screen = (ndc * 0.5 + 0.5) * viewport
|
|
512
|
+
*
|
|
513
|
+
* @param uniforms The uniform values for offset mode
|
|
514
|
+
* @param mainMatrix MapLibre's projection matrix
|
|
515
|
+
* @param viewport The viewport information
|
|
516
|
+
*/
|
|
517
|
+
export function createOffsetModeTransform(uniforms, mainMatrix, viewport) {
|
|
518
|
+
const m = mainMatrix;
|
|
519
|
+
// Use the center coordinates already rounded to Float32 (to stay consistent with
|
|
520
|
+
// projectionCenter)
|
|
521
|
+
const { centerLngLat, projectionCenter, unitsPerDegree, unitsPerDegree2 } = uniforms;
|
|
522
|
+
return {
|
|
523
|
+
project: (lngLat) => {
|
|
524
|
+
// 1. Compute the relative coordinates (using the center coordinates rounded to Float32)
|
|
525
|
+
const lngOffset = lngLat[0] - centerLngLat[0];
|
|
526
|
+
const latOffset = lngLat[1] - centerLngLat[1];
|
|
527
|
+
// 2. Convert into a Mercator offset (equivalent to the shader's project_offset)
|
|
528
|
+
const upd = [
|
|
529
|
+
unitsPerDegree[0] + unitsPerDegree2[0] * latOffset,
|
|
530
|
+
unitsPerDegree[1] + unitsPerDegree2[1] * latOffset,
|
|
531
|
+
unitsPerDegree[2] + unitsPerDegree2[2] * latOffset,
|
|
532
|
+
];
|
|
533
|
+
const mercX = lngOffset * upd[0];
|
|
534
|
+
const mercY = latOffset * upd[1];
|
|
535
|
+
// 3. viewProjectionMatrix * offset + projectionCenter
|
|
536
|
+
// offset.w = 0, so the fourth column of the matrix has no effect
|
|
537
|
+
const clipX = m[0] * mercX + m[4] * mercY + projectionCenter[0];
|
|
538
|
+
const clipY = m[1] * mercX + m[5] * mercY + projectionCenter[1];
|
|
539
|
+
const clipW = m[3] * mercX + m[7] * mercY + projectionCenter[3];
|
|
540
|
+
// 4. Convert to NDC
|
|
541
|
+
const ndcX = clipX / clipW;
|
|
542
|
+
const ndcY = clipY / clipW;
|
|
543
|
+
// 5. Convert to screen coordinates
|
|
544
|
+
const screenX = (ndcX * 0.5 + 0.5) * viewport.width;
|
|
545
|
+
const screenY = (1 - (ndcY * 0.5 + 0.5)) * viewport.height; // the Y axis is flipped
|
|
546
|
+
return { x: screenX, y: screenY };
|
|
547
|
+
},
|
|
548
|
+
unproject: (point) => {
|
|
549
|
+
// The inverse transform: screen coordinates -> geographic coordinates
|
|
550
|
+
// 1. Screen coordinates -> NDC
|
|
551
|
+
const ndcX = (point.x / viewport.width) * 2 - 1;
|
|
552
|
+
const ndcY = -((point.y / viewport.height) * 2 - 1); // the Y axis is flipped
|
|
553
|
+
// The inverse transform is non-linear, so an approximate solution is found with
|
|
554
|
+
// Newton's method
|
|
555
|
+
// A linear approximation is used as the initial value
|
|
556
|
+
// Estimate the initial clipW using the w component of projectionCenter
|
|
557
|
+
const initialClipW = projectionCenter[3];
|
|
558
|
+
// clipX = ndcX * clipW, clipY = ndcY * clipW
|
|
559
|
+
// clipX = m[0]*mercX + m[4]*mercY + projectionCenter[0]
|
|
560
|
+
// clipY = m[1]*mercX + m[5]*mercY + projectionCenter[1]
|
|
561
|
+
// clipW = m[3]*mercX + m[7]*mercY + projectionCenter[3]
|
|
562
|
+
// Initial estimate: solve the linear equations taking clipW ~= projectionCenter[3]
|
|
563
|
+
const clipX0 = ndcX * initialClipW;
|
|
564
|
+
const clipY0 = ndcY * initialClipW;
|
|
565
|
+
// Find mercX and mercY (a 2x2 system of simultaneous equations)
|
|
566
|
+
// m[0]*mercX + m[4]*mercY = clipX0 - projectionCenter[0]
|
|
567
|
+
// m[1]*mercX + m[5]*mercY = clipY0 - projectionCenter[1]
|
|
568
|
+
const det = m[0] * m[5] - m[1] * m[4];
|
|
569
|
+
if (Math.abs(det) < 1e-10) {
|
|
570
|
+
// Return the center for a singular matrix
|
|
571
|
+
return { lng: centerLngLat[0], lat: centerLngLat[1] };
|
|
572
|
+
}
|
|
573
|
+
const bx = clipX0 - projectionCenter[0];
|
|
574
|
+
const by = clipY0 - projectionCenter[1];
|
|
575
|
+
const mercX = (m[5] * bx - m[4] * by) / det;
|
|
576
|
+
const mercY = (m[0] * by - m[1] * bx) / det;
|
|
577
|
+
// Mercator offset -> geographic coordinate offset (the inverse transform)
|
|
578
|
+
// mercX = lngOffset * unitsPerDegree[0]
|
|
579
|
+
// mercY = latOffset * (unitsPerDegree[1] + unitsPerDegree2[1] * latOffset)
|
|
580
|
+
// Solve the quadratic equation
|
|
581
|
+
const lngOffset = mercX / unitsPerDegree[0];
|
|
582
|
+
// The quadratic equation in latOffset:
|
|
583
|
+
// unitsPerDegree2[1] * latOffset^2 + unitsPerDegree[1] * latOffset - mercY = 0
|
|
584
|
+
let latOffset;
|
|
585
|
+
if (Math.abs(unitsPerDegree2[1]) < 1e-15) {
|
|
586
|
+
// Linear approximation
|
|
587
|
+
latOffset = mercY / unitsPerDegree[1];
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
const a = unitsPerDegree2[1];
|
|
591
|
+
const b = unitsPerDegree[1];
|
|
592
|
+
const c = -mercY;
|
|
593
|
+
const discriminant = b * b - 4 * a * c;
|
|
594
|
+
if (discriminant < 0) {
|
|
595
|
+
latOffset = mercY / unitsPerDegree[1]; // fallback
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
// Choosing the sign: pick the smaller solution (the one closer to the center)
|
|
599
|
+
const sqrtD = Math.sqrt(discriminant);
|
|
600
|
+
const lat1 = (-b + sqrtD) / (2 * a);
|
|
601
|
+
const lat2 = (-b - sqrtD) / (2 * a);
|
|
602
|
+
latOffset = Math.abs(lat1) < Math.abs(lat2) ? lat1 : lat2;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return {
|
|
606
|
+
lng: centerLngLat[0] + lngOffset,
|
|
607
|
+
lat: centerLngLat[1] + latOffset,
|
|
608
|
+
};
|
|
609
|
+
},
|
|
610
|
+
};
|
|
611
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FeatureDrawer } from '../renderers/drawer.js';
|
|
2
|
+
import type { SDFLineRenderer } from '../renderers/line/sdf-line.js';
|
|
3
|
+
import type { PointInstanceRenderer } from '../renderers/point/point-instance.js';
|
|
4
|
+
import type { PointShapeRenderer } from '../renderers/point/point-shape.js';
|
|
5
|
+
import type { PolygonBatchRenderer } from '../renderers/polygon/batch.js';
|
|
6
|
+
import type { SDFPolygonRenderer } from '../renderers/polygon/sdf-polygon.js';
|
|
7
|
+
import type { StrokeRenderer } from '../renderers/stroke.js';
|
|
8
|
+
import type { TentativeRenderer } from '../ui/tentative.js';
|
|
9
|
+
import type { QuadShader } from './quad.js';
|
|
10
|
+
/**
|
|
11
|
+
* The renderers managed by ShaderInitializer
|
|
12
|
+
*/
|
|
13
|
+
export interface ShaderInitializerRenderers {
|
|
14
|
+
featureDrawer: FeatureDrawer | null;
|
|
15
|
+
tentativeRenderer: TentativeRenderer | null;
|
|
16
|
+
quadShader: QuadShader | null;
|
|
17
|
+
strokeRenderer: StrokeRenderer | null;
|
|
18
|
+
pointShapeRenderer: PointShapeRenderer | null;
|
|
19
|
+
pointInstanceRenderer: PointInstanceRenderer | null;
|
|
20
|
+
sdfLineRenderer: SDFLineRenderer | null;
|
|
21
|
+
polygonBatchRenderer: PolygonBatchRenderer | null;
|
|
22
|
+
sdfPolygonRenderer: SDFPolygonRenderer | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a ShaderInitializer
|
|
26
|
+
*/
|
|
27
|
+
export declare function createShaderInitializer(renderers: ShaderInitializerRenderers): ShaderInitializer;
|