@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,727 @@
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
+ #include "s2/s2latlng_rect.h"
19
+
20
+ #include <algorithm>
21
+ #include <cmath>
22
+ #include <iosfwd>
23
+ #include <iostream>
24
+
25
+ #include "s2/base/logging.h"
26
+ #include "s2/util/coding/coder.h"
27
+ #include "s2/s2cap.h"
28
+ #include "s2/s2cell.h"
29
+ #include "s2/s2debug.h"
30
+ #include "s2/s2edge_crossings.h"
31
+ #include "s2/s2edge_distances.h"
32
+ #include "s2/s2pointutil.h"
33
+
34
+ using std::fabs;
35
+ using std::max;
36
+ using std::min;
37
+
38
+ static const unsigned char kCurrentLosslessEncodingVersionNumber = 1;
39
+
40
+ S2LatLngRect S2LatLngRect::FromCenterSize(const S2LatLng& center,
41
+ const S2LatLng& size) {
42
+ return FromPoint(center).Expanded(0.5 * size);
43
+ }
44
+
45
+ S2LatLngRect S2LatLngRect::FromPoint(const S2LatLng& p) {
46
+ S2_DLOG_IF(ERROR, !p.is_valid())
47
+ << "Invalid S2LatLng in S2LatLngRect::GetDistance: " << p;
48
+
49
+ return S2LatLngRect(p, p);
50
+ }
51
+
52
+ S2LatLngRect S2LatLngRect::FromPointPair(const S2LatLng& p1,
53
+ const S2LatLng& p2) {
54
+ S2_DLOG_IF(ERROR, !p1.is_valid())
55
+ << "Invalid S2LatLng in S2LatLngRect::FromPointPair: " << p1;
56
+
57
+ S2_DLOG_IF(ERROR, !p2.is_valid())
58
+ << "Invalid S2LatLng in S2LatLngRect::FromPointPair: " << p2;
59
+
60
+ return S2LatLngRect(R1Interval::FromPointPair(p1.lat().radians(),
61
+ p2.lat().radians()),
62
+ S1Interval::FromPointPair(p1.lng().radians(),
63
+ p2.lng().radians()));
64
+ }
65
+
66
+ S2LatLngRect* S2LatLngRect::Clone() const {
67
+ return new S2LatLngRect(*this);
68
+ }
69
+
70
+ S2LatLng S2LatLngRect::GetVertex(int k) const {
71
+ // Twiddle bits to return the points in CCW order (lower left, lower right,
72
+ // upper right, upper left).
73
+ int i = (k >> 1) & 1;
74
+ return S2LatLng::FromRadians(lat_[i], lng_[i ^ (k & 1)]);
75
+ }
76
+
77
+ S2LatLng S2LatLngRect::GetCenter() const {
78
+ return S2LatLng::FromRadians(lat_.GetCenter(), lng_.GetCenter());
79
+ }
80
+
81
+ S2LatLng S2LatLngRect::GetSize() const {
82
+ return S2LatLng::FromRadians(lat_.GetLength(), lng_.GetLength());
83
+ }
84
+
85
+ double S2LatLngRect::Area() const {
86
+ if (is_empty()) return 0.0;
87
+ // This is the size difference of the two spherical caps, multiplied by
88
+ // the longitude ratio.
89
+ return lng().GetLength() * (sin(lat_hi()) - sin(lat_lo()));
90
+ }
91
+
92
+ S2Point S2LatLngRect::GetCentroid() const {
93
+ // When a sphere is divided into slices of constant thickness by a set of
94
+ // parallel planes, all slices have the same surface area. This implies
95
+ // that the z-component of the centroid is simply the midpoint of the
96
+ // z-interval spanned by the S2LatLngRect.
97
+ //
98
+ // Similarly, it is easy to see that the (x,y) of the centroid lies in the
99
+ // plane through the midpoint of the rectangle's longitude interval. We
100
+ // only need to determine the distance "d" of this point from the z-axis.
101
+ //
102
+ // Let's restrict our attention to a particular z-value. In this z-plane,
103
+ // the S2LatLngRect is a circular arc. The centroid of this arc lies on a
104
+ // radial line through the midpoint of the arc, and at a distance from the
105
+ // z-axis of
106
+ //
107
+ // r * (sin(alpha) / alpha)
108
+ //
109
+ // where r = sqrt(1-z^2) is the radius of the arc, and "alpha" is half of
110
+ // the arc length (i.e., the arc covers longitudes [-alpha, alpha]).
111
+ //
112
+ // To find the centroid distance from the z-axis for the entire rectangle,
113
+ // we just need to integrate over the z-interval. This gives
114
+ //
115
+ // d = Integrate[sqrt(1-z^2)*sin(alpha)/alpha, z1..z2] / (z2 - z1)
116
+ //
117
+ // where [z1, z2] is the range of z-values covered by the rectangle. This
118
+ // simplifies to
119
+ //
120
+ // d = sin(alpha)/(2*alpha*(z2-z1))*(z2*r2 - z1*r1 + theta2 - theta1)
121
+ //
122
+ // where [theta1, theta2] is the latitude interval, z1=sin(theta1),
123
+ // z2=sin(theta2), r1=cos(theta1), and r2=cos(theta2).
124
+ //
125
+ // Finally, we want to return not the centroid itself, but the centroid
126
+ // scaled by the area of the rectangle. The area of the rectangle is
127
+ //
128
+ // A = 2 * alpha * (z2 - z1)
129
+ //
130
+ // which fortunately appears in the denominator of "d".
131
+
132
+ if (is_empty()) return S2Point();
133
+ double z1 = sin(lat_lo()), z2 = sin(lat_hi());
134
+ double r1 = cos(lat_lo()), r2 = cos(lat_hi());
135
+ double alpha = 0.5 * lng_.GetLength();
136
+ double r = sin(alpha) * (r2 * z2 - r1 * z1 + lat_.GetLength());
137
+ double lng = lng_.GetCenter();
138
+ double z = alpha * (z2 + z1) * (z2 - z1); // scaled by the area
139
+ return S2Point(r * cos(lng), r * sin(lng), z);
140
+ }
141
+
142
+ bool S2LatLngRect::Contains(const S2LatLng& ll) const {
143
+ S2_DLOG_IF(ERROR, !ll.is_valid())
144
+ << "Invalid S2LatLng in S2LatLngRect::Contains: " << ll;
145
+
146
+ return (lat_.Contains(ll.lat().radians()) &&
147
+ lng_.Contains(ll.lng().radians()));
148
+ }
149
+
150
+ bool S2LatLngRect::InteriorContains(const S2Point& p) const {
151
+ return InteriorContains(S2LatLng(p));
152
+ }
153
+
154
+ bool S2LatLngRect::InteriorContains(const S2LatLng& ll) const {
155
+ S2_DLOG_IF(ERROR, !ll.is_valid())
156
+ << "Invalid S2LatLng in S2LatLngRect::InteriorContains: " << ll;
157
+
158
+ return (lat_.InteriorContains(ll.lat().radians()) &&
159
+ lng_.InteriorContains(ll.lng().radians()));
160
+ }
161
+
162
+ bool S2LatLngRect::Contains(const S2LatLngRect& other) const {
163
+ return lat_.Contains(other.lat_) && lng_.Contains(other.lng_);
164
+ }
165
+
166
+ bool S2LatLngRect::InteriorContains(const S2LatLngRect& other) const {
167
+ return (lat_.InteriorContains(other.lat_) &&
168
+ lng_.InteriorContains(other.lng_));
169
+ }
170
+
171
+ bool S2LatLngRect::Intersects(const S2LatLngRect& other) const {
172
+ return lat_.Intersects(other.lat_) && lng_.Intersects(other.lng_);
173
+ }
174
+
175
+ bool S2LatLngRect::InteriorIntersects(const S2LatLngRect& other) const {
176
+ return (lat_.InteriorIntersects(other.lat_) &&
177
+ lng_.InteriorIntersects(other.lng_));
178
+ }
179
+
180
+ bool S2LatLngRect::BoundaryIntersects(const S2Point& v0,
181
+ const S2Point& v1) const {
182
+ if (is_empty()) return false;
183
+ if (!lng_.is_full()) {
184
+ if (IntersectsLngEdge(v0, v1, lat_, lng_.lo())) return true;
185
+ if (IntersectsLngEdge(v0, v1, lat_, lng_.hi())) return true;
186
+ }
187
+ if (lat_.lo() != -M_PI_2 && IntersectsLatEdge(v0, v1, lat_.lo(), lng_)) {
188
+ return true;
189
+ }
190
+ if (lat_.hi() != M_PI_2 && IntersectsLatEdge(v0, v1, lat_.hi(), lng_)) {
191
+ return true;
192
+ }
193
+ return false;
194
+ }
195
+
196
+ void S2LatLngRect::AddPoint(const S2Point& p) {
197
+ AddPoint(S2LatLng(p));
198
+ }
199
+
200
+ void S2LatLngRect::AddPoint(const S2LatLng& ll) {
201
+ S2_DLOG_IF(ERROR, !ll.is_valid())
202
+ << "Invalid S2LatLng in S2LatLngRect::AddPoint: " << ll;
203
+
204
+ lat_.AddPoint(ll.lat().radians());
205
+ lng_.AddPoint(ll.lng().radians());
206
+ }
207
+
208
+ S2LatLngRect S2LatLngRect::Expanded(const S2LatLng& margin) const {
209
+ R1Interval lat = lat_.Expanded(margin.lat().radians());
210
+ S1Interval lng = lng_.Expanded(margin.lng().radians());
211
+ if (lat.is_empty() || lng.is_empty()) return Empty();
212
+ return S2LatLngRect(lat.Intersection(FullLat()), lng);
213
+ }
214
+
215
+ S2LatLngRect S2LatLngRect::PolarClosure() const {
216
+ if (lat_.lo() == -M_PI_2 || lat_.hi() == M_PI_2) {
217
+ return S2LatLngRect(lat_, S1Interval::Full());
218
+ }
219
+ return *this;
220
+ }
221
+
222
+ S2LatLngRect S2LatLngRect::Union(const S2LatLngRect& other) const {
223
+ return S2LatLngRect(lat_.Union(other.lat_),
224
+ lng_.Union(other.lng_));
225
+ }
226
+
227
+ S2LatLngRect S2LatLngRect::Intersection(const S2LatLngRect& other) const {
228
+ R1Interval lat = lat_.Intersection(other.lat_);
229
+ S1Interval lng = lng_.Intersection(other.lng_);
230
+ if (lat.is_empty() || lng.is_empty()) {
231
+ // The lat/lng ranges must either be both empty or both non-empty.
232
+ return Empty();
233
+ }
234
+ return S2LatLngRect(lat, lng);
235
+ }
236
+
237
+ S2LatLngRect S2LatLngRect::ExpandedByDistance(S1Angle distance) const {
238
+ if (distance >= S1Angle::Zero()) {
239
+ // The most straightforward approach is to build a cap centered on each
240
+ // vertex and take the union of all the bounding rectangles (including the
241
+ // original rectangle; this is necessary for very large rectangles).
242
+
243
+ // TODO(ericv): Update this code to use an algorithm like the one below.
244
+ S1ChordAngle radius(distance);
245
+ S2LatLngRect r = *this;
246
+ for (int k = 0; k < 4; ++k) {
247
+ r = r.Union(S2Cap(GetVertex(k).ToPoint(), radius).GetRectBound());
248
+ }
249
+ return r;
250
+ } else {
251
+ // Shrink the latitude interval unless the latitude interval contains a pole
252
+ // and the longitude interval is full, in which case the rectangle has no
253
+ // boundary at that pole.
254
+ R1Interval lat_result(
255
+ lat().lo() <= FullLat().lo() && lng().is_full() ?
256
+ FullLat().lo() : lat().lo() - distance.radians(),
257
+ lat().hi() >= FullLat().hi() && lng().is_full() ?
258
+ FullLat().hi() : lat().hi() + distance.radians());
259
+ if (lat_result.is_empty()) {
260
+ return S2LatLngRect::Empty();
261
+ }
262
+
263
+ // Maximum absolute value of a latitude in lat_result. At this latitude,
264
+ // the cap occupies the largest longitude interval.
265
+ double max_abs_lat = max(-lat_result.lo(), lat_result.hi());
266
+
267
+ // Compute the largest longitude interval that the cap occupies. We use the
268
+ // law of sines for spherical triangles. For the details, see the comment in
269
+ // S2Cap::GetRectBound().
270
+ //
271
+ // When sin_a >= sin_c, the cap covers all the latitude.
272
+ double sin_a = sin(-distance.radians());
273
+ double sin_c = cos(max_abs_lat);
274
+ double max_lng_margin = sin_a < sin_c ? asin(sin_a / sin_c) : M_PI_2;
275
+
276
+ S1Interval lng_result = lng().Expanded(-max_lng_margin);
277
+ if (lng_result.is_empty()) {
278
+ return S2LatLngRect::Empty();
279
+ }
280
+ return S2LatLngRect(lat_result, lng_result);
281
+ }
282
+ }
283
+
284
+ S2Cap S2LatLngRect::GetCapBound() const {
285
+ // We consider two possible bounding caps, one whose axis passes
286
+ // through the center of the lat-long rectangle and one whose axis
287
+ // is the north or south pole. We return the smaller of the two caps.
288
+
289
+ if (is_empty()) return S2Cap::Empty();
290
+
291
+ double pole_z, pole_angle;
292
+ if (lat_.lo() + lat_.hi() < 0) {
293
+ // South pole axis yields smaller cap.
294
+ pole_z = -1;
295
+ pole_angle = M_PI_2 + lat_.hi();
296
+ } else {
297
+ pole_z = 1;
298
+ pole_angle = M_PI_2 - lat_.lo();
299
+ }
300
+ S2Cap pole_cap(S2Point(0, 0, pole_z), S1Angle::Radians(pole_angle));
301
+
302
+ // For bounding rectangles that span 180 degrees or less in longitude, the
303
+ // maximum cap size is achieved at one of the rectangle vertices. For
304
+ // rectangles that are larger than 180 degrees, we punt and always return a
305
+ // bounding cap centered at one of the two poles.
306
+ double lng_span = lng_.hi() - lng_.lo();
307
+ if (remainder(lng_span, 2 * M_PI) >= 0 && lng_span < 2 * M_PI) {
308
+ S2Cap mid_cap(GetCenter().ToPoint(), S1Angle::Radians(0));
309
+ for (int k = 0; k < 4; ++k) {
310
+ mid_cap.AddPoint(GetVertex(k).ToPoint());
311
+ }
312
+ if (mid_cap.height() < pole_cap.height())
313
+ return mid_cap;
314
+ }
315
+ return pole_cap;
316
+ }
317
+
318
+ S2LatLngRect S2LatLngRect::GetRectBound() const {
319
+ return *this;
320
+ }
321
+
322
+ bool S2LatLngRect::Contains(const S2Cell& cell) const {
323
+ // A latitude-longitude rectangle contains a cell if and only if it contains
324
+ // the cell's bounding rectangle. This test is exact from a mathematical
325
+ // point of view, assuming that the bounds returned by S2Cell::GetRectBound()
326
+ // are tight. However, note that there can be a loss of precision when
327
+ // converting between representations -- for example, if an S2Cell is
328
+ // converted to a polygon, the polygon's bounding rectangle may not contain
329
+ // the cell's bounding rectangle. This has some slightly unexpected side
330
+ // effects; for instance, if one creates an S2Polygon from an S2Cell, the
331
+ // polygon will contain the cell, but the polygon's bounding box will not.
332
+ return Contains(cell.GetRectBound());
333
+ }
334
+
335
+ bool S2LatLngRect::MayIntersect(const S2Cell& cell) const {
336
+ // This test is cheap but is NOT exact (see s2latlng_rect.h).
337
+ return Intersects(cell.GetRectBound());
338
+ }
339
+
340
+ void S2LatLngRect::Encode(Encoder* encoder) const {
341
+ encoder->Ensure(40); // sufficient
342
+
343
+ encoder->put8(kCurrentLosslessEncodingVersionNumber);
344
+ encoder->putdouble(lat_.lo());
345
+ encoder->putdouble(lat_.hi());
346
+ encoder->putdouble(lng_.lo());
347
+ encoder->putdouble(lng_.hi());
348
+
349
+ S2_DCHECK_GE(encoder->avail(), 0);
350
+ }
351
+
352
+ bool S2LatLngRect::Decode(Decoder* decoder) {
353
+ if (decoder->avail() < sizeof(unsigned char) + 4 * sizeof(double))
354
+ return false;
355
+ unsigned char version = decoder->get8();
356
+ if (version > kCurrentLosslessEncodingVersionNumber) return false;
357
+
358
+ double lat_lo = decoder->getdouble();
359
+ double lat_hi = decoder->getdouble();
360
+ lat_ = R1Interval(lat_lo, lat_hi);
361
+ double lng_lo = decoder->getdouble();
362
+ double lng_hi = decoder->getdouble();
363
+ lng_ = S1Interval(lng_lo, lng_hi);
364
+
365
+ if (!is_valid()) {
366
+ S2_DLOG_IF(ERROR, FLAGS_s2debug)
367
+ << "Invalid result in S2LatLngRect::Decode: " << *this;
368
+ return false;
369
+ }
370
+
371
+ return true;
372
+ }
373
+
374
+ bool S2LatLngRect::IntersectsLngEdge(const S2Point& a, const S2Point& b,
375
+ const R1Interval& lat, double lng) {
376
+ // Return true if the segment AB intersects the given edge of constant
377
+ // longitude. The nice thing about edges of constant longitude is that
378
+ // they are straight lines on the sphere (geodesics).
379
+
380
+ return S2::CrossingSign(
381
+ a, b, S2LatLng::FromRadians(lat.lo(), lng).ToPoint(),
382
+ S2LatLng::FromRadians(lat.hi(), lng).ToPoint()) > 0;
383
+ }
384
+
385
+ bool S2LatLngRect::IntersectsLatEdge(const S2Point& a, const S2Point& b,
386
+ double lat, const S1Interval& lng) {
387
+ // Return true if the segment AB intersects the given edge of constant
388
+ // latitude. Unfortunately, lines of constant latitude are curves on
389
+ // the sphere. They can intersect a straight edge in 0, 1, or 2 points.
390
+ S2_DCHECK(S2::IsUnitLength(a));
391
+ S2_DCHECK(S2::IsUnitLength(b));
392
+
393
+ // First, compute the normal to the plane AB that points vaguely north.
394
+ Vector3_d z = S2::RobustCrossProd(a, b).Normalize();
395
+ if (z[2] < 0) z = -z;
396
+
397
+ // Extend this to an orthonormal frame (x,y,z) where x is the direction
398
+ // where the great circle through AB achieves its maximium latitude.
399
+ Vector3_d y = S2::RobustCrossProd(z, S2Point(0, 0, 1)).Normalize();
400
+ Vector3_d x = y.CrossProd(z);
401
+ S2_DCHECK(S2::IsUnitLength(x));
402
+ S2_DCHECK_GE(x[2], 0);
403
+
404
+ // Compute the angle "theta" from the x-axis (in the x-y plane defined
405
+ // above) where the great circle intersects the given line of latitude.
406
+ double sin_lat = sin(lat);
407
+ if (fabs(sin_lat) >= x[2]) {
408
+ return false; // The great circle does not reach the given latitude.
409
+ }
410
+ S2_DCHECK_GT(x[2], 0);
411
+ double cos_theta = sin_lat / x[2];
412
+ double sin_theta = sqrt(1 - cos_theta * cos_theta);
413
+ double theta = atan2(sin_theta, cos_theta);
414
+
415
+ // The candidate intersection points are located +/- theta in the x-y
416
+ // plane. For an intersection to be valid, we need to check that the
417
+ // intersection point is contained in the interior of the edge AB and
418
+ // also that it is contained within the given longitude interval "lng".
419
+
420
+ // Compute the range of theta values spanned by the edge AB.
421
+ S1Interval ab_theta = S1Interval::FromPointPair(
422
+ atan2(a.DotProd(y), a.DotProd(x)),
423
+ atan2(b.DotProd(y), b.DotProd(x)));
424
+
425
+ if (ab_theta.Contains(theta)) {
426
+ // Check if the intersection point is also in the given "lng" interval.
427
+ S2Point isect = x * cos_theta + y * sin_theta;
428
+ if (lng.Contains(atan2(isect[1], isect[0]))) return true;
429
+ }
430
+ if (ab_theta.Contains(-theta)) {
431
+ // Check if the intersection point is also in the given "lng" interval.
432
+ S2Point isect = x * cos_theta - y * sin_theta;
433
+ if (lng.Contains(atan2(isect[1], isect[0]))) return true;
434
+ }
435
+ return false;
436
+ }
437
+
438
+ bool S2LatLngRect::Intersects(const S2Cell& cell) const {
439
+ // First we eliminate the cases where one region completely contains the
440
+ // other. Once these are disposed of, then the regions will intersect
441
+ // if and only if their boundaries intersect.
442
+
443
+ if (is_empty()) return false;
444
+ if (Contains(cell.GetCenterRaw())) return true;
445
+ if (cell.Contains(GetCenter().ToPoint())) return true;
446
+
447
+ // Quick rejection test (not required for correctness).
448
+ if (!Intersects(cell.GetRectBound())) return false;
449
+
450
+ // Precompute the cell vertices as points and latitude-longitudes. We also
451
+ // check whether the S2Cell contains any corner of the rectangle, or
452
+ // vice-versa, since the edge-crossing tests only check the edge interiors.
453
+
454
+ S2Point cell_v[4];
455
+ S2LatLng cell_ll[4];
456
+ for (int i = 0; i < 4; ++i) {
457
+ cell_v[i] = cell.GetVertex(i); // Must be normalized.
458
+ cell_ll[i] = S2LatLng(cell_v[i]);
459
+ if (Contains(cell_ll[i])) return true;
460
+ if (cell.Contains(GetVertex(i).ToPoint())) return true;
461
+ }
462
+
463
+ // Now check whether the boundaries intersect. Unfortunately, a
464
+ // latitude-longitude rectangle does not have straight edges -- two edges
465
+ // are curved, and at least one of them is concave.
466
+
467
+ for (int i = 0; i < 4; ++i) {
468
+ S1Interval edge_lng = S1Interval::FromPointPair(
469
+ cell_ll[i].lng().radians(), cell_ll[(i+1)&3].lng().radians());
470
+ if (!lng_.Intersects(edge_lng)) continue;
471
+
472
+ const S2Point& a = cell_v[i];
473
+ const S2Point& b = cell_v[(i+1)&3];
474
+ if (edge_lng.Contains(lng_.lo())) {
475
+ if (IntersectsLngEdge(a, b, lat_, lng_.lo())) return true;
476
+ }
477
+ if (edge_lng.Contains(lng_.hi())) {
478
+ if (IntersectsLngEdge(a, b, lat_, lng_.hi())) return true;
479
+ }
480
+ if (IntersectsLatEdge(a, b, lat_.lo(), lng_)) return true;
481
+ if (IntersectsLatEdge(a, b, lat_.hi(), lng_)) return true;
482
+ }
483
+ return false;
484
+ }
485
+
486
+ S1Angle S2LatLngRect::GetDistance(const S2LatLngRect& other) const {
487
+ const S2LatLngRect& a = *this;
488
+ const S2LatLngRect& b = other;
489
+ S2_DCHECK(!a.is_empty());
490
+ S2_DCHECK(!b.is_empty());
491
+
492
+ // First, handle the trivial cases where the longitude intervals overlap.
493
+ if (a.lng().Intersects(b.lng())) {
494
+ if (a.lat().Intersects(b.lat()))
495
+ return S1Angle::Radians(0); // Intersection between a and b.
496
+
497
+ // We found an overlap in the longitude interval, but not in the latitude
498
+ // interval. This means the shortest path travels along some line of
499
+ // longitude connecting the high-latitude of the lower rect with the
500
+ // low-latitude of the higher rect.
501
+ S1Angle lo, hi;
502
+ if (a.lat().lo() > b.lat().hi()) {
503
+ lo = b.lat_hi();
504
+ hi = a.lat_lo();
505
+ } else {
506
+ lo = a.lat_hi();
507
+ hi = b.lat_lo();
508
+ }
509
+ return hi - lo;
510
+ }
511
+
512
+ // The longitude intervals don't overlap. In this case, the closest points
513
+ // occur somewhere on the pair of longitudinal edges which are nearest in
514
+ // longitude-space.
515
+ S1Angle a_lng, b_lng;
516
+ S1Interval lo_hi = S1Interval::FromPointPair(a.lng().lo(), b.lng().hi());
517
+ S1Interval hi_lo = S1Interval::FromPointPair(a.lng().hi(), b.lng().lo());
518
+ if (lo_hi.GetLength() < hi_lo.GetLength()) {
519
+ a_lng = a.lng_lo();
520
+ b_lng = b.lng_hi();
521
+ } else {
522
+ a_lng = a.lng_hi();
523
+ b_lng = b.lng_lo();
524
+ }
525
+
526
+ // The shortest distance between the two longitudinal segments will include at
527
+ // least one segment endpoint. We could probably narrow this down further to a
528
+ // single point-edge distance by comparing the relative latitudes of the
529
+ // endpoints, but for the sake of clarity, we'll do all four point-edge
530
+ // distance tests.
531
+ S2Point a_lo = S2LatLng(a.lat_lo(), a_lng).ToPoint();
532
+ S2Point a_hi = S2LatLng(a.lat_hi(), a_lng).ToPoint();
533
+ S2Point b_lo = S2LatLng(b.lat_lo(), b_lng).ToPoint();
534
+ S2Point b_hi = S2LatLng(b.lat_hi(), b_lng).ToPoint();
535
+ return min(S2::GetDistance(a_lo, b_lo, b_hi),
536
+ min(S2::GetDistance(a_hi, b_lo, b_hi),
537
+ min(S2::GetDistance(b_lo, a_lo, a_hi),
538
+ S2::GetDistance(b_hi, a_lo, a_hi))));
539
+ }
540
+
541
+ S1Angle S2LatLngRect::GetDistance(const S2LatLng& p) const {
542
+ // The algorithm here is the same as in GetDistance(S2LatLngRect), only
543
+ // with simplified calculations.
544
+ const S2LatLngRect& a = *this;
545
+ S2_DLOG_IF(ERROR, a.is_empty())
546
+ << "Empty S2LatLngRect in S2LatLngRect::GetDistance: " << a;
547
+
548
+ S2_DLOG_IF(ERROR, !p.is_valid())
549
+ << "Invalid S2LatLng in S2LatLngRect::GetDistance: " << p;
550
+
551
+ if (a.lng().Contains(p.lng().radians())) {
552
+ return S1Angle::Radians(max(0.0, max(p.lat().radians() - a.lat().hi(),
553
+ a.lat().lo() - p.lat().radians())));
554
+ }
555
+
556
+ S1Interval interval(a.lng().hi(), a.lng().GetComplementCenter());
557
+ double a_lng;
558
+ if (interval.Contains(p.lng().radians())) {
559
+ a_lng = a.lng().hi();
560
+ } else {
561
+ a_lng = a.lng().lo();
562
+ }
563
+ S2Point lo = S2LatLng::FromRadians(a.lat().lo(), a_lng).ToPoint();
564
+ S2Point hi = S2LatLng::FromRadians(a.lat().hi(), a_lng).ToPoint();
565
+ return S2::GetDistance(p.ToPoint(), lo, hi);
566
+ }
567
+
568
+ S1Angle S2LatLngRect::GetHausdorffDistance(const S2LatLngRect& other) const {
569
+ return max(GetDirectedHausdorffDistance(other),
570
+ other.GetDirectedHausdorffDistance(*this));
571
+ }
572
+
573
+ S1Angle S2LatLngRect::GetDirectedHausdorffDistance(
574
+ const S2LatLngRect& other) const {
575
+ if (is_empty()) {
576
+ return S1Angle::Radians(0);
577
+ }
578
+ if (other.is_empty()) {
579
+ return S1Angle::Radians(M_PI); // maximum possible distance on S2
580
+ }
581
+
582
+ double lng_distance = lng().GetDirectedHausdorffDistance(other.lng());
583
+ S2_DCHECK_GE(lng_distance, 0);
584
+ return GetDirectedHausdorffDistance(lng_distance, lat(), other.lat());
585
+ }
586
+
587
+ // Return the directed Hausdorff distance from one longitudinal edge spanning
588
+ // latitude range 'a_lat' to the other longitudinal edge spanning latitude
589
+ // range 'b_lat', with their longitudinal difference given by 'lng_diff'.
590
+ S1Angle S2LatLngRect::GetDirectedHausdorffDistance(
591
+ double lng_diff, const R1Interval& a, const R1Interval& b) {
592
+ // By symmetry, we can assume a's longtitude is 0 and b's longtitude is
593
+ // lng_diff. Call b's two endpoints b_lo and b_hi. Let H be the hemisphere
594
+ // containing a and delimited by the longitude line of b. The Voronoi diagram
595
+ // of b on H has three edges (portions of great circles) all orthogonal to b
596
+ // and meeting at b_lo cross b_hi.
597
+ // E1: (b_lo, b_lo cross b_hi)
598
+ // E2: (b_hi, b_lo cross b_hi)
599
+ // E3: (-b_mid, b_lo cross b_hi), where b_mid is the midpoint of b
600
+ //
601
+ // They subdivide H into three Voronoi regions. Depending on how longitude 0
602
+ // (which contains edge a) intersects these regions, we distinguish two cases:
603
+ // Case 1: it intersects three regions. This occurs when lng_diff <= M_PI_2.
604
+ // Case 2: it intersects only two regions. This occurs when lng_diff > M_PI_2.
605
+ //
606
+ // In the first case, the directed Hausdorff distance to edge b can only be
607
+ // realized by the following points on a:
608
+ // A1: two endpoints of a.
609
+ // A2: intersection of a with the equator, if b also intersects the equator.
610
+ //
611
+ // In the second case, the directed Hausdorff distance to edge b can only be
612
+ // realized by the following points on a:
613
+ // B1: two endpoints of a.
614
+ // B2: intersection of a with E3
615
+ // B3: farthest point from b_lo to the interior of D, and farthest point from
616
+ // b_hi to the interior of U, if any, where D (resp. U) is the portion
617
+ // of edge a below (resp. above) the intersection point from B2.
618
+
619
+ S2_DCHECK_GE(lng_diff, 0);
620
+ S2_DCHECK_LE(lng_diff, M_PI);
621
+
622
+ if (lng_diff == 0) {
623
+ return S1Angle::Radians(a.GetDirectedHausdorffDistance(b));
624
+ }
625
+
626
+ // Assumed longtitude of b.
627
+ double b_lng = lng_diff;
628
+ // Two endpoints of b.
629
+ S2Point b_lo = S2LatLng::FromRadians(b.lo(), b_lng).ToPoint();
630
+ S2Point b_hi = S2LatLng::FromRadians(b.hi(), b_lng).ToPoint();
631
+
632
+ // Handling of each case outlined at the top of the function starts here.
633
+ // This is initialized a few lines below.
634
+ S1Angle max_distance;
635
+
636
+ // Cases A1 and B1.
637
+ S2Point a_lo = S2LatLng::FromRadians(a.lo(), 0).ToPoint();
638
+ S2Point a_hi = S2LatLng::FromRadians(a.hi(), 0).ToPoint();
639
+ max_distance = S2::GetDistance(a_lo, b_lo, b_hi);
640
+ max_distance = max(
641
+ max_distance, S2::GetDistance(a_hi, b_lo, b_hi));
642
+
643
+ if (lng_diff <= M_PI_2) {
644
+ // Case A2.
645
+ if (a.Contains(0) && b.Contains(0)) {
646
+ max_distance = max(max_distance, S1Angle::Radians(lng_diff));
647
+ }
648
+ } else {
649
+ // Case B2.
650
+ const S2Point& p = GetBisectorIntersection(b, b_lng);
651
+ double p_lat = S2LatLng::Latitude(p).radians();
652
+ if (a.Contains(p_lat)) {
653
+ max_distance = max(max_distance, S1Angle(p, b_lo));
654
+ }
655
+
656
+ // Case B3.
657
+ if (p_lat > a.lo()) {
658
+ max_distance = max(max_distance, GetInteriorMaxDistance(
659
+ R1Interval(a.lo(), min(p_lat, a.hi())), b_lo));
660
+ }
661
+ if (p_lat < a.hi()) {
662
+ max_distance = max(max_distance, GetInteriorMaxDistance(
663
+ R1Interval(max(p_lat, a.lo()), a.hi()), b_hi));
664
+ }
665
+ }
666
+
667
+ return max_distance;
668
+ }
669
+
670
+ // Return the intersection of longitude 0 with the bisector of an edge
671
+ // on longitude 'lng' and spanning latitude range 'lat'.
672
+ S2Point S2LatLngRect::GetBisectorIntersection(const R1Interval& lat,
673
+ double lng) {
674
+ lng = fabs(lng);
675
+ double lat_center = lat.GetCenter();
676
+ // A vector orthogonal to the bisector of the given longitudinal edge.
677
+ S2LatLng ortho_bisector;
678
+ if (lat_center >= 0) {
679
+ ortho_bisector = S2LatLng::FromRadians(lat_center - M_PI_2, lng);
680
+ } else {
681
+ ortho_bisector = S2LatLng::FromRadians(-lat_center - M_PI_2, lng - M_PI);
682
+ }
683
+ // A vector orthogonal to longitude 0.
684
+ static const S2Point ortho_lng = S2Point(0, -1, 0);
685
+ return S2::RobustCrossProd(ortho_lng, ortho_bisector.ToPoint());
686
+ }
687
+
688
+ // Return max distance from a point b to the segment spanning latitude range
689
+ // a_lat on longitude 0, if the max occurs in the interior of a_lat. Otherwise
690
+ // return -1.
691
+ S1Angle S2LatLngRect::GetInteriorMaxDistance(const R1Interval& a_lat,
692
+ const S2Point& b) {
693
+ // Longitude 0 is in the y=0 plane. b.x() >= 0 implies that the maximum
694
+ // does not occur in the interior of a_lat.
695
+ if (a_lat.is_empty() || b.x() >= 0) return S1Angle::Radians(-1);
696
+
697
+ // Project b to the y=0 plane. The antipodal of the normalized projection is
698
+ // the point at which the maxium distance from b occurs, if it is contained
699
+ // in a_lat.
700
+ S2Point intersection_point = S2Point(-b.x(), 0, -b.z()).Normalize();
701
+ if (a_lat.InteriorContains(
702
+ S2LatLng::Latitude(intersection_point).radians())) {
703
+ return S1Angle(b, intersection_point);
704
+ } else {
705
+ return S1Angle::Radians(-1);
706
+ }
707
+ }
708
+
709
+ bool S2LatLngRect::Contains(const S2Point& p) const {
710
+ return Contains(S2LatLng(p));
711
+ }
712
+
713
+ bool S2LatLngRect::ApproxEquals(const S2LatLngRect& other,
714
+ S1Angle max_error) const {
715
+ return (lat_.ApproxEquals(other.lat_, max_error.radians()) &&
716
+ lng_.ApproxEquals(other.lng_, max_error.radians()));
717
+ }
718
+
719
+ bool S2LatLngRect::ApproxEquals(const S2LatLngRect& other,
720
+ const S2LatLng& max_error) const {
721
+ return (lat_.ApproxEquals(other.lat_, max_error.lat().radians()) &&
722
+ lng_.ApproxEquals(other.lng_, max_error.lng().radians()));
723
+ }
724
+
725
+ std::ostream& operator<<(std::ostream& os, const S2LatLngRect& r) {
726
+ return os << "[Lo" << r.lo() << ", Hi" << r.hi() << "]";
727
+ }