@sentryware/s2-node 0.0.6

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 (471) hide show
  1. package/.circleci/config.yml +45 -0
  2. package/.dockerignore +1 -0
  3. package/.gitmodules +3 -0
  4. package/CHANGELOG.md +33 -0
  5. package/LICENSE +201 -0
  6. package/README.md +147 -0
  7. package/binding.gyp +170 -0
  8. package/docker/Dockerfile.node20.test +8 -0
  9. package/docker/Dockerfile.node22.test +8 -0
  10. package/docker/Dockerfile.node24.test +8 -0
  11. package/index.d.ts +117 -0
  12. package/index.js +6 -0
  13. package/jest.config.js +184 -0
  14. package/package.json +43 -0
  15. package/publish-linux.sh +18 -0
  16. package/publish-osx.sh +19 -0
  17. package/src/builder.cc +84 -0
  18. package/src/builder.h +29 -0
  19. package/src/cell.cc +71 -0
  20. package/src/cell.h +26 -0
  21. package/src/cell_id.cc +210 -0
  22. package/src/cell_id.h +44 -0
  23. package/src/cell_union.cc +237 -0
  24. package/src/cell_union.h +34 -0
  25. package/src/earth.cc +185 -0
  26. package/src/earth.h +33 -0
  27. package/src/latlng.cc +132 -0
  28. package/src/latlng.h +28 -0
  29. package/src/loop.cc +51 -0
  30. package/src/loop.h +21 -0
  31. package/src/point.cc +69 -0
  32. package/src/point.h +23 -0
  33. package/src/polygon.cc +36 -0
  34. package/src/polygon.h +20 -0
  35. package/src/polyline.cc +186 -0
  36. package/src/polyline.h +34 -0
  37. package/src/region_coverer.cc +450 -0
  38. package/src/region_coverer.h +56 -0
  39. package/src/s2.cc +27 -0
  40. package/test/Cell.test.js +37 -0
  41. package/test/CellId.test.js +135 -0
  42. package/test/CellUnion.test.js +150 -0
  43. package/test/Earth.test.js +62 -0
  44. package/test/LatLng.test.js +45 -0
  45. package/test/Point.test.js +14 -0
  46. package/test/Polyline.test.js +78 -0
  47. package/test/RegionCoverer.test.js +301 -0
  48. package/test.sh +16 -0
  49. package/third_party/s2geometry/.travis.yml +163 -0
  50. package/third_party/s2geometry/AUTHORS +13 -0
  51. package/third_party/s2geometry/CONTRIBUTING.md +65 -0
  52. package/third_party/s2geometry/CONTRIBUTORS +30 -0
  53. package/third_party/s2geometry/LICENSE +202 -0
  54. package/third_party/s2geometry/NOTICE +5 -0
  55. package/third_party/s2geometry/README.md +127 -0
  56. package/third_party/s2geometry/doc/examples/point_index.cc +44 -0
  57. package/third_party/s2geometry/doc/examples/term_index.cc +99 -0
  58. package/third_party/s2geometry/doc/examples/term_index.py +101 -0
  59. package/third_party/s2geometry/src/python/coder.i +125 -0
  60. package/third_party/s2geometry/src/python/pywraps2_test.py +786 -0
  61. package/third_party/s2geometry/src/python/s2.i +37 -0
  62. package/third_party/s2geometry/src/python/s2_common.i +756 -0
  63. package/third_party/s2geometry/src/s2/_fp_contract_off.h +60 -0
  64. package/third_party/s2geometry/src/s2/base/casts.h +318 -0
  65. package/third_party/s2geometry/src/s2/base/commandlineflags.h +67 -0
  66. package/third_party/s2geometry/src/s2/base/integral_types.h +31 -0
  67. package/third_party/s2geometry/src/s2/base/log_severity.h +40 -0
  68. package/third_party/s2geometry/src/s2/base/logging.h +173 -0
  69. package/third_party/s2geometry/src/s2/base/mutex.h +61 -0
  70. package/third_party/s2geometry/src/s2/base/port.h +999 -0
  71. package/third_party/s2geometry/src/s2/base/spinlock.h +60 -0
  72. package/third_party/s2geometry/src/s2/base/stringprintf.cc +107 -0
  73. package/third_party/s2geometry/src/s2/base/stringprintf.h +53 -0
  74. package/third_party/s2geometry/src/s2/base/strtoint.cc +65 -0
  75. package/third_party/s2geometry/src/s2/base/strtoint.h +106 -0
  76. package/third_party/s2geometry/src/s2/base/timer.h +50 -0
  77. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.cc +164 -0
  78. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.h +110 -0
  79. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector_test.cc +232 -0
  80. package/third_party/s2geometry/src/s2/encoded_s2point_vector.cc +838 -0
  81. package/third_party/s2geometry/src/s2/encoded_s2point_vector.h +140 -0
  82. package/third_party/s2geometry/src/s2/encoded_s2point_vector_test.cc +344 -0
  83. package/third_party/s2geometry/src/s2/encoded_s2shape_index.cc +181 -0
  84. package/third_party/s2geometry/src/s2/encoded_s2shape_index.h +276 -0
  85. package/third_party/s2geometry/src/s2/encoded_s2shape_index_test.cc +244 -0
  86. package/third_party/s2geometry/src/s2/encoded_string_vector.cc +66 -0
  87. package/third_party/s2geometry/src/s2/encoded_string_vector.h +164 -0
  88. package/third_party/s2geometry/src/s2/encoded_string_vector_test.cc +69 -0
  89. package/third_party/s2geometry/src/s2/encoded_uint_vector.h +299 -0
  90. package/third_party/s2geometry/src/s2/encoded_uint_vector_test.cc +124 -0
  91. package/third_party/s2geometry/src/s2/id_set_lexicon.cc +81 -0
  92. package/third_party/s2geometry/src/s2/id_set_lexicon.h +199 -0
  93. package/third_party/s2geometry/src/s2/id_set_lexicon_test.cc +70 -0
  94. package/third_party/s2geometry/src/s2/mutable_s2shape_index.cc +1585 -0
  95. package/third_party/s2geometry/src/s2/mutable_s2shape_index.h +600 -0
  96. package/third_party/s2geometry/src/s2/mutable_s2shape_index_test.cc +589 -0
  97. package/third_party/s2geometry/src/s2/r1interval.h +220 -0
  98. package/third_party/s2geometry/src/s2/r1interval_test.cc +185 -0
  99. package/third_party/s2geometry/src/s2/r2.h +26 -0
  100. package/third_party/s2geometry/src/s2/r2rect.cc +93 -0
  101. package/third_party/s2geometry/src/s2/r2rect.h +234 -0
  102. package/third_party/s2geometry/src/s2/r2rect_test.cc +228 -0
  103. package/third_party/s2geometry/src/s2/s1angle.cc +54 -0
  104. package/third_party/s2geometry/src/s2/s1angle.h +336 -0
  105. package/third_party/s2geometry/src/s2/s1angle_test.cc +185 -0
  106. package/third_party/s2geometry/src/s2/s1chord_angle.cc +159 -0
  107. package/third_party/s2geometry/src/s2/s1chord_angle.h +369 -0
  108. package/third_party/s2geometry/src/s2/s1chord_angle_test.cc +207 -0
  109. package/third_party/s2geometry/src/s2/s1interval.cc +296 -0
  110. package/third_party/s2geometry/src/s2/s1interval.h +266 -0
  111. package/third_party/s2geometry/src/s2/s1interval_test.cc +469 -0
  112. package/third_party/s2geometry/src/s2/s2boolean_operation.cc +2391 -0
  113. package/third_party/s2geometry/src/s2/s2boolean_operation.h +501 -0
  114. package/third_party/s2geometry/src/s2/s2boolean_operation_test.cc +1400 -0
  115. package/third_party/s2geometry/src/s2/s2builder.cc +1828 -0
  116. package/third_party/s2geometry/src/s2/s2builder.h +1057 -0
  117. package/third_party/s2geometry/src/s2/s2builder_graph.cc +1084 -0
  118. package/third_party/s2geometry/src/s2/s2builder_graph.h +799 -0
  119. package/third_party/s2geometry/src/s2/s2builder_graph_test.cc +462 -0
  120. package/third_party/s2geometry/src/s2/s2builder_layer.h +50 -0
  121. package/third_party/s2geometry/src/s2/s2builder_test.cc +1329 -0
  122. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.cc +313 -0
  123. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.h +221 -0
  124. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer_test.cc +261 -0
  125. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.cc +392 -0
  126. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.h +86 -0
  127. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies_test.cc +182 -0
  128. package/third_party/s2geometry/src/s2/s2builderutil_graph_shape.h +57 -0
  129. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.cc +212 -0
  130. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.h +218 -0
  131. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer_test.cc +367 -0
  132. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.cc +74 -0
  133. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.h +122 -0
  134. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer_test.cc +167 -0
  135. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.cc +191 -0
  136. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.h +211 -0
  137. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer_test.cc +312 -0
  138. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.cc +105 -0
  139. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.h +174 -0
  140. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer_test.cc +220 -0
  141. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.cc +98 -0
  142. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.h +292 -0
  143. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer_test.cc +233 -0
  144. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.cc +354 -0
  145. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.h +239 -0
  146. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions_test.cc +716 -0
  147. package/third_party/s2geometry/src/s2/s2builderutil_testing.cc +37 -0
  148. package/third_party/s2geometry/src/s2/s2builderutil_testing.h +100 -0
  149. package/third_party/s2geometry/src/s2/s2builderutil_testing_test.cc +85 -0
  150. package/third_party/s2geometry/src/s2/s2cap.cc +347 -0
  151. package/third_party/s2geometry/src/s2/s2cap.h +286 -0
  152. package/third_party/s2geometry/src/s2/s2cap_test.cc +379 -0
  153. package/third_party/s2geometry/src/s2/s2cell.cc +552 -0
  154. package/third_party/s2geometry/src/s2/s2cell.h +249 -0
  155. package/third_party/s2geometry/src/s2/s2cell_id.cc +619 -0
  156. package/third_party/s2geometry/src/s2/s2cell_id.h +705 -0
  157. package/third_party/s2geometry/src/s2/s2cell_id_test.cc +633 -0
  158. package/third_party/s2geometry/src/s2/s2cell_index.cc +149 -0
  159. package/third_party/s2geometry/src/s2/s2cell_index.h +660 -0
  160. package/third_party/s2geometry/src/s2/s2cell_index_test.cc +411 -0
  161. package/third_party/s2geometry/src/s2/s2cell_test.cc +687 -0
  162. package/third_party/s2geometry/src/s2/s2cell_union.cc +515 -0
  163. package/third_party/s2geometry/src/s2/s2cell_union.h +399 -0
  164. package/third_party/s2geometry/src/s2/s2cell_union_test.cc +598 -0
  165. package/third_party/s2geometry/src/s2/s2centroids.cc +84 -0
  166. package/third_party/s2geometry/src/s2/s2centroids.h +87 -0
  167. package/third_party/s2geometry/src/s2/s2centroids_test.cc +82 -0
  168. package/third_party/s2geometry/src/s2/s2closest_cell_query.cc +123 -0
  169. package/third_party/s2geometry/src/s2/s2closest_cell_query.h +385 -0
  170. package/third_party/s2geometry/src/s2/s2closest_cell_query_base.h +841 -0
  171. package/third_party/s2geometry/src/s2/s2closest_cell_query_base_test.cc +63 -0
  172. package/third_party/s2geometry/src/s2/s2closest_cell_query_test.cc +412 -0
  173. package/third_party/s2geometry/src/s2/s2closest_edge_query.cc +106 -0
  174. package/third_party/s2geometry/src/s2/s2closest_edge_query.h +421 -0
  175. package/third_party/s2geometry/src/s2/s2closest_edge_query_base.h +946 -0
  176. package/third_party/s2geometry/src/s2/s2closest_edge_query_base_test.cc +59 -0
  177. package/third_party/s2geometry/src/s2/s2closest_edge_query_test.cc +505 -0
  178. package/third_party/s2geometry/src/s2/s2closest_edge_query_testing.h +91 -0
  179. package/third_party/s2geometry/src/s2/s2closest_point_query.cc +66 -0
  180. package/third_party/s2geometry/src/s2/s2closest_point_query.h +465 -0
  181. package/third_party/s2geometry/src/s2/s2closest_point_query_base.h +767 -0
  182. package/third_party/s2geometry/src/s2/s2closest_point_query_base_test.cc +63 -0
  183. package/third_party/s2geometry/src/s2/s2closest_point_query_test.cc +312 -0
  184. package/third_party/s2geometry/src/s2/s2contains_point_query.h +328 -0
  185. package/third_party/s2geometry/src/s2/s2contains_point_query_test.cc +159 -0
  186. package/third_party/s2geometry/src/s2/s2contains_vertex_query.cc +39 -0
  187. package/third_party/s2geometry/src/s2/s2contains_vertex_query.h +66 -0
  188. package/third_party/s2geometry/src/s2/s2contains_vertex_query_test.cc +67 -0
  189. package/third_party/s2geometry/src/s2/s2convex_hull_query.cc +198 -0
  190. package/third_party/s2geometry/src/s2/s2convex_hull_query.h +110 -0
  191. package/third_party/s2geometry/src/s2/s2convex_hull_query_test.cc +208 -0
  192. package/third_party/s2geometry/src/s2/s2coords.cc +146 -0
  193. package/third_party/s2geometry/src/s2/s2coords.h +459 -0
  194. package/third_party/s2geometry/src/s2/s2coords_internal.h +71 -0
  195. package/third_party/s2geometry/src/s2/s2coords_test.cc +218 -0
  196. package/third_party/s2geometry/src/s2/s2crossing_edge_query.cc +380 -0
  197. package/third_party/s2geometry/src/s2/s2crossing_edge_query.h +220 -0
  198. package/third_party/s2geometry/src/s2/s2crossing_edge_query_test.cc +382 -0
  199. package/third_party/s2geometry/src/s2/s2debug.cc +23 -0
  200. package/third_party/s2geometry/src/s2/s2debug.h +69 -0
  201. package/third_party/s2geometry/src/s2/s2distance_target.h +165 -0
  202. package/third_party/s2geometry/src/s2/s2earth.cc +52 -0
  203. package/third_party/s2geometry/src/s2/s2earth.h +268 -0
  204. package/third_party/s2geometry/src/s2/s2earth_test.cc +146 -0
  205. package/third_party/s2geometry/src/s2/s2edge_clipping.cc +462 -0
  206. package/third_party/s2geometry/src/s2/s2edge_clipping.h +183 -0
  207. package/third_party/s2geometry/src/s2/s2edge_clipping_test.cc +335 -0
  208. package/third_party/s2geometry/src/s2/s2edge_crosser.cc +85 -0
  209. package/third_party/s2geometry/src/s2/s2edge_crosser.h +343 -0
  210. package/third_party/s2geometry/src/s2/s2edge_crosser_test.cc +264 -0
  211. package/third_party/s2geometry/src/s2/s2edge_crossings.cc +515 -0
  212. package/third_party/s2geometry/src/s2/s2edge_crossings.h +138 -0
  213. package/third_party/s2geometry/src/s2/s2edge_crossings_internal.h +59 -0
  214. package/third_party/s2geometry/src/s2/s2edge_crossings_test.cc +246 -0
  215. package/third_party/s2geometry/src/s2/s2edge_distances.cc +419 -0
  216. package/third_party/s2geometry/src/s2/s2edge_distances.h +192 -0
  217. package/third_party/s2geometry/src/s2/s2edge_distances_test.cc +539 -0
  218. package/third_party/s2geometry/src/s2/s2edge_tessellator.cc +276 -0
  219. package/third_party/s2geometry/src/s2/s2edge_tessellator.h +101 -0
  220. package/third_party/s2geometry/src/s2/s2edge_tessellator_test.cc +492 -0
  221. package/third_party/s2geometry/src/s2/s2edge_vector_shape.h +85 -0
  222. package/third_party/s2geometry/src/s2/s2edge_vector_shape_test.cc +66 -0
  223. package/third_party/s2geometry/src/s2/s2error.cc +29 -0
  224. package/third_party/s2geometry/src/s2/s2error.h +147 -0
  225. package/third_party/s2geometry/src/s2/s2error_test.cc +31 -0
  226. package/third_party/s2geometry/src/s2/s2furthest_edge_query.cc +117 -0
  227. package/third_party/s2geometry/src/s2/s2furthest_edge_query.h +439 -0
  228. package/third_party/s2geometry/src/s2/s2furthest_edge_query_test.cc +487 -0
  229. package/third_party/s2geometry/src/s2/s2latlng.cc +90 -0
  230. package/third_party/s2geometry/src/s2/s2latlng.h +234 -0
  231. package/third_party/s2geometry/src/s2/s2latlng_rect.cc +727 -0
  232. package/third_party/s2geometry/src/s2/s2latlng_rect.h +434 -0
  233. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.cc +344 -0
  234. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.h +89 -0
  235. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder_test.cc +306 -0
  236. package/third_party/s2geometry/src/s2/s2latlng_rect_test.cc +1030 -0
  237. package/third_party/s2geometry/src/s2/s2latlng_test.cc +165 -0
  238. package/third_party/s2geometry/src/s2/s2lax_loop_shape.cc +104 -0
  239. package/third_party/s2geometry/src/s2/s2lax_loop_shape.h +153 -0
  240. package/third_party/s2geometry/src/s2/s2lax_loop_shape_test.cc +101 -0
  241. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.cc +348 -0
  242. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.h +183 -0
  243. package/third_party/s2geometry/src/s2/s2lax_polygon_shape_test.cc +234 -0
  244. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.cc +118 -0
  245. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.h +124 -0
  246. package/third_party/s2geometry/src/s2/s2lax_polyline_shape_test.cc +62 -0
  247. package/third_party/s2geometry/src/s2/s2loop.cc +1509 -0
  248. package/third_party/s2geometry/src/s2/s2loop.h +711 -0
  249. package/third_party/s2geometry/src/s2/s2loop_measures.cc +313 -0
  250. package/third_party/s2geometry/src/s2/s2loop_measures.h +280 -0
  251. package/third_party/s2geometry/src/s2/s2loop_measures_test.cc +367 -0
  252. package/third_party/s2geometry/src/s2/s2loop_test.cc +1371 -0
  253. package/third_party/s2geometry/src/s2/s2max_distance_targets.cc +265 -0
  254. package/third_party/s2geometry/src/s2/s2max_distance_targets.h +241 -0
  255. package/third_party/s2geometry/src/s2/s2max_distance_targets_test.cc +367 -0
  256. package/third_party/s2geometry/src/s2/s2measures.cc +128 -0
  257. package/third_party/s2geometry/src/s2/s2measures.h +78 -0
  258. package/third_party/s2geometry/src/s2/s2measures_test.cc +135 -0
  259. package/third_party/s2geometry/src/s2/s2metrics.cc +122 -0
  260. package/third_party/s2geometry/src/s2/s2metrics.h +199 -0
  261. package/third_party/s2geometry/src/s2/s2metrics_test.cc +127 -0
  262. package/third_party/s2geometry/src/s2/s2min_distance_targets.cc +295 -0
  263. package/third_party/s2geometry/src/s2/s2min_distance_targets.h +273 -0
  264. package/third_party/s2geometry/src/s2/s2min_distance_targets_test.cc +239 -0
  265. package/third_party/s2geometry/src/s2/s2padded_cell.cc +162 -0
  266. package/third_party/s2geometry/src/s2/s2padded_cell.h +108 -0
  267. package/third_party/s2geometry/src/s2/s2padded_cell_test.cc +138 -0
  268. package/third_party/s2geometry/src/s2/s2point.h +38 -0
  269. package/third_party/s2geometry/src/s2/s2point_compression.cc +388 -0
  270. package/third_party/s2geometry/src/s2/s2point_compression.h +78 -0
  271. package/third_party/s2geometry/src/s2/s2point_compression_test.cc +305 -0
  272. package/third_party/s2geometry/src/s2/s2point_index.h +345 -0
  273. package/third_party/s2geometry/src/s2/s2point_index_test.cc +147 -0
  274. package/third_party/s2geometry/src/s2/s2point_region.cc +72 -0
  275. package/third_party/s2geometry/src/s2/s2point_region.h +76 -0
  276. package/third_party/s2geometry/src/s2/s2point_region_test.cc +100 -0
  277. package/third_party/s2geometry/src/s2/s2point_span.h +57 -0
  278. package/third_party/s2geometry/src/s2/s2point_test.cc +47 -0
  279. package/third_party/s2geometry/src/s2/s2point_vector_shape.h +127 -0
  280. package/third_party/s2geometry/src/s2/s2point_vector_shape_test.cc +59 -0
  281. package/third_party/s2geometry/src/s2/s2pointutil.cc +131 -0
  282. package/third_party/s2geometry/src/s2/s2pointutil.h +138 -0
  283. package/third_party/s2geometry/src/s2/s2pointutil_test.cc +157 -0
  284. package/third_party/s2geometry/src/s2/s2polygon.cc +1569 -0
  285. package/third_party/s2geometry/src/s2/s2polygon.h +934 -0
  286. package/third_party/s2geometry/src/s2/s2polygon_test.cc +3025 -0
  287. package/third_party/s2geometry/src/s2/s2polyline.cc +645 -0
  288. package/third_party/s2geometry/src/s2/s2polyline.h +379 -0
  289. package/third_party/s2geometry/src/s2/s2polyline_alignment.cc +414 -0
  290. package/third_party/s2geometry/src/s2/s2polyline_alignment.h +245 -0
  291. package/third_party/s2geometry/src/s2/s2polyline_alignment_internal.h +158 -0
  292. package/third_party/s2geometry/src/s2/s2polyline_alignment_test.cc +610 -0
  293. package/third_party/s2geometry/src/s2/s2polyline_measures.cc +42 -0
  294. package/third_party/s2geometry/src/s2/s2polyline_measures.h +53 -0
  295. package/third_party/s2geometry/src/s2/s2polyline_measures_test.cc +57 -0
  296. package/third_party/s2geometry/src/s2/s2polyline_simplifier.cc +187 -0
  297. package/third_party/s2geometry/src/s2/s2polyline_simplifier.h +109 -0
  298. package/third_party/s2geometry/src/s2/s2polyline_simplifier_test.cc +165 -0
  299. package/third_party/s2geometry/src/s2/s2polyline_test.cc +554 -0
  300. package/third_party/s2geometry/src/s2/s2predicates.cc +1486 -0
  301. package/third_party/s2geometry/src/s2/s2predicates.h +282 -0
  302. package/third_party/s2geometry/src/s2/s2predicates_internal.h +135 -0
  303. package/third_party/s2geometry/src/s2/s2predicates_test.cc +1427 -0
  304. package/third_party/s2geometry/src/s2/s2projections.cc +109 -0
  305. package/third_party/s2geometry/src/s2/s2projections.h +161 -0
  306. package/third_party/s2geometry/src/s2/s2projections_test.cc +78 -0
  307. package/third_party/s2geometry/src/s2/s2r2rect.cc +88 -0
  308. package/third_party/s2geometry/src/s2/s2r2rect.h +292 -0
  309. package/third_party/s2geometry/src/s2/s2r2rect_test.cc +312 -0
  310. package/third_party/s2geometry/src/s2/s2region.cc +26 -0
  311. package/third_party/s2geometry/src/s2/s2region.h +142 -0
  312. package/third_party/s2geometry/src/s2/s2region_coverer.cc +514 -0
  313. package/third_party/s2geometry/src/s2/s2region_coverer.h +356 -0
  314. package/third_party/s2geometry/src/s2/s2region_coverer_test.cc +509 -0
  315. package/third_party/s2geometry/src/s2/s2region_intersection.cc +84 -0
  316. package/third_party/s2geometry/src/s2/s2region_intersection.h +79 -0
  317. package/third_party/s2geometry/src/s2/s2region_term_indexer.cc +270 -0
  318. package/third_party/s2geometry/src/s2/s2region_term_indexer.h +299 -0
  319. package/third_party/s2geometry/src/s2/s2region_term_indexer_test.cc +209 -0
  320. package/third_party/s2geometry/src/s2/s2region_test.cc +370 -0
  321. package/third_party/s2geometry/src/s2/s2region_union.cc +90 -0
  322. package/third_party/s2geometry/src/s2/s2region_union.h +83 -0
  323. package/third_party/s2geometry/src/s2/s2region_union_test.cc +89 -0
  324. package/third_party/s2geometry/src/s2/s2shape.h +283 -0
  325. package/third_party/s2geometry/src/s2/s2shape_index.cc +321 -0
  326. package/third_party/s2geometry/src/s2/s2shape_index.h +781 -0
  327. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.cc +113 -0
  328. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.h +135 -0
  329. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region_test.cc +162 -0
  330. package/third_party/s2geometry/src/s2/s2shape_index_measures.cc +92 -0
  331. package/third_party/s2geometry/src/s2/s2shape_index_measures.h +100 -0
  332. package/third_party/s2geometry/src/s2/s2shape_index_measures_test.cc +136 -0
  333. package/third_party/s2geometry/src/s2/s2shape_index_region.h +350 -0
  334. package/third_party/s2geometry/src/s2/s2shape_index_region_test.cc +161 -0
  335. package/third_party/s2geometry/src/s2/s2shape_index_test.cc +24 -0
  336. package/third_party/s2geometry/src/s2/s2shape_measures.cc +138 -0
  337. package/third_party/s2geometry/src/s2/s2shape_measures.h +95 -0
  338. package/third_party/s2geometry/src/s2/s2shape_measures_test.cc +139 -0
  339. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.cc +120 -0
  340. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.h +66 -0
  341. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries_test.cc +170 -0
  342. package/third_party/s2geometry/src/s2/s2shapeutil_coding.cc +253 -0
  343. package/third_party/s2geometry/src/s2/s2shapeutil_coding.h +283 -0
  344. package/third_party/s2geometry/src/s2/s2shapeutil_coding_test.cc +54 -0
  345. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.cc +40 -0
  346. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.h +41 -0
  347. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force_test.cc +55 -0
  348. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges.h +57 -0
  349. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges_test.cc +43 -0
  350. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.cc +45 -0
  351. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.h +72 -0
  352. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator_test.cc +116 -0
  353. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.cc +107 -0
  354. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.h +48 -0
  355. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point_test.cc +104 -0
  356. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.cc +58 -0
  357. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.h +65 -0
  358. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator_test.cc +61 -0
  359. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge.h +58 -0
  360. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge_id.h +97 -0
  361. package/third_party/s2geometry/src/s2/s2shapeutil_testing.cc +104 -0
  362. package/third_party/s2geometry/src/s2/s2shapeutil_testing.h +36 -0
  363. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +440 -0
  364. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.h +72 -0
  365. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs_test.cc +184 -0
  366. package/third_party/s2geometry/src/s2/s2testing.cc +464 -0
  367. package/third_party/s2geometry/src/s2/s2testing.h +385 -0
  368. package/third_party/s2geometry/src/s2/s2testing_test.cc +166 -0
  369. package/third_party/s2geometry/src/s2/s2text_format.cc +506 -0
  370. package/third_party/s2geometry/src/s2/s2text_format.h +289 -0
  371. package/third_party/s2geometry/src/s2/s2text_format_test.cc +417 -0
  372. package/third_party/s2geometry/src/s2/s2wedge_relations.cc +80 -0
  373. package/third_party/s2geometry/src/s2/s2wedge_relations.h +64 -0
  374. package/third_party/s2geometry/src/s2/s2wedge_relations_test.cc +89 -0
  375. package/third_party/s2geometry/src/s2/sequence_lexicon.h +296 -0
  376. package/third_party/s2geometry/src/s2/sequence_lexicon_test.cc +113 -0
  377. package/third_party/s2geometry/src/s2/strings/ostringstream.cc +35 -0
  378. package/third_party/s2geometry/src/s2/strings/ostringstream.h +105 -0
  379. package/third_party/s2geometry/src/s2/strings/serialize.cc +46 -0
  380. package/third_party/s2geometry/src/s2/strings/serialize.h +40 -0
  381. package/third_party/s2geometry/src/s2/third_party/absl/algorithm/algorithm.h +187 -0
  382. package/third_party/s2geometry/src/s2/third_party/absl/base/attributes.h +666 -0
  383. package/third_party/s2geometry/src/s2/third_party/absl/base/casts.h +189 -0
  384. package/third_party/s2geometry/src/s2/third_party/absl/base/config.h +462 -0
  385. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.cc +129 -0
  386. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.h +394 -0
  387. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/atomic_hook.h +168 -0
  388. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/identity.h +33 -0
  389. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/inline_variable.h +117 -0
  390. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/invoke.h +188 -0
  391. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.cc +254 -0
  392. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.h +205 -0
  393. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.cc +106 -0
  394. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.h +71 -0
  395. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/unaligned_access.h +322 -0
  396. package/third_party/s2geometry/src/s2/third_party/absl/base/log_severity.h +77 -0
  397. package/third_party/s2geometry/src/s2/third_party/absl/base/macros.h +236 -0
  398. package/third_party/s2geometry/src/s2/third_party/absl/base/optimization.h +177 -0
  399. package/third_party/s2geometry/src/s2/third_party/absl/base/policy_checks.h +124 -0
  400. package/third_party/s2geometry/src/s2/third_party/absl/base/port.h +97 -0
  401. package/third_party/s2geometry/src/s2/third_party/absl/base/thread_annotations.h +277 -0
  402. package/third_party/s2geometry/src/s2/third_party/absl/container/fixed_array.h +523 -0
  403. package/third_party/s2geometry/src/s2/third_party/absl/container/inlined_vector.h +1453 -0
  404. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/compressed_tuple.h +191 -0
  405. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/container_memory.h +424 -0
  406. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/layout.h +739 -0
  407. package/third_party/s2geometry/src/s2/third_party/absl/memory/memory.h +755 -0
  408. package/third_party/s2geometry/src/s2/third_party/absl/meta/type_traits.h +436 -0
  409. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.cc +232 -0
  410. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.h +656 -0
  411. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_have_intrinsic.inc +3 -0
  412. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_no_intrinsic.inc +3 -0
  413. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.cc +198 -0
  414. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.h +239 -0
  415. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii_ctype.h +66 -0
  416. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/bits.h +53 -0
  417. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.cc +110 -0
  418. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.h +146 -0
  419. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/resize_uninitialized.h +72 -0
  420. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.cc +38 -0
  421. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.h +89 -0
  422. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.cc +909 -0
  423. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.h +187 -0
  424. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.cc +240 -0
  425. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.h +398 -0
  426. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_join.h +22 -0
  427. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.cc +47 -0
  428. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.h +43 -0
  429. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.cc +245 -0
  430. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.h +602 -0
  431. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.cc +42 -0
  432. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.h +130 -0
  433. package/third_party/s2geometry/src/s2/third_party/absl/types/span.h +793 -0
  434. package/third_party/s2geometry/src/s2/third_party/absl/utility/utility.h +299 -0
  435. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.cc +274 -0
  436. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.h +53 -0
  437. package/third_party/s2geometry/src/s2/util/bits/bits.cc +155 -0
  438. package/third_party/s2geometry/src/s2/util/bits/bits.h +745 -0
  439. package/third_party/s2geometry/src/s2/util/coding/coder.cc +83 -0
  440. package/third_party/s2geometry/src/s2/util/coding/coder.h +553 -0
  441. package/third_party/s2geometry/src/s2/util/coding/nth-derivative.h +134 -0
  442. package/third_party/s2geometry/src/s2/util/coding/transforms.h +62 -0
  443. package/third_party/s2geometry/src/s2/util/coding/varint.cc +289 -0
  444. package/third_party/s2geometry/src/s2/util/coding/varint.h +476 -0
  445. package/third_party/s2geometry/src/s2/util/endian/endian.h +859 -0
  446. package/third_party/s2geometry/src/s2/util/gtl/btree.h +2471 -0
  447. package/third_party/s2geometry/src/s2/util/gtl/btree_container.h +411 -0
  448. package/third_party/s2geometry/src/s2/util/gtl/btree_map.h +79 -0
  449. package/third_party/s2geometry/src/s2/util/gtl/btree_set.h +73 -0
  450. package/third_party/s2geometry/src/s2/util/gtl/compact_array.h +653 -0
  451. package/third_party/s2geometry/src/s2/util/gtl/container_logging.h +291 -0
  452. package/third_party/s2geometry/src/s2/util/gtl/dense_hash_set.h +358 -0
  453. package/third_party/s2geometry/src/s2/util/gtl/densehashtable.h +1493 -0
  454. package/third_party/s2geometry/src/s2/util/gtl/hashtable_common.h +253 -0
  455. package/third_party/s2geometry/src/s2/util/gtl/layout.h +28 -0
  456. package/third_party/s2geometry/src/s2/util/gtl/legacy_random_shuffle.h +77 -0
  457. package/third_party/s2geometry/src/s2/util/hash/mix.h +76 -0
  458. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.cc +832 -0
  459. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.h +646 -0
  460. package/third_party/s2geometry/src/s2/util/math/mathutil.cc +75 -0
  461. package/third_party/s2geometry/src/s2/util/math/mathutil.h +189 -0
  462. package/third_party/s2geometry/src/s2/util/math/matrix3x3.h +574 -0
  463. package/third_party/s2geometry/src/s2/util/math/vector.h +569 -0
  464. package/third_party/s2geometry/src/s2/util/math/vector3_hash.h +54 -0
  465. package/third_party/s2geometry/src/s2/util/units/length-units.cc +21 -0
  466. package/third_party/s2geometry/src/s2/util/units/length-units.h +135 -0
  467. package/third_party/s2geometry/src/s2/util/units/physical-units.h +313 -0
  468. package/third_party/s2geometry/src/s2/value_lexicon.h +234 -0
  469. package/third_party/s2geometry/src/s2/value_lexicon_test.cc +121 -0
  470. package/third_party/s2geometry/third_party/cmake/FindGFlags.cmake +48 -0
  471. package/third_party/s2geometry/third_party/cmake/FindGlog.cmake +48 -0
