@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,563 @@
1
+ const CollisionIndex = require('./collision_index');
2
+
3
+ const EXTENT = require('../data/extent');
4
+ const symbolSize = require('./symbol_size');
5
+ const projection = require('./projection');
6
+ const properties = require('../style/style_layer/symbol_style_layer_properties');
7
+ const symbolLayoutProperties = properties.layout;
8
+ const assert = require('assert');
9
+ const pixelsToTileUnits = require('../source/pixels_to_tile_units');
10
+
11
+ class OpacityState {
12
+ constructor(prevState, increment, placed, skipFade) {
13
+ if (prevState) {
14
+ this.opacity = Math.max(0, Math.min(1, prevState.opacity + (prevState.placed ? increment : -increment)));
15
+ } else {
16
+ this.opacity = skipFade && placed ? 1 : 0;
17
+ }
18
+ this.placed = placed;
19
+ }
20
+ isHidden() {
21
+ return this.opacity === 0 && !this.placed;
22
+ }
23
+ }
24
+
25
+ class JointOpacityState {
26
+ constructor(prevState, increment, placedText, placedIcon, skipFade) {
27
+ this.text = new OpacityState(prevState ? prevState.text : null, increment, placedText, skipFade);
28
+ this.icon = new OpacityState(prevState ? prevState.icon : null, increment, placedIcon, skipFade);
29
+ }
30
+ isHidden() {
31
+ return this.text.isHidden() && this.icon.isHidden();
32
+ }
33
+ }
34
+
35
+ class JointPlacement {
36
+ // skipFade = outside viewport, but within CollisionIndex::viewportPadding px of the edge
37
+ // Because these symbols aren't onscreen yet, we can skip the "fade in" animation,
38
+ // and if a subsequent viewport change brings them into view, they'll be fully
39
+ // visible right away.
40
+ constructor(text, icon, skipFade) {
41
+ this.text = text;
42
+ this.icon = icon;
43
+ this.skipFade = skipFade;
44
+ }
45
+ }
46
+
47
+ class RetainedQueryData {
48
+ constructor(bucketInstanceId, featureIndex, sourceLayerIndex, bucketIndex, tileID) {
49
+ this.bucketInstanceId = bucketInstanceId;
50
+ this.featureIndex = featureIndex;
51
+ this.sourceLayerIndex = sourceLayerIndex;
52
+ this.bucketIndex = bucketIndex;
53
+ this.tileID = tileID;
54
+ }
55
+ }
56
+
57
+ class CollisionGroups {
58
+ constructor(crossSourceCollisions) {
59
+ this.crossSourceCollisions = crossSourceCollisions;
60
+ this.maxGroupID = 0;
61
+ this.collisionGroups = {};
62
+ }
63
+
64
+ get(sourceID) {
65
+ // The predicate/groupID mechanism allows for arbitrary grouping,
66
+ // but the current interface defines one source == one group when
67
+ // crossSourceCollisions == true.
68
+ if (!this.crossSourceCollisions) {
69
+ if (!this.collisionGroups[sourceID]) {
70
+ const nextGroupID = ++this.maxGroupID;
71
+ this.collisionGroups[sourceID] = {
72
+ ID: nextGroupID,
73
+ predicate: key => {
74
+ return key.collisionGroupID === nextGroupID;
75
+ }
76
+ };
77
+ }
78
+ return this.collisionGroups[sourceID];
79
+ }
80
+ return { ID: 0, predicate: null };
81
+ }
82
+ }
83
+
84
+ class Placement {
85
+ constructor(transform, fadeDuration, crossSourceCollisions) {
86
+ this.transform = transform.clone();
87
+ this.collisionIndex = new CollisionIndex(this.transform);
88
+ this.placements = {};
89
+ this.opacities = {};
90
+ this.stale = false;
91
+ this.fadeDuration = fadeDuration;
92
+ this.retainedQueryData = {};
93
+ this.collisionGroups = new CollisionGroups(crossSourceCollisions);
94
+ }
95
+
96
+ placeLayerTile(styleLayer, tile, showCollisionBoxes, seenCrossTileIDs) {
97
+ const symbolBucket = tile.getBucket(styleLayer);
98
+ const bucketFeatureIndex = tile.latestFeatureIndex;
99
+ if (!symbolBucket || !bucketFeatureIndex || styleLayer.id !== symbolBucket.layerIds[0]) return;
100
+
101
+ const collisionBoxArray = tile.collisionBoxArray;
102
+
103
+ const layout = symbolBucket.layers[0].layout;
104
+
105
+ const scale = 2 ** (this.transform.zoom - tile.tileID.overscaledZ);
106
+ const textPixelRatio = tile.tileSize / EXTENT;
107
+
108
+ const posMatrix = this.transform.calculatePosMatrix(tile.tileID.toUnwrapped());
109
+
110
+ const textLabelPlaneMatrix = projection.getLabelPlaneMatrix(
111
+ posMatrix,
112
+ layout.get('text-pitch-alignment') === 'map',
113
+ layout.get('text-rotation-alignment') === 'map',
114
+ this.transform,
115
+ pixelsToTileUnits(tile, 1, this.transform.zoom)
116
+ );
117
+
118
+ const iconLabelPlaneMatrix = projection.getLabelPlaneMatrix(
119
+ posMatrix,
120
+ layout.get('icon-pitch-alignment') === 'map',
121
+ layout.get('icon-rotation-alignment') === 'map',
122
+ this.transform,
123
+ pixelsToTileUnits(tile, 1, this.transform.zoom)
124
+ );
125
+
126
+ // As long as this placement lives, we have to hold onto this bucket's
127
+ // matching FeatureIndex/data for querying purposes
128
+ this.retainedQueryData[symbolBucket.bucketInstanceId] = new RetainedQueryData(
129
+ symbolBucket.bucketInstanceId,
130
+ bucketFeatureIndex,
131
+ symbolBucket.sourceLayerIndex,
132
+ symbolBucket.index,
133
+ tile.tileID
134
+ );
135
+
136
+ this.placeLayerBucket(
137
+ symbolBucket,
138
+ posMatrix,
139
+ textLabelPlaneMatrix,
140
+ iconLabelPlaneMatrix,
141
+ scale,
142
+ textPixelRatio,
143
+ showCollisionBoxes,
144
+ tile.holdingForFade(),
145
+ seenCrossTileIDs,
146
+ collisionBoxArray
147
+ );
148
+ }
149
+
150
+ placeLayerBucket(
151
+ bucket,
152
+ posMatrix,
153
+ textLabelPlaneMatrix,
154
+ iconLabelPlaneMatrix,
155
+ scale,
156
+ textPixelRatio,
157
+ showCollisionBoxes,
158
+ holdingForFade,
159
+ seenCrossTileIDs,
160
+ collisionBoxArray
161
+ ) {
162
+ const layout = bucket.layers[0].layout;
163
+
164
+ const partiallyEvaluatedTextSize = symbolSize.evaluateSizeForZoom(
165
+ bucket.textSizeData,
166
+ this.transform.zoom,
167
+ symbolLayoutProperties.properties['text-size']
168
+ );
169
+
170
+ const textOptional = layout.get('text-optional');
171
+ const iconOptional = layout.get('icon-optional');
172
+
173
+ const collisionGroup = this.collisionGroups.get(bucket.sourceID);
174
+
175
+ for (const symbolInstance of bucket.symbolInstances) {
176
+ if (!seenCrossTileIDs[symbolInstance.crossTileID]) {
177
+ if (holdingForFade) {
178
+ // Mark all symbols from this tile as "not placed", but don't add to seenCrossTileIDs, because we don't
179
+ // know yet if we have a duplicate in a parent tile that _should_ be placed.
180
+ this.placements[symbolInstance.crossTileID] = new JointPlacement(false, false, false);
181
+ continue;
182
+ }
183
+
184
+ let placeText = false;
185
+ let placeIcon = false;
186
+ let offscreen = true;
187
+
188
+ let placedGlyphBoxes = null;
189
+ let placedGlyphCircles = null;
190
+ let placedIconBoxes = null;
191
+
192
+ let textFeatureIndex = 0;
193
+ let iconFeatureIndex = 0;
194
+
195
+ if (!symbolInstance.collisionArrays) {
196
+ symbolInstance.collisionArrays = bucket.deserializeCollisionBoxes(
197
+ collisionBoxArray,
198
+ symbolInstance.textBoxStartIndex,
199
+ symbolInstance.textBoxEndIndex,
200
+ symbolInstance.iconBoxStartIndex,
201
+ symbolInstance.iconBoxEndIndex
202
+ );
203
+ }
204
+
205
+ if (symbolInstance.collisionArrays.textFeatureIndex) {
206
+ textFeatureIndex = symbolInstance.collisionArrays.textFeatureIndex;
207
+ }
208
+ if (symbolInstance.collisionArrays.textBox) {
209
+ placedGlyphBoxes = this.collisionIndex.placeCollisionBox(
210
+ symbolInstance.collisionArrays.textBox,
211
+ layout.get('text-allow-overlap'),
212
+ textPixelRatio,
213
+ posMatrix,
214
+ collisionGroup.predicate
215
+ );
216
+ placeText = placedGlyphBoxes.box.length > 0;
217
+ offscreen = offscreen && placedGlyphBoxes.offscreen;
218
+ }
219
+ const textCircles = symbolInstance.collisionArrays.textCircles;
220
+ if (textCircles) {
221
+ const placedSymbol = bucket.text.placedSymbolArray.get(symbolInstance.placedTextSymbolIndices[0]);
222
+ const fontSize = symbolSize.evaluateSizeForFeature(
223
+ bucket.textSizeData,
224
+ partiallyEvaluatedTextSize,
225
+ placedSymbol
226
+ );
227
+ placedGlyphCircles = this.collisionIndex.placeCollisionCircles(
228
+ textCircles,
229
+ layout.get('text-allow-overlap'),
230
+ scale,
231
+ textPixelRatio,
232
+ symbolInstance.key,
233
+ placedSymbol,
234
+ bucket.lineVertexArray,
235
+ bucket.glyphOffsetArray,
236
+ fontSize,
237
+ posMatrix,
238
+ textLabelPlaneMatrix,
239
+ showCollisionBoxes,
240
+ layout.get('text-pitch-alignment') === 'map',
241
+ collisionGroup.predicate
242
+ );
243
+ // If text-allow-overlap is set, force "placedCircles" to true
244
+ // In theory there should always be at least one circle placed
245
+ // in this case, but for now quirks in text-anchor
246
+ // and text-offset may prevent that from being true.
247
+ placeText = layout.get('text-allow-overlap') || placedGlyphCircles.circles.length > 0;
248
+ offscreen = offscreen && placedGlyphCircles.offscreen;
249
+ }
250
+
251
+ if (symbolInstance.collisionArrays.iconFeatureIndex) {
252
+ iconFeatureIndex = symbolInstance.collisionArrays.iconFeatureIndex;
253
+ }
254
+ if (symbolInstance.collisionArrays.iconBox) {
255
+ placedIconBoxes = this.collisionIndex.placeCollisionBox(
256
+ symbolInstance.collisionArrays.iconBox,
257
+ layout.get('icon-allow-overlap'),
258
+ textPixelRatio,
259
+ posMatrix,
260
+ collisionGroup.predicate
261
+ );
262
+ placeIcon = placedIconBoxes.box.length > 0;
263
+ offscreen = offscreen && placedIconBoxes.offscreen;
264
+ }
265
+
266
+ const iconWithoutText =
267
+ textOptional || (symbolInstance.numGlyphVertices === 0 && symbolInstance.numVerticalGlyphVertices === 0);
268
+ const textWithoutIcon = iconOptional || symbolInstance.numIconVertices === 0;
269
+
270
+ // Combine the scales for icons and text.
271
+ if (!iconWithoutText && !textWithoutIcon) {
272
+ placeIcon = placeText = placeIcon && placeText;
273
+ } else if (!textWithoutIcon) {
274
+ placeText = placeIcon && placeText;
275
+ } else if (!iconWithoutText) {
276
+ placeIcon = placeIcon && placeText;
277
+ }
278
+
279
+ if (placeText && placedGlyphBoxes) {
280
+ this.collisionIndex.insertCollisionBox(
281
+ placedGlyphBoxes.box,
282
+ layout.get('text-ignore-placement'),
283
+ bucket.bucketInstanceId,
284
+ textFeatureIndex,
285
+ collisionGroup.ID
286
+ );
287
+ }
288
+ if (placeIcon && placedIconBoxes) {
289
+ this.collisionIndex.insertCollisionBox(
290
+ placedIconBoxes.box,
291
+ layout.get('icon-ignore-placement'),
292
+ bucket.bucketInstanceId,
293
+ iconFeatureIndex,
294
+ collisionGroup.ID
295
+ );
296
+ }
297
+ if (placeText && placedGlyphCircles) {
298
+ this.collisionIndex.insertCollisionCircles(
299
+ placedGlyphCircles.circles,
300
+ layout.get('text-ignore-placement'),
301
+ bucket.bucketInstanceId,
302
+ textFeatureIndex,
303
+ collisionGroup.ID
304
+ );
305
+ }
306
+
307
+ assert(symbolInstance.crossTileID !== 0);
308
+ assert(bucket.bucketInstanceId !== 0);
309
+
310
+ this.placements[symbolInstance.crossTileID] = new JointPlacement(
311
+ placeText,
312
+ placeIcon,
313
+ offscreen || bucket.justReloaded
314
+ );
315
+ seenCrossTileIDs[symbolInstance.crossTileID] = true;
316
+ }
317
+ }
318
+
319
+ bucket.justReloaded = false;
320
+ }
321
+
322
+ commit(prevPlacement, now) {
323
+ this.commitTime = now;
324
+
325
+ let placementChanged = false;
326
+
327
+ const increment =
328
+ prevPlacement && this.fadeDuration !== 0 ? (this.commitTime - prevPlacement.commitTime) / this.fadeDuration : 1;
329
+
330
+ const prevOpacities = prevPlacement ? prevPlacement.opacities : {};
331
+
332
+ // add the opacities from the current placement, and copy their current values from the previous placement
333
+ for (const crossTileID in this.placements) {
334
+ const jointPlacement = this.placements[crossTileID];
335
+ const prevOpacity = prevOpacities[crossTileID];
336
+ if (prevOpacity) {
337
+ this.opacities[crossTileID] = new JointOpacityState(
338
+ prevOpacity,
339
+ increment,
340
+ jointPlacement.text,
341
+ jointPlacement.icon
342
+ );
343
+ placementChanged =
344
+ placementChanged ||
345
+ jointPlacement.text !== prevOpacity.text.placed ||
346
+ jointPlacement.icon !== prevOpacity.icon.placed;
347
+ } else {
348
+ this.opacities[crossTileID] = new JointOpacityState(
349
+ null,
350
+ increment,
351
+ jointPlacement.text,
352
+ jointPlacement.icon,
353
+ jointPlacement.skipFade
354
+ );
355
+ placementChanged = placementChanged || jointPlacement.text || jointPlacement.icon;
356
+ }
357
+ }
358
+
359
+ // copy and update values from the previous placement that aren't in the current placement but haven't finished fading
360
+ for (const crossTileID in prevOpacities) {
361
+ const prevOpacity = prevOpacities[crossTileID];
362
+ if (!this.opacities[crossTileID]) {
363
+ const jointOpacity = new JointOpacityState(prevOpacity, increment, false, false);
364
+ if (!jointOpacity.isHidden()) {
365
+ this.opacities[crossTileID] = jointOpacity;
366
+ placementChanged = placementChanged || prevOpacity.text.placed || prevOpacity.icon.placed;
367
+ }
368
+ }
369
+ }
370
+
371
+ // this.lastPlacementChangeTime is the time of the last commit() that
372
+ // resulted in a placement change -- in other words, the start time of
373
+ // the last symbol fade animation
374
+ assert(!prevPlacement || prevPlacement.lastPlacementChangeTime !== undefined);
375
+ if (placementChanged) {
376
+ this.lastPlacementChangeTime = now;
377
+ } else if (typeof this.lastPlacementChangeTime !== 'number') {
378
+ this.lastPlacementChangeTime = prevPlacement ? prevPlacement.lastPlacementChangeTime : now;
379
+ }
380
+ }
381
+
382
+ updateLayerOpacities(styleLayer, tiles) {
383
+ const seenCrossTileIDs = {};
384
+
385
+ for (const tile of tiles) {
386
+ const symbolBucket = tile.getBucket(styleLayer);
387
+ if (symbolBucket && tile.latestFeatureIndex && styleLayer.id === symbolBucket.layerIds[0]) {
388
+ this.updateBucketOpacities(symbolBucket, seenCrossTileIDs, tile.collisionBoxArray);
389
+ }
390
+ }
391
+ }
392
+
393
+ updateBucketOpacities(bucket, seenCrossTileIDs, collisionBoxArray) {
394
+ if (bucket.hasTextData()) bucket.text.opacityVertexArray.clear();
395
+ if (bucket.hasIconData()) bucket.icon.opacityVertexArray.clear();
396
+ if (bucket.hasCollisionBoxData()) bucket.collisionBox.collisionVertexArray.clear();
397
+ if (bucket.hasCollisionCircleData()) bucket.collisionCircle.collisionVertexArray.clear();
398
+
399
+ const layout = bucket.layers[0].layout;
400
+ const duplicateOpacityState = new JointOpacityState(null, 0, false, false, true);
401
+ const defaultOpacityState = new JointOpacityState(
402
+ null,
403
+ 0,
404
+ layout.get('text-allow-overlap'),
405
+ layout.get('icon-allow-overlap'),
406
+ true
407
+ );
408
+
409
+ for (let s = 0; s < bucket.symbolInstances.length; s++) {
410
+ const symbolInstance = bucket.symbolInstances[s];
411
+ const isDuplicate = seenCrossTileIDs[symbolInstance.crossTileID];
412
+
413
+ let opacityState = this.opacities[symbolInstance.crossTileID];
414
+ if (isDuplicate) {
415
+ opacityState = duplicateOpacityState;
416
+ } else if (!opacityState) {
417
+ opacityState = defaultOpacityState;
418
+ // store the state so that future placements use it as a starting point
419
+ this.opacities[symbolInstance.crossTileID] = opacityState;
420
+ }
421
+
422
+ seenCrossTileIDs[symbolInstance.crossTileID] = true;
423
+
424
+ const hasText = symbolInstance.numGlyphVertices > 0 || symbolInstance.numVerticalGlyphVertices > 0;
425
+ const hasIcon = symbolInstance.numIconVertices > 0;
426
+
427
+ if (hasText) {
428
+ const packedOpacity = packOpacity(opacityState.text);
429
+ // Vertical text fades in/out on collision the same way as corresponding
430
+ // horizontal text. Switch between vertical/horizontal should be instantaneous
431
+ const opacityEntryCount = (symbolInstance.numGlyphVertices + symbolInstance.numVerticalGlyphVertices) / 4;
432
+ for (let i = 0; i < opacityEntryCount; i++) {
433
+ bucket.text.opacityVertexArray.emplaceBack(packedOpacity);
434
+ }
435
+ for (const placedTextSymbolIndex of symbolInstance.placedTextSymbolIndices) {
436
+ const placedSymbol = bucket.text.placedSymbolArray.get(placedTextSymbolIndex);
437
+ // If this label is completely faded, mark it so that we don't have to calculate
438
+ // its position at render time
439
+ placedSymbol.hidden = opacityState.text.isHidden();
440
+ }
441
+ }
442
+
443
+ if (hasIcon) {
444
+ const packedOpacity = packOpacity(opacityState.icon);
445
+ for (let i = 0; i < symbolInstance.numIconVertices / 4; i++) {
446
+ bucket.icon.opacityVertexArray.emplaceBack(packedOpacity);
447
+ }
448
+ const placedSymbol = bucket.icon.placedSymbolArray.get(s);
449
+ placedSymbol.hidden = opacityState.icon.isHidden();
450
+ }
451
+
452
+ if (!symbolInstance.collisionArrays) {
453
+ symbolInstance.collisionArrays = bucket.deserializeCollisionBoxes(
454
+ collisionBoxArray,
455
+ symbolInstance.textBoxStartIndex,
456
+ symbolInstance.textBoxEndIndex,
457
+ symbolInstance.iconBoxStartIndex,
458
+ symbolInstance.iconBoxEndIndex
459
+ );
460
+ }
461
+
462
+ const collisionArrays = symbolInstance.collisionArrays;
463
+ if (collisionArrays) {
464
+ if (collisionArrays.textBox && bucket.hasCollisionBoxData()) {
465
+ updateCollisionVertices(bucket.collisionBox.collisionVertexArray, opacityState.text.placed, false);
466
+ }
467
+
468
+ if (collisionArrays.iconBox && bucket.hasCollisionBoxData()) {
469
+ updateCollisionVertices(bucket.collisionBox.collisionVertexArray, opacityState.icon.placed, false);
470
+ }
471
+
472
+ const textCircles = collisionArrays.textCircles;
473
+ if (textCircles && bucket.hasCollisionCircleData()) {
474
+ for (let k = 0; k < textCircles.length; k += 5) {
475
+ const notUsed = isDuplicate || textCircles[k + 4] === 0;
476
+ updateCollisionVertices(bucket.collisionCircle.collisionVertexArray, opacityState.text.placed, notUsed);
477
+ }
478
+ }
479
+ }
480
+ }
481
+
482
+ bucket.sortFeatures(this.transform.angle);
483
+ if (this.retainedQueryData[bucket.bucketInstanceId]) {
484
+ this.retainedQueryData[bucket.bucketInstanceId].featureSortOrder = bucket.featureSortOrder;
485
+ }
486
+
487
+ if (bucket.hasTextData() && bucket.text.opacityVertexBuffer) {
488
+ bucket.text.opacityVertexBuffer.updateData(bucket.text.opacityVertexArray);
489
+ }
490
+ if (bucket.hasIconData() && bucket.icon.opacityVertexBuffer) {
491
+ bucket.icon.opacityVertexBuffer.updateData(bucket.icon.opacityVertexArray);
492
+ }
493
+ if (bucket.hasCollisionBoxData() && bucket.collisionBox.collisionVertexBuffer) {
494
+ bucket.collisionBox.collisionVertexBuffer.updateData(bucket.collisionBox.collisionVertexArray);
495
+ }
496
+ if (bucket.hasCollisionCircleData() && bucket.collisionCircle.collisionVertexBuffer) {
497
+ bucket.collisionCircle.collisionVertexBuffer.updateData(bucket.collisionCircle.collisionVertexArray);
498
+ }
499
+
500
+ assert(bucket.text.opacityVertexArray.length === bucket.text.layoutVertexArray.length / 4);
501
+ assert(bucket.icon.opacityVertexArray.length === bucket.icon.layoutVertexArray.length / 4);
502
+ }
503
+
504
+ symbolFadeChange(now) {
505
+ return this.fadeDuration === 0 ? 1 : (now - this.commitTime) / this.fadeDuration;
506
+ }
507
+
508
+ hasTransitions(now) {
509
+ return this.stale || now - this.lastPlacementChangeTime < this.fadeDuration;
510
+ }
511
+
512
+ stillRecent(now) {
513
+ return this.commitTime !== 'undefined' && this.commitTime + this.fadeDuration > now;
514
+ }
515
+
516
+ setStale() {
517
+ this.stale = true;
518
+ }
519
+ }
520
+
521
+ function updateCollisionVertices(collisionVertexArray, placed, notUsed) {
522
+ collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0);
523
+ collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0);
524
+ collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0);
525
+ collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0);
526
+ }
527
+
528
+ // All four vertices for a glyph will have the same opacity state
529
+ // So we pack the opacity into a uint8, and then repeat it four times
530
+ // to make a single uint32 that we can upload for each glyph in the
531
+ // label.
532
+ const shift25 = 2 ** 25;
533
+ const shift24 = 2 ** 24;
534
+ const shift17 = 2 ** 17;
535
+ const shift16 = 2 ** 16;
536
+ const shift9 = 2 ** 9;
537
+ const shift8 = 2 ** 8;
538
+ const shift1 = 2 ** 1;
539
+ function packOpacity(opacityState) {
540
+ if (opacityState.opacity === 0 && !opacityState.placed) {
541
+ return 0;
542
+ }
543
+ if (opacityState.opacity === 1 && opacityState.placed) {
544
+ return 4294967295;
545
+ }
546
+ const targetBit = opacityState.placed ? 1 : 0;
547
+ const opacityBits = Math.floor(opacityState.opacity * 127);
548
+ return (
549
+ opacityBits * shift25 +
550
+ targetBit * shift24 +
551
+ opacityBits * shift17 +
552
+ targetBit * shift16 +
553
+ opacityBits * shift9 +
554
+ targetBit * shift8 +
555
+ opacityBits * shift1 +
556
+ targetBit
557
+ );
558
+ }
559
+
560
+ module.exports = {
561
+ RetainedQueryData,
562
+ Placement
563
+ };