@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,1030 @@
1
+ // Copyright 2005 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
+ // Most of the S2LatLngRect methods have trivial implementations that
19
+ // use the R1Interval and S1Interval classes, so most of the testing
20
+ // is done in those unit tests.
21
+
22
+ #include "s2/s2latlng_rect.h"
23
+
24
+ #include <algorithm>
25
+ #include <cmath>
26
+
27
+ #include <gtest/gtest.h>
28
+ #include "s2/util/coding/coder.h"
29
+ #include "s2/s1angle.h"
30
+ #include "s2/s2cap.h"
31
+ #include "s2/s2cell.h"
32
+ #include "s2/s2edge_distances.h"
33
+ #include "s2/s2latlng.h"
34
+ #include "s2/s2pointutil.h"
35
+ #include "s2/s2testing.h"
36
+ #include "s2/s2text_format.h"
37
+
38
+ using s2textformat::MakePointOrDie;
39
+ using std::fabs;
40
+ using std::min;
41
+
42
+ static S2LatLngRect RectFromDegrees(double lat_lo, double lng_lo,
43
+ double lat_hi, double lng_hi) {
44
+ // Convenience method to construct a rectangle. This method is
45
+ // intentionally *not* in the S2LatLngRect interface because the
46
+ // argument order is ambiguous, but hopefully it's not too confusing
47
+ // within the context of this unit test.
48
+
49
+ return S2LatLngRect(S2LatLng::FromDegrees(lat_lo, lng_lo).Normalized(),
50
+ S2LatLng::FromDegrees(lat_hi, lng_hi).Normalized());
51
+ }
52
+
53
+ TEST(S2LatLngRect, EmptyAndFull) {
54
+ // Test basic properties of empty and full rectangles.
55
+ S2LatLngRect empty = S2LatLngRect::Empty();
56
+ S2LatLngRect full = S2LatLngRect::Full();
57
+ EXPECT_TRUE(empty.is_valid());
58
+ EXPECT_TRUE(empty.is_empty());
59
+ EXPECT_FALSE(empty.is_point());
60
+ EXPECT_TRUE(full.is_valid());
61
+ EXPECT_TRUE(full.is_full());
62
+ EXPECT_FALSE(full.is_point());
63
+ // Check that the default S2LatLngRect is identical to Empty().
64
+ S2LatLngRect default_empty;
65
+ EXPECT_TRUE(default_empty.is_valid());
66
+ EXPECT_TRUE(default_empty.is_empty());
67
+ EXPECT_EQ(empty.lat().bounds(), default_empty.lat().bounds());
68
+ EXPECT_EQ(empty.lng().bounds(), default_empty.lng().bounds());
69
+ }
70
+
71
+ TEST(S2LatLngRect, Accessors) {
72
+ // Check various accessor methods.
73
+ S2LatLngRect d1 = RectFromDegrees(-90, 0, -45, 180);
74
+ EXPECT_DOUBLE_EQ(d1.lat_lo().degrees(), -90);
75
+ EXPECT_DOUBLE_EQ(d1.lat_hi().degrees(), -45);
76
+ EXPECT_DOUBLE_EQ(d1.lng_lo().degrees(), 0);
77
+ EXPECT_DOUBLE_EQ(d1.lng_hi().degrees(), 180);
78
+ EXPECT_EQ(d1.lat(), R1Interval(-M_PI_2, -M_PI_4));
79
+ EXPECT_EQ(d1.lng(), S1Interval(0, M_PI));
80
+ }
81
+
82
+ TEST(S2LatLngRect, ApproxEquals) {
83
+ // S1Interval and R1Interval have additional testing.
84
+
85
+ EXPECT_TRUE(S2LatLngRect::Empty().ApproxEquals(RectFromDegrees(1, 5, 1, 5)));
86
+ EXPECT_TRUE(RectFromDegrees(1, 5, 1, 5).ApproxEquals(S2LatLngRect::Empty()));
87
+ EXPECT_FALSE(RectFromDegrees(1, 5, 1, 5).
88
+ ApproxEquals(RectFromDegrees(2, 7, 2, 7)));
89
+
90
+ // Test the max_error (double) parameter.
91
+ EXPECT_TRUE(RectFromDegrees(10, 10, 20, 20).
92
+ ApproxEquals(RectFromDegrees(11, 11, 19, 19),
93
+ S1Angle::Degrees(1.001)));
94
+ EXPECT_FALSE(RectFromDegrees(10, 10, 20, 20).
95
+ ApproxEquals(RectFromDegrees(11, 11, 19, 19),
96
+ S1Angle::Degrees(0.999)));
97
+
98
+ // Test the max_error (S2LatLng) parameter.
99
+ EXPECT_TRUE(RectFromDegrees(0, 10, 20, 30).
100
+ ApproxEquals(RectFromDegrees(-1, 8, 21, 32),
101
+ S2LatLng::FromDegrees(1.001, 2.001)));
102
+ EXPECT_FALSE(RectFromDegrees(0, 10, 20, 30).
103
+ ApproxEquals(RectFromDegrees(-1, 8, 21, 32),
104
+ S2LatLng::FromDegrees(0.999, 1.999)));
105
+ }
106
+
107
+ TEST(S2LatLngRect, FromCenterSize) {
108
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(80, 170),
109
+ S2LatLng::FromDegrees(40, 60)).
110
+ ApproxEquals(RectFromDegrees(60, 140, 90, -160)));
111
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(10, 40),
112
+ S2LatLng::FromDegrees(210, 400)).
113
+ is_full());
114
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(-90, 180),
115
+ S2LatLng::FromDegrees(20, 50)).
116
+ ApproxEquals(RectFromDegrees(-90, 155, -80, -155)));
117
+ }
118
+
119
+ TEST(S2LatLngRect, FromPoint) {
120
+ S2LatLng p = S2LatLng::FromDegrees(23, 47);
121
+ EXPECT_EQ(S2LatLngRect::FromPoint(p), S2LatLngRect(p, p));
122
+ EXPECT_TRUE(S2LatLngRect::FromPoint(p).is_point());
123
+ }
124
+
125
+ TEST(S2LatLngRect, FromPointPair) {
126
+ EXPECT_EQ(S2LatLngRect::FromPointPair(S2LatLng::FromDegrees(-35, -140),
127
+ S2LatLng::FromDegrees(15, 155)),
128
+ RectFromDegrees(-35, 155, 15, -140));
129
+ EXPECT_EQ(S2LatLngRect::FromPointPair(S2LatLng::FromDegrees(25, -70),
130
+ S2LatLng::FromDegrees(-90, 80)),
131
+ RectFromDegrees(-90, -70, 25, 80));
132
+ }
133
+
134
+ TEST(S2LatLngRect, GetCenterSize) {
135
+ S2LatLngRect r1(R1Interval(0, M_PI_2), S1Interval(-M_PI, 0));
136
+ EXPECT_EQ(r1.GetCenter(), S2LatLng::FromRadians(M_PI_4, -M_PI_2));
137
+ EXPECT_EQ(r1.GetSize(), S2LatLng::FromRadians(M_PI_2, M_PI));
138
+ EXPECT_LT(S2LatLngRect::Empty().GetSize().lat().radians(), 0);
139
+ EXPECT_LT(S2LatLngRect::Empty().GetSize().lng().radians(), 0);
140
+ }
141
+
142
+ TEST(S2LatLngRect, GetVertex) {
143
+ S2LatLngRect r1(R1Interval(0, M_PI_2), S1Interval(-M_PI, 0));
144
+ EXPECT_EQ(r1.GetVertex(0), S2LatLng::FromRadians(0, M_PI));
145
+ EXPECT_EQ(r1.GetVertex(1), S2LatLng::FromRadians(0, 0));
146
+ EXPECT_EQ(r1.GetVertex(2), S2LatLng::FromRadians(M_PI_2, 0));
147
+ EXPECT_EQ(r1.GetVertex(3), S2LatLng::FromRadians(M_PI_2, M_PI));
148
+
149
+ // Make sure that GetVertex() returns vertices in CCW order.
150
+ for (int i = 0; i < 4; ++i) {
151
+ double lat = M_PI_4 * (i - 2);
152
+ double lng = M_PI_2 * (i - 2) + 0.2;
153
+ S2LatLngRect r(R1Interval(lat, lat + M_PI_4),
154
+ S1Interval(remainder(lng, 2 * M_PI),
155
+ remainder(lng + M_PI_2, 2 * M_PI)));
156
+ for (int k = 0; k < 4; ++k) {
157
+ EXPECT_TRUE(S2::SimpleCCW(r.GetVertex(k - 1).ToPoint(),
158
+ r.GetVertex(k).ToPoint(),
159
+ r.GetVertex(k + 1).ToPoint()));
160
+ }
161
+ }
162
+ }
163
+
164
+ TEST(S2LatLngRect, Contains) {
165
+ // Contains(S2LatLng), InteriorContains(S2LatLng), Contains()
166
+ S2LatLng eq_m180 = S2LatLng::FromRadians(0, -M_PI);
167
+ S2LatLng north_pole = S2LatLng::FromRadians(M_PI_2, 0);
168
+ S2LatLngRect r1(eq_m180, north_pole);
169
+
170
+ EXPECT_TRUE(r1.Contains(S2LatLng::FromDegrees(30, -45)));
171
+ EXPECT_TRUE(r1.InteriorContains(S2LatLng::FromDegrees(30, -45)));
172
+ EXPECT_FALSE(r1.Contains(S2LatLng::FromDegrees(30, 45)));
173
+ EXPECT_FALSE(r1.InteriorContains(S2LatLng::FromDegrees(30, 45)));
174
+ EXPECT_TRUE(r1.Contains(eq_m180));
175
+ EXPECT_FALSE(r1.InteriorContains(eq_m180));
176
+ EXPECT_TRUE(r1.Contains(north_pole));
177
+ EXPECT_FALSE(r1.InteriorContains(north_pole));
178
+ EXPECT_TRUE(r1.Contains(S2Point(0.5, -0.3, 0.1)));
179
+ EXPECT_FALSE(r1.Contains(S2Point(0.5, 0.2, 0.1)));
180
+ }
181
+
182
+ static void TestIntervalOps(const S2LatLngRect& x, const S2LatLngRect& y,
183
+ const char* expected_relation,
184
+ const S2LatLngRect& expected_union,
185
+ const S2LatLngRect& expected_intersection) {
186
+ // Test all of the interval operations on the given pair of intervals.
187
+ // "expected_relation" is a sequence of "T" and "F" characters corresponding
188
+ // to the expected results of Contains(), InteriorContains(), Intersects(),
189
+ // and InteriorIntersects() respectively.
190
+
191
+ EXPECT_EQ(x.Contains(y), expected_relation[0] == 'T');
192
+ EXPECT_EQ(x.InteriorContains(y), expected_relation[1] == 'T');
193
+ EXPECT_EQ(x.Intersects(y), expected_relation[2] == 'T');
194
+ EXPECT_EQ(x.InteriorIntersects(y), expected_relation[3] == 'T');
195
+
196
+ EXPECT_EQ(x.Contains(y), x.Union(y) == x);
197
+ EXPECT_EQ(x.Intersects(y), !x.Intersection(y).is_empty());
198
+
199
+ EXPECT_EQ(x.Union(y), expected_union);
200
+ EXPECT_EQ(x.Intersection(y), expected_intersection);
201
+
202
+ if (y.GetSize() == S2LatLng::FromRadians(0, 0)) {
203
+ S2LatLngRect r = x;
204
+ r.AddPoint(y.lo());
205
+ EXPECT_EQ(r, expected_union);
206
+ }
207
+ }
208
+
209
+ TEST(S2LatLngRect, IntervalOps) {
210
+ // Contains(S2LatLngRect), InteriorContains(S2LatLngRect),
211
+ // Intersects(), InteriorIntersects(), Union(), Intersection().
212
+ //
213
+ // Much more testing of these methods is done in s1interval_test
214
+ // and r1interval_test.
215
+
216
+ // Rectangle "r1" covers one-quarter of the sphere.
217
+ S2LatLngRect r1 = RectFromDegrees(0, -180, 90, 0);
218
+
219
+ // Test operations where one rectangle consists of a single point.
220
+ S2LatLngRect r1_mid = RectFromDegrees(45, -90, 45, -90);
221
+ TestIntervalOps(r1, r1_mid, "TTTT", r1, r1_mid);
222
+
223
+ S2LatLngRect req_m180 = RectFromDegrees(0, -180, 0, -180);
224
+ TestIntervalOps(r1, req_m180, "TFTF", r1, req_m180);
225
+
226
+ S2LatLngRect rnorth_pole = RectFromDegrees(90, 0, 90, 0);
227
+ TestIntervalOps(r1, rnorth_pole, "TFTF", r1, rnorth_pole);
228
+
229
+ TestIntervalOps(r1, RectFromDegrees(-10, -1, 1, 20), "FFTT",
230
+ RectFromDegrees(-10, 180, 90, 20),
231
+ RectFromDegrees(0, -1, 1, 0));
232
+ TestIntervalOps(r1, RectFromDegrees(-10, -1, 0, 20), "FFTF",
233
+ RectFromDegrees(-10, 180, 90, 20),
234
+ RectFromDegrees(0, -1, 0, 0));
235
+ TestIntervalOps(r1, RectFromDegrees(-10, 0, 1, 20), "FFTF",
236
+ RectFromDegrees(-10, 180, 90, 20),
237
+ RectFromDegrees(0, 0, 1, 0));
238
+
239
+ TestIntervalOps(RectFromDegrees(-15, -160, -15, -150),
240
+ RectFromDegrees(20, 145, 25, 155), "FFFF",
241
+ RectFromDegrees(-15, 145, 25, -150),
242
+ S2LatLngRect::Empty());
243
+ TestIntervalOps(RectFromDegrees(70, -10, 90, -140),
244
+ RectFromDegrees(60, 175, 80, 5), "FFTT",
245
+ RectFromDegrees(60, -180, 90, 180),
246
+ RectFromDegrees(70, 175, 80, 5));
247
+
248
+ // Check that the intersection of two rectangles that overlap in latitude
249
+ // but not longitude is valid, and vice versa.
250
+ TestIntervalOps(RectFromDegrees(12, 30, 60, 60),
251
+ RectFromDegrees(0, 0, 30, 18), "FFFF",
252
+ RectFromDegrees(0, 0, 60, 60), S2LatLngRect::Empty());
253
+ TestIntervalOps(RectFromDegrees(0, 0, 18, 42),
254
+ RectFromDegrees(30, 12, 42, 60), "FFFF",
255
+ RectFromDegrees(0, 0, 42, 60), S2LatLngRect::Empty());
256
+ }
257
+
258
+ TEST(BoundaryIntersects, EmptyRectangle) {
259
+ S2LatLngRect rect = S2LatLngRect::Empty();
260
+ S2Point lo(rect.lo()), hi(rect.hi());
261
+ EXPECT_FALSE(rect.BoundaryIntersects(lo, lo));
262
+ EXPECT_FALSE(rect.BoundaryIntersects(lo, hi));
263
+ }
264
+
265
+ TEST(BoundaryIntersects, FullRectangle) {
266
+ S2LatLngRect rect = S2LatLngRect::Full();
267
+ S2Point lo(rect.lo()), hi(rect.hi());
268
+ EXPECT_FALSE(rect.BoundaryIntersects(lo, lo));
269
+ EXPECT_FALSE(rect.BoundaryIntersects(lo, hi));
270
+ }
271
+
272
+ TEST(BoundaryIntersects, SphericalLune) {
273
+ // This rectangle only has two non-degenerate sides.
274
+ S2LatLngRect rect = RectFromDegrees(-90, 100, 90, 120);
275
+ EXPECT_FALSE(rect.BoundaryIntersects(
276
+ MakePointOrDie("60:60"), MakePointOrDie("90:60")));
277
+ EXPECT_FALSE(rect.BoundaryIntersects(
278
+ MakePointOrDie("-60:110"), MakePointOrDie("60:110")));
279
+ EXPECT_TRUE(rect.BoundaryIntersects(
280
+ MakePointOrDie("-60:95"), MakePointOrDie("60:110")));
281
+ EXPECT_TRUE(rect.BoundaryIntersects(
282
+ MakePointOrDie("60:115"), MakePointOrDie("80:125")));
283
+ }
284
+
285
+ TEST(BoundaryIntersects, NorthHemisphere) {
286
+ // This rectangle only has only one non-degenerate side.
287
+ S2LatLngRect rect = RectFromDegrees(0, -180, 90, 180);
288
+ EXPECT_FALSE(rect.BoundaryIntersects(
289
+ MakePointOrDie("60:-180"), MakePointOrDie("90:-180")));
290
+ EXPECT_FALSE(rect.BoundaryIntersects(
291
+ MakePointOrDie("60:-170"), MakePointOrDie("60:170")));
292
+ EXPECT_TRUE(rect.BoundaryIntersects(
293
+ MakePointOrDie("-10:-180"), MakePointOrDie("10:-180")));
294
+ }
295
+
296
+ TEST(BoundaryIntersects, SouthHemisphere) {
297
+ // This rectangle only has only one non-degenerate side.
298
+ S2LatLngRect rect = RectFromDegrees(-90, -180, 0, 180);
299
+ EXPECT_FALSE(rect.BoundaryIntersects(
300
+ MakePointOrDie("-90:-180"), MakePointOrDie("-60:-180")));
301
+ EXPECT_FALSE(rect.BoundaryIntersects(
302
+ MakePointOrDie("-60:-170"), MakePointOrDie("-60:170")));
303
+ EXPECT_TRUE(rect.BoundaryIntersects(
304
+ MakePointOrDie("-10:-180"), MakePointOrDie("10:-180")));
305
+ }
306
+
307
+ TEST(BoundaryIntersects, RectCrossingAntiMeridian) {
308
+ S2LatLngRect rect = RectFromDegrees(20, 170, 40, -170);
309
+ EXPECT_TRUE(rect.Contains(MakePointOrDie("30:180")));
310
+
311
+ // Check that crossings of all four sides are detected.
312
+ EXPECT_TRUE(rect.BoundaryIntersects(
313
+ MakePointOrDie("25:160"), MakePointOrDie("25:180")));
314
+ EXPECT_TRUE(rect.BoundaryIntersects(
315
+ MakePointOrDie("25:-160"), MakePointOrDie("25:-180")));
316
+ EXPECT_TRUE(rect.BoundaryIntersects(
317
+ MakePointOrDie("15:175"), MakePointOrDie("30:175")));
318
+ EXPECT_TRUE(rect.BoundaryIntersects(
319
+ MakePointOrDie("45:175"), MakePointOrDie("30:175")));
320
+
321
+ // Check that the edges on the opposite side of the sphere but at the same
322
+ // latitude do not intersect the rectangle boundary.
323
+ EXPECT_FALSE(rect.BoundaryIntersects(
324
+ MakePointOrDie("25:-20"), MakePointOrDie("25:0")));
325
+ EXPECT_FALSE(rect.BoundaryIntersects(
326
+ MakePointOrDie("25:20"), MakePointOrDie("25:0")));
327
+ EXPECT_FALSE(rect.BoundaryIntersects(
328
+ MakePointOrDie("15:-5"), MakePointOrDie("30:-5")));
329
+ EXPECT_FALSE(rect.BoundaryIntersects(
330
+ MakePointOrDie("45:-5"), MakePointOrDie("30:-5")));
331
+ }
332
+
333
+ TEST(S2LatLngRect, AddPoint) {
334
+ S2LatLngRect p = S2LatLngRect::Empty();
335
+ p.AddPoint(S2LatLng::FromDegrees(0, 0));
336
+ EXPECT_TRUE(p.is_point());
337
+ p.AddPoint(S2LatLng::FromRadians(0, -M_PI_2));
338
+ EXPECT_FALSE(p.is_point());
339
+ p.AddPoint(S2LatLng::FromRadians(M_PI_4, -M_PI));
340
+ p.AddPoint(S2Point(0, 0, 1));
341
+ EXPECT_EQ(p, RectFromDegrees(0, -180, 90, 0));
342
+ }
343
+
344
+ TEST(S2LatLngRect, Expanded) {
345
+ EXPECT_TRUE(RectFromDegrees(70, 150, 80, 170).
346
+ Expanded(S2LatLng::FromDegrees(20, 30)).
347
+ ApproxEquals(RectFromDegrees(50, 120, 90, -160)));
348
+ EXPECT_TRUE(S2LatLngRect::Empty().Expanded(S2LatLng::FromDegrees(20, 30)).
349
+ is_empty());
350
+ EXPECT_TRUE(S2LatLngRect::Full().Expanded(S2LatLng::FromDegrees(500, 500)).
351
+ is_full());
352
+ EXPECT_TRUE(RectFromDegrees(-90, 170, 10, 20).
353
+ Expanded(S2LatLng::FromDegrees(30, 80)).
354
+ ApproxEquals(RectFromDegrees(-90, -180, 40, 180)));
355
+
356
+ // Negative margins.
357
+ EXPECT_TRUE(RectFromDegrees(10, -50, 60, 70).
358
+ Expanded(S2LatLng::FromDegrees(-10, -10)).
359
+ ApproxEquals(RectFromDegrees(20, -40, 50, 60)));
360
+ EXPECT_TRUE(RectFromDegrees(-20, -180, 20, 180).
361
+ Expanded(S2LatLng::FromDegrees(-10, -10)).
362
+ ApproxEquals(RectFromDegrees(-10, -180, 10, 180)));
363
+ EXPECT_TRUE(RectFromDegrees(-20, -180, 20, 180).
364
+ Expanded(S2LatLng::FromDegrees(-30, -30)).is_empty());
365
+ EXPECT_TRUE(RectFromDegrees(-90, 10, 90, 11).
366
+ Expanded(S2LatLng::FromDegrees(-10, -10)).is_empty());
367
+ EXPECT_TRUE(RectFromDegrees(-90, 10, 90, 100).
368
+ Expanded(S2LatLng::FromDegrees(-10, -10)).
369
+ ApproxEquals(RectFromDegrees(-80, 20, 80, 90)));
370
+ EXPECT_TRUE(S2LatLngRect::Empty().Expanded(S2LatLng::FromDegrees(-50, -500)).
371
+ is_empty());
372
+ EXPECT_TRUE(S2LatLngRect::Full().Expanded(S2LatLng::FromDegrees(-50, -50)).
373
+ ApproxEquals(RectFromDegrees(-40, -180, 40, 180)));
374
+
375
+ // Mixed margins.
376
+ EXPECT_TRUE(RectFromDegrees(10, -50, 60, 70).
377
+ Expanded(S2LatLng::FromDegrees(-10, 30)).
378
+ ApproxEquals(RectFromDegrees(20, -80, 50, 100)));
379
+ EXPECT_TRUE(RectFromDegrees(-20, -180, 20, 180).
380
+ Expanded(S2LatLng::FromDegrees(10, -500)).
381
+ ApproxEquals(RectFromDegrees(-30, -180, 30, 180)));
382
+ EXPECT_TRUE(RectFromDegrees(-90, -180, 80, 180).
383
+ Expanded(S2LatLng::FromDegrees(-30, 500)).
384
+ ApproxEquals(RectFromDegrees(-60, -180, 50, 180)));
385
+ EXPECT_TRUE(RectFromDegrees(-80, -100, 80, 150).
386
+ Expanded(S2LatLng::FromDegrees(30, -50)).
387
+ ApproxEquals(RectFromDegrees(-90, -50, 90, 100)));
388
+ EXPECT_TRUE(RectFromDegrees(0, -180, 50, 180).
389
+ Expanded(S2LatLng::FromDegrees(-30, 500)).is_empty());
390
+ EXPECT_TRUE(RectFromDegrees(-80, 10, 70, 20).
391
+ Expanded(S2LatLng::FromDegrees(30, -200)).is_empty());
392
+ EXPECT_TRUE(S2LatLngRect::Empty().Expanded(S2LatLng::FromDegrees(100, -100)).
393
+ is_empty());
394
+ EXPECT_TRUE(S2LatLngRect::Full().Expanded(S2LatLng::FromDegrees(100, -100)).
395
+ is_full());
396
+
397
+ }
398
+
399
+ TEST(S2LatLngRect, PolarClosure) {
400
+ EXPECT_EQ(RectFromDegrees(-89, 0, 89, 1),
401
+ RectFromDegrees(-89, 0, 89, 1).PolarClosure());
402
+ EXPECT_EQ(RectFromDegrees(-90, -180, -45, 180),
403
+ RectFromDegrees(-90, -30, -45, 100).PolarClosure());
404
+ EXPECT_EQ(RectFromDegrees(89, -180, 90, 180),
405
+ RectFromDegrees(89, 145, 90, 146).PolarClosure());
406
+ EXPECT_EQ(S2LatLngRect::Full(),
407
+ RectFromDegrees(-90, -145, 90, -144).PolarClosure());
408
+ }
409
+
410
+ TEST(ExpandedByDistance, PositiveDistance) {
411
+ EXPECT_TRUE(RectFromDegrees(0, 170, 0, -170).
412
+ ExpandedByDistance(S1Angle::Degrees(15)).ApproxEquals(
413
+ RectFromDegrees(-15, 155, 15, -155)));
414
+ EXPECT_TRUE(RectFromDegrees(60, 150, 80, 10).
415
+ ExpandedByDistance(S1Angle::Degrees(15)).ApproxEquals(
416
+ RectFromDegrees(45, -180, 90, 180)));
417
+ }
418
+
419
+ TEST(ExpandedByDistance, NegativeDistanceNorthEast) {
420
+ S2LatLngRect in_rect = RectFromDegrees(0.0, 0.0, 30.0, 90.0);
421
+ S1Angle distance = S1Angle::Degrees(5.0);
422
+
423
+ S2LatLngRect out_rect =
424
+ in_rect.ExpandedByDistance(distance).ExpandedByDistance(-distance);
425
+
426
+ EXPECT_TRUE(out_rect.ApproxEquals(in_rect)) << out_rect;
427
+ }
428
+
429
+ TEST(ExpandedByDistance, NegativeDistanceSouthWest) {
430
+ S2LatLngRect in_rect = RectFromDegrees(-30.0, -90.0, 0.0, 0.0);
431
+ S1Angle distance = S1Angle::Degrees(5.0);
432
+
433
+ S2LatLngRect out_rect =
434
+ in_rect.ExpandedByDistance(distance).ExpandedByDistance(-distance);
435
+
436
+ EXPECT_TRUE(out_rect.ApproxEquals(in_rect)) << out_rect;
437
+ }
438
+
439
+ TEST(ExpandedByDistance, NegativeDistanceLatWithNorthPole) {
440
+ S2LatLngRect rect = RectFromDegrees(0.0, -90.0, 90.0, 180.0)
441
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
442
+
443
+ EXPECT_TRUE(rect.ApproxEquals(RectFromDegrees(5.0, 0.0, 85.0, 90.0)))
444
+ << rect;
445
+ }
446
+
447
+ TEST(ExpandedByDistance, NegativeDistanceLatWithNorthPoleAndLngFull) {
448
+ S2LatLngRect rect = RectFromDegrees(0.0, -180.0, 90.0, 180.0)
449
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
450
+
451
+ EXPECT_TRUE(rect.ApproxEquals(RectFromDegrees(5.0, -180.0, 90.0, 180.0)))
452
+ << rect;
453
+ }
454
+
455
+ TEST(ExpandedByDistance, NegativeDistanceLatWithSouthPole) {
456
+ S2LatLngRect rect = RectFromDegrees(-90.0, -90.0, 0.0, 180.0)
457
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
458
+
459
+ EXPECT_TRUE(rect.ApproxEquals(RectFromDegrees(-85.0, 0.0, -5.0, 90.0)))
460
+ << rect;
461
+ }
462
+
463
+ TEST(ExpandedByDistance, NegativeDistanceLatWithSouthPoleAndLngFull) {
464
+ S2LatLngRect rect = RectFromDegrees(-90.0, -180.0, 0.0, 180.0)
465
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
466
+
467
+ EXPECT_TRUE(rect.ApproxEquals(RectFromDegrees(-90.0, -180.0, -5.0, 180.0)))
468
+ << rect;
469
+ }
470
+
471
+ TEST(ExpandedByDistance, NegativeDistanceLngFull) {
472
+ S2LatLngRect rect = RectFromDegrees(0.0, -180.0, 30.0, 180.0)
473
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
474
+
475
+ EXPECT_TRUE(rect.ApproxEquals(RectFromDegrees(5.0, -180.0, 25.0, 180.0)))
476
+ << rect;
477
+ }
478
+
479
+ TEST(ExpandedByDistance, NegativeDistanceLatResultEmpty) {
480
+ S2LatLngRect rect = RectFromDegrees(0.0, 0.0, 9.9, 90.0)
481
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
482
+
483
+ EXPECT_TRUE(rect.is_empty()) << rect;
484
+ }
485
+
486
+ TEST(ExpandedByDistance, NegativeDistanceLngResultEmpty) {
487
+ S2LatLngRect rect = RectFromDegrees(0.0, 0.0, 30.0, 11.0)
488
+ .ExpandedByDistance(-S1Angle::Degrees(5.0));
489
+
490
+ // The cap center is at latitude 30 - 5 = 25 degrees. The length of the
491
+ // latitude 25 degree line is 0.906 times the length of the equator. Thus the
492
+ // cap whose radius is 5 degrees covers the rectangle whose latitude interval
493
+ // is 11 degrees.
494
+ EXPECT_TRUE(rect.is_empty()) << rect;
495
+ }
496
+
497
+ TEST(S2LatLngRect, GetCapBound) {
498
+ // Bounding cap at center is smaller:
499
+ EXPECT_TRUE(RectFromDegrees(-45, -45, 45, 45).GetCapBound().
500
+ ApproxEquals(S2Cap::FromCenterHeight(S2Point(1, 0, 0), 0.5)));
501
+
502
+ // Bounding cap at north pole is smaller:
503
+ EXPECT_TRUE(RectFromDegrees(88, -80, 89, 80).GetCapBound().
504
+ ApproxEquals(S2Cap(S2Point(0, 0, 1), S1Angle::Degrees(2))));
505
+
506
+ // Longitude span > 180 degrees:
507
+ EXPECT_TRUE(RectFromDegrees(-30, -150, -10, 50).GetCapBound().
508
+ ApproxEquals(S2Cap(S2Point(0, 0, -1), S1Angle::Degrees(80))));
509
+ }
510
+
511
+ static void TestCellOps(const S2LatLngRect& r, const S2Cell& cell,
512
+ int level) {
513
+ // Test the relationship between the given rectangle and cell:
514
+ // 0 == no intersection, 1 == MayIntersect, 2 == Intersects,
515
+ // 3 == Vertex Containment, 4 == Contains
516
+
517
+ bool vertex_contained = false;
518
+ for (int i = 0; i < 4; ++i) {
519
+ if (r.Contains(cell.GetVertexRaw(i)) ||
520
+ (!r.is_empty() && cell.Contains(r.GetVertex(i).ToPoint())))
521
+ vertex_contained = true;
522
+ }
523
+ EXPECT_EQ(r.MayIntersect(cell), level >= 1);
524
+ EXPECT_EQ(r.Intersects(cell), level >= 2);
525
+ EXPECT_EQ(vertex_contained, level >= 3);
526
+ EXPECT_EQ(r.Contains(cell), level >= 4);
527
+ }
528
+
529
+ TEST(S2LatLngRect, CellOps) {
530
+ // Contains(S2Cell), MayIntersect(S2Cell), Intersects(S2Cell)
531
+
532
+ // Special cases.
533
+ TestCellOps(S2LatLngRect::Empty(), S2Cell::FromFacePosLevel(3, 0, 0), 0);
534
+ TestCellOps(S2LatLngRect::Full(), S2Cell::FromFacePosLevel(2, 0, 0), 4);
535
+ TestCellOps(S2LatLngRect::Full(), S2Cell::FromFacePosLevel(5, 0, 25), 4);
536
+
537
+ // This rectangle includes the first quadrant of face 0. It's expanded
538
+ // slightly because cell bounding rectangles are slightly conservative.
539
+ S2LatLngRect r4 = RectFromDegrees(-45.1, -45.1, 0.1, 0.1);
540
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 0), 3);
541
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 1), 4);
542
+ TestCellOps(r4, S2Cell::FromFacePosLevel(1, 0, 1), 0);
543
+
544
+ // This rectangle intersects the first quadrant of face 0.
545
+ S2LatLngRect r5 = RectFromDegrees(-10, -45, 10, 0);
546
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 0), 3);
547
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 1), 3);
548
+ TestCellOps(r5, S2Cell::FromFacePosLevel(1, 0, 1), 0);
549
+
550
+ // Rectangle consisting of a single point.
551
+ TestCellOps(RectFromDegrees(4, 4, 4, 4), S2Cell::FromFace(0), 3);
552
+
553
+ // Rectangles that intersect the bounding rectangle of a face
554
+ // but not the face itself.
555
+ TestCellOps(RectFromDegrees(41, -87, 42, -79), S2Cell::FromFace(2), 1);
556
+ TestCellOps(RectFromDegrees(-41, 160, -40, -160), S2Cell::FromFace(5), 1);
557
+
558
+ // This is the leaf cell at the top right hand corner of face 0.
559
+ // It has two angles of 60 degrees and two of 120 degrees.
560
+ S2Cell cell0tr(S2Point(1 + 1e-12, 1, 1));
561
+ S2LatLngRect bound0tr = cell0tr.GetRectBound();
562
+ S2LatLng v0(cell0tr.GetVertexRaw(0));
563
+ TestCellOps(RectFromDegrees(v0.lat().degrees() - 1e-8,
564
+ v0.lng().degrees() - 1e-8,
565
+ v0.lat().degrees() - 2e-10,
566
+ v0.lng().degrees() + 1e-10),
567
+ cell0tr, 1);
568
+
569
+ // Rectangles that intersect a face but where no vertex of one region
570
+ // is contained by the other region. The first one passes through
571
+ // a corner of one of the face cells.
572
+ TestCellOps(RectFromDegrees(-37, -70, -36, -20), S2Cell::FromFace(5), 2);
573
+
574
+ // These two intersect like a diamond and a square.
575
+ S2Cell cell202 = S2Cell::FromFacePosLevel(2, 0, 2);
576
+ S2LatLngRect bound202 = cell202.GetRectBound();
577
+ TestCellOps(RectFromDegrees(bound202.lo().lat().degrees() + 3,
578
+ bound202.lo().lng().degrees() + 3,
579
+ bound202.hi().lat().degrees() - 3,
580
+ bound202.hi().lng().degrees() - 3),
581
+ cell202, 2);
582
+ }
583
+
584
+ TEST(S2LatLngRect, EncodeDecode) {
585
+ S2LatLngRect r = RectFromDegrees(-20, -80, 10, 20);
586
+ Encoder encoder;
587
+ r.Encode(&encoder);
588
+ Decoder decoder(encoder.base(), encoder.length());
589
+ S2LatLngRect decoded_rect = S2LatLngRect::Empty();
590
+ EXPECT_TRUE(decoded_rect.Decode(&decoder));
591
+ EXPECT_EQ(r, decoded_rect);
592
+ }
593
+
594
+ TEST(S2LatLngRect, Area) {
595
+ EXPECT_EQ(S2LatLngRect::Empty().Area(), 0.0);
596
+ EXPECT_DOUBLE_EQ(S2LatLngRect::Full().Area(), 4 * M_PI);
597
+ EXPECT_DOUBLE_EQ(RectFromDegrees(0, 0, 90, 90).Area(), M_PI_2);
598
+ }
599
+
600
+ // Recursively verify that when a rectangle is split into two pieces, the
601
+ // centroids of the children sum to give the centroid of the parent.
602
+ static void TestCentroidSplitting(const S2LatLngRect& r, int splits_left) {
603
+ S2LatLngRect child0, child1;
604
+ if (S2Testing::rnd.OneIn(2)) {
605
+ double lat = S2Testing::rnd.UniformDouble(r.lat().lo(), r.lat().hi());
606
+ child0 = S2LatLngRect(R1Interval(r.lat().lo(), lat), r.lng());
607
+ child1 = S2LatLngRect(R1Interval(lat, r.lat().hi()), r.lng());
608
+ } else {
609
+ S2_DCHECK_LE(r.lng().lo(), r.lng().hi());
610
+ double lng = S2Testing::rnd.UniformDouble(r.lng().lo(), r.lng().hi());
611
+ child0 = S2LatLngRect(r.lat(), S1Interval(r.lng().lo(), lng));
612
+ child1 = S2LatLngRect(r.lat(), S1Interval(lng, r.lng().hi()));
613
+ }
614
+ EXPECT_LE(
615
+ (r.GetCentroid() - child0.GetCentroid() - child1.GetCentroid()).Norm(),
616
+ 1e-15);
617
+ if (splits_left > 0) {
618
+ TestCentroidSplitting(child0, splits_left - 1);
619
+ TestCentroidSplitting(child1, splits_left - 1);
620
+ }
621
+ }
622
+
623
+ TEST(S2LatLngRect, GetCentroid) {
624
+ S2Testing::Random* rnd = &S2Testing::rnd;
625
+
626
+ // Empty and full rectangles.
627
+ EXPECT_EQ(S2Point(), S2LatLngRect::Empty().GetCentroid());
628
+ EXPECT_LE(S2LatLngRect::Full().GetCentroid().Norm(), 1e-15);
629
+
630
+ // Rectangles that cover the full longitude range.
631
+ for (int i = 0; i < 100; ++i) {
632
+ double lat1 = rnd->UniformDouble(-M_PI_2, M_PI_2);
633
+ double lat2 = rnd->UniformDouble(-M_PI_2, M_PI_2);
634
+ S2LatLngRect r(R1Interval::FromPointPair(lat1, lat2), S1Interval::Full());
635
+ S2Point centroid = r.GetCentroid();
636
+ EXPECT_NEAR(0.5 * (sin(lat1) + sin(lat2)) * r.Area(), centroid.z(), 1e-15);
637
+ EXPECT_LE(Vector2_d(centroid.x(), centroid.y()).Norm(), 1e-15);
638
+ }
639
+
640
+ // Rectangles that cover the full latitude range.
641
+ for (int i = 0; i < 100; ++i) {
642
+ double lng1 = rnd->UniformDouble(-M_PI, M_PI);
643
+ double lng2 = rnd->UniformDouble(-M_PI, M_PI);
644
+ S2LatLngRect r(S2LatLngRect::FullLat(),
645
+ S1Interval::FromPointPair(lng1, lng2));
646
+ S2Point centroid = r.GetCentroid();
647
+ EXPECT_LE(fabs(centroid.z()), 1e-15);
648
+ EXPECT_NEAR(r.lng().GetCenter(), S2LatLng(centroid).lng().radians(), 1e-15);
649
+ double alpha = 0.5 * r.lng().GetLength();
650
+ EXPECT_NEAR(0.25 * M_PI * sin(alpha) / alpha * r.Area(),
651
+ Vector2_d(centroid.x(), centroid.y()).Norm(), 1e-15);
652
+ }
653
+
654
+ // Finally, verify that when a rectangle is recursively split into pieces,
655
+ // the centroids of the pieces add to give the centroid of their parent.
656
+ // To make the code simpler we avoid rectangles that cross the 180 degree
657
+ // line of longitude.
658
+ TestCentroidSplitting(
659
+ S2LatLngRect(S2LatLngRect::FullLat(), S1Interval(-3.14, 3.14)),
660
+ 10 /*splits_left*/);
661
+ }
662
+
663
+ // Returns the minimum distance from X to the latitude line segment defined by
664
+ // the given latitude and longitude interval.
665
+ S1Angle GetDistance(const S2LatLng& x,
666
+ const S1Angle& lat,
667
+ const S1Interval& interval) {
668
+ EXPECT_TRUE(x.is_valid());
669
+ EXPECT_TRUE(interval.is_valid());
670
+
671
+ // Is X inside the longitude interval?
672
+ if (interval.Contains(x.lng().radians()))
673
+ return (x.lat() - lat).abs();
674
+
675
+ // Return the distance to the closer endpoint.
676
+ return min(x.GetDistance(S2LatLng(lat, S1Angle::Radians(interval.lo()))),
677
+ x.GetDistance(S2LatLng(lat, S1Angle::Radians(interval.hi()))));
678
+ }
679
+
680
+ static S1Angle BruteForceDistance(const S2LatLngRect& a,
681
+ const S2LatLngRect& b) {
682
+ if (a.Intersects(b))
683
+ return S1Angle::Radians(0);
684
+
685
+ // Compare every point in 'a' against every latitude edge and longitude edge
686
+ // in 'b', and vice-versa, for a total of 16 point-vs-latitude-edge tests and
687
+ // 16 point-vs-longitude-edge tests.
688
+ S2LatLng pnt_a[4], pnt_b[4];
689
+ pnt_a[0] = S2LatLng(a.lat_lo(), a.lng_lo());
690
+ pnt_a[1] = S2LatLng(a.lat_lo(), a.lng_hi());
691
+ pnt_a[2] = S2LatLng(a.lat_hi(), a.lng_hi());
692
+ pnt_a[3] = S2LatLng(a.lat_hi(), a.lng_lo());
693
+ pnt_b[0] = S2LatLng(b.lat_lo(), b.lng_lo());
694
+ pnt_b[1] = S2LatLng(b.lat_lo(), b.lng_hi());
695
+ pnt_b[2] = S2LatLng(b.lat_hi(), b.lng_hi());
696
+ pnt_b[3] = S2LatLng(b.lat_hi(), b.lng_lo());
697
+
698
+ // Make arrays containing the lo/hi latitudes and the lo/hi longitude edges.
699
+ S1Angle lat_a[2] = { a.lat_lo(), a.lat_hi() };
700
+ S1Angle lat_b[2] = { b.lat_lo(), b.lat_hi() };
701
+ S2Point lng_edge_a[2][2] = { { pnt_a[0].ToPoint(), pnt_a[3].ToPoint() },
702
+ { pnt_a[1].ToPoint(), pnt_a[2].ToPoint() } };
703
+ S2Point lng_edge_b[2][2] = { { pnt_b[0].ToPoint(), pnt_b[3].ToPoint() },
704
+ { pnt_b[1].ToPoint(), pnt_b[2].ToPoint() } };
705
+
706
+ S1Angle min_distance = S1Angle::Degrees(180.0);
707
+ for (int i = 0; i < 4; ++i) {
708
+ // For each point in a and b.
709
+ const S2LatLng& current_a = pnt_a[i];
710
+ const S2LatLng& current_b = pnt_b[i];
711
+
712
+ for (int j = 0; j < 2; ++j) {
713
+ // Get distances to latitude and longitude edges.
714
+ S1Angle a_to_lat = GetDistance(current_a, lat_b[j], b.lng());
715
+ S1Angle b_to_lat = GetDistance(current_b, lat_a[j], a.lng());
716
+ S1Angle a_to_lng = S2::GetDistance(
717
+ current_a.ToPoint(), lng_edge_b[j][0], lng_edge_b[j][1]);
718
+ S1Angle b_to_lng = S2::GetDistance(
719
+ current_b.ToPoint(), lng_edge_a[j][0], lng_edge_a[j][1]);
720
+
721
+ min_distance = min(min_distance,
722
+ min(a_to_lat, min(b_to_lat, min(a_to_lng, b_to_lng))));
723
+ }
724
+ }
725
+ return min_distance;
726
+ }
727
+
728
+ static S1Angle BruteForceRectPointDistance(const S2LatLngRect& a,
729
+ const S2LatLng& b) {
730
+ if (a.Contains(b)) {
731
+ return S1Angle::Radians(0);
732
+ }
733
+
734
+ S1Angle b_to_lo_lat = GetDistance(b, a.lat_lo(), a.lng());
735
+ S1Angle b_to_hi_lat = GetDistance(b, a.lat_hi(), a.lng());
736
+ S1Angle b_to_lo_lng = S2::GetDistance(
737
+ b.ToPoint(),
738
+ S2LatLng(a.lat_lo(), a.lng_lo()).ToPoint(),
739
+ S2LatLng(a.lat_hi(), a.lng_lo()).ToPoint());
740
+ S1Angle b_to_hi_lng = S2::GetDistance(
741
+ b.ToPoint(),
742
+ S2LatLng(a.lat_lo(), a.lng_hi()).ToPoint(),
743
+ S2LatLng(a.lat_hi(), a.lng_hi()).ToPoint());
744
+ return min(b_to_lo_lat, min(b_to_hi_lat, min(b_to_lo_lng, b_to_hi_lng)));
745
+ }
746
+
747
+ // This method verifies a.GetDistance(b) by comparing its result against a
748
+ // brute-force implementation. The correctness of the brute-force version is
749
+ // much easier to verify by inspection.
750
+ static void VerifyGetDistance(const S2LatLngRect& a, const S2LatLngRect& b) {
751
+ S1Angle distance1 = BruteForceDistance(a, b);
752
+ S1Angle distance2 = a.GetDistance(b);
753
+ EXPECT_NEAR(distance1.radians() - distance2.radians(), 0, 1e-10)
754
+ << a << ":" << b;
755
+ }
756
+
757
+ static S2LatLngRect PointRectFromDegrees(double lat, double lng) {
758
+ return S2LatLngRect::FromPoint(
759
+ S2LatLng::FromDegrees(lat, lng).Normalized());
760
+ }
761
+
762
+ // This method verifies a.GetDistance(b), where b is a S2LatLng, by comparing
763
+ // its result against a.GetDistance(c), c being the point rectangle created
764
+ // from b.
765
+ static void VerifyGetRectPointDistance(
766
+ const S2LatLngRect& a, const S2LatLng& p) {
767
+ S1Angle distance1 = BruteForceRectPointDistance(a, p.Normalized());
768
+ S1Angle distance2 = a.GetDistance(p.Normalized());
769
+ EXPECT_NEAR(fabs(distance1.radians() - distance2.radians()), 0, 1e-10)
770
+ << a << ":" << p;
771
+ }
772
+
773
+ TEST(S2LatLngRect, GetDistanceOverlapping) {
774
+ // Check pairs of rectangles that overlap: (should all return 0):
775
+ S2LatLngRect a = RectFromDegrees(0, 0, 2, 2);
776
+ S2LatLngRect b = PointRectFromDegrees(0, 0);
777
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(a));
778
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(b));
779
+ EXPECT_EQ(S1Angle::Radians(0), b.GetDistance(b));
780
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(S2LatLng::FromDegrees(0, 0)));
781
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(0, 1, 2, 3)));
782
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(0, 2, 2, 4)));
783
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(1, 0, 3, 2)));
784
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(2, 0, 4, 2)));
785
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(1, 1, 3, 3)));
786
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(2, 2, 4, 4)));
787
+ }
788
+
789
+ TEST(S2LatLngRect, GetDistanceRectVsPoint) {
790
+ // Rect that spans 180.
791
+ S2LatLngRect a = RectFromDegrees(-1, -1, 2, 1);
792
+ VerifyGetDistance(a, PointRectFromDegrees(-2, -1));
793
+ VerifyGetDistance(a, PointRectFromDegrees(1, 2));
794
+
795
+ VerifyGetDistance(PointRectFromDegrees(-2, -1), a);
796
+ VerifyGetDistance(PointRectFromDegrees(1, 2), a);
797
+
798
+ VerifyGetRectPointDistance(a, S2LatLng::FromDegrees(-2, -1));
799
+ VerifyGetRectPointDistance(a, S2LatLng::FromDegrees(1, 2));
800
+
801
+ // Tests near the north pole.
802
+ S2LatLngRect b = RectFromDegrees(86, 0, 88, 2);
803
+ VerifyGetDistance(b, PointRectFromDegrees(87, 3));
804
+ VerifyGetDistance(b, PointRectFromDegrees(87, -1));
805
+ VerifyGetDistance(b, PointRectFromDegrees(89, 1));
806
+ VerifyGetDistance(b, PointRectFromDegrees(89, 181));
807
+ VerifyGetDistance(b, PointRectFromDegrees(85, 1));
808
+ VerifyGetDistance(b, PointRectFromDegrees(85, 181));
809
+ VerifyGetDistance(b, PointRectFromDegrees(90, 0));
810
+
811
+ VerifyGetDistance(PointRectFromDegrees(87, 3), b);
812
+ VerifyGetDistance(PointRectFromDegrees(87, -1), b);
813
+ VerifyGetDistance(PointRectFromDegrees(89, 1), b);
814
+ VerifyGetDistance(PointRectFromDegrees(89, 181), b);
815
+ VerifyGetDistance(PointRectFromDegrees(85, 1), b);
816
+ VerifyGetDistance(PointRectFromDegrees(85, 181), b);
817
+ VerifyGetDistance(PointRectFromDegrees(90, 0), b);
818
+
819
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(87, 3));
820
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(87, -1));
821
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(89, 1));
822
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(89, 181));
823
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(85, 1));
824
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(85, 181));
825
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(90, 0));
826
+
827
+ // Rect that touches the north pole.
828
+ S2LatLngRect c = RectFromDegrees(88, 0, 90, 2);
829
+ VerifyGetDistance(c, PointRectFromDegrees(89, 3));
830
+ VerifyGetDistance(c, PointRectFromDegrees(89, 90));
831
+ VerifyGetDistance(c, PointRectFromDegrees(89, 181));
832
+ VerifyGetDistance(PointRectFromDegrees(89, 3), c);
833
+ VerifyGetDistance(PointRectFromDegrees(89, 90), c);
834
+ VerifyGetDistance(PointRectFromDegrees(89, 181), c);
835
+ }
836
+
837
+ TEST(S2LatLngRect, GetDistanceRectVsRect) {
838
+ // Rect that spans 180.
839
+ S2LatLngRect a = RectFromDegrees(-1, -1, 2, 1);
840
+ VerifyGetDistance(a, RectFromDegrees(0, 2, 1, 3));
841
+ VerifyGetDistance(a, RectFromDegrees(-2, -3, -1, -2));
842
+
843
+ // Tests near the south pole.
844
+ S2LatLngRect b = RectFromDegrees(-87, 0, -85, 3);
845
+ VerifyGetDistance(b, RectFromDegrees(-89, 1, -88, 2));
846
+ VerifyGetDistance(b, RectFromDegrees(-84, 1, -83, 2));
847
+ VerifyGetDistance(b, RectFromDegrees(-88, 90, -86, 91));
848
+ VerifyGetDistance(b, RectFromDegrees(-84, -91, -83, -90));
849
+ VerifyGetDistance(b, RectFromDegrees(-90, 181, -89, 182));
850
+ VerifyGetDistance(b, RectFromDegrees(-84, 181, -83, 182));
851
+ }
852
+
853
+ TEST(S2LatLngRect, GetDistanceRandomPairs) {
854
+ // Test random pairs.
855
+ for (int i = 0; i < 10000; ++i) {
856
+ S2LatLngRect a =
857
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
858
+ S2LatLng(S2Testing::RandomPoint()));
859
+ S2LatLngRect b =
860
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
861
+ S2LatLng(S2Testing::RandomPoint()));
862
+ VerifyGetDistance(a, b);
863
+
864
+
865
+ S2LatLng c(S2Testing::RandomPoint());
866
+ VerifyGetRectPointDistance(a, c);
867
+ VerifyGetRectPointDistance(b, c);
868
+ }
869
+ }
870
+
871
+ // This function assumes that GetDirectedHausdorffDistance() always returns
872
+ // a distance from some point in a to b. So the function mainly tests whether
873
+ // the returned distance is large enough, and only does a weak test on whether
874
+ // it is small enough.
875
+ static void VerifyGetDirectedHausdorffDistance(const S2LatLngRect& a,
876
+ const S2LatLngRect& b) {
877
+ S1Angle hausdorff_distance = a.GetDirectedHausdorffDistance(b);
878
+
879
+ static const double kResolution = 0.1;
880
+ // Record the max sample distance as well as the sample point realizing the
881
+ // max for easier debugging.
882
+ S1Angle max_distance;
883
+ double lat_max, lng_max;
884
+
885
+ int sample_size_on_lat =
886
+ static_cast<int>(a.lat().GetLength() / kResolution) + 1;
887
+ int sample_size_on_lng =
888
+ static_cast<int>(a.lng().GetLength() / kResolution) + 1;
889
+ double delta_on_lat = a.lat().GetLength() / sample_size_on_lat;
890
+ double delta_on_lng = a.lng().GetLength() / sample_size_on_lng;
891
+
892
+ double lng = a.lng().lo();
893
+ for (int i = 0; i <= sample_size_on_lng; ++i, lng += delta_on_lng) {
894
+ double lat = a.lat().lo();
895
+ for (int j = 0; j <= sample_size_on_lat; ++j, lat += delta_on_lat) {
896
+ S2LatLng latlng = S2LatLng::FromRadians(lat, lng).Normalized();
897
+ S1Angle distance_to_b = b.GetDistance(latlng);
898
+
899
+ if (distance_to_b >= max_distance) {
900
+ max_distance = distance_to_b;
901
+ lat_max = lat;
902
+ lng_max = lng;
903
+ }
904
+ }
905
+ }
906
+
907
+ EXPECT_LE(max_distance.radians(), hausdorff_distance.radians() + 1e-10)
908
+ << a << ":" << b;
909
+ EXPECT_GE(max_distance.radians(), hausdorff_distance.radians() - kResolution)
910
+ << a << ":" << b;
911
+ }
912
+
913
+
914
+ TEST(S2LatLngRect, GetDirectedHausdorffDistanceRandomPairs) {
915
+ // Test random pairs.
916
+ const int kIters = 1000;
917
+ for (int i = 0; i < kIters; ++i) {
918
+ S2LatLngRect a =
919
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
920
+ S2LatLng(S2Testing::RandomPoint()));
921
+ S2LatLngRect b =
922
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
923
+ S2LatLng(S2Testing::RandomPoint()));
924
+ // a and b are *minimum* bounding rectangles of two random points, in
925
+ // particular, their Voronoi diagrams are always of the same topology. We
926
+ // take the "complements" of a and b for more thorough testing.
927
+ S2LatLngRect a2(a.lat(), a.lng().Complement());
928
+ S2LatLngRect b2(b.lat(), b.lng().Complement());
929
+
930
+ // Note that "a" and "b" come from the same distribution, so there is no
931
+ // need to test pairs such as (b, a), (b, a2), etc.
932
+ VerifyGetDirectedHausdorffDistance(a, b);
933
+ VerifyGetDirectedHausdorffDistance(a, b2);
934
+ VerifyGetDirectedHausdorffDistance(a2, b);
935
+ VerifyGetDirectedHausdorffDistance(a2, b2);
936
+ }
937
+ }
938
+
939
+ TEST(S2LatLngRect, GetDirectedHausdorffDistanceContained) {
940
+ // Caller rect is contained in callee rect. Should return 0.
941
+ S2LatLngRect a = RectFromDegrees(-10, 20, -5, 90);
942
+ EXPECT_EQ(S1Angle::Radians(0),
943
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-10, 20, -5, 90)));
944
+ EXPECT_EQ(S1Angle::Radians(0),
945
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-10, 19, -5, 91)));
946
+ EXPECT_EQ(S1Angle::Radians(0),
947
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-11, 20, -4, 90)));
948
+ EXPECT_EQ(S1Angle::Radians(0),
949
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-11, 19, -4, 91)));
950
+ }
951
+
952
+ TEST(S2LatLngRect, GetDirectHausdorffDistancePointToRect) {
953
+ // The Hausdorff distance from a point to a rect should be the same as its
954
+ // distance to the rect.
955
+ S2LatLngRect a1 = PointRectFromDegrees(5, 8);
956
+ S2LatLngRect a2 = PointRectFromDegrees(90, 10); // north pole
957
+
958
+ S2LatLngRect b = RectFromDegrees(-85, -50, -80, 10);
959
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
960
+ a1.GetDistance(b).radians());
961
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
962
+ a2.GetDistance(b).radians());
963
+
964
+ b = RectFromDegrees(4, -10, 80, 10);
965
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
966
+ a1.GetDistance(b).radians());
967
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
968
+ a2.GetDistance(b).radians());
969
+
970
+ b = RectFromDegrees(70, 170, 80, -170);
971
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
972
+ a1.GetDistance(b).radians());
973
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
974
+ a2.GetDistance(b).radians());
975
+ }
976
+
977
+ TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToPoint) {
978
+ S2LatLngRect a = RectFromDegrees(1, -8, 10, 20);
979
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(5, 8));
980
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(-6, -100));
981
+ // south pole
982
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(-90, -20));
983
+ // north pole
984
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(90, 0));
985
+ }
986
+
987
+ TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToRectNearPole) {
988
+ // Tests near south pole.
989
+ S2LatLngRect a = RectFromDegrees(-87, 0, -85, 3);
990
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-89, 1, -88, 2));
991
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, 1, -83, 2));
992
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-88, 90, -86, 91));
993
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, -91, -83, -90));
994
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-90, 181, -89, 182));
995
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, 181, -83, 182));
996
+ }
997
+
998
+ TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToRectDegenerateCases) {
999
+ // Rectangles that contain poles.
1000
+ VerifyGetDirectedHausdorffDistance(
1001
+ RectFromDegrees(0, 10, 90, 20), RectFromDegrees(-4, -10, 4, 0));
1002
+ VerifyGetDirectedHausdorffDistance(
1003
+ RectFromDegrees(-4, -10, 4, 0), RectFromDegrees(0, 10, 90, 20));
1004
+
1005
+ // Two rectangles share same or complement longitudinal intervals.
1006
+ S2LatLngRect a = RectFromDegrees(-50, -10, 50, 10);
1007
+ S2LatLngRect b = RectFromDegrees(30, -10, 60, 10);
1008
+ VerifyGetDirectedHausdorffDistance(a, b);
1009
+ S2LatLngRect c(a.lat(), a.lng().Complement());
1010
+ VerifyGetDirectedHausdorffDistance(c, b);
1011
+
1012
+ // rectangle a touches b_opposite_lng.
1013
+ VerifyGetDirectedHausdorffDistance(
1014
+ RectFromDegrees(10, 170, 30, 180), RectFromDegrees(-50, -10, 50, 10));
1015
+ VerifyGetDirectedHausdorffDistance(
1016
+ RectFromDegrees(10, -180, 30, -170), RectFromDegrees(-50, -10, 50, 10));
1017
+
1018
+ // rectangle b's Voronoi diagram is degenerate (lng interval spans 180
1019
+ // degrees), and a touches the degenerate Voronoi vertex.
1020
+ VerifyGetDirectedHausdorffDistance(
1021
+ RectFromDegrees(-30, 170, 30, 180), RectFromDegrees(-10, -90, 10, 90));
1022
+ VerifyGetDirectedHausdorffDistance(
1023
+ RectFromDegrees(-30, -180, 30, -170), RectFromDegrees(-10, -90, 10, 90));
1024
+
1025
+ // rectangle a touches a voronoi vertex of rectangle b.
1026
+ VerifyGetDirectedHausdorffDistance(
1027
+ RectFromDegrees(-20, 105, 20, 110), RectFromDegrees(-30, 5, 30, 15));
1028
+ VerifyGetDirectedHausdorffDistance(
1029
+ RectFromDegrees(-20, 95, 20, 105), RectFromDegrees(-30, 5, 30, 15));
1030
+ }