@@ -0,0 +1,414 @@
1
+ // Copyright 2017 Google Inc. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS-IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+
16
+
17
+ #include "s2/s2polyline_alignment.h"
18
+ #include "s2/s2polyline_alignment_internal.h"
19
+
20
+ #include <algorithm>
21
+ #include <numeric>
22
+ #include <sstream>
23
+ #include <string>
24
+ #include <utility>
25
+ #include <vector>
26
+
27
+ #include "s2/base/logging.h"
28
+ #include "s2/third_party/absl/memory/memory.h"
29
+ #include "s2/util/math/mathutil.h"
30
+
31
+ namespace s2polyline_alignment {
32
+
33
+ Window::Window(const std::vector<ColumnStride>& strides) {
34
+ S2_DCHECK(!strides.empty()) << "Cannot construct empty window.";
35
+ S2_DCHECK(strides[0].start == 0) << "First element of start_cols is non-zero.";
36
+ strides_ = strides;
37
+ rows_ = strides.size();
38
+ cols_ = strides.back().end;
39
+ S2_DCHECK(this->IsValid()) << "Constructor validity check fail.";
40
+ }
41
+
42
+ Window::Window(const WarpPath& warp_path) {
43
+ S2_DCHECK(!warp_path.empty()) << "Cannot construct window from empty warp path.";
44
+ S2_DCHECK(warp_path.front() == std::make_pair(0, 0)) << "Must start at (0, 0).";
45
+ rows_ = warp_path.back().first + 1;
46
+ S2_DCHECK(rows_ > 0) << "Must have at least one row.";
47
+ cols_ = warp_path.back().second + 1;
48
+ S2_DCHECK(cols_ > 0) << "Must have at least one column.";
49
+ strides_.resize(rows_);
50
+
51
+ int prev_row = 0;
52
+ int curr_row = 0;
53
+ int stride_start = 0;
54
+ int stride_stop = 0;
55
+ for (const auto& pair : warp_path) {
56
+ curr_row = pair.first;
57
+ if (curr_row > prev_row) {
58
+ strides_[prev_row] = {stride_start, stride_stop};
59
+ stride_start = pair.second;
60
+ prev_row = curr_row;
61
+ }
62
+ stride_stop = pair.second + 1;
63
+ }
64
+ S2_DCHECK_EQ(curr_row, rows_ - 1);
65
+ strides_[rows_ - 1] = {stride_start, stride_stop};
66
+ S2_DCHECK(this->IsValid()) << "Constructor validity check fail.";
67
+ }
68
+
69
+ Window Window::Upsample(const int new_rows, const int new_cols) const {
70
+ S2_DCHECK(new_rows >= rows_) << "Upsampling: New_rows < current_rows";
71
+ S2_DCHECK(new_cols >= cols_) << "Upsampling: New_cols < current_cols";
72
+ const double row_scale = static_cast<double>(new_rows) / rows_;
73
+ const double col_scale = static_cast<double>(new_cols) / cols_;
74
+ std::vector<ColumnStride> new_strides(new_rows);
75
+ ColumnStride from_stride;
76
+ for (int row = 0; row < new_rows; ++row) {
77
+ from_stride = strides_[static_cast<int>((row + 0.5) / row_scale)];
78
+ new_strides[row] = {static_cast<int>(col_scale * from_stride.start + 0.5),
79
+ static_cast<int>(col_scale * from_stride.end + 0.5)};
80
+ }
81
+ return Window(new_strides);
82
+ }
83
+
84
+ // This code takes advantage of the fact that the dilation window is square to
85
+ // ensure that we can compute the stride for each output row in constant time.
86
+ // TODO (mrdmnd): a potential optimization might be to combine this method and
87
+ // the Upsample method into a single "Expand" method. For the sake of
88
+ // testing, I haven't done that here, but I think it would be fairly
89
+ // straightforward to do so. This method generally isn't very expensive so it
90
+ // feels unnecessary to combine them.
91
+ Window Window::Dilate(const int radius) const {
92
+ S2_DCHECK(radius >= 0) << "Negative dilation radius.";
93
+ std::vector<ColumnStride> new_strides(rows_);
94
+ int prev_row, next_row;
95
+ for (int row = 0; row < rows_; ++row) {
96
+ prev_row = std::max(0, row - radius);
97
+ next_row = std::min(row + radius, rows_ - 1);
98
+ new_strides[row] = {std::max(0, strides_[prev_row].start - radius),
99
+ std::min(strides_[next_row].end + radius, cols_)};
100
+ }
101
+ return Window(new_strides);
102
+ }
103
+
104
+ // Debug string implemented primarily for testing purposes.
105
+ string Window::DebugString() const {
106
+ std::stringstream buffer;
107
+ for (int row = 0; row < rows_; ++row) {
108
+ for (int col = 0; col < cols_; ++col) {
109
+ buffer << (strides_[row].InRange(col) ? " *" : " .");
110
+ }
111
+ buffer << std::endl;
112
+ }
113
+ return buffer.str();
114
+ }
115
+
116
+ // Valid Windows require the following structural conditions to hold:
117
+ // 1) All rows must consist of a single contiguous stride of `true` values.
118
+ // 2) All strides are greater than zero length (i.e. no empty rows).
119
+ // 3) The index of the first `true` column in a row must be at least as
120
+ // large as the index of the first `true` column in the previous row.
121
+ // 4) The index of the last `true` column in a row must be at least as large
122
+ // as the index of the last `true` column in the previous row.
123
+ // 5) strides[0].start = 0 (the first cell is always filled).
124
+ // 6) strides[n_rows-1].end = n_cols (the last cell is filled).
125
+ bool Window::IsValid() const {
126
+ if (rows_ <= 0 || cols_ <= 0 || strides_.front().start != 0 ||
127
+ strides_.back().end != cols_) {
128
+ return false;
129
+ }
130
+
131
+ ColumnStride prev = {-1, -1};
132
+ for (const auto& curr : strides_) {
133
+ if (curr.end <= curr.start || curr.start < prev.start ||
134
+ curr.end < prev.end) {
135
+ return false;
136
+ }
137
+ prev = curr;
138
+ }
139
+ return true;
140
+ }
141
+
142
+ inline double BoundsCheckedTableCost(const int row, const int col,
143
+ const ColumnStride& stride,
144
+ const CostTable& table) {
145
+ if (row < 0 && col < 0) {
146
+ return 0.0;
147
+ } else if (row < 0 || col < 0 || !stride.InRange(col)) {
148
+ return DOUBLE_MAX;
149
+ } else {
150
+ return table[row][col];
151
+ }
152
+ }
153
+
154
+ // Perform dynamic timewarping by filling in the DP table on cells that are
155
+ // inside our search window. For an exact (all-squares) evaluation, this
156
+ // incurs bounds checking overhead - we don't need to ensure that we're inside
157
+ // the appropriate cells in the window, because it's guaranteed. Structuring
158
+ // the program to reuse code for both the EXACT and WINDOWED cases by
159
+ // abstracting EXACT as a window with full-covering strides is done for
160
+ // maintainability reasons. One potential optimization here might be to overload
161
+ // this function to skip bounds checking when the window is full.
162
+ //
163
+ // As a note of general interest, the Dynamic Timewarp algorithm as stated here
164
+ // prefers shorter warp paths, when two warp paths might be equally costly. This
165
+ // is because it favors progressing in the sequences simultaneously due to the
166
+ // equal weighting of a diagonal step in the cost table with a horizontal or
167
+ // vertical step. This may be counterintuitive, but represents the standard
168
+ // implementation of this algorithm. TODO(user) - future implementations could
169
+ // allow weights on the lookup costs to mitigate this.
170
+ //
171
+ // This is the hottest routine in the whole package, please be careful to
172
+ // profile any future changes made here.
173
+ //
174
+ // This method takes time proportional to the number of cells in the window,
175
+ // which can range from O(max(a, b)) cells (best) to O(a*b) cells (worst)
176
+ VertexAlignment DynamicTimewarp(const S2Polyline& a, const S2Polyline& b,
177
+ const Window& w) {
178
+ const int rows = a.num_vertices();
179
+ const int cols = b.num_vertices();
180
+ auto costs = CostTable(rows, std::vector<double>(cols));
181
+
182
+ ColumnStride curr;
183
+ ColumnStride prev = ColumnStride::All();
184
+ for (int row = 0; row < rows; ++row) {
185
+ curr = w.GetColumnStride(row);
186
+ for (int col = curr.start; col < curr.end; ++col) {
187
+ double d_cost = BoundsCheckedTableCost(row - 1, col - 1, prev, costs);
188
+ double u_cost = BoundsCheckedTableCost(row - 1, col - 0, prev, costs);
189
+ double l_cost = BoundsCheckedTableCost(row - 0, col - 1, curr, costs);
190
+ costs[row][col] = std::min({d_cost, u_cost, l_cost}) +
191
+ (a.vertex(row) - b.vertex(col)).Norm2();
192
+ }
193
+ prev = curr;
194
+ }
195
+
196
+ // Now we walk back through the cost table and build up the warp path.
197
+ // Somewhat surprisingly, it is faster to recover the path this way than it
198
+ // is to save the comparisons from the computation we *already did* to get the
199
+ // direction we came from. The author speculates that this behavior is
200
+ // assignment-cost-related: to persist direction, we have to do extra
201
+ // stores/loads of "directional" information, and the extra assignment cost
202
+ // this incurs is larger than the cost to simply redo the comparisons.
203
+ // It's probably worth revisiting this assumption in the future.
204
+ // As it turns out, the following code ends up effectively free.
205
+ WarpPath warp_path;
206
+ warp_path.reserve(std::max(a.num_vertices(), b.num_vertices()));
207
+ int row = a.num_vertices() - 1;
208
+ int col = b.num_vertices() - 1;
209
+ curr = w.GetCheckedColumnStride(row);
210
+ prev = w.GetCheckedColumnStride(row - 1);
211
+ while (row >= 0 && col >= 0) {
212
+ warp_path.push_back({row, col});
213
+ double d_cost = BoundsCheckedTableCost(row - 1, col - 1, prev, costs);
214
+ double u_cost = BoundsCheckedTableCost(row - 1, col - 0, prev, costs);
215
+ double l_cost = BoundsCheckedTableCost(row - 0, col - 1, curr, costs);
216
+ if (d_cost <= u_cost && d_cost <= l_cost) {
217
+ row -= 1;
218
+ col -= 1;
219
+ curr = w.GetCheckedColumnStride(row);
220
+ prev = w.GetCheckedColumnStride(row - 1);
221
+ } else if (u_cost <= l_cost) {
222
+ row -= 1;
223
+ curr = w.GetCheckedColumnStride(row);
224
+ prev = w.GetCheckedColumnStride(row - 1);
225
+ } else {
226
+ col -= 1;
227
+ }
228
+ }
229
+ std::reverse(warp_path.begin(), warp_path.end());
230
+ return VertexAlignment(costs.back().back(), warp_path);
231
+ }
232
+
233
+ std::unique_ptr<S2Polyline> HalfResolution(const S2Polyline& in) {
234
+ const int n = in.num_vertices();
235
+ std::vector<S2Point> vertices;
236
+ vertices.reserve(n / 2);
237
+ for (int i = 0; i < n; i += 2) {
238
+ vertices.push_back(in.vertex(i));
239
+ }
240
+ return absl::make_unique<S2Polyline>(vertices);
241
+ }
242
+
243
+ // Helper methods for GetMedoidPolyline and GetConsensusPolyline to auto-select
244
+ // appropriate cost function / alignment functions.
245
+ double CostFn(const S2Polyline& a, const S2Polyline& b, bool approx) {
246
+ return approx ? GetApproxVertexAlignment(a, b).alignment_cost
247
+ : GetExactVertexAlignmentCost(a, b);
248
+ }
249
+
250
+ VertexAlignment AlignmentFn(const S2Polyline& a, const S2Polyline& b,
251
+ bool approx) {
252
+ return approx ? GetApproxVertexAlignment(a, b)
253
+ : GetExactVertexAlignment(a, b);
254
+ }
255
+
256
+ // PUBLIC API IMPLEMENTATION DETAILS
257
+
258
+ // This is the constant-space implementation of Dynamic Timewarp that can
259
+ // compute the alignment cost, but not the warp path.
260
+ double GetExactVertexAlignmentCost(const S2Polyline& a, const S2Polyline& b) {
261
+ const int a_n = a.num_vertices();
262
+ const int b_n = b.num_vertices();
263
+ S2_CHECK(a_n > 0) << "A is empty polyline.";
264
+ S2_CHECK(b_n > 0) << "B is empty polyline.";
265
+ std::vector<double> cost(b_n, DOUBLE_MAX);
266
+ double left_diag_min_cost = 0;
267
+ for (int row = 0; row < a_n; ++row) {
268
+ for (int col = 0; col < b_n; ++col) {
269
+ double up_cost = cost[col];
270
+ cost[col] = std::min(left_diag_min_cost, up_cost) +
271
+ (a.vertex(row) - b.vertex(col)).Norm2();
272
+ left_diag_min_cost = std::min(cost[col], up_cost);
273
+ }
274
+ left_diag_min_cost = DOUBLE_MAX;
275
+ }
276
+ return cost.back();
277
+ }
278
+
279
+ VertexAlignment GetExactVertexAlignment(const S2Polyline& a,
280
+ const S2Polyline& b) {
281
+ const int a_n = a.num_vertices();
282
+ const int b_n = b.num_vertices();
283
+ S2_CHECK(a_n > 0) << "A is empty polyline.";
284
+ S2_CHECK(b_n > 0) << "B is empty polyline.";
285
+ const auto w = Window(std::vector<ColumnStride>(a_n, {0, b_n}));
286
+ return DynamicTimewarp(a, b, w);
287
+ }
288
+
289
+ VertexAlignment GetApproxVertexAlignment(const S2Polyline& a,
290
+ const S2Polyline& b,
291
+ const int radius) {
292
+ // Determined experimentally, through benchmarking, as about the points at
293
+ // which ExactAlignment is faster than ApproxAlignment, so we use these as
294
+ // our switchover points to exact computation mode.
295
+ const int kSizeSwitchover = 32;
296
+ const double kDensitySwitchover = 0.85;
297
+ const int a_n = a.num_vertices();
298
+ const int b_n = b.num_vertices();
299
+ S2_CHECK(a_n > 0) << "A is empty polyline.";
300
+ S2_CHECK(b_n > 0) << "B is empty polyline.";
301
+ S2_CHECK(radius >= 0) << "Radius is negative.";
302
+
303
+ // If we've hit the point where doing a full, direct solve is guaranteed to
304
+ // be faster, then terminate the recursion and do that.
305
+ if (a_n - radius < kSizeSwitchover || b_n - radius < kSizeSwitchover) {
306
+ return GetExactVertexAlignment(a, b);
307
+ }
308
+
309
+ // If we've hit the point where the window will be probably be so full that we
310
+ // might as well compute an exact solution, then terminate recursion to do so.
311
+ if (std::max(a_n, b_n) * (2 * radius + 1) > a_n * b_n * kDensitySwitchover) {
312
+ return GetExactVertexAlignment(a, b);
313
+ }
314
+
315
+ // Otherwise, shrink the input polylines, recursively compute the vertex
316
+ // alignment using this method, and then compute the final alignment using
317
+ // the projected alignment `proj` on an upsampled, dilated window.
318
+ const auto a_half = HalfResolution(a);
319
+ const auto b_half = HalfResolution(b);
320
+ const auto proj = GetApproxVertexAlignment(*a_half, *b_half, radius);
321
+ const auto w = Window(proj.warp_path).Upsample(a_n, b_n).Dilate(radius);
322
+ return DynamicTimewarp(a, b, w);
323
+ }
324
+
325
+ // This method calls the approx method with a reasonable default for radius.
326
+ VertexAlignment GetApproxVertexAlignment(const S2Polyline& a,
327
+ const S2Polyline& b) {
328
+ const int max_length = std::max(a.num_vertices(), b.num_vertices());
329
+ const int radius = static_cast<int>(std::pow(max_length, 0.25));
330
+ return GetApproxVertexAlignment(a, b, radius);
331
+ }
332
+
333
+ // We use some of the symmetry of our metric to avoid computing all N^2
334
+ // alignments. Specifically, because cost_fn(a, b) = cost_fn(b, a), and
335
+ // cost_fn(a, a) = 0, we can compute only the lower triangle of cost matrix
336
+ // and then mirror it across the diagonal to save on cost_fn invocations.
337
+ int GetMedoidPolyline(const std::vector<std::unique_ptr<S2Polyline>>& polylines,
338
+ const MedoidOptions options) {
339
+ const int num_polylines = polylines.size();
340
+ const bool approx = options.approx();
341
+ S2_CHECK_GT(num_polylines, 0);
342
+
343
+ // costs[i] stores total cost of aligning [i] with all other polylines.
344
+ std::vector<double> costs(num_polylines, 0.0);
345
+ for (int i = 0; i < num_polylines; ++i) {
346
+ for (int j = i + 1; j < num_polylines; ++j) {
347
+ double cost = CostFn(*polylines[i], *polylines[j], approx);
348
+ costs[i] += cost;
349
+ costs[j] += cost;
350
+ }
351
+ }
352
+ return std::min_element(costs.begin(), costs.end()) - costs.begin();
353
+ }
354
+
355
+ // Implements Iterative Dynamic Timewarp Barycenter Averaging algorithm from
356
+ //
357
+ // https://pdfs.semanticscholar.org/a596/8ca9488199291ffe5473643142862293d69d.pdf
358
+ //
359
+ // Algorithm:
360
+ // Initialize consensus sequence with either the medoid or an arbitrary
361
+ // element (chosen here to be the first element in the input collection).
362
+ // While the consensus polyline `consensus` hasn't converged and we haven't
363
+ // exceeded our iteration cap:
364
+ // For each polyline `p` in the input,
365
+ // Compute vertex alignment from the current consensus to `p`.
366
+ // For each (c_index, p_index) pair in the warp path,
367
+ // Add the S2Point pts->vertex(p_index) to S2Point consensus[c_index]
368
+ // Normalize (compute centroid) of each consensus point.
369
+ // Determine if consensus is converging; if no vertex has moved or we've hit
370
+ // the iteration cap, halt.
371
+ //
372
+ // This algorithm takes O(iteration_cap * num_polylines) pairwise alignments.
373
+
374
+ std::unique_ptr<S2Polyline> GetConsensusPolyline(
375
+ const std::vector<std::unique_ptr<S2Polyline>>& polylines,
376
+ const ConsensusOptions options) {
377
+ const int num_polylines = polylines.size();
378
+ S2_CHECK_GT(num_polylines, 0);
379
+ const bool approx = options.approx();
380
+
381
+ // Seed a consensus polyline, either arbitrarily with first element, or with
382
+ // the medoid. If seeding with medoid, inherit approx parameter from options.
383
+ int seed_index = 0;
384
+ if (options.seed_medoid()) {
385
+ MedoidOptions medoid_options;
386
+ medoid_options.set_approx(approx);
387
+ seed_index = GetMedoidPolyline(polylines, medoid_options);
388
+ }
389
+ auto consensus = std::unique_ptr<S2Polyline>(polylines[seed_index]->Clone());
390
+ const int num_consensus_vertices = consensus->num_vertices();
391
+ S2_DCHECK_GT(num_consensus_vertices, 1);
392
+
393
+ bool converged = false;
394
+ int iterations = 0;
395
+ while (!converged && iterations < options.iteration_cap()) {
396
+ std::vector<S2Point> points(num_consensus_vertices, S2Point());
397
+ for (const auto& polyline : polylines) {
398
+ const auto alignment = AlignmentFn(*consensus, *polyline, approx);
399
+ for (const auto& pair : alignment.warp_path) {
400
+ points[pair.first] += polyline->vertex(pair.second);
401
+ }
402
+ }
403
+ for (S2Point& p : points) {
404
+ p = p.Normalize();
405
+ }
406
+
407
+ ++iterations;
408
+ auto new_consensus = absl::make_unique<S2Polyline>(points);
409
+ converged = new_consensus->ApproxEquals(*consensus);
410
+ consensus = std::move(new_consensus);
411
+ }
412
+ return consensus;
413
+ }
414
+ } // namespace s2polyline_alignment
@@ -0,0 +1,245 @@
1
+ // Copyright 2017 Google Inc. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS-IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+
16
+
17
+ #ifndef S2_S2POLYLINE_ALIGNMENT_H_
18
+ #define S2_S2POLYLINE_ALIGNMENT_H_
19
+
20
+ #include <memory>
21
+ #include <vector>
22
+
23
+ #include "s2/s2polyline.h"
24
+
25
+ // This library provides code to compute vertex alignments between S2Polylines.
26
+ //
27
+ // A vertex "alignment" or "warp" between two polylines is a matching between
28
+ // pairs of their vertices. Users can imagine pairing each vertex from
29
+ // S2Polyline `a` with at least one other vertex in S2Polyline `b`. The "cost"
30
+ // of an arbitrary alignment is defined as the summed value of the squared
31
+ // chordal distance between each pair of points in the warp path. An "optimal
32
+ // alignment" for a pair of polylines is defined as the alignment with least
33
+ // cost. Note: optimal alignments are not necessarily unique. The standard way
34
+ // of computing an optimal alignment between two sequences is the use of the
35
+ // `Dynamic Timewarp` algorithm.
36
+ //
37
+ // We provide three methods for computing (via Dynamic Timewarp) the optimal
38
+ // alignment between two S2Polylines. These methods are performance-sensitive,
39
+ // and have been reasonably optimized for space- and time- usage. On modern
40
+ // hardware, it is possible to compute exact alignments between 4096x4096
41
+ // element polylines in ~70ms, and approximate alignments much more quickly.
42
+ //
43
+ // The results of an alignment operation are captured in a VertexAlignment
44
+ // object. In particular, a VertexAlignment keeps track of the total cost of
45
+ // alignment, as well as the warp path (a sequence of pairs of indices into each
46
+ // polyline whose vertices are linked together in the optimal alignment)
47
+ //
48
+ // For a worked example, consider the polylines
49
+ //
50
+ // a = [(1, 0), (5, 0), (6, 0), (9, 0)] and
51
+ // b = [(2, 0), (7, 0), (8, 0)].
52
+ //
53
+ // The "cost matrix" between these two polylines (using squared chordal
54
+ // distance, .Norm2(), as our distance function) looks like this:
55
+ //
56
+ // (2, 0) (7, 0) (8, 0)
57
+ // (1, 0) 1 36 49
58
+ // (5, 0) 9 4 9
59
+ // (6, 0) 16 1 4
60
+ // (9, 0) 49 4 1
61
+ //
62
+ // The Dynamic Timewarp DP table for this cost matrix has cells defined by
63
+ //
64
+ // table[i][j] = cost(i,j) + min(table[i-1][j-1], table[i][j-1], table[i-1, j])
65
+ //
66
+ // (2, 0) (7, 0) (8, 0)
67
+ // (1, 0) 1 37 86
68
+ // (5, 0) 10 5 14
69
+ // (6, 0) 26 6 9
70
+ // (9, 0) 75 10 7
71
+ //
72
+ // Starting at the bottom right corner of the DP table, we can work our way
73
+ // backwards to the upper left corner to recover the reverse of the warp path:
74
+ // (3, 2) -> (2, 1) -> (1, 1) -> (0, 0). The VertexAlignment produced containing
75
+ // this has alignment_cost = 7 and warp_path = {(0, 0), (1, 1), (2, 1), (3, 2)}.
76
+ //
77
+ // We also provide methods for performing alignment of multiple sequences. These
78
+ // methods return a single, representative polyline from a non-empty collection
79
+ // of polylines, for various definitions of "representative."
80
+ //
81
+ // GetMedoidPolyline() returns a new polyline (point-for-point-equal to some
82
+ // existing polyline from the collection) that minimizes the summed vertex
83
+ // alignment cost to all other polylines in the collection.
84
+ //
85
+ // GetConsensusPolyline() returns a new polyline (unlikely to be present in the
86
+ // input collection) that represents a "weighted consensus" polyline. This
87
+ // polyline is constructed iteratively using the Dynamic Timewarp Barycenter
88
+ // Averaging algorithm of F. Petitjean, A. Ketterlin, and P. Gancarski, which
89
+ // can be found here:
90
+ // https://pdfs.semanticscholar.org/a596/8ca9488199291ffe5473643142862293d69d.pdf
91
+
92
+ namespace s2polyline_alignment {
93
+
94
+ typedef std::vector<std::pair<int, int>> WarpPath;
95
+
96
+ struct VertexAlignment {
97
+ // `alignment_cost` represents the sum of the squared chordal distances
98
+ // between each pair of vertices in the warp path. Specifically,
99
+ // cost = sum_{(i, j) \in path} (a.vertex(i) - b.vertex(j)).Norm2();
100
+ // This means that the units of alignment_cost are "squared distance". This is
101
+ // an optimization to avoid the (expensive) atan computation of the true
102
+ // spherical angular distance between the points, as well as an unnecessary
103
+ // square root. All we need to compute vertex alignment is a metric that
104
+ // satisifies the triangle inequality, and squared chordal distance works as
105
+ // well as spherical S1Angle distance for this purpose.
106
+ double alignment_cost;
107
+
108
+ // Each entry (i, j) of `warp_path` represents a pairing between vertex
109
+ // a.vertex(i) and vertex b.vertex(j) in the optimal alignment.
110
+ // The warp_path is defined in forward order, such that the result of
111
+ // aligning polylines `a` and `b` is always a warp_path with warp_path.front()
112
+ // = {0,0} and warp_path.back() = {a.num_vertices() - 1, b.num_vertices() - 1}
113
+ // Note that this DOES NOT define an alignment from a point sequence to an
114
+ // edge sequence. That functionality may come at a later date.
115
+ WarpPath warp_path;
116
+
117
+ VertexAlignment(const double cost, const WarpPath& path)
118
+ : alignment_cost(cost), warp_path(path) {}
119
+ };
120
+
121
+ // GetExactVertexAlignment takes two non-empty polylines as input, and returns
122
+ // the VertexAlignment corresponding to the optimal alignment between them. This
123
+ // method is quadratic O(A*B) in both space and time complexity.
124
+ VertexAlignment GetExactVertexAlignment(const S2Polyline& a,
125
+ const S2Polyline& b);
126
+
127
+ // GetExactVertexAlignmentCost takes two non-empty polylines as input, and
128
+ // returns the *cost* of their optimal alignment. A standard, traditional
129
+ // dynamic timewarp algorithm can output both a warp path and a cost, but
130
+ // requires quadratic space to reconstruct the path by walking back through the
131
+ // Dynamic Programming cost table. If all you really need is the warp cost (i.e.
132
+ // you're inducing a similarity metric between S2Polylines, or something
133
+ // equivalent), you can overwrite the DP table and use constant space -
134
+ // O(max(A,B)). This method provides that space-efficiency optimization.
135
+ double GetExactVertexAlignmentCost(const S2Polyline& a, const S2Polyline& b);
136
+
137
+ // GetApproxVertexAlignment takes two non-empty polylines `a` and `b` as input,
138
+ // and a `radius` paramater GetApproxVertexAlignment (quickly) computes an
139
+ // approximately optimal vertex alignment of points between polylines `a` and
140
+ // `b` by implementing the algorithm described in `FastDTW: Toward Accurate
141
+ // Dynamic Time Warping in Linear Time and Space` by Stan Salvador and Philip
142
+ // Chan. Details can be found below:
143
+ //
144
+ // https://pdfs.semanticscholar.org/05a2/0cde15e172fc82f32774dd0cf4fe5827cad2.pdf
145
+ //
146
+ // The `radius` parameter controls the distance we search outside of the
147
+ // projected warp path during the refining step. Smaller values of `radius`
148
+ // correspond to a smaller search window, and therefore distance computation on
149
+ // fewer cells, which leads to a faster (but worse) approximation.
150
+ // This method is O(max(A, B)) in both space and time complexity.
151
+ VertexAlignment GetApproxVertexAlignment(const S2Polyline& a,
152
+ const S2Polyline& b, const int radius);
153
+
154
+ // A convience overload for GetApproxVertexAlignment which computes and uses
155
+ // suggested default parameter of radius = max(a.size(), b.size())^0.25
156
+ VertexAlignment GetApproxVertexAlignment(const S2Polyline& a,
157
+ const S2Polyline& b);
158
+
159
+ // GetMedoidPolyline returns the index `p` of a "medoid" polyline from a
160
+ // non-empty collection of `polylines` such that
161
+ //
162
+ // sum_{all j in `polylines`} VertexAlignmentCost(p, j) is minimized.
163
+ //
164
+ // In the case of a tie for minimal summed alignment cost, we return the lowest
165
+ // index - this tie is guaranteed to happen in the two-polyline-input case.
166
+ //
167
+ // ASYMPTOTIC BEHAVIOR:
168
+ // Computation may require up to (N^2 - N) / 2 alignment cost function
169
+ // evaluations, for N input polylines. For polylines of length U, V, the
170
+ // alignment cost function evaluation is O(U+V) if options.approx = true and
171
+ // O(U*V) if options.approx = false.
172
+
173
+ class MedoidOptions {
174
+ public:
175
+ // If options.approx = false, we compute vertex alignment costs exactly.
176
+ // If options.approx = true, we use approximate vertex alignment
177
+ // computation, called with the default radius parameter.
178
+ bool approx() const { return approx_; }
179
+ void set_approx(bool approx) { approx_ = approx; }
180
+
181
+ private:
182
+ bool approx_ = true;
183
+ };
184
+
185
+ int GetMedoidPolyline(const std::vector<std::unique_ptr<S2Polyline>>& polylines,
186
+ const MedoidOptions options);
187
+
188
+ // GetConsensusPolyline allocates and returns a new "consensus" polyline from a
189
+ // non-empty collection of polylines. We iteratively apply Dynamic Timewarp
190
+ // Barycenter Averaging to an initial `seed` polyline, which improves the
191
+ // consensus alignment quality each iteration. For implementation details, see
192
+ //
193
+ // https://pdfs.semanticscholar.org/a596/8ca9488199291ffe5473643142862293d69d.pdf
194
+ //
195
+ // The returned polyline from this method is unlikely to be point-for-point
196
+ // equal to an input polyline, whereas a polyline returned from
197
+ // GetMedoidPolyline() is guaranteed to match an input polyline point-for-point.
198
+ // NOTE: the number of points in our returned consensus polyline is always equal
199
+ // to the number of points in the initial seed, which is implementation-defined.
200
+ // If the collection of polylines has a large resolution distribution, it might
201
+ // be a good idea to reinterpolate them to have about the same number of points.
202
+ // In practice, this doesn't seem to matter, but is probably worth noting.
203
+ //
204
+ // ASYMPTOTIC BEHAVIOR:
205
+ // Seeding this algorithm requires O(1) vertex alignments if seed_medoid =
206
+ // false, and O(N^2) vertex alignments if seed_medoid = true. Once the seed
207
+ // polyline is chosen, computing the consensus polyline requires at most
208
+ // (iteration_cap)*N vertex alignments. For polylines of length U, V, the
209
+ // alignment cost function evaluation is O(U+V) if options.approx = true, and
210
+ // O(U*V) if options.approx = false.
211
+
212
+ class ConsensusOptions {
213
+ public:
214
+ // If options.approx = false, vertex alignments are computed with
215
+ // GetExactVertexAlignment. If options.approx = true, vertex alignments are
216
+ // computed with GetApproxVertexAlignment, called with default radius
217
+ // parameter.
218
+ bool approx() const { return approx_; }
219
+ void set_approx(bool approx) { approx_ = approx; }
220
+
221
+ // If options.seed_medoid = true, we seed the consensus polyline with the
222
+ // medoid of the collection. This is a more expensive approach, but may result
223
+ // in higher quality consensus sequences by avoiding bad arbitrary initial
224
+ // seeds. Seeding with the medoid will incur up to (N^2 - N) / 2 evaluations
225
+ // of the vertex alignment function. If options.seed_medoid = false, we seed
226
+ // the consensus polyline by taking an arbitrary element from the collection.
227
+ bool seed_medoid() const { return seed_medoid_; }
228
+ void set_seed_medoid(bool seed_medoid) { seed_medoid_ = seed_medoid; }
229
+
230
+ // options.iteration_cap controls the maximum number of DBA refining steps we
231
+ // apply to the initial seed.
232
+ int iteration_cap() const { return iteration_cap_; }
233
+ void set_iteration_cap(int iteration_cap) { iteration_cap_ = iteration_cap; }
234
+
235
+ private:
236
+ bool approx_ = true;
237
+ bool seed_medoid_ = false;
238
+ int iteration_cap_ = 5;
239
+ };
240
+
241
+ std::unique_ptr<S2Polyline> GetConsensusPolyline(
242
+ const std::vector<std::unique_ptr<S2Polyline>>& polylines,
243
+ const ConsensusOptions options);
244
+ } // namespace s2polyline_alignment
245
+ #endif // S2_S2POLYLINE_ALIGNMENT_H_