@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,767 @@
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
+ // Author: ericv@google.com (Eric Veach)
17
+ //
18
+ // See S2ClosestPointQueryBase (defined below) for an overview.
19
+
20
+ #ifndef S2_S2CLOSEST_POINT_QUERY_BASE_H_
21
+ #define S2_S2CLOSEST_POINT_QUERY_BASE_H_
22
+
23
+ #include <vector>
24
+
25
+ #include "s2/base/logging.h"
26
+ #include "s2/third_party/absl/container/inlined_vector.h"
27
+ #include "s2/s1chord_angle.h"
28
+ #include "s2/s2cap.h"
29
+ #include "s2/s2cell_id.h"
30
+ #include "s2/s2cell_union.h"
31
+ #include "s2/s2distance_target.h"
32
+ #include "s2/s2edge_distances.h"
33
+ #include "s2/s2point_index.h"
34
+ #include "s2/s2region_coverer.h"
35
+
36
+ // Options that control the set of points returned. Note that by default
37
+ // *all* points are returned, so you will always want to set either the
38
+ // max_results() option or the max_distance() option (or both).
39
+ //
40
+ // This class is also available as S2ClosestPointQueryBase<Data>::Options.
41
+ // (It is defined here to avoid depending on the "Data" template argument.)
42
+ //
43
+ // The Distance template argument is described below.
44
+ template <class Distance>
45
+ class S2ClosestPointQueryBaseOptions {
46
+ public:
47
+ using Delta = typename Distance::Delta;
48
+
49
+ S2ClosestPointQueryBaseOptions();
50
+
51
+ // Specifies that at most "max_results" points should be returned.
52
+ //
53
+ // REQUIRES: max_results >= 1
54
+ // DEFAULT: numeric_limits<int>::max()
55
+ int max_results() const;
56
+ void set_max_results(int max_results);
57
+ static constexpr int kMaxMaxResults = std::numeric_limits<int>::max();
58
+
59
+ // Specifies that only points whose distance to the target is less than
60
+ // "max_distance" should be returned.
61
+ //
62
+ // Note that points whose distance is exactly equal to "max_distance" are
63
+ // not returned. In most cases this doesn't matter (since distances are
64
+ // not computed exactly in the first place), but if such points are needed
65
+ // then you can retrieve them by specifying "max_distance" as the next
66
+ // largest representable Distance. For example, if Distance is an
67
+ // S1ChordAngle then you can specify max_distance.Successor().
68
+ //
69
+ // DEFAULT: Distance::Infinity()
70
+ Distance max_distance() const;
71
+ void set_max_distance(Distance max_distance);
72
+
73
+ // Specifies that points up to max_error() further away than the true
74
+ // closest points may be substituted in the result set, as long as such
75
+ // points satisfy all the remaining search criteria (such as max_distance).
76
+ // This option only has an effect if max_results() is also specified;
77
+ // otherwise all points closer than max_distance() will always be returned.
78
+ //
79
+ // Note that this does not affect how the distance between points is
80
+ // computed; it simply gives the algorithm permission to stop the search
81
+ // early as soon as the best possible improvement drops below max_error().
82
+ //
83
+ // This can be used to implement distance predicates efficiently. For
84
+ // example, to determine whether the minimum distance is less than D, the
85
+ // IsDistanceLess() method sets max_results() == 1 and max_distance() ==
86
+ // max_error() == D. This causes the algorithm to terminate as soon as it
87
+ // finds any point whose distance is less than D, rather than continuing to
88
+ // search for a point that is even closer.
89
+ //
90
+ // DEFAULT: Distance::Delta::Zero()
91
+ Delta max_error() const;
92
+ void set_max_error(Delta max_error);
93
+
94
+ // Specifies that points must be contained by the given S2Region. "region"
95
+ // is owned by the caller and must persist during the lifetime of this
96
+ // object. The value may be changed between calls to FindClosestPoints(),
97
+ // or reset by calling set_region(nullptr).
98
+ //
99
+ // Note that if you want to set the region to a disc around a target point,
100
+ // it is faster to use a PointTarget with set_max_distance() instead. You
101
+ // can also call both methods, e.g. to set a maximum distance and also
102
+ // require that points lie within a given rectangle.
103
+ const S2Region* region() const;
104
+ void set_region(const S2Region* region);
105
+
106
+ // Specifies that distances should be computed by examining every point
107
+ // rather than using the S2ShapeIndex. This is useful for testing,
108
+ // benchmarking, and debugging.
109
+ //
110
+ // DEFAULT: false
111
+ bool use_brute_force() const;
112
+ void set_use_brute_force(bool use_brute_force);
113
+
114
+ private:
115
+ Distance max_distance_ = Distance::Infinity();
116
+ Delta max_error_ = Delta::Zero();
117
+ const S2Region* region_ = nullptr;
118
+ int max_results_ = kMaxMaxResults;
119
+ bool use_brute_force_ = false;
120
+ };
121
+
122
+ // S2ClosestPointQueryBase is a templatized class for finding the closest
123
+ // point(s) to a given target. It is not intended to be used directly, but
124
+ // rather to serve as the implementation of various specialized classes with
125
+ // more convenient APIs (such as S2ClosestPointQuery). It is flexible enough
126
+ // so that it can be adapted to compute maximum distances and even potentially
127
+ // Hausdorff distances.
128
+ //
129
+ // By using the appropriate options, this class can answer questions such as:
130
+ //
131
+ // - Find the minimum distance between a point collection A and a target B.
132
+ // - Find all points in collection A that are within a distance D of target B.
133
+ // - Find the k points of collection A that are closest to a given point P.
134
+ //
135
+ // The target is any class that implements the S2DistanceTarget interface.
136
+ // There are predefined targets for points, edges, S2Cells, and S2ShapeIndexes
137
+ // (arbitrary collctions of points, polylines, and polygons).
138
+ //
139
+ // The Distance template argument is used to represent distances. Usually it
140
+ // is a thin wrapper around S1ChordAngle, but another distance type may be
141
+ // used as long as it implements the Distance concept described in
142
+ // s2distance_targets.h. For example this can be used to measure maximum
143
+ // distances, to get more accuracy, or to measure non-spheroidal distances.
144
+ template <class Distance, class Data>
145
+ class S2ClosestPointQueryBase {
146
+ public:
147
+ using Delta = typename Distance::Delta;
148
+ using Index = S2PointIndex<Data>;
149
+ using PointData = typename Index::PointData;
150
+ using Options = S2ClosestPointQueryBaseOptions<Distance>;
151
+
152
+ // The Target class represents the geometry to which the distance is
153
+ // measured. For example, there can be subtypes for measuring the distance
154
+ // to a point, an edge, or to an S2ShapeIndex (an arbitrary collection of
155
+ // geometry).
156
+ //
157
+ // Implementations do *not* need to be thread-safe. They may cache data or
158
+ // allocate temporary data structures in order to improve performance.
159
+ using Target = S2DistanceTarget<Distance>;
160
+
161
+ // Each "Result" object represents a closest point.
162
+ class Result {
163
+ public:
164
+ // The default constructor creates an "empty" result, with a distance() of
165
+ // Infinity() and non-dereferencable point() and data() values.
166
+ Result() : distance_(Distance::Infinity()), point_data_(nullptr) {}
167
+
168
+ // Constructs a Result object for the given point.
169
+ Result(Distance distance, const PointData* point_data)
170
+ : distance_(distance), point_data_(point_data) {}
171
+
172
+ // Returns true if this Result object does not refer to any data point.
173
+ // (The only case where an empty Result is returned is when the
174
+ // FindClosestPoint() method does not find any points that meet the
175
+ // specified criteria.)
176
+ bool is_empty() const { return point_data_ == nullptr; }
177
+
178
+ // The distance from the target to this point.
179
+ Distance distance() const { return distance_; }
180
+
181
+ // The point itself.
182
+ const S2Point& point() const { return point_data_->point(); }
183
+
184
+ // The client-specified data associated with this point.
185
+ const Data& data() const { return point_data_->data(); }
186
+
187
+ // Returns true if two Result objects are identical.
188
+ friend bool operator==(const Result& x, const Result& y) {
189
+ return (x.distance_ == y.distance_ && x.point_data_ == y.point_data_);
190
+ }
191
+
192
+ // Compares two Result objects first by distance, then by point_data().
193
+ friend bool operator<(const Result& x, const Result& y) {
194
+ if (x.distance_ < y.distance_) return true;
195
+ if (y.distance_ < x.distance_) return false;
196
+ return x.point_data_ < y.point_data_;
197
+ }
198
+
199
+ private:
200
+ Distance distance_;
201
+ const PointData* point_data_;
202
+ };
203
+
204
+ // The minimum number of points that a cell must contain to enqueue it
205
+ // rather than processing its contents immediately.
206
+ static constexpr int kMinPointsToEnqueue = 13;
207
+
208
+ // Default constructor; requires Init() to be called.
209
+ S2ClosestPointQueryBase();
210
+ ~S2ClosestPointQueryBase();
211
+
212
+ // Convenience constructor that calls Init().
213
+ explicit S2ClosestPointQueryBase(const Index* index);
214
+
215
+ // S2ClosestPointQueryBase is not copyable.
216
+ S2ClosestPointQueryBase(const S2ClosestPointQueryBase&) = delete;
217
+ void operator=(const S2ClosestPointQueryBase&) = delete;
218
+
219
+ // Initializes the query.
220
+ // REQUIRES: ReInit() must be called if "index" is modified.
221
+ void Init(const Index* index);
222
+
223
+ // Reinitializes the query. This method must be called whenever the
224
+ // underlying index is modified.
225
+ void ReInit();
226
+
227
+ // Return a reference to the underlying S2PointIndex.
228
+ const Index& index() const;
229
+
230
+ // Returns the closest points to the given target that satisfy the given
231
+ // options. This method may be called multiple times.
232
+ std::vector<Result> FindClosestPoints(Target* target, const Options& options);
233
+
234
+ // This version can be more efficient when this method is called many times,
235
+ // since it does not require allocating a new vector on each call.
236
+ void FindClosestPoints(Target* target, const Options& options,
237
+ std::vector<Result>* results);
238
+
239
+ // Convenience method that returns exactly one point. If no points satisfy
240
+ // the given search criteria, then a Result with distance() == Infinity()
241
+ // and is_empty() == true is returned.
242
+ //
243
+ // REQUIRES: options.max_results() == 1
244
+ Result FindClosestPoint(Target* target, const Options& options);
245
+
246
+ private:
247
+ using Iterator = typename Index::Iterator;
248
+
249
+ const Options& options() const { return *options_; }
250
+ void FindClosestPointsInternal(Target* target, const Options& options);
251
+ void FindClosestPointsBruteForce();
252
+ void FindClosestPointsOptimized();
253
+ void InitQueue();
254
+ void InitCovering();
255
+ void AddInitialRange(S2CellId first_id, S2CellId last_id);
256
+ void MaybeAddResult(const PointData* point_data);
257
+ bool ProcessOrEnqueue(S2CellId id, Iterator* iter, bool seek);
258
+
259
+ const Index* index_;
260
+ const Options* options_;
261
+ Target* target_;
262
+
263
+ // True if max_error() must be subtracted from priority queue cell distances
264
+ // in order to ensure that such distances are measured conservatively. This
265
+ // is true only if the target takes advantage of max_error() in order to
266
+ // return faster results, and 0 < max_error() < distance_limit_.
267
+ bool use_conservative_cell_distance_;
268
+
269
+ // For the optimized algorihm we precompute the top-level S2CellIds that
270
+ // will be added to the priority queue. There can be at most 6 of these
271
+ // cells. Essentially this is just a covering of the indexed points.
272
+ std::vector<S2CellId> index_covering_;
273
+
274
+ // The distance beyond which we can safely ignore further candidate points.
275
+ // (Candidates that are exactly at the limit are ignored; this is more
276
+ // efficient for UpdateMinDistance() and should not affect clients since
277
+ // distance measurements have a small amount of error anyway.)
278
+ //
279
+ // Initially this is the same as the maximum distance specified by the user,
280
+ // but it can also be updated by the algorithm (see MaybeAddResult).
281
+ Distance distance_limit_;
282
+
283
+ // The current result set is stored in one of three ways:
284
+ //
285
+ // - If max_results() == 1, the best result is kept in result_singleton_.
286
+ //
287
+ // - If max_results() == "infinity", results are appended to result_vector_
288
+ // and sorted/uniqued at the end.
289
+ //
290
+ // - Otherwise results are kept in a priority queue so that we can
291
+ // progressively reduce the distance limit once max_results() results
292
+ // have been found.
293
+ Result result_singleton_;
294
+ std::vector<Result> result_vector_;
295
+ std::priority_queue<Result, absl::InlinedVector<Result, 16>> result_set_;
296
+
297
+ // The algorithm maintains a priority queue of unprocessed S2CellIds, sorted
298
+ // in increasing order of distance from the target.
299
+ struct QueueEntry {
300
+ // A lower bound on the distance from the target to "id". This is the key
301
+ // of the priority queue.
302
+ Distance distance;
303
+
304
+ // The cell being queued.
305
+ S2CellId id;
306
+
307
+ QueueEntry(Distance _distance, S2CellId _id)
308
+ : distance(_distance), id(_id) {}
309
+
310
+ bool operator<(const QueueEntry& other) const {
311
+ // The priority queue returns the largest elements first, so we want the
312
+ // "largest" entry to have the smallest distance.
313
+ return other.distance < distance;
314
+ }
315
+ };
316
+ using CellQueue =
317
+ std::priority_queue<QueueEntry, absl::InlinedVector<QueueEntry, 16>>;
318
+ CellQueue queue_;
319
+
320
+ // Temporaries, defined here to avoid multiple allocations / initializations.
321
+
322
+ Iterator iter_;
323
+ std::vector<S2CellId> region_covering_;
324
+ std::vector<S2CellId> max_distance_covering_;
325
+ std::vector<S2CellId> intersection_with_region_;
326
+ std::vector<S2CellId> intersection_with_max_distance_;
327
+ const PointData* tmp_point_data_[kMinPointsToEnqueue - 1];
328
+ };
329
+
330
+
331
+ ////////////////// Implementation details follow ////////////////////
332
+
333
+
334
+ template <class Distance> inline
335
+ S2ClosestPointQueryBaseOptions<Distance>::S2ClosestPointQueryBaseOptions() {
336
+ }
337
+
338
+ template <class Distance>
339
+ inline int S2ClosestPointQueryBaseOptions<Distance>::max_results() const {
340
+ return max_results_;
341
+ }
342
+
343
+ template <class Distance>
344
+ inline void S2ClosestPointQueryBaseOptions<Distance>::set_max_results(
345
+ int max_results) {
346
+ S2_DCHECK_GE(max_results, 1);
347
+ max_results_ = max_results;
348
+ }
349
+
350
+ template <class Distance>
351
+ inline Distance S2ClosestPointQueryBaseOptions<Distance>::max_distance()
352
+ const {
353
+ return max_distance_;
354
+ }
355
+
356
+ template <class Distance>
357
+ inline void S2ClosestPointQueryBaseOptions<Distance>::set_max_distance(
358
+ Distance max_distance) {
359
+ max_distance_ = max_distance;
360
+ }
361
+
362
+ template <class Distance>
363
+ inline typename Distance::Delta
364
+ S2ClosestPointQueryBaseOptions<Distance>::max_error() const {
365
+ return max_error_;
366
+ }
367
+
368
+ template <class Distance>
369
+ inline void S2ClosestPointQueryBaseOptions<Distance>::set_max_error(
370
+ Delta max_error) {
371
+ max_error_ = max_error;
372
+ }
373
+
374
+ template <class Distance>
375
+ inline const S2Region* S2ClosestPointQueryBaseOptions<Distance>::region()
376
+ const {
377
+ return region_;
378
+ }
379
+
380
+ template <class Distance>
381
+ inline void S2ClosestPointQueryBaseOptions<Distance>::set_region(
382
+ const S2Region* region) {
383
+ region_ = region;
384
+ }
385
+
386
+ template <class Distance>
387
+ inline bool S2ClosestPointQueryBaseOptions<Distance>::use_brute_force() const {
388
+ return use_brute_force_;
389
+ }
390
+
391
+ template <class Distance>
392
+ inline void S2ClosestPointQueryBaseOptions<Distance>::set_use_brute_force(
393
+ bool use_brute_force) {
394
+ use_brute_force_ = use_brute_force;
395
+ }
396
+
397
+ template <class Distance, class Data>
398
+ S2ClosestPointQueryBase<Distance, Data>::S2ClosestPointQueryBase() {
399
+ }
400
+
401
+ template <class Distance, class Data>
402
+ S2ClosestPointQueryBase<Distance, Data>::~S2ClosestPointQueryBase() {
403
+ // Prevent inline destructor bloat by providing a definition.
404
+ }
405
+
406
+ template <class Distance, class Data>
407
+ inline S2ClosestPointQueryBase<Distance, Data>::S2ClosestPointQueryBase(
408
+ const S2PointIndex<Data>* index) : S2ClosestPointQueryBase() {
409
+ Init(index);
410
+ }
411
+
412
+ template <class Distance, class Data>
413
+ void S2ClosestPointQueryBase<Distance, Data>::Init(
414
+ const S2PointIndex<Data>* index) {
415
+ index_ = index;
416
+ ReInit();
417
+ }
418
+
419
+ template <class Distance, class Data>
420
+ void S2ClosestPointQueryBase<Distance, Data>::ReInit() {
421
+ iter_.Init(index_);
422
+ index_covering_.clear();
423
+ }
424
+
425
+ template <class Distance, class Data>
426
+ inline const S2PointIndex<Data>&
427
+ S2ClosestPointQueryBase<Distance, Data>::index() const {
428
+ return *index_;
429
+ }
430
+
431
+ template <class Distance, class Data>
432
+ inline std::vector<typename S2ClosestPointQueryBase<Distance, Data>::Result>
433
+ S2ClosestPointQueryBase<Distance, Data>::FindClosestPoints(
434
+ Target* target, const Options& options) {
435
+ std::vector<Result> results;
436
+ FindClosestPoints(target, options, &results);
437
+ return results;
438
+ }
439
+
440
+ template <class Distance, class Data>
441
+ typename S2ClosestPointQueryBase<Distance, Data>::Result
442
+ S2ClosestPointQueryBase<Distance, Data>::FindClosestPoint(
443
+ Target* target, const Options& options) {
444
+ S2_DCHECK_EQ(options.max_results(), 1);
445
+ FindClosestPointsInternal(target, options);
446
+ return result_singleton_;
447
+ }
448
+
449
+ template <class Distance, class Data>
450
+ void S2ClosestPointQueryBase<Distance, Data>::FindClosestPoints(
451
+ Target* target, const Options& options, std::vector<Result>* results) {
452
+ FindClosestPointsInternal(target, options);
453
+ results->clear();
454
+ if (options.max_results() == 1) {
455
+ if (!result_singleton_.is_empty()) {
456
+ results->push_back(result_singleton_);
457
+ }
458
+ } else if (options.max_results() == Options::kMaxMaxResults) {
459
+ std::sort(result_vector_.begin(), result_vector_.end());
460
+ std::unique_copy(result_vector_.begin(), result_vector_.end(),
461
+ std::back_inserter(*results));
462
+ result_vector_.clear();
463
+ } else {
464
+ results->reserve(result_set_.size());
465
+ for (; !result_set_.empty(); result_set_.pop()) {
466
+ results->push_back(result_set_.top());
467
+ }
468
+ // The priority queue returns the largest elements first.
469
+ std::reverse(results->begin(), results->end());
470
+ S2_DCHECK(std::is_sorted(results->begin(), results->end()));
471
+ }
472
+ }
473
+
474
+ template <class Distance, class Data>
475
+ void S2ClosestPointQueryBase<Distance, Data>::FindClosestPointsInternal(
476
+ Target* target, const Options& options) {
477
+ target_ = target;
478
+ options_ = &options;
479
+
480
+ distance_limit_ = options.max_distance();
481
+ result_singleton_ = Result();
482
+ S2_DCHECK(result_vector_.empty());
483
+ S2_DCHECK(result_set_.empty());
484
+ S2_DCHECK_GE(target->max_brute_force_index_size(), 0);
485
+ if (distance_limit_ == Distance::Zero()) return;
486
+
487
+ if (options.max_results() == Options::kMaxMaxResults &&
488
+ options.max_distance() == Distance::Infinity() &&
489
+ options.region() == nullptr) {
490
+ S2_LOG(WARNING) << "Returning all points "
491
+ "(max_results/max_distance/region not set)";
492
+ }
493
+
494
+ // If max_error() > 0 and the target takes advantage of this, then we may
495
+ // need to adjust the distance estimates to the priority queue cells to
496
+ // ensure that they are always a lower bound on the true distance. For
497
+ // example, suppose max_distance == 100, max_error == 30, and we compute the
498
+ // distance to the target from some cell C0 as d(C0) == 80. Then because
499
+ // the target takes advantage of max_error(), the true distance could be as
500
+ // low as 50. In order not to miss edges contained by such cells, we need
501
+ // to subtract max_error() from the distance estimates. This behavior is
502
+ // controlled by the use_conservative_cell_distance_ flag.
503
+ //
504
+ // However there is one important case where this adjustment is not
505
+ // necessary, namely when max_distance() < max_error(). This is because
506
+ // max_error() only affects the algorithm once at least max_results() edges
507
+ // have been found that satisfy the given distance limit. At that point,
508
+ // max_error() is subtracted from distance_limit_ in order to ensure that
509
+ // any further matches are closer by at least that amount. But when
510
+ // max_distance() < max_error(), this reduces the distance limit to 0,
511
+ // i.e. all remaining candidate cells and edges can safely be discarded.
512
+ // (Note that this is how IsDistanceLess() and friends are implemented.)
513
+ //
514
+ // Note that Distance::Delta only supports operator==.
515
+ bool target_uses_max_error = (!(options.max_error() == Delta::Zero()) &&
516
+ target_->set_max_error(options.max_error()));
517
+
518
+ // Note that we can't compare max_error() and distance_limit_ directly
519
+ // because one is a Delta and one is a Distance. Instead we subtract them.
520
+ use_conservative_cell_distance_ = target_uses_max_error &&
521
+ (distance_limit_ == Distance::Infinity() ||
522
+ Distance::Zero() < distance_limit_ - options.max_error());
523
+
524
+ // Note that given point is processed only once (unlike S2ClosestEdgeQuery),
525
+ // and therefore we don't need to worry about the possibility of having
526
+ // duplicate points in the results.
527
+ if (options.use_brute_force() ||
528
+ index_->num_points() <= target_->max_brute_force_index_size()) {
529
+ FindClosestPointsBruteForce();
530
+ } else {
531
+ FindClosestPointsOptimized();
532
+ }
533
+ }
534
+
535
+ template <class Distance, class Data>
536
+ void S2ClosestPointQueryBase<Distance, Data>::FindClosestPointsBruteForce() {
537
+ for (iter_.Begin(); !iter_.done(); iter_.Next()) {
538
+ MaybeAddResult(&iter_.point_data());
539
+ }
540
+ }
541
+
542
+ template <class Distance, class Data>
543
+ void S2ClosestPointQueryBase<Distance, Data>::FindClosestPointsOptimized() {
544
+ InitQueue();
545
+ while (!queue_.empty()) {
546
+ // We need to copy the top entry before removing it, and we need to remove
547
+ // it before adding any new entries to the queue.
548
+ QueueEntry entry = queue_.top();
549
+ queue_.pop();
550
+ // Work around weird parse error in gcc 4.9 by using a local variable for
551
+ // entry.distance.
552
+ Distance distance = entry.distance;
553
+ if (!(distance < distance_limit_)) {
554
+ queue_ = CellQueue(); // Clear any remaining entries.
555
+ break;
556
+ }
557
+ S2CellId child = entry.id.child_begin();
558
+ // We already know that it has too many points, so process its children.
559
+ // Each child may either be processed directly or enqueued again. The
560
+ // loop is optimized so that we don't seek unnecessarily.
561
+ bool seek = true;
562
+ for (int i = 0; i < 4; ++i, child = child.next()) {
563
+ seek = ProcessOrEnqueue(child, &iter_, seek);
564
+ }
565
+ }
566
+ }
567
+
568
+ template <class Distance, class Data>
569
+ void S2ClosestPointQueryBase<Distance, Data>::InitQueue() {
570
+ S2_DCHECK(queue_.empty());
571
+
572
+ // Optimization: rather than starting with the entire index, see if we can
573
+ // limit the search region to a small disc. Then we can find a covering for
574
+ // that disc and intersect it with the covering for the index. This can
575
+ // save a lot of work when the search region is small.
576
+ S2Cap cap = target_->GetCapBound();
577
+ if (cap.is_empty()) return; // Empty target.
578
+ if (options().max_results() == 1) {
579
+ // If the user is searching for just the closest point, we can compute an
580
+ // upper bound on search radius by seeking to the center of the target's
581
+ // bounding cap and looking at the adjacent index points (in S2CellId
582
+ // order). The minimum distance to either of these points is an upper
583
+ // bound on the search radius.
584
+ //
585
+ // TODO(ericv): The same strategy would also work for small values of
586
+ // max_results() > 1, e.g. max_results() == 20, except that we would need to
587
+ // examine more neighbors (at least 20, and preferably 20 in each
588
+ // direction). It's not clear whether this is a common case, though, and
589
+ // also this would require extending MaybeAddResult() so that it can
590
+ // remove duplicate entries. (The points added here may be re-added by
591
+ // ProcessOrEnqueue(), but this is okay when max_results() == 1.)
592
+ iter_.Seek(S2CellId(cap.center()));
593
+ if (!iter_.done()) {
594
+ MaybeAddResult(&iter_.point_data());
595
+ }
596
+ if (iter_.Prev()) {
597
+ MaybeAddResult(&iter_.point_data());
598
+ }
599
+ // Skip the rest of the algorithm if we found a matching point.
600
+ if (distance_limit_ == Distance::Zero()) return;
601
+ }
602
+ // We start with a covering of the set of indexed points, then intersect it
603
+ // with the given region (if any) and maximum search radius disc (if any).
604
+ if (index_covering_.empty()) InitCovering();
605
+ const std::vector<S2CellId>* initial_cells = &index_covering_;
606
+ if (options().region()) {
607
+ S2RegionCoverer coverer;
608
+ coverer.mutable_options()->set_max_cells(4);
609
+ coverer.GetCovering(*options().region(), &region_covering_);
610
+ S2CellUnion::GetIntersection(index_covering_, region_covering_,
611
+ &intersection_with_region_);
612
+ initial_cells = &intersection_with_region_;
613
+ }
614
+ if (distance_limit_ < Distance::Infinity()) {
615
+ S2RegionCoverer coverer;
616
+ coverer.mutable_options()->set_max_cells(4);
617
+ S1ChordAngle radius = cap.radius() + distance_limit_.GetChordAngleBound();
618
+ S2Cap search_cap(cap.center(), radius);
619
+ coverer.GetFastCovering(search_cap, &max_distance_covering_);
620
+ S2CellUnion::GetIntersection(*initial_cells, max_distance_covering_,
621
+ &intersection_with_max_distance_);
622
+ initial_cells = &intersection_with_max_distance_;
623
+ }
624
+ iter_.Begin();
625
+ for (int i = 0; i < initial_cells->size() && !iter_.done(); ++i) {
626
+ S2CellId id = (*initial_cells)[i];
627
+ ProcessOrEnqueue(id, &iter_, id.range_min() > iter_.id() /*seek*/);
628
+ }
629
+ }
630
+
631
+ template <class Distance, class Data>
632
+ void S2ClosestPointQueryBase<Distance, Data>::InitCovering() {
633
+ // Compute the "index covering", which is a small number of S2CellIds that
634
+ // cover the indexed points. There are two cases:
635
+ //
636
+ // - If the index spans more than one face, then there is one covering cell
637
+ // per spanned face, just big enough to cover the index cells on that face.
638
+ //
639
+ // - If the index spans only one face, then we find the smallest cell "C"
640
+ // that covers the index cells on that face (just like the case above).
641
+ // Then for each of the 4 children of "C", if the child contains any index
642
+ // cells then we create a covering cell that is big enough to just fit
643
+ // those index cells (i.e., shrinking the child as much as possible to fit
644
+ // its contents). This essentially replicates what would happen if we
645
+ // started with "C" as the covering cell, since "C" would immediately be
646
+ // split, except that we take the time to prune the children further since
647
+ // this will save work on every subsequent query.
648
+ index_covering_.reserve(6);
649
+ iter_.Finish();
650
+ if (!iter_.Prev()) return; // Empty index.
651
+ S2CellId index_last_id = iter_.id();
652
+ iter_.Begin();
653
+ if (iter_.id() != index_last_id) {
654
+ // The index has at least two cells. Choose a level such that the entire
655
+ // index can be spanned with at most 6 cells (if the index spans multiple
656
+ // faces) or 4 cells (it the index spans a single face).
657
+ int level = iter_.id().GetCommonAncestorLevel(index_last_id) + 1;
658
+
659
+ // Visit each potential covering cell except the last (handled below).
660
+ S2CellId last_id = index_last_id.parent(level);
661
+ for (S2CellId id = iter_.id().parent(level);
662
+ id != last_id; id = id.next()) {
663
+ // Skip any covering cells that don't contain any index cells.
664
+ if (id.range_max() < iter_.id()) continue;
665
+
666
+ // Find the range of index cells contained by this covering cell and
667
+ // then shrink the cell if necessary so that it just covers them.
668
+ S2CellId cell_first_id = iter_.id();
669
+ iter_.Seek(id.range_max().next());
670
+ iter_.Prev();
671
+ S2CellId cell_last_id = iter_.id();
672
+ iter_.Next();
673
+ AddInitialRange(cell_first_id, cell_last_id);
674
+ }
675
+ }
676
+ AddInitialRange(iter_.id(), index_last_id);
677
+ }
678
+
679
+ // Adds a cell to index_covering_ that covers the given inclusive range.
680
+ //
681
+ // REQUIRES: "first" and "last" have a common ancestor.
682
+ template <class Distance, class Data>
683
+ void S2ClosestPointQueryBase<Distance, Data>::AddInitialRange(
684
+ S2CellId first_id, S2CellId last_id) {
685
+ // Add the lowest common ancestor of the given range.
686
+ int level = first_id.GetCommonAncestorLevel(last_id);
687
+ S2_DCHECK_GE(level, 0);
688
+ index_covering_.push_back(first_id.parent(level));
689
+ }
690
+
691
+ template <class Distance, class Data>
692
+ void S2ClosestPointQueryBase<Distance, Data>::MaybeAddResult(
693
+ const PointData* point_data) {
694
+ Distance distance = distance_limit_;
695
+ if (!target_->UpdateMinDistance(point_data->point(), &distance)) return;
696
+
697
+ const S2Region* region = options().region();
698
+ if (region && !region->Contains(point_data->point())) return;
699
+
700
+ Result result(distance, point_data);
701
+ if (options().max_results() == 1) {
702
+ // Optimization for the common case where only the closest point is wanted.
703
+ result_singleton_ = result;
704
+ distance_limit_ = result.distance() - options().max_error();
705
+ } else if (options().max_results() == Options::kMaxMaxResults) {
706
+ result_vector_.push_back(result); // Sort/unique at end.
707
+ } else {
708
+ // Add this point to result_set_. Note that with the current algorithm
709
+ // each candidate point is considered at most once (except for one special
710
+ // case where max_results() == 1, see InitQueue for details), so we don't
711
+ // need to worry about possibly adding a duplicate entry here.
712
+ if (result_set_.size() >= options().max_results()) {
713
+ result_set_.pop(); // Replace the furthest result point.
714
+ }
715
+ result_set_.push(result);
716
+ if (result_set_.size() >= options().max_results()) {
717
+ distance_limit_ = result_set_.top().distance() - options().max_error();
718
+ }
719
+ }
720
+ }
721
+
722
+ // Either process the contents of the given cell immediately, or add it to the
723
+ // queue to be subdivided. If "seek" is false, then "iter" must already be
724
+ // positioned at the first indexed point within or after this cell.
725
+ //
726
+ // Returns "true" if the cell was added to the queue, and "false" if it was
727
+ // processed immediately, in which case "iter" is left positioned at the next
728
+ // cell in S2CellId order.
729
+ template <class Distance, class Data>
730
+ bool S2ClosestPointQueryBase<Distance, Data>::ProcessOrEnqueue(
731
+ S2CellId id, Iterator* iter, bool seek) {
732
+ if (seek) iter->Seek(id.range_min());
733
+ if (id.is_leaf()) {
734
+ // Leaf cells can't be subdivided.
735
+ for (; !iter->done() && iter->id() == id; iter->Next()) {
736
+ MaybeAddResult(&iter->point_data());
737
+ }
738
+ return false; // No need to seek to next child.
739
+ }
740
+ S2CellId last = id.range_max();
741
+ int num_points = 0;
742
+ for (; !iter->done() && iter->id() <= last; iter->Next()) {
743
+ if (num_points == kMinPointsToEnqueue - 1) {
744
+ // This cell has too many points (including this one), so enqueue it.
745
+ S2Cell cell(id);
746
+ Distance distance = distance_limit_;
747
+ // We check "region_" second because it may be relatively expensive.
748
+ if (target_->UpdateMinDistance(cell, &distance) &&
749
+ (!options().region() || options().region()->MayIntersect(cell))) {
750
+ if (use_conservative_cell_distance_) {
751
+ // Ensure that "distance" is a lower bound on distance to the cell.
752
+ distance = distance - options().max_error();
753
+ }
754
+ queue_.push(QueueEntry(distance, id));
755
+ }
756
+ return true; // Seek to next child.
757
+ }
758
+ tmp_point_data_[num_points++] = &iter->point_data();
759
+ }
760
+ // There were few enough points that we might as well process them now.
761
+ for (int i = 0; i < num_points; ++i) {
762
+ MaybeAddResult(tmp_point_data_[i]);
763
+ }
764
+ return false; // No need to seek to next child.
765
+ }
766
+
767
+ #endif // S2_S2CLOSEST_POINT_QUERY_BASE_H_