@mapwhit/tilerenderer 0.47.1

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.
Files changed (356) hide show
  1. package/LICENSE.txt +87 -0
  2. package/README.md +25 -0
  3. package/build/min/.dir +0 -0
  4. package/build/min/package.json +3 -0
  5. package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
  6. package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
  7. package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
  8. package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
  9. package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
  10. package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
  11. package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
  12. package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
  13. package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
  14. package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
  15. package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
  16. package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
  17. package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
  18. package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
  19. package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
  20. package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
  21. package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
  22. package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
  23. package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
  24. package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
  25. package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
  26. package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
  27. package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
  28. package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
  29. package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
  30. package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
  31. package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
  32. package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
  33. package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
  34. package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
  35. package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
  36. package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
  37. package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
  38. package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
  39. package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
  40. package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
  41. package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
  42. package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
  43. package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
  44. package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
  45. package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
  46. package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
  47. package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
  48. package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
  49. package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
  50. package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
  51. package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
  52. package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
  53. package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
  54. package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
  55. package/package.json +44 -0
  56. package/src/css/mapbox-gl.css +506 -0
  57. package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
  58. package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
  59. package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
  60. package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
  61. package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
  62. package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
  63. package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
  64. package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
  65. package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
  66. package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
  67. package/src/data/array_types.js +1138 -0
  68. package/src/data/bucket/circle_attributes.js +5 -0
  69. package/src/data/bucket/circle_bucket.js +118 -0
  70. package/src/data/bucket/fill_attributes.js +5 -0
  71. package/src/data/bucket/fill_bucket.js +166 -0
  72. package/src/data/bucket/fill_extrusion_attributes.js +11 -0
  73. package/src/data/bucket/fill_extrusion_bucket.js +247 -0
  74. package/src/data/bucket/heatmap_bucket.js +12 -0
  75. package/src/data/bucket/line_attributes.js +11 -0
  76. package/src/data/bucket/line_bucket.js +625 -0
  77. package/src/data/bucket/pattern_attributes.js +9 -0
  78. package/src/data/bucket/pattern_bucket_features.js +44 -0
  79. package/src/data/bucket/symbol_attributes.js +95 -0
  80. package/src/data/bucket/symbol_bucket.js +697 -0
  81. package/src/data/bucket.js +53 -0
  82. package/src/data/dem_data.js +126 -0
  83. package/src/data/extent.js +17 -0
  84. package/src/data/feature_index.js +254 -0
  85. package/src/data/index_array_type.js +14 -0
  86. package/src/data/load_geometry.js +42 -0
  87. package/src/data/pos_attributes.js +3 -0
  88. package/src/data/program_configuration.js +782 -0
  89. package/src/data/raster_bounds_attributes.js +6 -0
  90. package/src/data/segment.js +63 -0
  91. package/src/geo/coordinate.js +78 -0
  92. package/src/geo/lng_lat.js +129 -0
  93. package/src/geo/lng_lat_bounds.js +253 -0
  94. package/src/geo/transform.js +605 -0
  95. package/src/gl/color_mode.js +21 -0
  96. package/src/gl/context.js +193 -0
  97. package/src/gl/cull_face_mode.js +22 -0
  98. package/src/gl/depth_mode.js +18 -0
  99. package/src/gl/framebuffer.js +28 -0
  100. package/src/gl/index_buffer.js +52 -0
  101. package/src/gl/stencil_mode.js +17 -0
  102. package/src/gl/types.js +0 -0
  103. package/src/gl/value.js +676 -0
  104. package/src/gl/vertex_buffer.js +101 -0
  105. package/src/index.js +50 -0
  106. package/src/render/draw_background.js +60 -0
  107. package/src/render/draw_circle.js +55 -0
  108. package/src/render/draw_collision_debug.js +45 -0
  109. package/src/render/draw_debug.js +429 -0
  110. package/src/render/draw_fill.js +143 -0
  111. package/src/render/draw_fill_extrusion.js +101 -0
  112. package/src/render/draw_heatmap.js +159 -0
  113. package/src/render/draw_hillshade.js +144 -0
  114. package/src/render/draw_line.js +99 -0
  115. package/src/render/draw_raster.js +151 -0
  116. package/src/render/draw_symbol.js +231 -0
  117. package/src/render/glyph_atlas.js +55 -0
  118. package/src/render/glyph_manager.js +145 -0
  119. package/src/render/image_atlas.js +97 -0
  120. package/src/render/image_manager.js +183 -0
  121. package/src/render/line_atlas.js +139 -0
  122. package/src/render/painter.js +483 -0
  123. package/src/render/program/background_program.js +46 -0
  124. package/src/render/program/circle_program.js +40 -0
  125. package/src/render/program/clipping_mask_program.js +11 -0
  126. package/src/render/program/collision_program.js +28 -0
  127. package/src/render/program/debug_program.js +13 -0
  128. package/src/render/program/fill_extrusion_program.js +76 -0
  129. package/src/render/program/fill_program.js +60 -0
  130. package/src/render/program/heatmap_program.js +46 -0
  131. package/src/render/program/hillshade_program.js +77 -0
  132. package/src/render/program/line_program.js +119 -0
  133. package/src/render/program/pattern.js +57 -0
  134. package/src/render/program/program_uniforms.js +46 -0
  135. package/src/render/program/raster_program.js +50 -0
  136. package/src/render/program/symbol_program.js +112 -0
  137. package/src/render/program.js +133 -0
  138. package/src/render/texture.js +88 -0
  139. package/src/render/tile_mask.js +108 -0
  140. package/src/render/uniform_binding.js +129 -0
  141. package/src/render/vertex_array_object.js +155 -0
  142. package/src/shaders/README.md +42 -0
  143. package/src/shaders/_prelude.fragment.glsl +17 -0
  144. package/src/shaders/_prelude.vertex.glsl +73 -0
  145. package/src/shaders/background.fragment.glsl +10 -0
  146. package/src/shaders/background.vertex.glsl +7 -0
  147. package/src/shaders/background_pattern.fragment.glsl +28 -0
  148. package/src/shaders/background_pattern.vertex.glsl +20 -0
  149. package/src/shaders/circle.fragment.glsl +39 -0
  150. package/src/shaders/circle.vertex.glsl +63 -0
  151. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  152. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  153. package/src/shaders/collision_box.fragment.glsl +21 -0
  154. package/src/shaders/collision_box.vertex.glsl +26 -0
  155. package/src/shaders/collision_circle.fragment.glsl +34 -0
  156. package/src/shaders/collision_circle.vertex.glsl +36 -0
  157. package/src/shaders/debug.fragment.glsl +5 -0
  158. package/src/shaders/debug.vertex.glsl +7 -0
  159. package/src/shaders/encode_attribute.js +19 -0
  160. package/src/shaders/fill.fragment.glsl +13 -0
  161. package/src/shaders/fill.vertex.glsl +13 -0
  162. package/src/shaders/fill_extrusion.fragment.glsl +16 -0
  163. package/src/shaders/fill_extrusion.vertex.glsl +66 -0
  164. package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
  165. package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
  166. package/src/shaders/fill_outline.fragment.glsl +17 -0
  167. package/src/shaders/fill_outline.vertex.glsl +17 -0
  168. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  169. package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
  170. package/src/shaders/fill_pattern.fragment.glsl +36 -0
  171. package/src/shaders/fill_pattern.vertex.glsl +36 -0
  172. package/src/shaders/heatmap.fragment.glsl +21 -0
  173. package/src/shaders/heatmap.vertex.glsl +53 -0
  174. package/src/shaders/heatmap_texture.fragment.glsl +14 -0
  175. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  176. package/src/shaders/hillshade.fragment.glsl +52 -0
  177. package/src/shaders/hillshade.vertex.glsl +11 -0
  178. package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
  179. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  180. package/src/shaders/index.js +194 -0
  181. package/src/shaders/line.fragment.glsl +28 -0
  182. package/src/shaders/line.vertex.glsl +84 -0
  183. package/src/shaders/line_gradient.fragment.glsl +34 -0
  184. package/src/shaders/line_gradient.vertex.glsl +84 -0
  185. package/src/shaders/line_pattern.fragment.glsl +69 -0
  186. package/src/shaders/line_pattern.vertex.glsl +88 -0
  187. package/src/shaders/line_sdf.fragment.glsl +44 -0
  188. package/src/shaders/line_sdf.vertex.glsl +95 -0
  189. package/src/shaders/raster.fragment.glsl +52 -0
  190. package/src/shaders/raster.vertex.glsl +21 -0
  191. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  192. package/src/shaders/symbol_icon.vertex.glsl +91 -0
  193. package/src/shaders/symbol_sdf.fragment.glsl +50 -0
  194. package/src/shaders/symbol_sdf.vertex.glsl +117 -0
  195. package/src/source/geojson_source.js +267 -0
  196. package/src/source/geojson_worker_source.js +210 -0
  197. package/src/source/geojson_wrapper.js +67 -0
  198. package/src/source/image_source.js +213 -0
  199. package/src/source/load_tilejson.js +40 -0
  200. package/src/source/pixels_to_tile_units.js +17 -0
  201. package/src/source/query_features.js +198 -0
  202. package/src/source/raster_dem_tile_source.js +140 -0
  203. package/src/source/raster_dem_tile_worker_source.js +26 -0
  204. package/src/source/raster_tile_source.js +126 -0
  205. package/src/source/rtl_text_plugin.js +63 -0
  206. package/src/source/source.js +75 -0
  207. package/src/source/source_cache.js +794 -0
  208. package/src/source/source_state.js +55 -0
  209. package/src/source/tile.js +332 -0
  210. package/src/source/tile_bounds.js +40 -0
  211. package/src/source/tile_cache.js +122 -0
  212. package/src/source/tile_id.js +150 -0
  213. package/src/source/vector_tile_source.js +144 -0
  214. package/src/source/vector_tile_worker_source.js +126 -0
  215. package/src/source/worker.js +175 -0
  216. package/src/source/worker_source.js +14 -0
  217. package/src/source/worker_tile.js +199 -0
  218. package/src/style/create_style_layer.js +25 -0
  219. package/src/style/evaluation_parameters.js +45 -0
  220. package/src/style/light.js +112 -0
  221. package/src/style/load_glyph_range.js +17 -0
  222. package/src/style/load_sprite.js +26 -0
  223. package/src/style/parse_glyph_pbf.js +45 -0
  224. package/src/style/pauseable_placement.js +88 -0
  225. package/src/style/properties.js +691 -0
  226. package/src/style/query_utils.js +39 -0
  227. package/src/style/style.js +955 -0
  228. package/src/style/style_layer/background_style_layer.js +11 -0
  229. package/src/style/style_layer/background_style_layer_properties.js +25 -0
  230. package/src/style/style_layer/circle_style_layer.js +93 -0
  231. package/src/style/style_layer/circle_style_layer_properties.js +76 -0
  232. package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
  233. package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
  234. package/src/style/style_layer/fill_style_layer.js +46 -0
  235. package/src/style/style_layer/fill_style_layer_properties.js +45 -0
  236. package/src/style/style_layer/heatmap_style_layer.js +51 -0
  237. package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
  238. package/src/style/style_layer/hillshade_style_layer.js +15 -0
  239. package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
  240. package/src/style/style_layer/line_style_layer.js +129 -0
  241. package/src/style/style_layer/line_style_layer_properties.js +104 -0
  242. package/src/style/style_layer/raster_style_layer.js +11 -0
  243. package/src/style/style_layer/raster_style_layer_properties.js +55 -0
  244. package/src/style/style_layer/symbol_style_layer.js +66 -0
  245. package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
  246. package/src/style/style_layer.js +183 -0
  247. package/src/style/style_layer_index.js +61 -0
  248. package/src/style/zoom_history.js +36 -0
  249. package/src/style-spec/deref.js +51 -0
  250. package/src/style-spec/error/parsing_error.js +8 -0
  251. package/src/style-spec/error/validation_error.js +10 -0
  252. package/src/style-spec/expression/compound_expression.js +118 -0
  253. package/src/style-spec/expression/definitions/array.js +82 -0
  254. package/src/style-spec/expression/definitions/assertion.js +69 -0
  255. package/src/style-spec/expression/definitions/at.js +57 -0
  256. package/src/style-spec/expression/definitions/case.js +73 -0
  257. package/src/style-spec/expression/definitions/coalesce.js +68 -0
  258. package/src/style-spec/expression/definitions/coercion.js +96 -0
  259. package/src/style-spec/expression/definitions/collator.js +102 -0
  260. package/src/style-spec/expression/definitions/equals.js +93 -0
  261. package/src/style-spec/expression/definitions/index.js +407 -0
  262. package/src/style-spec/expression/definitions/interpolate.js +235 -0
  263. package/src/style-spec/expression/definitions/length.js +54 -0
  264. package/src/style-spec/expression/definitions/let.js +60 -0
  265. package/src/style-spec/expression/definitions/literal.js +64 -0
  266. package/src/style-spec/expression/definitions/match.js +142 -0
  267. package/src/style-spec/expression/definitions/step.js +116 -0
  268. package/src/style-spec/expression/definitions/var.js +38 -0
  269. package/src/style-spec/expression/evaluation_context.js +35 -0
  270. package/src/style-spec/expression/index.js +329 -0
  271. package/src/style-spec/expression/is_constant.js +63 -0
  272. package/src/style-spec/expression/parsing_context.js +213 -0
  273. package/src/style-spec/expression/parsing_error.js +9 -0
  274. package/src/style-spec/expression/runtime_error.js +12 -0
  275. package/src/style-spec/expression/scope.js +34 -0
  276. package/src/style-spec/expression/stops.js +37 -0
  277. package/src/style-spec/expression/types.js +77 -0
  278. package/src/style-spec/expression/values.js +126 -0
  279. package/src/style-spec/feature_filter/README.md +55 -0
  280. package/src/style-spec/feature_filter/index.js +158 -0
  281. package/src/style-spec/function/convert.js +256 -0
  282. package/src/style-spec/function/index.js +299 -0
  283. package/src/style-spec/group_by_layout.js +68 -0
  284. package/src/style-spec/reference/v8.json +5356 -0
  285. package/src/style-spec/util/color.js +73 -0
  286. package/src/style-spec/util/color_spaces.js +128 -0
  287. package/src/style-spec/util/eval_support.js +8 -0
  288. package/src/style-spec/util/get_type.js +18 -0
  289. package/src/style-spec/util/interpolate.js +21 -0
  290. package/src/style-spec/util/properties.js +17 -0
  291. package/src/style-spec/util/ref_properties.js +1 -0
  292. package/src/style-spec/util/result.js +19 -0
  293. package/src/symbol/anchor.js +21 -0
  294. package/src/symbol/check_max_angle.js +75 -0
  295. package/src/symbol/clip_line.js +73 -0
  296. package/src/symbol/collision_feature.js +230 -0
  297. package/src/symbol/collision_index.js +379 -0
  298. package/src/symbol/cross_tile_symbol_index.js +270 -0
  299. package/src/symbol/get_anchors.js +177 -0
  300. package/src/symbol/grid_index.js +318 -0
  301. package/src/symbol/mergelines.js +75 -0
  302. package/src/symbol/opacity_state.js +21 -0
  303. package/src/symbol/placement.js +563 -0
  304. package/src/symbol/projection.js +601 -0
  305. package/src/symbol/quads.js +173 -0
  306. package/src/symbol/shaping.js +347 -0
  307. package/src/symbol/symbol_layout.js +519 -0
  308. package/src/symbol/symbol_size.js +110 -0
  309. package/src/symbol/transform_text.js +16 -0
  310. package/src/ui/anchor.js +24 -0
  311. package/src/ui/bind_handlers.js +199 -0
  312. package/src/ui/camera.js +954 -0
  313. package/src/ui/events.js +210 -0
  314. package/src/ui/handler/box_zoom.js +151 -0
  315. package/src/ui/handler/dblclick_zoom.js +91 -0
  316. package/src/ui/handler/drag_pan.js +285 -0
  317. package/src/ui/handler/drag_rotate.js +290 -0
  318. package/src/ui/handler/frame.js +28 -0
  319. package/src/ui/handler/inertia.js +45 -0
  320. package/src/ui/handler/keyboard.js +148 -0
  321. package/src/ui/handler/scroll_zoom.js +284 -0
  322. package/src/ui/handler/touch_zoom_rotate.js +263 -0
  323. package/src/ui/map.js +1645 -0
  324. package/src/util/actor.js +104 -0
  325. package/src/util/async.js +23 -0
  326. package/src/util/browser.js +61 -0
  327. package/src/util/callback.js +26 -0
  328. package/src/util/classify_rings.js +43 -0
  329. package/src/util/color_ramp.js +24 -0
  330. package/src/util/config.js +24 -0
  331. package/src/util/dictionary_coder.js +25 -0
  332. package/src/util/dispatcher.js +68 -0
  333. package/src/util/dom.js +102 -0
  334. package/src/util/evented.js +182 -0
  335. package/src/util/find_pole_of_inaccessibility.js +129 -0
  336. package/src/util/global_worker_pool.js +15 -0
  337. package/src/util/image.js +124 -0
  338. package/src/util/interpolate.js +5 -0
  339. package/src/util/intersection_tests.js +207 -0
  340. package/src/util/is_char_in_unicode_block.js +287 -0
  341. package/src/util/loader/image.js +32 -0
  342. package/src/util/object.js +178 -0
  343. package/src/util/script_detection.js +337 -0
  344. package/src/util/struct_array.js +197 -0
  345. package/src/util/task_queue.js +57 -0
  346. package/src/util/throttle.js +26 -0
  347. package/src/util/tile_cover.js +114 -0
  348. package/src/util/token.js +13 -0
  349. package/src/util/unique_id.js +12 -0
  350. package/src/util/util.js +192 -0
  351. package/src/util/vectortile_to_geojson.js +44 -0
  352. package/src/util/verticalize_punctuation.js +112 -0
  353. package/src/util/warn.js +21 -0
  354. package/src/util/web_worker.js +5 -0
  355. package/src/util/web_worker_transfer.js +228 -0
  356. package/src/util/worker_pool.js +41 -0
