@react-x11/components 0.8.0 → 0.10.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/README.md +105 -38
- package/dist/charts/node.d.ts +12 -2
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +50 -16
- package/dist/charts/node.js.map +1 -1
- package/dist/charts/render.d.ts +12 -3
- package/dist/charts/render.d.ts.map +1 -1
- package/dist/charts/render.js +94 -25
- package/dist/charts/render.js.map +1 -1
- package/dist/code/index.d.ts.map +1 -1
- package/dist/code/index.js +3 -1
- package/dist/code/index.js.map +1 -1
- package/dist/code-editor/completion.d.ts.map +1 -1
- package/dist/code-editor/completion.js +3 -2
- package/dist/code-editor/completion.js.map +1 -1
- package/dist/code-editor/index.d.ts.map +1 -1
- package/dist/code-editor/index.js +19 -0
- package/dist/code-editor/index.js.map +1 -1
- package/dist/code-editor/node.d.ts +177 -7
- package/dist/code-editor/node.d.ts.map +1 -1
- package/dist/code-editor/node.js +1329 -164
- package/dist/code-editor/node.js.map +1 -1
- package/dist/code-language/languages/glsl.d.ts.map +1 -1
- package/dist/code-language/languages/glsl.js +10 -2
- package/dist/code-language/languages/glsl.js.map +1 -1
- package/dist/code-language/languages/javascript.d.ts.map +1 -1
- package/dist/code-language/languages/javascript.js +18 -3
- package/dist/code-language/languages/javascript.js.map +1 -1
- package/dist/code-language/languages/json.d.ts.map +1 -1
- package/dist/code-language/languages/json.js +10 -2
- package/dist/code-language/languages/json.js.map +1 -1
- package/dist/code-language/languages/shell.d.ts.map +1 -1
- package/dist/code-language/languages/shell.js +10 -2
- package/dist/code-language/languages/shell.js.map +1 -1
- package/dist/code-language/languages/sql.d.ts.map +1 -1
- package/dist/code-language/languages/sql.js +20 -2
- package/dist/code-language/languages/sql.js.map +1 -1
- package/dist/code-language/stream.d.ts +22 -0
- package/dist/code-language/stream.d.ts.map +1 -1
- package/dist/code-language/stream.js +259 -9
- package/dist/code-language/stream.js.map +1 -1
- package/dist/code-language/types.d.ts +5 -4
- package/dist/code-language/types.d.ts.map +1 -1
- package/dist/codeblock/index.d.ts +13 -2
- package/dist/codeblock/index.d.ts.map +1 -1
- package/dist/codeblock/index.js +20 -3
- package/dist/codeblock/index.js.map +1 -1
- package/dist/embed/client.d.ts +48 -3
- package/dist/embed/client.d.ts.map +1 -1
- package/dist/embed/client.js +79 -5
- package/dist/embed/client.js.map +1 -1
- package/dist/embed/index.d.ts +1 -1
- package/dist/embed/index.d.ts.map +1 -1
- package/dist/embed/index.js +1 -1
- package/dist/embed/index.js.map +1 -1
- package/dist/flow/draw.d.ts +50 -0
- package/dist/flow/draw.d.ts.map +1 -1
- package/dist/flow/draw.js +132 -33
- package/dist/flow/draw.js.map +1 -1
- package/dist/flow/gl/color.d.ts +13 -0
- package/dist/flow/gl/color.d.ts.map +1 -0
- package/dist/flow/gl/color.js +82 -0
- package/dist/flow/gl/color.js.map +1 -0
- package/dist/flow/gl/index.d.ts +60 -0
- package/dist/flow/gl/index.d.ts.map +1 -0
- package/dist/flow/gl/index.js +283 -0
- package/dist/flow/gl/index.js.map +1 -0
- package/dist/flow/gl/pack.d.ts +133 -0
- package/dist/flow/gl/pack.d.ts.map +1 -0
- package/dist/flow/gl/pack.js +408 -0
- package/dist/flow/gl/pack.js.map +1 -0
- package/dist/flow/gl/renderer.d.ts +95 -0
- package/dist/flow/gl/renderer.d.ts.map +1 -0
- package/dist/flow/gl/renderer.js +459 -0
- package/dist/flow/gl/renderer.js.map +1 -0
- package/dist/flow/gl/shaders.d.ts +79 -0
- package/dist/flow/gl/shaders.d.ts.map +1 -0
- package/dist/flow/gl/shaders.js +346 -0
- package/dist/flow/gl/shaders.js.map +1 -0
- package/dist/flow/gl/text.d.ts +318 -0
- package/dist/flow/gl/text.d.ts.map +1 -0
- package/dist/flow/gl/text.js +1103 -0
- package/dist/flow/gl/text.js.map +1 -0
- package/dist/flow/index.d.ts +1 -1
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +619 -64
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/node.d.ts +621 -72
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +2253 -1018
- package/dist/flow/node.js.map +1 -1
- package/dist/flow/paint.d.ts +35 -0
- package/dist/flow/paint.d.ts.map +1 -0
- package/dist/flow/paint.js +393 -0
- package/dist/flow/paint.js.map +1 -0
- package/dist/flow/paths.d.ts +14 -0
- package/dist/flow/paths.d.ts.map +1 -1
- package/dist/flow/paths.js +45 -19
- package/dist/flow/paths.js.map +1 -1
- package/dist/flow/scene.d.ts +584 -0
- package/dist/flow/scene.d.ts.map +1 -0
- package/dist/flow/scene.js +1453 -0
- package/dist/flow/scene.js.map +1 -0
- package/dist/flow/types.d.ts +111 -1
- package/dist/flow/types.d.ts.map +1 -1
- package/dist/html/controls.d.ts +28 -0
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +52 -2
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/calc.d.ts +14 -0
- package/dist/html/css/calc.d.ts.map +1 -0
- package/dist/html/css/calc.js +344 -0
- package/dist/html/css/calc.js.map +1 -0
- package/dist/html/css/cascade.d.ts +240 -6
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +1327 -66
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +23 -0
- package/dist/html/css/color.d.ts.map +1 -0
- package/dist/html/css/color.js +740 -0
- package/dist/html/css/color.js.map +1 -0
- package/dist/html/css/content.d.ts +92 -0
- package/dist/html/css/content.d.ts.map +1 -0
- package/dist/html/css/content.js +388 -0
- package/dist/html/css/content.js.map +1 -0
- package/dist/html/css/counter-styles.d.ts +76 -0
- package/dist/html/css/counter-styles.d.ts.map +1 -0
- package/dist/html/css/counter-styles.js +893 -0
- package/dist/html/css/counter-styles.js.map +1 -0
- package/dist/html/css/decode.d.ts +12 -0
- package/dist/html/css/decode.d.ts.map +1 -0
- package/dist/html/css/decode.js +116 -0
- package/dist/html/css/decode.js.map +1 -0
- package/dist/html/css/parse.d.ts +110 -10
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +1473 -180
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +498 -15
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +3698 -206
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.d.ts.map +1 -1
- package/dist/html/css/ua.js +57 -11
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +37 -3
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +122 -48
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/css/vars.d.ts +52 -0
- package/dist/html/css/vars.d.ts.map +1 -0
- package/dist/html/css/vars.js +358 -0
- package/dist/html/css/vars.js.map +1 -0
- package/dist/html/dom.d.ts +30 -4
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +278 -17
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +106 -0
- package/dist/html/fonts.d.ts.map +1 -0
- package/dist/html/fonts.js +565 -0
- package/dist/html/fonts.js.map +1 -0
- package/dist/html/gif.d.ts +15 -0
- package/dist/html/gif.d.ts.map +1 -0
- package/dist/html/gif.js +229 -0
- package/dist/html/gif.js.map +1 -0
- package/dist/html/index.d.ts +50 -11
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +115 -9
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +226 -3
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +2937 -197
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +340 -17
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +1714 -182
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +58 -0
- package/dist/html/layout/cache.d.ts.map +1 -0
- package/dist/html/layout/cache.js +224 -0
- package/dist/html/layout/cache.js.map +1 -0
- package/dist/html/layout/collapse.d.ts +45 -0
- package/dist/html/layout/collapse.d.ts.map +1 -0
- package/dist/html/layout/collapse.js +246 -0
- package/dist/html/layout/collapse.js.map +1 -0
- package/dist/html/layout/css-grid.d.ts +7 -0
- package/dist/html/layout/css-grid.d.ts.map +1 -0
- package/dist/html/layout/css-grid.js +900 -0
- package/dist/html/layout/css-grid.js.map +1 -0
- package/dist/html/layout/flex.d.ts.map +1 -1
- package/dist/html/layout/flex.js +1025 -89
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/floats.d.ts +45 -6
- package/dist/html/layout/floats.d.ts.map +1 -1
- package/dist/html/layout/floats.js +113 -14
- package/dist/html/layout/floats.js.map +1 -1
- package/dist/html/layout/grid-lines.d.ts +39 -0
- package/dist/html/layout/grid-lines.d.ts.map +1 -0
- package/dist/html/layout/grid-lines.js +119 -0
- package/dist/html/layout/grid-lines.js.map +1 -0
- package/dist/html/layout/grid.d.ts +53 -0
- package/dist/html/layout/grid.d.ts.map +1 -0
- package/dist/html/layout/grid.js +153 -0
- package/dist/html/layout/grid.js.map +1 -0
- package/dist/html/layout/inline.d.ts +151 -1
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +3375 -174
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/shaping.d.ts +6 -0
- package/dist/html/layout/shaping.d.ts.map +1 -0
- package/dist/html/layout/shaping.js +100 -0
- package/dist/html/layout/shaping.js.map +1 -0
- package/dist/html/layout/table.d.ts +3 -0
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +681 -175
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/layout/tracks.d.ts +44 -0
- package/dist/html/layout/tracks.d.ts.map +1 -0
- package/dist/html/layout/tracks.js +349 -0
- package/dist/html/layout/tracks.js.map +1 -0
- package/dist/html/node.d.ts +172 -5
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +1336 -103
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +92 -3
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +3503 -141
- package/dist/html/paint.js.map +1 -1
- package/dist/html/resources.d.ts +60 -14
- package/dist/html/resources.d.ts.map +1 -1
- package/dist/html/resources.js +122 -36
- package/dist/html/resources.js.map +1 -1
- package/dist/html/surfaces.d.ts +23 -0
- package/dist/html/surfaces.d.ts.map +1 -0
- package/dist/html/surfaces.js +68 -0
- package/dist/html/surfaces.js.map +1 -0
- package/dist/html/svg.d.ts +80 -0
- package/dist/html/svg.d.ts.map +1 -0
- package/dist/html/svg.js +435 -0
- package/dist/html/svg.js.map +1 -0
- package/dist/html/url.d.ts +23 -0
- package/dist/html/url.d.ts.map +1 -0
- package/dist/html/url.js +80 -0
- package/dist/html/url.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/collate.d.ts +3 -0
- package/dist/internal/collate.d.ts.map +1 -0
- package/dist/internal/collate.js +11 -0
- package/dist/internal/collate.js.map +1 -0
- package/dist/{markdown → internal/markdown}/ast.d.ts +23 -0
- package/dist/internal/markdown/ast.d.ts.map +1 -0
- package/dist/internal/markdown/ast.js +22 -0
- package/dist/internal/markdown/ast.js.map +1 -0
- package/dist/internal/markdown/parse.d.ts.map +1 -0
- package/dist/{markdown → internal/markdown}/parse.js +221 -30
- package/dist/internal/markdown/parse.js.map +1 -0
- package/dist/internal/markdown/stringify.d.ts +4 -0
- package/dist/internal/markdown/stringify.d.ts.map +1 -0
- package/dist/internal/markdown/stringify.js +684 -0
- package/dist/internal/markdown/stringify.js.map +1 -0
- package/dist/internal/markdown/tags.d.ts.map +1 -0
- package/dist/internal/markdown/tags.js.map +1 -0
- package/dist/internal/prewarm.d.ts +18 -0
- package/dist/internal/prewarm.d.ts.map +1 -0
- package/dist/internal/prewarm.js +42 -0
- package/dist/internal/prewarm.js.map +1 -0
- package/dist/internal/scroll.d.ts +3 -2
- package/dist/internal/scroll.d.ts.map +1 -1
- package/dist/internal/scroll.js +1 -0
- package/dist/internal/scroll.js.map +1 -1
- package/dist/internal/sdf.d.ts +20 -0
- package/dist/internal/sdf.d.ts.map +1 -0
- package/dist/internal/sdf.js +216 -0
- package/dist/internal/sdf.js.map +1 -0
- package/dist/internal/splice.d.ts +12 -0
- package/dist/internal/splice.d.ts.map +1 -0
- package/dist/internal/splice.js +23 -0
- package/dist/internal/splice.js.map +1 -0
- package/dist/internal/window.d.ts +12 -0
- package/dist/internal/window.d.ts.map +1 -1
- package/dist/internal/window.js +23 -6
- package/dist/internal/window.js.map +1 -1
- package/dist/maps/anchors.d.ts +103 -0
- package/dist/maps/anchors.d.ts.map +1 -0
- package/dist/maps/anchors.js +790 -0
- package/dist/maps/anchors.js.map +1 -0
- package/dist/maps/controller.d.ts +340 -0
- package/dist/maps/controller.d.ts.map +1 -0
- package/dist/maps/controller.js +822 -0
- package/dist/maps/controller.js.map +1 -0
- package/dist/maps/gl/buckets.d.ts +99 -0
- package/dist/maps/gl/buckets.d.ts.map +1 -0
- package/dist/maps/gl/buckets.js +365 -0
- package/dist/maps/gl/buckets.js.map +1 -0
- package/dist/maps/gl/build-worker.d.ts +15 -0
- package/dist/maps/gl/build-worker.d.ts.map +1 -0
- package/dist/maps/gl/build-worker.js +44 -0
- package/dist/maps/gl/build-worker.js.map +1 -0
- package/dist/maps/gl/color.d.ts +8 -0
- package/dist/maps/gl/color.d.ts.map +1 -0
- package/dist/maps/gl/color.js +57 -0
- package/dist/maps/gl/color.js.map +1 -0
- package/dist/maps/gl/cover.d.ts +70 -0
- package/dist/maps/gl/cover.d.ts.map +1 -0
- package/dist/maps/gl/cover.js +137 -0
- package/dist/maps/gl/cover.js.map +1 -0
- package/dist/maps/gl/index.d.ts +3 -0
- package/dist/maps/gl/index.d.ts.map +1 -0
- package/dist/maps/gl/index.js +20 -0
- package/dist/maps/gl/index.js.map +1 -0
- package/dist/maps/gl/markers.d.ts +28 -0
- package/dist/maps/gl/markers.d.ts.map +1 -0
- package/dist/maps/gl/markers.js +60 -0
- package/dist/maps/gl/markers.js.map +1 -0
- package/dist/maps/gl/overlays.d.ts +68 -0
- package/dist/maps/gl/overlays.d.ts.map +1 -0
- package/dist/maps/gl/overlays.js +300 -0
- package/dist/maps/gl/overlays.js.map +1 -0
- package/dist/maps/gl/pane.d.ts +12 -0
- package/dist/maps/gl/pane.d.ts.map +1 -0
- package/dist/maps/gl/pane.js +37 -0
- package/dist/maps/gl/pane.js.map +1 -0
- package/dist/maps/gl/placement.d.ts +124 -0
- package/dist/maps/gl/placement.d.ts.map +1 -0
- package/dist/maps/gl/placement.js +642 -0
- package/dist/maps/gl/placement.js.map +1 -0
- package/dist/maps/gl/renderer.d.ts +384 -0
- package/dist/maps/gl/renderer.d.ts.map +1 -0
- package/dist/maps/gl/renderer.js +1184 -0
- package/dist/maps/gl/renderer.js.map +1 -0
- package/dist/maps/gl/shaders.d.ts +121 -0
- package/dist/maps/gl/shaders.d.ts.map +1 -0
- package/dist/maps/gl/shaders.js +453 -0
- package/dist/maps/gl/shaders.js.map +1 -0
- package/dist/maps/gl/store.d.ts +125 -0
- package/dist/maps/gl/store.d.ts.map +1 -0
- package/dist/maps/gl/store.js +512 -0
- package/dist/maps/gl/store.js.map +1 -0
- package/dist/maps/gl/text.d.ts +283 -0
- package/dist/maps/gl/text.d.ts.map +1 -0
- package/dist/maps/gl/text.js +698 -0
- package/dist/maps/gl/text.js.map +1 -0
- package/dist/maps/gl/view.d.ts +345 -0
- package/dist/maps/gl/view.d.ts.map +1 -0
- package/dist/maps/gl/view.js +1209 -0
- package/dist/maps/gl/view.js.map +1 -0
- package/dist/maps/icons.d.ts +32 -0
- package/dist/maps/icons.d.ts.map +1 -0
- package/dist/maps/icons.js +151 -0
- package/dist/maps/icons.js.map +1 -0
- package/dist/maps/index.d.ts +3 -1
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/maps/index.js +218 -52
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/labels.d.ts +91 -18
- package/dist/maps/labels.d.ts.map +1 -1
- package/dist/maps/labels.js +376 -140
- package/dist/maps/labels.js.map +1 -1
- package/dist/maps/node.d.ts +179 -56
- package/dist/maps/node.d.ts.map +1 -1
- package/dist/maps/node.js +663 -537
- package/dist/maps/node.js.map +1 -1
- package/dist/maps/overlay.d.ts +72 -9
- package/dist/maps/overlay.d.ts.map +1 -1
- package/dist/maps/overlay.js +108 -28
- package/dist/maps/overlay.js.map +1 -1
- package/dist/maps/paint.d.ts +3 -0
- package/dist/maps/paint.d.ts.map +1 -1
- package/dist/maps/paint.js.map +1 -1
- package/dist/maps/proj.d.ts +62 -0
- package/dist/maps/proj.d.ts.map +1 -1
- package/dist/maps/proj.js +101 -0
- package/dist/maps/proj.js.map +1 -1
- package/dist/maps/renderer.d.ts +69 -0
- package/dist/maps/renderer.d.ts.map +1 -0
- package/dist/maps/renderer.js +66 -0
- package/dist/maps/renderer.js.map +1 -0
- package/dist/maps/sources.d.ts +30 -6
- package/dist/maps/sources.d.ts.map +1 -1
- package/dist/maps/sources.js +22 -3
- package/dist/maps/sources.js.map +1 -1
- package/dist/maps/style.d.ts +35 -0
- package/dist/maps/style.d.ts.map +1 -1
- package/dist/maps/style.js.map +1 -1
- package/dist/maps/styles.d.ts +12 -0
- package/dist/maps/styles.d.ts.map +1 -1
- package/dist/maps/styles.js +120 -6
- package/dist/maps/styles.js.map +1 -1
- package/dist/maps/theme.d.ts +19 -0
- package/dist/maps/theme.d.ts.map +1 -0
- package/dist/maps/theme.js +44 -0
- package/dist/maps/theme.js.map +1 -0
- package/dist/maps/tiles.d.ts +147 -27
- package/dist/maps/tiles.d.ts.map +1 -1
- package/dist/maps/tiles.js +221 -54
- package/dist/maps/tiles.js.map +1 -1
- package/dist/maps/types.d.ts +213 -21
- package/dist/maps/types.d.ts.map +1 -1
- package/dist/markdown/expressions.d.ts +1 -1
- package/dist/markdown/expressions.d.ts.map +1 -1
- package/dist/markdown/expressions.js.map +1 -1
- package/dist/markdown/index.d.ts +7 -6
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +121 -50
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/spans.d.ts +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/markdown/spans.js +6 -0
- package/dist/markdown/spans.js.map +1 -1
- package/dist/media-player/index.d.ts +11 -3
- package/dist/media-player/index.d.ts.map +1 -1
- package/dist/media-player/index.js +13 -2
- package/dist/media-player/index.js.map +1 -1
- package/dist/qml/containers.d.ts.map +1 -1
- package/dist/qml/containers.js +6 -1
- package/dist/qml/containers.js.map +1 -1
- package/dist/qml/interaction.d.ts.map +1 -1
- package/dist/qml/interaction.js +38 -5
- package/dist/qml/interaction.js.map +1 -1
- package/dist/qml/layouts.d.ts.map +1 -1
- package/dist/qml/layouts.js +21 -6
- package/dist/qml/layouts.js.map +1 -1
- package/dist/qml/qtquick.d.ts.map +1 -1
- package/dist/qml/qtquick.js +9 -2
- package/dist/qml/qtquick.js.map +1 -1
- package/dist/qml/react.d.ts.map +1 -1
- package/dist/qml/react.js +9 -7
- package/dist/qml/react.js.map +1 -1
- package/dist/reorder/clock.d.ts +7 -0
- package/dist/reorder/clock.d.ts.map +1 -0
- package/dist/reorder/clock.js +26 -0
- package/dist/reorder/clock.js.map +1 -0
- package/dist/reorder/index.d.ts +25 -3
- package/dist/reorder/index.d.ts.map +1 -1
- package/dist/reorder/index.js +64 -19
- package/dist/reorder/index.js.map +1 -1
- package/dist/rich-text-editor/clipboard.d.ts +23 -0
- package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
- package/dist/rich-text-editor/clipboard.js +307 -0
- package/dist/rich-text-editor/clipboard.js.map +1 -0
- package/dist/rich-text-editor/collab.d.ts +32 -0
- package/dist/rich-text-editor/collab.d.ts.map +1 -0
- package/dist/rich-text-editor/collab.js +55 -0
- package/dist/rich-text-editor/collab.js.map +1 -0
- package/dist/rich-text-editor/commands.d.ts +50 -0
- package/dist/rich-text-editor/commands.d.ts.map +1 -0
- package/dist/rich-text-editor/commands.js +376 -0
- package/dist/rich-text-editor/commands.js.map +1 -0
- package/dist/rich-text-editor/drag.d.ts +68 -0
- package/dist/rich-text-editor/drag.d.ts.map +1 -0
- package/dist/rich-text-editor/drag.js +148 -0
- package/dist/rich-text-editor/drag.js.map +1 -0
- package/dist/rich-text-editor/html.d.ts +145 -0
- package/dist/rich-text-editor/html.d.ts.map +1 -0
- package/dist/rich-text-editor/html.js +516 -0
- package/dist/rich-text-editor/html.js.map +1 -0
- package/dist/rich-text-editor/index.d.ts +252 -0
- package/dist/rich-text-editor/index.d.ts.map +1 -0
- package/dist/rich-text-editor/index.js +856 -0
- package/dist/rich-text-editor/index.js.map +1 -0
- package/dist/rich-text-editor/inline.d.ts +94 -0
- package/dist/rich-text-editor/inline.d.ts.map +1 -0
- package/dist/rich-text-editor/inline.js +252 -0
- package/dist/rich-text-editor/inline.js.map +1 -0
- package/dist/rich-text-editor/keymap.d.ts +71 -0
- package/dist/rich-text-editor/keymap.d.ts.map +1 -0
- package/dist/rich-text-editor/keymap.js +394 -0
- package/dist/rich-text-editor/keymap.js.map +1 -0
- package/dist/rich-text-editor/keys.d.ts +40 -0
- package/dist/rich-text-editor/keys.d.ts.map +1 -0
- package/dist/rich-text-editor/keys.js +202 -0
- package/dist/rich-text-editor/keys.js.map +1 -0
- package/dist/rich-text-editor/look.d.ts +71 -0
- package/dist/rich-text-editor/look.d.ts.map +1 -0
- package/dist/rich-text-editor/look.js +342 -0
- package/dist/rich-text-editor/look.js.map +1 -0
- package/dist/rich-text-editor/markdown.d.ts +18 -0
- package/dist/rich-text-editor/markdown.d.ts.map +1 -0
- package/dist/rich-text-editor/markdown.js +496 -0
- package/dist/rich-text-editor/markdown.js.map +1 -0
- package/dist/rich-text-editor/marks.d.ts +9 -0
- package/dist/rich-text-editor/marks.d.ts.map +1 -0
- package/dist/rich-text-editor/marks.js +83 -0
- package/dist/rich-text-editor/marks.js.map +1 -0
- package/dist/rich-text-editor/nodes.d.ts +135 -0
- package/dist/rich-text-editor/nodes.d.ts.map +1 -0
- package/dist/rich-text-editor/nodes.js +397 -0
- package/dist/rich-text-editor/nodes.js.map +1 -0
- package/dist/rich-text-editor/render.d.ts +68 -0
- package/dist/rich-text-editor/render.d.ts.map +1 -0
- package/dist/rich-text-editor/render.js +518 -0
- package/dist/rich-text-editor/render.js.map +1 -0
- package/dist/rich-text-editor/schema.d.ts +16 -0
- package/dist/rich-text-editor/schema.d.ts.map +1 -0
- package/dist/rich-text-editor/schema.js +386 -0
- package/dist/rich-text-editor/schema.js.map +1 -0
- package/dist/rich-text-editor/store.d.ts +11 -0
- package/dist/rich-text-editor/store.d.ts.map +1 -0
- package/dist/rich-text-editor/store.js +43 -0
- package/dist/rich-text-editor/store.js.map +1 -0
- package/dist/rich-text-editor/suggest.d.ts +127 -0
- package/dist/rich-text-editor/suggest.d.ts.map +1 -0
- package/dist/rich-text-editor/suggest.js +0 -0
- package/dist/rich-text-editor/suggest.js.map +1 -0
- package/dist/rich-text-editor/tables.d.ts +41 -0
- package/dist/rich-text-editor/tables.d.ts.map +1 -0
- package/dist/rich-text-editor/tables.js +204 -0
- package/dist/rich-text-editor/tables.js.map +1 -0
- package/dist/rich-text-editor/toolbar.d.ts +58 -0
- package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
- package/dist/rich-text-editor/toolbar.js +548 -0
- package/dist/rich-text-editor/toolbar.js.map +1 -0
- package/dist/rich-text-editor/view.d.ts +368 -0
- package/dist/rich-text-editor/view.d.ts.map +1 -0
- package/dist/rich-text-editor/view.js +1968 -0
- package/dist/rich-text-editor/view.js.map +1 -0
- package/dist/rich-text-editor/virtual.d.ts +54 -0
- package/dist/rich-text-editor/virtual.d.ts.map +1 -0
- package/dist/rich-text-editor/virtual.js +279 -0
- package/dist/rich-text-editor/virtual.js.map +1 -0
- package/dist/richtext/node.d.ts +71 -4
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +233 -28
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +13 -8
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +18 -8
- package/dist/richtext/runs.js.map +1 -1
- package/dist/table/index.d.ts.map +1 -1
- package/dist/table/index.js +23 -0
- package/dist/table/index.js.map +1 -1
- package/dist/table/rows.d.ts +3 -2
- package/dist/table/rows.d.ts.map +1 -1
- package/dist/table/rows.js +20 -6
- package/dist/table/rows.js.map +1 -1
- package/dist/terminal/backends.d.ts +4 -1
- package/dist/terminal/backends.d.ts.map +1 -1
- package/dist/terminal/backends.js.map +1 -1
- package/dist/terminal/index.d.ts +18 -7
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +32 -11
- package/dist/terminal/index.js.map +1 -1
- package/dist/terminal/vt/pty.d.ts +13 -2
- package/dist/terminal/vt/pty.d.ts.map +1 -1
- package/dist/terminal/vt/pty.js +18 -3
- package/dist/terminal/vt/pty.js.map +1 -1
- package/dist/terminal-output/index.d.ts.map +1 -1
- package/dist/terminal-output/index.js +6 -1
- package/dist/terminal-output/index.js.map +1 -1
- package/dist/three/canvas.d.ts.map +1 -1
- package/dist/three/canvas.js +85 -7
- package/dist/three/canvas.js.map +1 -1
- package/dist/three/events.d.ts +22 -4
- package/dist/three/events.d.ts.map +1 -1
- package/dist/three/events.js +34 -4
- package/dist/three/events.js.map +1 -1
- package/dist/tree/index.d.ts.map +1 -1
- package/dist/tree/index.js +17 -0
- package/dist/tree/index.js.map +1 -1
- package/package.json +59 -31
- package/src/charts/node.ts +68 -28
- package/src/charts/render.ts +120 -30
- package/src/code/index.ts +3 -1
- package/src/code-editor/completion.ts +3 -2
- package/src/code-editor/index.ts +19 -0
- package/src/code-editor/node.ts +1574 -184
- package/src/code-language/languages/glsl.ts +12 -2
- package/src/code-language/languages/javascript.ts +21 -4
- package/src/code-language/languages/json.ts +12 -2
- package/src/code-language/languages/shell.ts +12 -2
- package/src/code-language/languages/sql.ts +22 -2
- package/src/code-language/stream.ts +257 -17
- package/src/code-language/types.ts +5 -4
- package/src/codeblock/index.ts +20 -3
- package/src/embed/client.ts +102 -8
- package/src/embed/index.ts +2 -0
- package/src/flow/draw.ts +167 -41
- package/src/flow/gl/color.ts +85 -0
- package/src/flow/gl/index.ts +342 -0
- package/src/flow/gl/pack.ts +585 -0
- package/src/flow/gl/renderer.ts +679 -0
- package/src/flow/gl/shaders.ts +371 -0
- package/src/flow/gl/text.ts +1295 -0
- package/src/flow/index.ts +794 -67
- package/src/flow/node.ts +2496 -1256
- package/src/flow/paint.ts +511 -0
- package/src/flow/paths.ts +80 -15
- package/src/flow/scene.ts +2199 -0
- package/src/flow/types.ts +113 -1
- package/src/html/controls.ts +73 -2
- package/src/html/css/calc.ts +385 -0
- package/src/html/css/cascade.ts +1403 -62
- package/src/html/css/color.ts +755 -0
- package/src/html/css/content.ts +417 -0
- package/src/html/css/counter-styles.ts +973 -0
- package/src/html/css/decode.ts +130 -0
- package/src/html/css/parse.ts +1514 -160
- package/src/html/css/style.ts +4102 -222
- package/src/html/css/ua.ts +58 -12
- package/src/html/css/values.ts +150 -50
- package/src/html/css/vars.ts +348 -0
- package/src/html/dom.ts +284 -17
- package/src/html/fonts.ts +641 -0
- package/src/html/gif.ts +233 -0
- package/src/html/index.ts +180 -20
- package/src/html/layout/block.ts +3456 -230
- package/src/html/layout/boxes.ts +2100 -190
- package/src/html/layout/cache.ts +289 -0
- package/src/html/layout/collapse.ts +317 -0
- package/src/html/layout/css-grid.ts +1063 -0
- package/src/html/layout/flex.ts +1115 -106
- package/src/html/layout/floats.ts +128 -14
- package/src/html/layout/grid-lines.ts +141 -0
- package/src/html/layout/grid.ts +181 -0
- package/src/html/layout/inline.ts +3943 -192
- package/src/html/layout/shaping.ts +140 -0
- package/src/html/layout/table.ts +696 -186
- package/src/html/layout/tracks.ts +437 -0
- package/src/html/node.ts +1486 -121
- package/src/html/paint.ts +4293 -169
- package/src/html/resources.ts +161 -50
- package/src/html/surfaces.ts +81 -0
- package/src/html/svg.ts +493 -0
- package/src/html/url.ts +86 -0
- package/src/index.ts +4 -0
- package/src/internal/collate.ts +12 -0
- package/src/{markdown → internal/markdown}/ast.ts +35 -7
- package/src/{markdown → internal/markdown}/parse.ts +288 -35
- package/src/internal/markdown/stringify.ts +772 -0
- package/src/internal/prewarm.ts +45 -0
- package/src/internal/scroll.ts +5 -3
- package/src/internal/sdf.ts +227 -0
- package/src/internal/splice.ts +25 -0
- package/src/internal/window.ts +36 -5
- package/src/maps/anchors.ts +913 -0
- package/src/maps/controller.ts +1084 -0
- package/src/maps/gl/buckets.ts +461 -0
- package/src/maps/gl/build-worker.ts +66 -0
- package/src/maps/gl/color.ts +62 -0
- package/src/maps/gl/cover.ts +205 -0
- package/src/maps/gl/index.ts +23 -0
- package/src/maps/gl/markers.ts +83 -0
- package/src/maps/gl/overlays.ts +379 -0
- package/src/maps/gl/pane.ts +42 -0
- package/src/maps/gl/placement.ts +968 -0
- package/src/maps/gl/renderer.ts +1660 -0
- package/src/maps/gl/shaders.ts +489 -0
- package/src/maps/gl/store.ts +615 -0
- package/src/maps/gl/text.ts +868 -0
- package/src/maps/gl/view.ts +1489 -0
- package/src/maps/icons.ts +183 -0
- package/src/maps/index.ts +274 -81
- package/src/maps/labels.ts +457 -144
- package/src/maps/node.ts +832 -665
- package/src/maps/overlay.ts +148 -43
- package/src/maps/paint.ts +3 -0
- package/src/maps/proj.ts +118 -0
- package/src/maps/renderer.ts +155 -0
- package/src/maps/sources.ts +43 -6
- package/src/maps/style.ts +32 -0
- package/src/maps/styles.ts +215 -4
- package/src/maps/theme.ts +51 -0
- package/src/maps/tiles.ts +253 -62
- package/src/maps/types.ts +213 -21
- package/src/markdown/expressions.ts +5 -1
- package/src/markdown/index.ts +163 -78
- package/src/markdown/spans.ts +6 -1
- package/src/media-player/index.ts +18 -4
- package/src/qml/containers.tsx +6 -1
- package/src/qml/interaction.tsx +42 -5
- package/src/qml/layouts.tsx +21 -6
- package/src/qml/qtquick.tsx +9 -2
- package/src/qml/react.tsx +7 -5
- package/src/reorder/clock.ts +27 -0
- package/src/reorder/index.ts +100 -27
- package/src/rich-text-editor/clipboard.ts +439 -0
- package/src/rich-text-editor/collab.ts +91 -0
- package/src/rich-text-editor/commands.ts +448 -0
- package/src/rich-text-editor/dom-globals.d.ts +23 -0
- package/src/rich-text-editor/drag.ts +211 -0
- package/src/rich-text-editor/html.ts +619 -0
- package/src/rich-text-editor/index.ts +1364 -0
- package/src/rich-text-editor/inline.ts +345 -0
- package/src/rich-text-editor/keymap.ts +510 -0
- package/src/rich-text-editor/keys.ts +228 -0
- package/src/rich-text-editor/look.ts +427 -0
- package/src/rich-text-editor/markdown.ts +653 -0
- package/src/rich-text-editor/marks.ts +101 -0
- package/src/rich-text-editor/nodes.ts +497 -0
- package/src/rich-text-editor/render.ts +837 -0
- package/src/rich-text-editor/schema.ts +431 -0
- package/src/rich-text-editor/store.ts +39 -0
- package/src/rich-text-editor/suggest.ts +597 -0
- package/src/rich-text-editor/tables.ts +272 -0
- package/src/rich-text-editor/toolbar.ts +724 -0
- package/src/rich-text-editor/view.ts +2287 -0
- package/src/rich-text-editor/virtual.ts +372 -0
- package/src/richtext/node.ts +294 -44
- package/src/richtext/runs.ts +23 -12
- package/src/table/index.ts +29 -0
- package/src/table/rows.ts +18 -8
- package/src/terminal/backends.ts +4 -1
- package/src/terminal/index.ts +47 -15
- package/src/terminal/vt/pty.ts +16 -2
- package/src/terminal-output/index.ts +6 -1
- package/src/three/canvas.ts +102 -8
- package/src/three/events.ts +49 -9
- package/src/tree/index.ts +19 -0
- package/dist/markdown/ast.d.ts.map +0 -1
- package/dist/markdown/ast.js +0 -17
- package/dist/markdown/ast.js.map +0 -1
- package/dist/markdown/parse.d.ts.map +0 -1
- package/dist/markdown/parse.js.map +0 -1
- package/dist/markdown/tags.d.ts.map +0 -1
- package/dist/markdown/tags.js.map +0 -1
- /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.js +0 -0
- /package/src/{markdown → internal/markdown}/tags.ts +0 -0
|
@@ -0,0 +1,913 @@
|
|
|
1
|
+
// Where in a tile a label *could* go, worked out once per tile and never per
|
|
2
|
+
// frame — and by both renderers: the GL renderer with a tile's buckets, on
|
|
3
|
+
// its build workers (`./gl/buckets.ts`), and the retained renderer when it
|
|
4
|
+
// collects a tile's candidates (`./labels.ts`). One answer, so a map names
|
|
5
|
+
// the same streets in the same places whichever of them draws it.
|
|
6
|
+
//
|
|
7
|
+
// A point label's place is its point. A line label's place is the hard
|
|
8
|
+
// part, and the answer here is the one that makes a street name easy to
|
|
9
|
+
// read and hard to notice: **on the street, along its centre line, on a
|
|
10
|
+
// stretch that is straight** — the name set as one straight run of type,
|
|
11
|
+
// never bent around a corner, sitting on the road it names rather than
|
|
12
|
+
// beside it. Three steps get there:
|
|
13
|
+
//
|
|
14
|
+
// 1. **Merge.** A street is one feature per segment in every schema there
|
|
15
|
+
// is — `street_labels` offers "Westminster Bridge Road" 24 times in one
|
|
16
|
+
// London tile — so the pieces of each name are joined end to end into
|
|
17
|
+
// the polylines they were cut from. Without this, a straight avenue cut
|
|
18
|
+
// at every cross street has no stretch longer than a block.
|
|
19
|
+
// 2. **Straighten.** Each polyline is walked into its maximal straight
|
|
20
|
+
// *runs*: stretches whose every vertex stays within {@link STRAIGHT} of
|
|
21
|
+
// the chord between the run's ends. A gentle curve is a run; a corner
|
|
22
|
+
// ends one.
|
|
23
|
+
// 3. **Anchor.** Each run offers a few anchors on its chord — its middle,
|
|
24
|
+
// the middle of every block between two intersections, and every
|
|
25
|
+
// {@link SPACING} along a long one — each carrying how much straight run
|
|
26
|
+
// lies either side of it and how far it is from the nearest
|
|
27
|
+
// intersection. Whether a label *fits* there is a question of its width
|
|
28
|
+
// in pixels and so of the zoom, and is left to placement; what is
|
|
29
|
+
// computed here is the geometry that answers it at any zoom.
|
|
30
|
+
//
|
|
31
|
+
// Intersections are found from the label layer itself: a vertex two
|
|
32
|
+
// differently named streets share is a junction. A name set across a junction
|
|
33
|
+
// hides the street that crosses there, so placement prefers an anchor whose
|
|
34
|
+
// label clears one — the middle of a block — to one that does not.
|
|
35
|
+
//
|
|
36
|
+
// Everything leaves as one Float32Array and a string table, so a worker can
|
|
37
|
+
// hand it over with the buckets (see `./gl/store.ts`).
|
|
38
|
+
import { GeomType, GeometryBuffer } from './mvt.js';
|
|
39
|
+
import type { FeatureCursor, VectorTile, VectorTileLayer } from './mvt.js';
|
|
40
|
+
import type { PreparedStyle } from './paint.js';
|
|
41
|
+
import { latFromMercatorY } from './proj.js';
|
|
42
|
+
import type { TileId } from './proj.js';
|
|
43
|
+
import type { SymbolLayer } from './style.js';
|
|
44
|
+
|
|
45
|
+
// --- the fit rules both renderers place by ------------------------------------
|
|
46
|
+
|
|
47
|
+
/** A line label is set level — on whole pixels, which is sharper — when its
|
|
48
|
+
* street is this close to level, in radians. */
|
|
49
|
+
export const LEVEL_SNAP = 0.03;
|
|
50
|
+
/** How far a line label's run may depart from straight, as a fraction of
|
|
51
|
+
* the text's size at the zoom it is drawn at. */
|
|
52
|
+
export const STRAIGHT_FRACTION = 0.3;
|
|
53
|
+
/** Run that must remain past each end of a line label, in text heights —
|
|
54
|
+
* a name that stops exactly at a corner reads as bent. */
|
|
55
|
+
export const LINE_MARGIN = 0.5;
|
|
56
|
+
|
|
57
|
+
/** A name's width before it is measured: a lower-ish bound, from how wide
|
|
58
|
+
* Latin and CJK glyphs run. Only ever used to rule out what cannot fit. */
|
|
59
|
+
export function estimateWidth(text: string, size: number): number {
|
|
60
|
+
let em = 0;
|
|
61
|
+
for (const ch of text) em += ch.codePointAt(0)! >= 0x2e80 ? 0.95 : 0.5;
|
|
62
|
+
return em * size;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Floats per anchor record. */
|
|
66
|
+
export const LABEL_STRIDE = 10;
|
|
67
|
+
|
|
68
|
+
/** Field offsets within an anchor record. */
|
|
69
|
+
export const LabelField = {
|
|
70
|
+
/** The anchor, in tile units. */
|
|
71
|
+
x: 0,
|
|
72
|
+
y: 1,
|
|
73
|
+
/** The baseline's direction, radians, y down — always upright (see
|
|
74
|
+
* {@link upright}), so no name is ever read upside down. */
|
|
75
|
+
angle: 2,
|
|
76
|
+
/** Tile units of straight run either side of the anchor — how long a
|
|
77
|
+
* label it can carry. `-1` for a point label, which carries any. */
|
|
78
|
+
avail: 3,
|
|
79
|
+
/** Tile units either side of the anchor before an intersection. */
|
|
80
|
+
clear: 4,
|
|
81
|
+
/** The straight run's whole length, tile units; `0` for a point. */
|
|
82
|
+
length: 5,
|
|
83
|
+
/** The run's greatest departure from its chord, tile units. */
|
|
84
|
+
dev: 6,
|
|
85
|
+
/** Index into {@link GlLabelData.texts}. */
|
|
86
|
+
text: 7,
|
|
87
|
+
/** Index into the prepared style's layers. */
|
|
88
|
+
layer: 8,
|
|
89
|
+
/** Importance within the layer: a road's class, a place's population. */
|
|
90
|
+
priority: 9,
|
|
91
|
+
} as const;
|
|
92
|
+
|
|
93
|
+
/** A tile's label anchors. */
|
|
94
|
+
export interface GlLabelData {
|
|
95
|
+
texts: string[];
|
|
96
|
+
/** {@link LABEL_STRIDE} floats per anchor; see {@link LabelField}. */
|
|
97
|
+
anchors: Float32Array;
|
|
98
|
+
count: number;
|
|
99
|
+
ms: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** How far a run may depart from straight, in tile units: one pixel at
|
|
103
|
+
* the tile's own zoom (a 512-pixel tile is 4096 units), two at the next. */
|
|
104
|
+
export const STRAIGHT = 8;
|
|
105
|
+
/** The sharpest turn a run takes at one vertex, however small the
|
|
106
|
+
* departure — a kink reads as a corner under a line of text. */
|
|
107
|
+
const MAX_TURN = Math.cos((25 * Math.PI) / 180);
|
|
108
|
+
/** Anchors along a long run with no junction on it, in tile units — 256
|
|
109
|
+
* pixels at the tile's own zoom. */
|
|
110
|
+
export const SPACING = 2048;
|
|
111
|
+
/** The shortest run worth an anchor: 16 pixels at the tile's own zoom,
|
|
112
|
+
* which is a label only four levels of overzoom later. */
|
|
113
|
+
const MIN_RUN = 128;
|
|
114
|
+
/** "No junction within reach", in tile units. */
|
|
115
|
+
const FAR = 1e9;
|
|
116
|
+
|
|
117
|
+
/** A road's importance among roads: the order a map names them in. */
|
|
118
|
+
const ROAD_CLASS: Record<string, number> = {
|
|
119
|
+
motorway: 9,
|
|
120
|
+
trunk: 8,
|
|
121
|
+
primary: 7,
|
|
122
|
+
secondary: 6,
|
|
123
|
+
tertiary: 5,
|
|
124
|
+
unclassified: 4,
|
|
125
|
+
residential: 4,
|
|
126
|
+
living_street: 3,
|
|
127
|
+
pedestrian: 3,
|
|
128
|
+
service: 2,
|
|
129
|
+
track: 1,
|
|
130
|
+
footway: 1,
|
|
131
|
+
cycleway: 1,
|
|
132
|
+
path: 1,
|
|
133
|
+
bridleway: 1,
|
|
134
|
+
steps: 0,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const globals = globalThis as { performance?: { now(): number } };
|
|
138
|
+
const now = (): number => globals.performance?.now() ?? Date.now();
|
|
139
|
+
|
|
140
|
+
/** `collectLabels`' rule: the style's field, or the local `name` where a
|
|
141
|
+
* translation is missing — which is most features. */
|
|
142
|
+
function textOf(cursor: FeatureCursor, field: string): string {
|
|
143
|
+
const raw = cursor.get(field);
|
|
144
|
+
if (typeof raw === 'string' && raw.length > 0) return raw;
|
|
145
|
+
if (field === 'name') return '';
|
|
146
|
+
const local = cursor.get('name');
|
|
147
|
+
return typeof local === 'string' ? local : '';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function priorityOf(cursor: FeatureCursor): number {
|
|
151
|
+
const population = cursor.get('population');
|
|
152
|
+
if (typeof population === 'number' && population > 0) {
|
|
153
|
+
return Math.log10(population + 1);
|
|
154
|
+
}
|
|
155
|
+
const kind = cursor.get('kind');
|
|
156
|
+
return typeof kind === 'string' ? (ROAD_CLASS[kind] ?? 0) : 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A vertex as one number: tile coordinates are integers after scaling,
|
|
160
|
+
* and within ±32768 with the buffer included. */
|
|
161
|
+
const vertexKey = (x: number, y: number): number =>
|
|
162
|
+
(Math.round(x) + 32768) * 65536 + (Math.round(y) + 32768);
|
|
163
|
+
|
|
164
|
+
/** A growable array of anchor records. */
|
|
165
|
+
class AnchorWriter {
|
|
166
|
+
data = new Float32Array(LABEL_STRIDE * 256);
|
|
167
|
+
count = 0;
|
|
168
|
+
|
|
169
|
+
private _next(): number {
|
|
170
|
+
const at = this.count * LABEL_STRIDE;
|
|
171
|
+
if (at + LABEL_STRIDE > this.data.length) {
|
|
172
|
+
const grown = new Float32Array(this.data.length * 2);
|
|
173
|
+
grown.set(this.data);
|
|
174
|
+
this.data = grown;
|
|
175
|
+
}
|
|
176
|
+
this.count++;
|
|
177
|
+
return at;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
point(x: number, y: number, text: number, layer: number, priority: number) {
|
|
181
|
+
const at = this._next();
|
|
182
|
+
const d = this.data;
|
|
183
|
+
d[at + LabelField.x] = x;
|
|
184
|
+
d[at + LabelField.y] = y;
|
|
185
|
+
d[at + LabelField.angle] = 0;
|
|
186
|
+
d[at + LabelField.avail] = -1;
|
|
187
|
+
d[at + LabelField.clear] = FAR;
|
|
188
|
+
d[at + LabelField.length] = 0;
|
|
189
|
+
d[at + LabelField.dev] = 0;
|
|
190
|
+
d[at + LabelField.text] = text;
|
|
191
|
+
d[at + LabelField.layer] = layer;
|
|
192
|
+
d[at + LabelField.priority] = priority;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
line(
|
|
196
|
+
x: number,
|
|
197
|
+
y: number,
|
|
198
|
+
angle: number,
|
|
199
|
+
avail: number,
|
|
200
|
+
clear: number,
|
|
201
|
+
length: number,
|
|
202
|
+
dev: number,
|
|
203
|
+
text: number,
|
|
204
|
+
layer: number,
|
|
205
|
+
priority: number,
|
|
206
|
+
) {
|
|
207
|
+
const at = this._next();
|
|
208
|
+
const d = this.data;
|
|
209
|
+
d[at + LabelField.x] = x;
|
|
210
|
+
d[at + LabelField.y] = y;
|
|
211
|
+
d[at + LabelField.angle] = angle;
|
|
212
|
+
d[at + LabelField.avail] = avail;
|
|
213
|
+
d[at + LabelField.clear] = clear;
|
|
214
|
+
d[at + LabelField.length] = length;
|
|
215
|
+
d[at + LabelField.dev] = dev;
|
|
216
|
+
d[at + LabelField.text] = text;
|
|
217
|
+
d[at + LabelField.layer] = layer;
|
|
218
|
+
d[at + LabelField.priority] = priority;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
take(): Float32Array {
|
|
222
|
+
return this.data.slice(0, this.count * LABEL_STRIDE);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** One name's pieces in one tile, before merging. */
|
|
227
|
+
interface LineGroup {
|
|
228
|
+
text: number;
|
|
229
|
+
priority: number;
|
|
230
|
+
parts: number[][];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* A tile's label anchors, for every symbol layer of the style.
|
|
235
|
+
*
|
|
236
|
+
* `extent` is the tile-unit square the anchors are expressed in — the
|
|
237
|
+
* buckets' {@link import('./buckets.js').TILE_EXTENT}, passed in rather than
|
|
238
|
+
* imported so this module does not import the one that calls it. Anchors
|
|
239
|
+
* are kept only inside the tile's own square: the buffer past its edge is
|
|
240
|
+
* the neighbour's, and a label in it would be offered twice.
|
|
241
|
+
*/
|
|
242
|
+
export function buildTileLabels(
|
|
243
|
+
tile: VectorTile,
|
|
244
|
+
prepared: PreparedStyle,
|
|
245
|
+
extent: number,
|
|
246
|
+
/** Which tile: what turns a `snapInto` distance in metres into tile
|
|
247
|
+
* units. Without it no distance can be known, and only a point already
|
|
248
|
+
* inside a polygon moves. */
|
|
249
|
+
id?: TileId,
|
|
250
|
+
): GlLabelData {
|
|
251
|
+
const started = now();
|
|
252
|
+
const texts: string[] = [];
|
|
253
|
+
const index = new Map<string, number>();
|
|
254
|
+
const out = new AnchorWriter();
|
|
255
|
+
const buffer = new GeometryBuffer();
|
|
256
|
+
|
|
257
|
+
for (let i = 0; i < prepared.layers.length; i++) {
|
|
258
|
+
const { layer, filter } = prepared.layers[i];
|
|
259
|
+
if (layer.type !== 'symbol' || layer.visible === false) continue;
|
|
260
|
+
const source = tile.layers.get(layer.sourceLayer);
|
|
261
|
+
if (!source || source.length === 0) continue;
|
|
262
|
+
const symbol = layer as SymbolLayer;
|
|
263
|
+
const k = extent / source.extent;
|
|
264
|
+
const cursor = source.feature(0);
|
|
265
|
+
const groups = new Map<number, LineGroup>();
|
|
266
|
+
// Which name first touched each vertex, or -1 once a second did.
|
|
267
|
+
const touched = new Map<number, number>();
|
|
268
|
+
// A layer that snaps into polygons collects its points first — x, y,
|
|
269
|
+
// text, priority — since which point a polygon belongs to depends on
|
|
270
|
+
// every other point that could claim it.
|
|
271
|
+
const snap = symbol.snapInto;
|
|
272
|
+
const snaps: number[] | null = snap ? [] : null;
|
|
273
|
+
|
|
274
|
+
for (let f = 0; f < source.length; f++) {
|
|
275
|
+
source.seek(f, cursor);
|
|
276
|
+
if (!filter(cursor)) continue;
|
|
277
|
+
const text = textOf(cursor, symbol.textField);
|
|
278
|
+
if (text.length === 0) continue;
|
|
279
|
+
let t = index.get(text);
|
|
280
|
+
if (t === undefined) {
|
|
281
|
+
t = texts.length;
|
|
282
|
+
texts.push(text);
|
|
283
|
+
index.set(text, t);
|
|
284
|
+
}
|
|
285
|
+
const priority = priorityOf(cursor);
|
|
286
|
+
cursor.readGeometry(buffer);
|
|
287
|
+
if (buffer.points === 0) continue;
|
|
288
|
+
|
|
289
|
+
if (cursor.type === GeomType.LineString) {
|
|
290
|
+
let group = groups.get(t);
|
|
291
|
+
if (!group) {
|
|
292
|
+
group = { text: t, priority, parts: [] };
|
|
293
|
+
groups.set(t, group);
|
|
294
|
+
}
|
|
295
|
+
if (priority > group.priority) group.priority = priority;
|
|
296
|
+
for (let part = 0; part < buffer.parts; part++) {
|
|
297
|
+
const from = buffer.starts[part];
|
|
298
|
+
const to = buffer.starts[part + 1];
|
|
299
|
+
if (to - from < 2) continue;
|
|
300
|
+
const points: number[] = [];
|
|
301
|
+
for (let p = from; p < to; p++) {
|
|
302
|
+
const x = buffer.coords[p * 2] * k;
|
|
303
|
+
const y = buffer.coords[p * 2 + 1] * k;
|
|
304
|
+
// Consecutive duplicates would make zero-length segments, whose
|
|
305
|
+
// direction is undefined.
|
|
306
|
+
const n = points.length;
|
|
307
|
+
if (n > 0 && points[n - 2] === x && points[n - 1] === y) continue;
|
|
308
|
+
points.push(x, y);
|
|
309
|
+
const key = vertexKey(x, y);
|
|
310
|
+
const seen = touched.get(key);
|
|
311
|
+
if (seen === undefined) touched.set(key, t);
|
|
312
|
+
else if (seen !== t) touched.set(key, -1);
|
|
313
|
+
}
|
|
314
|
+
if (points.length >= 4) group.parts.push(points);
|
|
315
|
+
}
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const anchor = pointAnchor(buffer, cursor.type);
|
|
320
|
+
if (!anchor) continue;
|
|
321
|
+
const x = anchor.x * k;
|
|
322
|
+
const y = anchor.y * k;
|
|
323
|
+
if (snaps && cursor.type === GeomType.Point) {
|
|
324
|
+
// The buffer's points too, and judged before the tile's square:
|
|
325
|
+
// a polygon near the edge is claimed by points on either side of
|
|
326
|
+
// it, and both tiles that hold it must see the same claims.
|
|
327
|
+
snaps.push(x, y, t, priority);
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
|
|
331
|
+
out.point(x, y, t, i, priority);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (snap && snaps) {
|
|
335
|
+
const polygons = tile.layers.get(snap.sourceLayer);
|
|
336
|
+
const within = (snap.within ?? SNAP_WITHIN) / metresPerUnit(id, extent);
|
|
337
|
+
snapPoints(polygons, within, snaps, extent, i, out, buffer);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
for (const group of groups.values()) {
|
|
341
|
+
for (const chain of mergeParts(group.parts)) {
|
|
342
|
+
anchorChain(chain, touched, extent, group, i, out);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return { texts, anchors: out.take(), count: out.count, ms: now() - started };
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** How far a point is taken to belong to a polygon it is outside, metres,
|
|
351
|
+
* where the layer does not say. An address point in the lot sits a few
|
|
352
|
+
* metres off its house; much past this, the nearest building is as often
|
|
353
|
+
* a neighbour's — the house the number is for not being mapped at all. */
|
|
354
|
+
const SNAP_WITHIN = 15;
|
|
355
|
+
/** The earth's circumference at the equator, metres (Web Mercator's). */
|
|
356
|
+
const EQUATOR = 40075016.686;
|
|
357
|
+
|
|
358
|
+
/** Metres on the ground per tile unit, at the tile's middle row. */
|
|
359
|
+
function metresPerUnit(id: TileId | undefined, extent: number): number {
|
|
360
|
+
const n = 2 ** (id?.z ?? 0);
|
|
361
|
+
const lat = id ? latFromMercatorY((id.y + 0.5) / n) : 0;
|
|
362
|
+
return (EQUATOR * Math.cos((lat * Math.PI) / 180)) / (n * extent);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** One polygon's outer ring, in tile units: its points, its box, and the
|
|
366
|
+
* point inside it a label moved into it is set on. */
|
|
367
|
+
interface SnapRing {
|
|
368
|
+
points: number[];
|
|
369
|
+
x0: number;
|
|
370
|
+
y0: number;
|
|
371
|
+
x1: number;
|
|
372
|
+
y1: number;
|
|
373
|
+
cx: number;
|
|
374
|
+
cy: number;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/** The grid rings are found by, in tile units: a z14 tile is 16 cells a
|
|
378
|
+
* side, a few dozen buildings each. */
|
|
379
|
+
const SNAP_CELL = 256;
|
|
380
|
+
const snapCell = (gx: number, gy: number): number =>
|
|
381
|
+
(gx + 1024) * 4096 + (gy + 1024);
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Point labels moved into the polygon each one belongs to — a house number
|
|
385
|
+
* into its house.
|
|
386
|
+
*
|
|
387
|
+
* A point inside a polygon belongs to it; one outside, to the nearest
|
|
388
|
+
* polygon whose outline is within `within` tile units. It moves only if it
|
|
389
|
+
* is the **one** point its polygon is claimed by: a duplex's two numbers, or
|
|
390
|
+
* a garage nearer the street than the house, would otherwise pile several
|
|
391
|
+
* numbers onto one roof — and collision would then keep one of them, on a
|
|
392
|
+
* building that is not only its own. Every point that does not move stays
|
|
393
|
+
* exactly where the data put it.
|
|
394
|
+
*
|
|
395
|
+
* `points` are the whole tile's, buffer included, so a polygon near the edge
|
|
396
|
+
* is claimed alike in both tiles that hold it; each point is then anchored
|
|
397
|
+
* only in the tile its own position is in, as every other point is. One
|
|
398
|
+
* whose polygon's middle is in the next tile over stays put rather than
|
|
399
|
+
* move out of the tile that offers it.
|
|
400
|
+
*/
|
|
401
|
+
function snapPoints(
|
|
402
|
+
polygons: VectorTileLayer | undefined,
|
|
403
|
+
within: number,
|
|
404
|
+
points: readonly number[],
|
|
405
|
+
extent: number,
|
|
406
|
+
layer: number,
|
|
407
|
+
out: AnchorWriter,
|
|
408
|
+
buffer: GeometryBuffer,
|
|
409
|
+
): void {
|
|
410
|
+
const count = points.length / 4;
|
|
411
|
+
const target = new Int32Array(count).fill(-1);
|
|
412
|
+
const rings = polygons ? snapRings(polygons, extent, buffer) : [];
|
|
413
|
+
if (rings.length > 0) {
|
|
414
|
+
const grid = new Map<number, number[]>();
|
|
415
|
+
rings.forEach((ring, r) => {
|
|
416
|
+
for (let gx = cellOf(ring.x0); gx <= cellOf(ring.x1); gx++) {
|
|
417
|
+
for (let gy = cellOf(ring.y0); gy <= cellOf(ring.y1); gy++) {
|
|
418
|
+
const key = snapCell(gx, gy);
|
|
419
|
+
const list = grid.get(key);
|
|
420
|
+
if (list) list.push(r);
|
|
421
|
+
else grid.set(key, [r]);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
const claims = new Int32Array(rings.length);
|
|
426
|
+
// Which query last looked at each ring: a ring spanning several cells
|
|
427
|
+
// is one candidate, not several.
|
|
428
|
+
const seen = new Int32Array(rings.length).fill(-1);
|
|
429
|
+
for (let p = 0; p < count; p++) {
|
|
430
|
+
const r = ownerOf(
|
|
431
|
+
rings,
|
|
432
|
+
grid,
|
|
433
|
+
seen,
|
|
434
|
+
p,
|
|
435
|
+
points[p * 4],
|
|
436
|
+
points[p * 4 + 1],
|
|
437
|
+
within,
|
|
438
|
+
);
|
|
439
|
+
if (r >= 0) {
|
|
440
|
+
target[p] = r;
|
|
441
|
+
claims[r]++;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
for (let p = 0; p < count; p++) {
|
|
445
|
+
if (target[p] >= 0 && claims[target[p]] !== 1) target[p] = -1;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
for (let p = 0; p < count; p++) {
|
|
449
|
+
let x = points[p * 4];
|
|
450
|
+
let y = points[p * 4 + 1];
|
|
451
|
+
if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
|
|
452
|
+
const r = target[p];
|
|
453
|
+
if (r >= 0) {
|
|
454
|
+
const ring = rings[r];
|
|
455
|
+
if (
|
|
456
|
+
ring.cx >= 0 &&
|
|
457
|
+
ring.cy >= 0 &&
|
|
458
|
+
ring.cx < extent &&
|
|
459
|
+
ring.cy < extent
|
|
460
|
+
) {
|
|
461
|
+
x = ring.cx;
|
|
462
|
+
y = ring.cy;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
out.point(x, y, points[p * 4 + 2], layer, points[p * 4 + 3]);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const cellOf = (v: number): number => Math.floor(v / SNAP_CELL);
|
|
470
|
+
|
|
471
|
+
/** Every polygon's outer rings, in tile units. Holes are not a building's
|
|
472
|
+
* own ground, and a courtyard is not where a number goes. */
|
|
473
|
+
function snapRings(
|
|
474
|
+
source: VectorTileLayer,
|
|
475
|
+
extent: number,
|
|
476
|
+
buffer: GeometryBuffer,
|
|
477
|
+
): SnapRing[] {
|
|
478
|
+
const k = extent / source.extent;
|
|
479
|
+
const cursor = source.feature(0);
|
|
480
|
+
const rings: SnapRing[] = [];
|
|
481
|
+
for (let f = 0; f < source.length; f++) {
|
|
482
|
+
source.seek(f, cursor);
|
|
483
|
+
if (cursor.type !== GeomType.Polygon) continue;
|
|
484
|
+
cursor.readGeometry(buffer);
|
|
485
|
+
for (let part = 0; part < buffer.parts; part++) {
|
|
486
|
+
if (buffer.areas[part] <= 0) continue;
|
|
487
|
+
const from = buffer.starts[part];
|
|
488
|
+
const to = buffer.starts[part + 1];
|
|
489
|
+
if (to - from < 3) continue;
|
|
490
|
+
const points: number[] = [];
|
|
491
|
+
let x0 = Infinity;
|
|
492
|
+
let y0 = Infinity;
|
|
493
|
+
let x1 = -Infinity;
|
|
494
|
+
let y1 = -Infinity;
|
|
495
|
+
for (let p = from; p < to; p++) {
|
|
496
|
+
const x = buffer.coords[p * 2] * k;
|
|
497
|
+
const y = buffer.coords[p * 2 + 1] * k;
|
|
498
|
+
points.push(x, y);
|
|
499
|
+
if (x < x0) x0 = x;
|
|
500
|
+
if (x > x1) x1 = x;
|
|
501
|
+
if (y < y0) y0 = y;
|
|
502
|
+
if (y > y1) y1 = y;
|
|
503
|
+
}
|
|
504
|
+
const [cx, cy] = interiorPoint(points, x0, y0, x1, y1);
|
|
505
|
+
rings.push({ points, x0, y0, x1, y1, cx, cy });
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return rings;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* A point inside a ring to set a label on: its centroid, which is inside
|
|
513
|
+
* for all but the most contorted outline — 99.8% of the building rings in
|
|
514
|
+
* the tiles this was measured on — and where it is not, the middle of the
|
|
515
|
+
* widest span of the ring along the centroid's row.
|
|
516
|
+
*/
|
|
517
|
+
function interiorPoint(
|
|
518
|
+
points: readonly number[],
|
|
519
|
+
x0: number,
|
|
520
|
+
y0: number,
|
|
521
|
+
x1: number,
|
|
522
|
+
y1: number,
|
|
523
|
+
): [number, number] {
|
|
524
|
+
let area = 0;
|
|
525
|
+
let sx = 0;
|
|
526
|
+
let sy = 0;
|
|
527
|
+
const n = points.length;
|
|
528
|
+
for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
|
|
529
|
+
const cross = points[j] * points[i + 1] - points[i] * points[j + 1];
|
|
530
|
+
area += cross;
|
|
531
|
+
sx += (points[j] + points[i]) * cross;
|
|
532
|
+
sy += (points[j + 1] + points[i + 1]) * cross;
|
|
533
|
+
}
|
|
534
|
+
if (area === 0) return [(x0 + x1) / 2, (y0 + y1) / 2];
|
|
535
|
+
const cx = sx / (3 * area);
|
|
536
|
+
const cy = sy / (3 * area);
|
|
537
|
+
if (insideRing(points, cx, cy)) return [cx, cy];
|
|
538
|
+
const crossings: number[] = [];
|
|
539
|
+
for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
|
|
540
|
+
const ay = points[j + 1];
|
|
541
|
+
const by = points[i + 1];
|
|
542
|
+
if (ay > cy !== by > cy) {
|
|
543
|
+
crossings.push(
|
|
544
|
+
points[j] + ((cy - ay) / (by - ay)) * (points[i] - points[j]),
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
crossings.sort((a, b) => a - b);
|
|
549
|
+
let best = -1;
|
|
550
|
+
let mid = (x0 + x1) / 2;
|
|
551
|
+
for (let c = 0; c + 1 < crossings.length; c += 2) {
|
|
552
|
+
const span = crossings[c + 1] - crossings[c];
|
|
553
|
+
if (span > best) {
|
|
554
|
+
best = span;
|
|
555
|
+
mid = (crossings[c] + crossings[c + 1]) / 2;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return [mid, cy];
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/** Even-odd: whether `x, y` is inside the ring. */
|
|
562
|
+
function insideRing(points: readonly number[], x: number, y: number): boolean {
|
|
563
|
+
let inside = false;
|
|
564
|
+
const n = points.length;
|
|
565
|
+
for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
|
|
566
|
+
const xi = points[i];
|
|
567
|
+
const yi = points[i + 1];
|
|
568
|
+
const xj = points[j];
|
|
569
|
+
const yj = points[j + 1];
|
|
570
|
+
if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) {
|
|
571
|
+
inside = !inside;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return inside;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** How far `x, y` is from the ring's outline. */
|
|
578
|
+
function distanceToRing(points: readonly number[], x: number, y: number) {
|
|
579
|
+
let best = Infinity;
|
|
580
|
+
const n = points.length;
|
|
581
|
+
for (let i = 0, j = n - 2; i < n; j = i, i += 2) {
|
|
582
|
+
const ax = points[j];
|
|
583
|
+
const ay = points[j + 1];
|
|
584
|
+
const dx = points[i] - ax;
|
|
585
|
+
const dy = points[i + 1] - ay;
|
|
586
|
+
const length = dx * dx + dy * dy;
|
|
587
|
+
const t =
|
|
588
|
+
length > 0
|
|
589
|
+
? Math.max(0, Math.min(1, ((x - ax) * dx + (y - ay) * dy) / length))
|
|
590
|
+
: 0;
|
|
591
|
+
const d = Math.hypot(x - ax - t * dx, y - ay - t * dy);
|
|
592
|
+
if (d < best) best = d;
|
|
593
|
+
}
|
|
594
|
+
return best;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/** The ring a point belongs to — the one it is inside, else the nearest
|
|
598
|
+
* within `within` — or -1. */
|
|
599
|
+
function ownerOf(
|
|
600
|
+
rings: readonly SnapRing[],
|
|
601
|
+
grid: Map<number, number[]>,
|
|
602
|
+
seen: Int32Array,
|
|
603
|
+
query: number,
|
|
604
|
+
x: number,
|
|
605
|
+
y: number,
|
|
606
|
+
within: number,
|
|
607
|
+
): number {
|
|
608
|
+
let best = -1;
|
|
609
|
+
let bestDistance = within;
|
|
610
|
+
for (let gx = cellOf(x - within); gx <= cellOf(x + within); gx++) {
|
|
611
|
+
for (let gy = cellOf(y - within); gy <= cellOf(y + within); gy++) {
|
|
612
|
+
for (const r of grid.get(snapCell(gx, gy)) ?? []) {
|
|
613
|
+
if (seen[r] === query) continue;
|
|
614
|
+
seen[r] = query;
|
|
615
|
+
const ring = rings[r];
|
|
616
|
+
// Past the box by more than the distance allowed: not a candidate.
|
|
617
|
+
const bx = Math.max(ring.x0 - x, 0, x - ring.x1);
|
|
618
|
+
const by = Math.max(ring.y0 - y, 0, y - ring.y1);
|
|
619
|
+
if (bx > bestDistance || by > bestDistance) continue;
|
|
620
|
+
if (bx === 0 && by === 0 && insideRing(ring.points, x, y)) return r;
|
|
621
|
+
const d = distanceToRing(ring.points, x, y);
|
|
622
|
+
if (d <= bestDistance) {
|
|
623
|
+
best = r;
|
|
624
|
+
bestDistance = d;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return best;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Where a point-like feature's label goes: the point, or for a polygon the
|
|
634
|
+
* middle of its largest ring's box — a cheap stand-in for the pole of
|
|
635
|
+
* inaccessibility that lands inside every convex shape.
|
|
636
|
+
*/
|
|
637
|
+
function pointAnchor(
|
|
638
|
+
buffer: GeometryBuffer,
|
|
639
|
+
type: GeomType,
|
|
640
|
+
): { x: number; y: number } | null {
|
|
641
|
+
if (buffer.points === 0) return null;
|
|
642
|
+
if (type === GeomType.Point) {
|
|
643
|
+
return { x: buffer.coords[0], y: buffer.coords[1] };
|
|
644
|
+
}
|
|
645
|
+
let best = 0;
|
|
646
|
+
let bestArea = -1;
|
|
647
|
+
for (let part = 0; part < buffer.parts; part++) {
|
|
648
|
+
const area = Math.abs(buffer.areas[part]);
|
|
649
|
+
if (area > bestArea) {
|
|
650
|
+
bestArea = area;
|
|
651
|
+
best = part;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const b = best * 4;
|
|
655
|
+
return {
|
|
656
|
+
x: (buffer.partBounds[b] + buffer.partBounds[b + 2]) / 2,
|
|
657
|
+
y: (buffer.partBounds[b + 1] + buffer.partBounds[b + 3]) / 2,
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Join one name's pieces into the polylines they were cut from.
|
|
663
|
+
*
|
|
664
|
+
* Pieces meet at shared end points, in either direction. Where more than one
|
|
665
|
+
* piece continues from a point — a fork, or a dual carriageway's two halves
|
|
666
|
+
* — the one that turns least is taken, so a chain follows the street the way
|
|
667
|
+
* a reader's eye does. Every piece is used exactly once.
|
|
668
|
+
*/
|
|
669
|
+
export function mergeParts(parts: readonly number[][]): number[][] {
|
|
670
|
+
const ends = new Map<number, number[]>();
|
|
671
|
+
const add = (key: number, end: number): void => {
|
|
672
|
+
const list = ends.get(key);
|
|
673
|
+
if (list) list.push(end);
|
|
674
|
+
else ends.set(key, [end]);
|
|
675
|
+
};
|
|
676
|
+
for (let i = 0; i < parts.length; i++) {
|
|
677
|
+
const p = parts[i];
|
|
678
|
+
add(vertexKey(p[0], p[1]), i * 2);
|
|
679
|
+
add(vertexKey(p[p.length - 2], p[p.length - 1]), i * 2 + 1);
|
|
680
|
+
}
|
|
681
|
+
const used = new Uint8Array(parts.length);
|
|
682
|
+
|
|
683
|
+
/** The unused piece that continues from `(x, y)` heading `(dx, dy)` with
|
|
684
|
+
* the least turn, oriented to start there; or null. */
|
|
685
|
+
const next = (
|
|
686
|
+
x: number,
|
|
687
|
+
y: number,
|
|
688
|
+
dx: number,
|
|
689
|
+
dy: number,
|
|
690
|
+
): number[] | null => {
|
|
691
|
+
const list = ends.get(vertexKey(x, y));
|
|
692
|
+
if (!list) return null;
|
|
693
|
+
let best: number[] | null = null;
|
|
694
|
+
let bestIndex = -1;
|
|
695
|
+
let bestDot = -Infinity;
|
|
696
|
+
for (const end of list) {
|
|
697
|
+
const i = end >> 1;
|
|
698
|
+
if (used[i]) continue;
|
|
699
|
+
const p = parts[i];
|
|
700
|
+
const oriented = end & 1 ? reversed(p) : p;
|
|
701
|
+
const ux = oriented[2] - oriented[0];
|
|
702
|
+
const uy = oriented[3] - oriented[1];
|
|
703
|
+
const len = Math.hypot(ux, uy) || 1;
|
|
704
|
+
const dot = (ux * dx + uy * dy) / len;
|
|
705
|
+
if (dot > bestDot) {
|
|
706
|
+
bestDot = dot;
|
|
707
|
+
best = oriented;
|
|
708
|
+
bestIndex = i;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
if (best) used[bestIndex] = 1;
|
|
712
|
+
return best;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
const chains: number[][] = [];
|
|
716
|
+
for (let i = 0; i < parts.length; i++) {
|
|
717
|
+
if (used[i]) continue;
|
|
718
|
+
used[i] = 1;
|
|
719
|
+
let chain = parts[i].slice();
|
|
720
|
+
// Forward from the end, then forward from the start of the reversed
|
|
721
|
+
// chain — which is backward from the original start.
|
|
722
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
723
|
+
for (;;) {
|
|
724
|
+
const n = chain.length;
|
|
725
|
+
const dx = chain[n - 2] - chain[n - 4];
|
|
726
|
+
const dy = chain[n - 1] - chain[n - 3];
|
|
727
|
+
const len = Math.hypot(dx, dy) || 1;
|
|
728
|
+
const more = next(chain[n - 2], chain[n - 1], dx / len, dy / len);
|
|
729
|
+
if (!more) break;
|
|
730
|
+
for (let j = 2; j < more.length; j++) chain.push(more[j]);
|
|
731
|
+
}
|
|
732
|
+
chain = reversed(chain);
|
|
733
|
+
}
|
|
734
|
+
chains.push(chain);
|
|
735
|
+
}
|
|
736
|
+
return chains;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
function reversed(points: readonly number[]): number[] {
|
|
740
|
+
const out = new Array<number>(points.length);
|
|
741
|
+
for (let i = 0, j = points.length - 2; j >= 0; i += 2, j -= 2) {
|
|
742
|
+
out[i] = points[j];
|
|
743
|
+
out[i + 1] = points[j + 1];
|
|
744
|
+
}
|
|
745
|
+
return out;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/** A maximal straight stretch of a chain: vertices `[from, to]`. */
|
|
749
|
+
export interface StraightRun {
|
|
750
|
+
from: number;
|
|
751
|
+
to: number;
|
|
752
|
+
/** The chord's length, and the furthest vertex from it. */
|
|
753
|
+
length: number;
|
|
754
|
+
dev: number;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* A chain's maximal straight runs, greedily from its start: a run grows a
|
|
759
|
+
* vertex at a time while every vertex inside it stays within `tolerance`
|
|
760
|
+
* of the chord and no vertex turns sharper than {@link MAX_TURN}. A run
|
|
761
|
+
* ends at the last vertex that kept it straight, and the next one starts
|
|
762
|
+
* there, so runs share their end points and cover the whole chain.
|
|
763
|
+
*/
|
|
764
|
+
export function straightRuns(
|
|
765
|
+
chain: readonly number[],
|
|
766
|
+
tolerance = STRAIGHT,
|
|
767
|
+
): StraightRun[] {
|
|
768
|
+
const n = chain.length / 2;
|
|
769
|
+
const runs: StraightRun[] = [];
|
|
770
|
+
let from = 0;
|
|
771
|
+
while (from < n - 1) {
|
|
772
|
+
let to = from + 1;
|
|
773
|
+
let dev = 0;
|
|
774
|
+
while (to + 1 < n) {
|
|
775
|
+
const d = deviation(chain, from, to + 1);
|
|
776
|
+
if (d > tolerance || !gentle(chain, to)) break;
|
|
777
|
+
dev = d;
|
|
778
|
+
to++;
|
|
779
|
+
}
|
|
780
|
+
const length = Math.hypot(
|
|
781
|
+
chain[to * 2] - chain[from * 2],
|
|
782
|
+
chain[to * 2 + 1] - chain[from * 2 + 1],
|
|
783
|
+
);
|
|
784
|
+
runs.push({ from, to, length, dev });
|
|
785
|
+
from = to;
|
|
786
|
+
}
|
|
787
|
+
return runs;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/** The greatest distance of vertices strictly inside `(from, to)` from the
|
|
791
|
+
* chord between them. */
|
|
792
|
+
function deviation(chain: readonly number[], from: number, to: number): number {
|
|
793
|
+
const ax = chain[from * 2];
|
|
794
|
+
const ay = chain[from * 2 + 1];
|
|
795
|
+
const dx = chain[to * 2] - ax;
|
|
796
|
+
const dy = chain[to * 2 + 1] - ay;
|
|
797
|
+
const len = Math.hypot(dx, dy);
|
|
798
|
+
if (len === 0) return Infinity;
|
|
799
|
+
let worst = 0;
|
|
800
|
+
for (let m = from + 1; m < to; m++) {
|
|
801
|
+
const px = chain[m * 2] - ax;
|
|
802
|
+
const py = chain[m * 2 + 1] - ay;
|
|
803
|
+
// Off the chord's ends counts as off the chord: a run that doubles back
|
|
804
|
+
// is not straight however close its points stay to the line.
|
|
805
|
+
const along = (px * dx + py * dy) / len;
|
|
806
|
+
const off =
|
|
807
|
+
along < 0
|
|
808
|
+
? Math.hypot(px, py)
|
|
809
|
+
: along > len
|
|
810
|
+
? Math.hypot(px - dx, py - dy)
|
|
811
|
+
: Math.abs(px * dy - py * dx) / len;
|
|
812
|
+
if (off > worst) worst = off;
|
|
813
|
+
}
|
|
814
|
+
return worst;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/** Whether the turn at vertex `m` is gentle enough to stay in a run. */
|
|
818
|
+
function gentle(chain: readonly number[], m: number): boolean {
|
|
819
|
+
const ax = chain[m * 2] - chain[m * 2 - 2];
|
|
820
|
+
const ay = chain[m * 2 + 1] - chain[m * 2 - 1];
|
|
821
|
+
const bx = chain[m * 2 + 2] - chain[m * 2];
|
|
822
|
+
const by = chain[m * 2 + 3] - chain[m * 2 + 1];
|
|
823
|
+
const la = Math.hypot(ax, ay);
|
|
824
|
+
const lb = Math.hypot(bx, by);
|
|
825
|
+
if (la === 0 || lb === 0) return true;
|
|
826
|
+
return (ax * bx + ay * by) / (la * lb) >= MAX_TURN;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/** How far past vertical a name still reads bottom to top. */
|
|
830
|
+
const VERTICAL_BIAS = (10 * Math.PI) / 180;
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* A direction, turned to read left to right — and, near vertical, bottom
|
|
834
|
+
* to top: within [-π/2 - 10°, π/2 - 10°), y down, so -π/2 points up the
|
|
835
|
+
* screen. Without the bias, two streets a few degrees either side of
|
|
836
|
+
* vertical read in opposite directions side by side; with it, every
|
|
837
|
+
* near-vertical name reads the way maps set them, upward.
|
|
838
|
+
*/
|
|
839
|
+
export function upright(angle: number): number {
|
|
840
|
+
let a = angle;
|
|
841
|
+
while (a >= Math.PI / 2 - VERTICAL_BIAS) a -= Math.PI;
|
|
842
|
+
while (a < -Math.PI / 2 - VERTICAL_BIAS) a += Math.PI;
|
|
843
|
+
return a;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/** Every anchor one merged chain offers. */
|
|
847
|
+
function anchorChain(
|
|
848
|
+
chain: readonly number[],
|
|
849
|
+
touched: Map<number, number>,
|
|
850
|
+
extent: number,
|
|
851
|
+
group: LineGroup,
|
|
852
|
+
layer: number,
|
|
853
|
+
out: AnchorWriter,
|
|
854
|
+
): void {
|
|
855
|
+
for (const run of straightRuns(chain)) {
|
|
856
|
+
const L = run.length;
|
|
857
|
+
if (L < MIN_RUN) continue;
|
|
858
|
+
const ax = chain[run.from * 2];
|
|
859
|
+
const ay = chain[run.from * 2 + 1];
|
|
860
|
+
const ux = (chain[run.to * 2] - ax) / L;
|
|
861
|
+
const uy = (chain[run.to * 2 + 1] - ay) / L;
|
|
862
|
+
// Where along the chord the run's junctions are.
|
|
863
|
+
const junctions: number[] = [];
|
|
864
|
+
for (let m = run.from; m <= run.to; m++) {
|
|
865
|
+
const x = chain[m * 2];
|
|
866
|
+
const y = chain[m * 2 + 1];
|
|
867
|
+
if (touched.get(vertexKey(x, y)) !== -1) continue;
|
|
868
|
+
junctions.push((x - ax) * ux + (y - ay) * uy);
|
|
869
|
+
}
|
|
870
|
+
junctions.sort((a, b) => a - b);
|
|
871
|
+
|
|
872
|
+
// The run's middle, the middle of every block, and — on a run with no
|
|
873
|
+
// junction at all — every SPACING either side of the middle.
|
|
874
|
+
const at: number[] = [L / 2];
|
|
875
|
+
const bounds = [0, ...junctions, L];
|
|
876
|
+
for (let b = 0; b + 1 < bounds.length; b++) {
|
|
877
|
+
if (bounds[b + 1] - bounds[b] >= MIN_RUN) {
|
|
878
|
+
at.push((bounds[b] + bounds[b + 1]) / 2);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (junctions.length === 0) {
|
|
882
|
+
for (let s = SPACING; L / 2 + s <= L - SPACING / 2; s += SPACING) {
|
|
883
|
+
at.push(L / 2 + s, L / 2 - s);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
at.sort((a, b) => a - b);
|
|
887
|
+
|
|
888
|
+
const angle = upright(Math.atan2(uy, ux));
|
|
889
|
+
let last = -Infinity;
|
|
890
|
+
for (const s of at) {
|
|
891
|
+
// Two anchors closer than a few pixels are one anchor twice.
|
|
892
|
+
if (s - last < 32) continue;
|
|
893
|
+
last = s;
|
|
894
|
+
const x = ax + ux * s;
|
|
895
|
+
const y = ay + uy * s;
|
|
896
|
+
if (x < 0 || y < 0 || x >= extent || y >= extent) continue;
|
|
897
|
+
let clear = FAR;
|
|
898
|
+
for (const j of junctions) clear = Math.min(clear, Math.abs(j - s));
|
|
899
|
+
out.line(
|
|
900
|
+
x,
|
|
901
|
+
y,
|
|
902
|
+
angle,
|
|
903
|
+
Math.min(s, L - s),
|
|
904
|
+
clear,
|
|
905
|
+
L,
|
|
906
|
+
run.dev,
|
|
907
|
+
group.text,
|
|
908
|
+
layer,
|
|
909
|
+
group.priority,
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|