@@ -0,0 +1,625 @@
1
+ const { LineLayoutArray } = require('../array_types');
2
+
3
+ const { members: layoutAttributes } = require('./line_attributes');
4
+ const SegmentVector = require('../segment');
5
+ const { ProgramConfigurationSet } = require('../program_configuration');
6
+ const { TriangleIndexArray } = require('../index_array_type');
7
+ const EXTENT = require('../extent');
8
+ const mvt = require('@mapbox/vector-tile');
9
+ const vectorTileFeatureTypes = mvt.VectorTileFeature.types;
10
+ const { register } = require('../../util/web_worker_transfer');
11
+ const { hasPattern, addPatternDependencies } = require('./pattern_bucket_features');
12
+ const loadGeometry = require('../load_geometry');
13
+ const EvaluationParameters = require('../../style/evaluation_parameters');
14
+
15
+ // NOTE ON EXTRUDE SCALE:
16
+ // scale the extrusion vector so that the normal length is this value.
17
+ // contains the "texture" normals (-1..1). this is distinct from the extrude
18
+ // normals for line joins, because the x-value remains 0 for the texture
19
+ // normal array, while the extrude normal actually moves the vertex to create
20
+ // the acute/bevelled line join.
21
+ const EXTRUDE_SCALE = 63;
22
+
23
+ /*
24
+ * Sharp corners cause dashed lines to tilt because the distance along the line
25
+ * is the same at both the inner and outer corners. To improve the appearance of
26
+ * dashed lines we add extra points near sharp corners so that a smaller part
27
+ * of the line is tilted.
28
+ *
29
+ * COS_HALF_SHARP_CORNER controls how sharp a corner has to be for us to add an
30
+ * extra vertex. The default is 75 degrees.
31
+ *
32
+ * The newly created vertices are placed SHARP_CORNER_OFFSET pixels from the corner.
33
+ */
34
+ const COS_HALF_SHARP_CORNER = Math.cos((75 / 2) * (Math.PI / 180));
35
+ const SHARP_CORNER_OFFSET = 15;
36
+
37
+ // The number of bits that is used to store the line distance in the buffer.
38
+ const LINE_DISTANCE_BUFFER_BITS = 15;
39
+
40
+ // We don't have enough bits for the line distance as we'd like to have, so
41
+ // use this value to scale the line distance (in tile units) down to a smaller
42
+ // value. This lets us store longer distances while sacrificing precision.
43
+ const LINE_DISTANCE_SCALE = 1 / 2;
44
+
45
+ // The maximum line distance, in tile units, that fits in the buffer.
46
+ const MAX_LINE_DISTANCE = 2 ** (LINE_DISTANCE_BUFFER_BITS - 1) / LINE_DISTANCE_SCALE;
47
+
48
+ function addLineVertex(layoutVertexBuffer, point, extrude, round, up, dir, linesofar) {
49
+ layoutVertexBuffer.emplaceBack(
50
+ // a_pos_normal
51
+ point.x,
52
+ point.y,
53
+ round ? 1 : 0,
54
+ up ? 1 : -1,
55
+ // a_data
56
+ // add 128 to store a byte in an unsigned byte
57
+ Math.round(EXTRUDE_SCALE * extrude.x) + 128,
58
+ Math.round(EXTRUDE_SCALE * extrude.y) + 128,
59
+ // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
60
+ // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
61
+ // room for the direction value). The upper 8 bits of `linesofar` are placed in
62
+ // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
63
+ // we can store longer distances while sacrificing precision.
64
+ ((dir === 0 ? 0 : dir < 0 ? -1 : 1) + 1) | (((linesofar * LINE_DISTANCE_SCALE) & 0x3f) << 2),
65
+ (linesofar * LINE_DISTANCE_SCALE) >> 6
66
+ );
67
+ }
68
+
69
+ /**
70
+ * @private
71
+ */
72
+ class LineBucket {
73
+ constructor(options) {
74
+ this.zoom = options.zoom;
75
+ this.overscaling = options.overscaling;
76
+ this.layers = options.layers;
77
+ this.layerIds = this.layers.map(layer => layer.id);
78
+ this.index = options.index;
79
+ this.features = [];
80
+ this.hasPattern = false;
81
+
82
+ this.layoutVertexArray = new LineLayoutArray();
83
+ this.indexArray = new TriangleIndexArray();
84
+ this.programConfigurations = new ProgramConfigurationSet(layoutAttributes, options.layers, options.zoom);
85
+ this.segments = new SegmentVector();
86
+ }
87
+
88
+ populate(features, options) {
89
+ this.features = [];
90
+ this.hasPattern = hasPattern('line', this.layers, options);
91
+
92
+ for (const { feature, index, sourceLayerIndex } of features) {
93
+ if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) continue;
94
+
95
+ const geometry = loadGeometry(feature);
96
+
97
+ const patternFeature = {
98
+ sourceLayerIndex,
99
+ index,
100
+ geometry,
101
+ properties: feature.properties,
102
+ type: feature.type,
103
+ patterns: {}
104
+ };
105
+
106
+ if (typeof feature.id !== 'undefined') {
107
+ patternFeature.id = feature.id;
108
+ }
109
+
110
+ if (this.hasPattern) {
111
+ this.features.push(addPatternDependencies('line', this.layers, patternFeature, this.zoom, options));
112
+ } else {
113
+ this.addFeature(patternFeature, geometry, index, {});
114
+ }
115
+
116
+ options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
117
+ }
118
+ }
119
+
120
+ update(states, vtLayer, imagePositions) {
121
+ if (!this.stateDependentLayers.length) return;
122
+ this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions);
123
+ }
124
+
125
+ addFeatures(options, imagePositions) {
126
+ for (const feature of this.features) {
127
+ const { geometry } = feature;
128
+ this.addFeature(feature, geometry, feature.index, imagePositions);
129
+ }
130
+ }
131
+
132
+ isEmpty() {
133
+ return this.layoutVertexArray.length === 0;
134
+ }
135
+
136
+ uploadPending() {
137
+ return !this.uploaded || this.programConfigurations.needsUpload;
138
+ }
139
+
140
+ upload(context) {
141
+ if (!this.uploaded) {
142
+ this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, layoutAttributes);
143
+ this.indexBuffer = context.createIndexBuffer(this.indexArray);
144
+ }
145
+ this.programConfigurations.upload(context);
146
+ this.uploaded = true;
147
+ }
148
+
149
+ destroy() {
150
+ if (!this.layoutVertexBuffer) return;
151
+ this.layoutVertexBuffer.destroy();
152
+ this.indexBuffer.destroy();
153
+ this.programConfigurations.destroy();
154
+ this.segments.destroy();
155
+ }
156
+
157
+ addFeature(feature, geometry, index, imagePositions) {
158
+ const layout = this.layers[0].layout;
159
+ const join = layout.get('line-join').evaluate(feature, {});
160
+ const cap = layout.get('line-cap');
161
+ const miterLimit = layout.get('line-miter-limit');
162
+ const roundLimit = layout.get('line-round-limit');
163
+
164
+ for (const line of geometry) {
165
+ this.addLine(line, feature, join, cap, miterLimit, roundLimit, index, imagePositions);
166
+ }
167
+ }
168
+
169
+ addLine(vertices, feature, join, cap, miterLimit, roundLimit, index, imagePositions) {
170
+ let lineDistances = null;
171
+ if (
172
+ !!feature.properties &&
173
+ feature.properties.hasOwnProperty('mapbox_clip_start') &&
174
+ feature.properties.hasOwnProperty('mapbox_clip_end')
175
+ ) {
176
+ lineDistances = {
177
+ start: feature.properties.mapbox_clip_start,
178
+ end: feature.properties.mapbox_clip_end,
179
+ tileTotal: undefined
180
+ };
181
+ }
182
+
183
+ const isPolygon = vectorTileFeatureTypes[feature.type] === 'Polygon';
184
+
185
+ // If the line has duplicate vertices at the ends, adjust start/length to remove them.
186
+ let len = vertices.length;
187
+ while (len >= 2 && vertices[len - 1].equals(vertices[len - 2])) {
188
+ len--;
189
+ }
190
+ let first = 0;
191
+ while (first < len - 1 && vertices[first].equals(vertices[first + 1])) {
192
+ first++;
193
+ }
194
+
195
+ // Ignore invalid geometry.
196
+ if (len < (isPolygon ? 3 : 2)) return;
197
+
198
+ if (lineDistances) {
199
+ lineDistances.tileTotal = calculateFullDistance(vertices, first, len);
200
+ }
201
+
202
+ if (join === 'bevel') miterLimit = 1.05;
203
+
204
+ const sharpCornerOffset = SHARP_CORNER_OFFSET * (EXTENT / (512 * this.overscaling));
205
+
206
+ const firstVertex = vertices[first];
207
+
208
+ // we could be more precise, but it would only save a negligible amount of space
209
+ const segment = this.segments.prepareSegment(len * 10, this.layoutVertexArray, this.indexArray);
210
+
211
+ this.distance = 0;
212
+
213
+ const beginCap = cap;
214
+ const endCap = isPolygon ? 'butt' : cap;
215
+ let startOfLine = true;
216
+ let currentVertex;
217
+ let prevVertex;
218
+ let nextVertex;
219
+ let prevNormal;
220
+ let nextNormal;
221
+ let offsetA;
222
+ let offsetB;
223
+
224
+ // the last three vertices added
225
+ this.e1 = this.e2 = this.e3 = -1;
226
+
227
+ if (isPolygon) {
228
+ currentVertex = vertices[len - 2];
229
+ nextNormal = firstVertex.sub(currentVertex)._unit()._perp();
230
+ }
231
+
232
+ for (let i = first; i < len; i++) {
233
+ nextVertex =
234
+ isPolygon && i === len - 1
235
+ ? vertices[first + 1]
236
+ : // if the line is closed, we treat the last vertex like the first
237
+ vertices[i + 1]; // just the next vertex
238
+
239
+ // if two consecutive vertices exist, skip the current one
240
+ if (nextVertex && vertices[i].equals(nextVertex)) continue;
241
+
242
+ if (nextNormal) prevNormal = nextNormal;
243
+ if (currentVertex) prevVertex = currentVertex;
244
+
245
+ currentVertex = vertices[i];
246
+
247
+ // Calculate the normal towards the next vertex in this line. In case
248
+ // there is no next vertex, pretend that the line is continuing straight,
249
+ // meaning that we are just using the previous normal.
250
+ nextNormal = nextVertex ? nextVertex.sub(currentVertex)._unit()._perp() : prevNormal;
251
+
252
+ // If we still don't have a previous normal, this is the beginning of a
253
+ // non-closed line, so we're doing a straight "join".
254
+ prevNormal = prevNormal || nextNormal;
255
+
256
+ // Determine the normal of the join extrusion. It is the angle bisector
257
+ // of the segments between the previous line and the next line.
258
+ // In the case of 180° angles, the prev and next normals cancel each other out:
259
+ // prevNormal + nextNormal = (0, 0), its magnitude is 0, so the unit vector would be
260
+ // undefined. In that case, we're keeping the joinNormal at (0, 0), so that the cosHalfAngle
261
+ // below will also become 0 and miterLength will become Infinity.
262
+ let joinNormal = prevNormal.add(nextNormal);
263
+ if (joinNormal.x !== 0 || joinNormal.y !== 0) {
264
+ joinNormal._unit();
265
+ }
266
+ /* joinNormal prevNormal
267
+ * ↖ ↑
268
+ * .________. prevVertex
269
+ * |
270
+ * nextNormal ← | currentVertex
271
+ * |
272
+ * nextVertex !
273
+ *
274
+ */
275
+
276
+ // Calculate the length of the miter (the ratio of the miter to the width).
277
+ // Find the cosine of the angle between the next and join normals
278
+ // using dot product. The inverse of that is the miter length.
279
+ const cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y;
280
+ const miterLength = cosHalfAngle !== 0 ? 1 / cosHalfAngle : Number.POSITIVE_INFINITY;
281
+
282
+ const isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex;
283
+
284
+ if (isSharpCorner && i > first) {
285
+ const prevSegmentLength = currentVertex.dist(prevVertex);
286
+ if (prevSegmentLength > 2 * sharpCornerOffset) {
287
+ const newPrevVertex = currentVertex.sub(
288
+ currentVertex
289
+ .sub(prevVertex)
290
+ ._mult(sharpCornerOffset / prevSegmentLength)
291
+ ._round()
292
+ );
293
+ this.distance += newPrevVertex.dist(prevVertex);
294
+ this.addCurrentVertex(newPrevVertex, this.distance, prevNormal.mult(1), 0, 0, false, segment, lineDistances);
295
+ prevVertex = newPrevVertex;
296
+ }
297
+ }
298
+
299
+ // The join if a middle vertex, otherwise the cap.
300
+ const middleVertex = prevVertex && nextVertex;
301
+ let currentJoin = middleVertex ? join : nextVertex ? beginCap : endCap;
302
+
303
+ if (middleVertex && currentJoin === 'round') {
304
+ if (miterLength < roundLimit) {
305
+ currentJoin = 'miter';
306
+ } else if (miterLength <= 2) {
307
+ currentJoin = 'fakeround';
308
+ }
309
+ }
310
+
311
+ if (currentJoin === 'miter' && miterLength > miterLimit) {
312
+ currentJoin = 'bevel';
313
+ }
314
+
315
+ if (currentJoin === 'bevel') {
316
+ // The maximum extrude length is 128 / 63 = 2 times the width of the line
317
+ // so if miterLength >= 2 we need to draw a different type of bevel here.
318
+ if (miterLength > 2) currentJoin = 'flipbevel';
319
+
320
+ // If the miterLength is really small and the line bevel wouldn't be visible,
321
+ // just draw a miter join to save a triangle.
322
+ if (miterLength < miterLimit) currentJoin = 'miter';
323
+ }
324
+
325
+ // Calculate how far along the line the currentVertex is
326
+ if (prevVertex) this.distance += currentVertex.dist(prevVertex);
327
+
328
+ if (currentJoin === 'miter') {
329
+ joinNormal._mult(miterLength);
330
+ this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false, segment, lineDistances);
331
+ } else if (currentJoin === 'flipbevel') {
332
+ // miter is too big, flip the direction to make a beveled join
333
+
334
+ if (miterLength > 100) {
335
+ // Almost parallel lines
336
+ joinNormal = nextNormal.clone().mult(-1);
337
+ } else {
338
+ const direction = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0 ? -1 : 1;
339
+ const bevelLength = (miterLength * prevNormal.add(nextNormal).mag()) / prevNormal.sub(nextNormal).mag();
340
+ joinNormal._perp()._mult(bevelLength * direction);
341
+ }
342
+ this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false, segment, lineDistances);
343
+ this.addCurrentVertex(currentVertex, this.distance, joinNormal.mult(-1), 0, 0, false, segment, lineDistances);
344
+ } else if (currentJoin === 'bevel' || currentJoin === 'fakeround') {
345
+ const lineTurnsLeft = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0;
346
+ const offset = -Math.sqrt(miterLength * miterLength - 1);
347
+ if (lineTurnsLeft) {
348
+ offsetB = 0;
349
+ offsetA = offset;
350
+ } else {
351
+ offsetA = 0;
352
+ offsetB = offset;
353
+ }
354
+
355
+ // Close previous segment with a bevel
356
+ if (!startOfLine) {
357
+ this.addCurrentVertex(
358
+ currentVertex,
359
+ this.distance,
360
+ prevNormal,
361
+ offsetA,
362
+ offsetB,
363
+ false,
364
+ segment,
365
+ lineDistances
366
+ );
367
+ }
368
+
369
+ if (currentJoin === 'fakeround') {
370
+ // The join angle is sharp enough that a round join would be visible.
371
+ // Bevel joins fill the gap between segments with a single pie slice triangle.
372
+ // Create a round join by adding multiple pie slices. The join isn't actually round, but
373
+ // it looks like it is at the sizes we render lines at.
374
+
375
+ // Add more triangles for sharper angles.
376
+ // This math is just a good enough approximation. It isn't "correct".
377
+ const n = Math.floor((0.5 - (cosHalfAngle - 0.5)) * 8);
378
+ let approxFractionalJoinNormal;
379
+
380
+ for (let m = 0; m < n; m++) {
381
+ approxFractionalJoinNormal = nextNormal
382
+ .mult((m + 1) / (n + 1))
383
+ ._add(prevNormal)
384
+ ._unit();
385
+ this.addPieSliceVertex(
386
+ currentVertex,
387
+ this.distance,
388
+ approxFractionalJoinNormal,
389
+ lineTurnsLeft,
390
+ segment,
391
+ lineDistances
392
+ );
393
+ }
394
+
395
+ this.addPieSliceVertex(currentVertex, this.distance, joinNormal, lineTurnsLeft, segment, lineDistances);
396
+
397
+ for (let k = n - 1; k >= 0; k--) {
398
+ approxFractionalJoinNormal = prevNormal
399
+ .mult((k + 1) / (n + 1))
400
+ ._add(nextNormal)
401
+ ._unit();
402
+ this.addPieSliceVertex(
403
+ currentVertex,
404
+ this.distance,
405
+ approxFractionalJoinNormal,
406
+ lineTurnsLeft,
407
+ segment,
408
+ lineDistances
409
+ );
410
+ }
411
+ }
412
+
413
+ // Start next segment
414
+ if (nextVertex) {
415
+ this.addCurrentVertex(
416
+ currentVertex,
417
+ this.distance,
418
+ nextNormal,
419
+ -offsetA,
420
+ -offsetB,
421
+ false,
422
+ segment,
423
+ lineDistances
424
+ );
425
+ }
426
+ } else if (currentJoin === 'butt') {
427
+ if (!startOfLine) {
428
+ // Close previous segment with a butt
429
+ this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false, segment, lineDistances);
430
+ }
431
+
432
+ // Start next segment with a butt
433
+ if (nextVertex) {
434
+ this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false, segment, lineDistances);
435
+ }
436
+ } else if (currentJoin === 'square') {
437
+ if (!startOfLine) {
438
+ // Close previous segment with a square cap
439
+ this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, false, segment, lineDistances);
440
+
441
+ // The segment is done. Unset vertices to disconnect segments.
442
+ this.e1 = this.e2 = -1;
443
+ }
444
+
445
+ // Start next segment
446
+ if (nextVertex) {
447
+ this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, false, segment, lineDistances);
448
+ }
449
+ } else if (currentJoin === 'round') {
450
+ if (!startOfLine) {
451
+ // Close previous segment with butt
452
+ this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false, segment, lineDistances);
453
+
454
+ // Add round cap or linejoin at end of segment
455
+ this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, true, segment, lineDistances);
456
+
457
+ // The segment is done. Unset vertices to disconnect segments.
458
+ this.e1 = this.e2 = -1;
459
+ }
460
+
461
+ // Start next segment with a butt
462
+ if (nextVertex) {
463
+ // Add round cap before first segment
464
+ this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, true, segment, lineDistances);
465
+
466
+ this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false, segment, lineDistances);
467
+ }
468
+ }
469
+
470
+ if (isSharpCorner && i < len - 1) {
471
+ const nextSegmentLength = currentVertex.dist(nextVertex);
472
+ if (nextSegmentLength > 2 * sharpCornerOffset) {
473
+ const newCurrentVertex = currentVertex.add(
474
+ nextVertex
475
+ .sub(currentVertex)
476
+ ._mult(sharpCornerOffset / nextSegmentLength)
477
+ ._round()
478
+ );
479
+ this.distance += newCurrentVertex.dist(currentVertex);
480
+ this.addCurrentVertex(
481
+ newCurrentVertex,
482
+ this.distance,
483
+ nextNormal.mult(1),
484
+ 0,
485
+ 0,
486
+ false,
487
+ segment,
488
+ lineDistances
489
+ );
490
+ currentVertex = newCurrentVertex;
491
+ }
492
+ }
493
+
494
+ startOfLine = false;
495
+ }
496
+
497
+ this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions);
498
+ }
499
+
500
+ /**
501
+ * Add two vertices to the buffers.
502
+ *
503
+ * @param {Object} currentVertex the line vertex to add buffer vertices for
504
+ * @param {number} distance the distance from the beginning of the line to the vertex
505
+ * @param {number} endLeft extrude to shift the left vertex along the line
506
+ * @param {number} endRight extrude to shift the left vertex along the line
507
+ * @param {boolean} round whether this is a round cap
508
+ * @private
509
+ */
510
+ addCurrentVertex(currentVertex, distance, normal, endLeft, endRight, round, segment, distancesForScaling) {
511
+ let extrude;
512
+ const layoutVertexArray = this.layoutVertexArray;
513
+ const indexArray = this.indexArray;
514
+
515
+ if (distancesForScaling) {
516
+ // For gradient lines, scale distance from tile units to [0, 2^15)
517
+ distance = scaleDistance(distance, distancesForScaling);
518
+ }
519
+
520
+ extrude = normal.clone();
521
+ if (endLeft) extrude._sub(normal.perp()._mult(endLeft));
522
+ addLineVertex(layoutVertexArray, currentVertex, extrude, round, false, endLeft, distance);
523
+ this.e3 = segment.vertexLength++;
524
+ if (this.e1 >= 0 && this.e2 >= 0) {
525
+ indexArray.emplaceBack(this.e1, this.e2, this.e3);
526
+ segment.primitiveLength++;
527
+ }
528
+ this.e1 = this.e2;
529
+ this.e2 = this.e3;
530
+
531
+ extrude = normal.mult(-1);
532
+ if (endRight) extrude._sub(normal.perp()._mult(endRight));
533
+ addLineVertex(layoutVertexArray, currentVertex, extrude, round, true, -endRight, distance);
534
+ this.e3 = segment.vertexLength++;
535
+ if (this.e1 >= 0 && this.e2 >= 0) {
536
+ indexArray.emplaceBack(this.e1, this.e2, this.e3);
537
+ segment.primitiveLength++;
538
+ }
539
+ this.e1 = this.e2;
540
+ this.e2 = this.e3;
541
+
542
+ // There is a maximum "distance along the line" that we can store in the buffers.
543
+ // When we get close to the distance, reset it to zero and add the vertex again with
544
+ // a distance of zero. The max distance is determined by the number of bits we allocate
545
+ // to `linesofar`.
546
+ if (distance > MAX_LINE_DISTANCE / 2 && !distancesForScaling) {
547
+ this.distance = 0;
548
+ this.addCurrentVertex(currentVertex, this.distance, normal, endLeft, endRight, round, segment);
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Add a single new vertex and a triangle using two previous vertices.
554
+ * This adds a pie slice triangle near a join to simulate round joins
555
+ *
556
+ * @param currentVertex the line vertex to add buffer vertices for
557
+ * @param distance the distance from the beginning of the line to the vertex
558
+ * @param extrude the offset of the new vertex from the currentVertex
559
+ * @param lineTurnsLeft whether the line is turning left or right at this angle
560
+ * @private
561
+ */
562
+ addPieSliceVertex(currentVertex, distance, extrude, lineTurnsLeft, segment, distancesForScaling) {
563
+ extrude = extrude.mult(lineTurnsLeft ? -1 : 1);
564
+ const layoutVertexArray = this.layoutVertexArray;
565
+ const indexArray = this.indexArray;
566
+
567
+ if (distancesForScaling) distance = scaleDistance(distance, distancesForScaling);
568
+
569
+ addLineVertex(layoutVertexArray, currentVertex, extrude, false, lineTurnsLeft, 0, distance);
570
+ this.e3 = segment.vertexLength++;
571
+ if (this.e1 >= 0 && this.e2 >= 0) {
572
+ indexArray.emplaceBack(this.e1, this.e2, this.e3);
573
+ segment.primitiveLength++;
574
+ }
575
+
576
+ if (lineTurnsLeft) {
577
+ this.e2 = this.e3;
578
+ } else {
579
+ this.e1 = this.e3;
580
+ }
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Knowing the ratio of the full linestring covered by this tiled feature, as well
586
+ * as the total distance (in tile units) of this tiled feature, and the distance
587
+ * (in tile units) of the current vertex, we can determine the relative distance
588
+ * of this vertex along the full linestring feature and scale it to [0, 2^15)
589
+ *
590
+ * @param {number} tileDistance the distance from the beginning of the tiled line to this vertex
591
+ * @param {Object} stats
592
+ * @param {number} stats.start the ratio (0-1) along a full original linestring feature of the start of this tiled line feature
593
+ * @param {number} stats.end the ratio (0-1) along a full original linestring feature of the end of this tiled line feature
594
+ * @param {number} stats.tileTotal the total distance, in tile units, of this tiled line feature
595
+ *
596
+ * @private
597
+ */
598
+ function scaleDistance(tileDistance, stats) {
599
+ return ((tileDistance / stats.tileTotal) * (stats.end - stats.start) + stats.start) * (MAX_LINE_DISTANCE - 1);
600
+ }
601
+
602
+ /**
603
+ * Calculate the total distance, in tile units, of this tiled line feature
604
+ *
605
+ * @param {Array<Point>} vertices the full geometry of this tiled line feature
606
+ * @param {number} first the index in the vertices array representing the first vertex we should consider
607
+ * @param {number} len the count of vertices we should consider from `first`
608
+ *
609
+ * @private
610
+ */
611
+ function calculateFullDistance(vertices, first, len) {
612
+ let currentVertex;
613
+ let nextVertex;
614
+ let total = 0;
615
+ for (let i = first; i < len - 1; i++) {
616
+ currentVertex = vertices[i];
617
+ nextVertex = vertices[i + 1];
618
+ total += currentVertex.dist(nextVertex);
619
+ }
620
+ return total;
621
+ }
622
+
623
+ register('LineBucket', LineBucket, { omit: ['layers', 'features'] });
624
+
625
+ module.exports = LineBucket;
@@ -0,0 +1,9 @@
1
+ const { createLayout } = require('../../util/struct_array');
2
+
3
+ const layout = createLayout([
4
+ // [tl.x, tl.y, br.x, br.y]
5
+ { name: 'a_pattern_from', components: 4, type: 'Uint16' },
6
+ { name: 'a_pattern_to', components: 4, type: 'Uint16' }
7
+ ]);
8
+
9
+ module.exports = layout;
@@ -0,0 +1,44 @@
1
+ function hasPattern(type, layers, options) {
2
+ const patterns = options.patternDependencies;
3
+ let hasPattern = false;
4
+
5
+ for (const layer of layers) {
6
+ const patternProperty = layer.paint.get(`${type}-pattern`);
7
+ if (!patternProperty.isConstant()) {
8
+ hasPattern = true;
9
+ }
10
+
11
+ const constantPattern = patternProperty.constantOr(null);
12
+ if (constantPattern) {
13
+ hasPattern = true;
14
+ patterns[constantPattern.to] = true;
15
+ patterns[constantPattern.from] = true;
16
+ }
17
+ }
18
+
19
+ return hasPattern;
20
+ }
21
+
22
+ function addPatternDependencies(type, layers, patternFeature, zoom, options) {
23
+ const patterns = options.patternDependencies;
24
+ for (const layer of layers) {
25
+ const patternProperty = layer.paint.get(`${type}-pattern`);
26
+
27
+ const patternPropertyValue = patternProperty.value;
28
+ if (patternPropertyValue.kind !== 'constant') {
29
+ const min = patternPropertyValue.evaluate({ zoom: zoom - 1 }, patternFeature, {});
30
+ const mid = patternPropertyValue.evaluate({ zoom: zoom }, patternFeature, {});
31
+ const max = patternPropertyValue.evaluate({ zoom: zoom + 1 }, patternFeature, {});
32
+ // add to patternDependencies
33
+ patterns[min] = true;
34
+ patterns[mid] = true;
35
+ patterns[max] = true;
36
+
37
+ // save for layout
38
+ patternFeature.patterns[layer.id] = { min, mid, max };
39
+ }
40
+ }
41
+ return patternFeature;
42
+ }
43
+
44
+ module.exports = { hasPattern, addPatternDependencies };