@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.
- package/.circleci/config.yml +45 -0
- package/.dockerignore +1 -0
- package/.gitmodules +3 -0
- package/CHANGELOG.md +33 -0
- package/LICENSE +201 -0
- package/README.md +147 -0
- package/binding.gyp +170 -0
- package/docker/Dockerfile.node20.test +8 -0
- package/docker/Dockerfile.node22.test +8 -0
- package/docker/Dockerfile.node24.test +8 -0
- package/index.d.ts +117 -0
- package/index.js +6 -0
- package/jest.config.js +184 -0
- package/package.json +43 -0
- package/publish-linux.sh +18 -0
- package/publish-osx.sh +19 -0
- package/src/builder.cc +84 -0
- package/src/builder.h +29 -0
- package/src/cell.cc +71 -0
- package/src/cell.h +26 -0
- package/src/cell_id.cc +210 -0
- package/src/cell_id.h +44 -0
- package/src/cell_union.cc +237 -0
- package/src/cell_union.h +34 -0
- package/src/earth.cc +185 -0
- package/src/earth.h +33 -0
- package/src/latlng.cc +132 -0
- package/src/latlng.h +28 -0
- package/src/loop.cc +51 -0
- package/src/loop.h +21 -0
- package/src/point.cc +69 -0
- package/src/point.h +23 -0
- package/src/polygon.cc +36 -0
- package/src/polygon.h +20 -0
- package/src/polyline.cc +186 -0
- package/src/polyline.h +34 -0
- package/src/region_coverer.cc +450 -0
- package/src/region_coverer.h +56 -0
- package/src/s2.cc +27 -0
- package/test/Cell.test.js +37 -0
- package/test/CellId.test.js +135 -0
- package/test/CellUnion.test.js +150 -0
- package/test/Earth.test.js +62 -0
- package/test/LatLng.test.js +45 -0
- package/test/Point.test.js +14 -0
- package/test/Polyline.test.js +78 -0
- package/test/RegionCoverer.test.js +301 -0
- package/test.sh +16 -0
- package/third_party/s2geometry/.travis.yml +163 -0
- package/third_party/s2geometry/AUTHORS +13 -0
- package/third_party/s2geometry/CONTRIBUTING.md +65 -0
- package/third_party/s2geometry/CONTRIBUTORS +30 -0
- package/third_party/s2geometry/LICENSE +202 -0
- package/third_party/s2geometry/NOTICE +5 -0
- package/third_party/s2geometry/README.md +127 -0
- package/third_party/s2geometry/doc/examples/point_index.cc +44 -0
- package/third_party/s2geometry/doc/examples/term_index.cc +99 -0
- package/third_party/s2geometry/doc/examples/term_index.py +101 -0
- package/third_party/s2geometry/src/python/coder.i +125 -0
- package/third_party/s2geometry/src/python/pywraps2_test.py +786 -0
- package/third_party/s2geometry/src/python/s2.i +37 -0
- package/third_party/s2geometry/src/python/s2_common.i +756 -0
- package/third_party/s2geometry/src/s2/_fp_contract_off.h +60 -0
- package/third_party/s2geometry/src/s2/base/casts.h +318 -0
- package/third_party/s2geometry/src/s2/base/commandlineflags.h +67 -0
- package/third_party/s2geometry/src/s2/base/integral_types.h +31 -0
- package/third_party/s2geometry/src/s2/base/log_severity.h +40 -0
- package/third_party/s2geometry/src/s2/base/logging.h +173 -0
- package/third_party/s2geometry/src/s2/base/mutex.h +61 -0
- package/third_party/s2geometry/src/s2/base/port.h +999 -0
- package/third_party/s2geometry/src/s2/base/spinlock.h +60 -0
- package/third_party/s2geometry/src/s2/base/stringprintf.cc +107 -0
- package/third_party/s2geometry/src/s2/base/stringprintf.h +53 -0
- package/third_party/s2geometry/src/s2/base/strtoint.cc +65 -0
- package/third_party/s2geometry/src/s2/base/strtoint.h +106 -0
- package/third_party/s2geometry/src/s2/base/timer.h +50 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.cc +164 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.h +110 -0
- package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector_test.cc +232 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector.cc +838 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector.h +140 -0
- package/third_party/s2geometry/src/s2/encoded_s2point_vector_test.cc +344 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index.cc +181 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index.h +276 -0
- package/third_party/s2geometry/src/s2/encoded_s2shape_index_test.cc +244 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector.cc +66 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector.h +164 -0
- package/third_party/s2geometry/src/s2/encoded_string_vector_test.cc +69 -0
- package/third_party/s2geometry/src/s2/encoded_uint_vector.h +299 -0
- package/third_party/s2geometry/src/s2/encoded_uint_vector_test.cc +124 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon.cc +81 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon.h +199 -0
- package/third_party/s2geometry/src/s2/id_set_lexicon_test.cc +70 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index.cc +1585 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index.h +600 -0
- package/third_party/s2geometry/src/s2/mutable_s2shape_index_test.cc +589 -0
- package/third_party/s2geometry/src/s2/r1interval.h +220 -0
- package/third_party/s2geometry/src/s2/r1interval_test.cc +185 -0
- package/third_party/s2geometry/src/s2/r2.h +26 -0
- package/third_party/s2geometry/src/s2/r2rect.cc +93 -0
- package/third_party/s2geometry/src/s2/r2rect.h +234 -0
- package/third_party/s2geometry/src/s2/r2rect_test.cc +228 -0
- package/third_party/s2geometry/src/s2/s1angle.cc +54 -0
- package/third_party/s2geometry/src/s2/s1angle.h +336 -0
- package/third_party/s2geometry/src/s2/s1angle_test.cc +185 -0
- package/third_party/s2geometry/src/s2/s1chord_angle.cc +159 -0
- package/third_party/s2geometry/src/s2/s1chord_angle.h +369 -0
- package/third_party/s2geometry/src/s2/s1chord_angle_test.cc +207 -0
- package/third_party/s2geometry/src/s2/s1interval.cc +296 -0
- package/third_party/s2geometry/src/s2/s1interval.h +266 -0
- package/third_party/s2geometry/src/s2/s1interval_test.cc +469 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation.cc +2391 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation.h +501 -0
- package/third_party/s2geometry/src/s2/s2boolean_operation_test.cc +1400 -0
- package/third_party/s2geometry/src/s2/s2builder.cc +1828 -0
- package/third_party/s2geometry/src/s2/s2builder.h +1057 -0
- package/third_party/s2geometry/src/s2/s2builder_graph.cc +1084 -0
- package/third_party/s2geometry/src/s2/s2builder_graph.h +799 -0
- package/third_party/s2geometry/src/s2/s2builder_graph_test.cc +462 -0
- package/third_party/s2geometry/src/s2/s2builder_layer.h +50 -0
- package/third_party/s2geometry/src/s2/s2builder_test.cc +1329 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.cc +313 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.h +221 -0
- package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer_test.cc +261 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.cc +392 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.h +86 -0
- package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies_test.cc +182 -0
- package/third_party/s2geometry/src/s2/s2builderutil_graph_shape.h +57 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.cc +212 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.h +218 -0
- package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.cc +74 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.h +122 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer_test.cc +167 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.cc +191 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.h +211 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.cc +105 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.h +174 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer_test.cc +220 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.cc +98 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.h +292 -0
- package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer_test.cc +233 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.cc +354 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.h +239 -0
- package/third_party/s2geometry/src/s2/s2builderutil_snap_functions_test.cc +716 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing.cc +37 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing.h +100 -0
- package/third_party/s2geometry/src/s2/s2builderutil_testing_test.cc +85 -0
- package/third_party/s2geometry/src/s2/s2cap.cc +347 -0
- package/third_party/s2geometry/src/s2/s2cap.h +286 -0
- package/third_party/s2geometry/src/s2/s2cap_test.cc +379 -0
- package/third_party/s2geometry/src/s2/s2cell.cc +552 -0
- package/third_party/s2geometry/src/s2/s2cell.h +249 -0
- package/third_party/s2geometry/src/s2/s2cell_id.cc +619 -0
- package/third_party/s2geometry/src/s2/s2cell_id.h +705 -0
- package/third_party/s2geometry/src/s2/s2cell_id_test.cc +633 -0
- package/third_party/s2geometry/src/s2/s2cell_index.cc +149 -0
- package/third_party/s2geometry/src/s2/s2cell_index.h +660 -0
- package/third_party/s2geometry/src/s2/s2cell_index_test.cc +411 -0
- package/third_party/s2geometry/src/s2/s2cell_test.cc +687 -0
- package/third_party/s2geometry/src/s2/s2cell_union.cc +515 -0
- package/third_party/s2geometry/src/s2/s2cell_union.h +399 -0
- package/third_party/s2geometry/src/s2/s2cell_union_test.cc +598 -0
- package/third_party/s2geometry/src/s2/s2centroids.cc +84 -0
- package/third_party/s2geometry/src/s2/s2centroids.h +87 -0
- package/third_party/s2geometry/src/s2/s2centroids_test.cc +82 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query.cc +123 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query.h +385 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_base.h +841 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_base_test.cc +63 -0
- package/third_party/s2geometry/src/s2/s2closest_cell_query_test.cc +412 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query.cc +106 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query.h +421 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_base.h +946 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_base_test.cc +59 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_test.cc +505 -0
- package/third_party/s2geometry/src/s2/s2closest_edge_query_testing.h +91 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query.cc +66 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query.h +465 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_base.h +767 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_base_test.cc +63 -0
- package/third_party/s2geometry/src/s2/s2closest_point_query_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2contains_point_query.h +328 -0
- package/third_party/s2geometry/src/s2/s2contains_point_query_test.cc +159 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query.cc +39 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query.h +66 -0
- package/third_party/s2geometry/src/s2/s2contains_vertex_query_test.cc +67 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query.cc +198 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query.h +110 -0
- package/third_party/s2geometry/src/s2/s2convex_hull_query_test.cc +208 -0
- package/third_party/s2geometry/src/s2/s2coords.cc +146 -0
- package/third_party/s2geometry/src/s2/s2coords.h +459 -0
- package/third_party/s2geometry/src/s2/s2coords_internal.h +71 -0
- package/third_party/s2geometry/src/s2/s2coords_test.cc +218 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query.cc +380 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query.h +220 -0
- package/third_party/s2geometry/src/s2/s2crossing_edge_query_test.cc +382 -0
- package/third_party/s2geometry/src/s2/s2debug.cc +23 -0
- package/third_party/s2geometry/src/s2/s2debug.h +69 -0
- package/third_party/s2geometry/src/s2/s2distance_target.h +165 -0
- package/third_party/s2geometry/src/s2/s2earth.cc +52 -0
- package/third_party/s2geometry/src/s2/s2earth.h +268 -0
- package/third_party/s2geometry/src/s2/s2earth_test.cc +146 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping.cc +462 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping.h +183 -0
- package/third_party/s2geometry/src/s2/s2edge_clipping_test.cc +335 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser.cc +85 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser.h +343 -0
- package/third_party/s2geometry/src/s2/s2edge_crosser_test.cc +264 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings.cc +515 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings.h +138 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings_internal.h +59 -0
- package/third_party/s2geometry/src/s2/s2edge_crossings_test.cc +246 -0
- package/third_party/s2geometry/src/s2/s2edge_distances.cc +419 -0
- package/third_party/s2geometry/src/s2/s2edge_distances.h +192 -0
- package/third_party/s2geometry/src/s2/s2edge_distances_test.cc +539 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator.cc +276 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator.h +101 -0
- package/third_party/s2geometry/src/s2/s2edge_tessellator_test.cc +492 -0
- package/third_party/s2geometry/src/s2/s2edge_vector_shape.h +85 -0
- package/third_party/s2geometry/src/s2/s2edge_vector_shape_test.cc +66 -0
- package/third_party/s2geometry/src/s2/s2error.cc +29 -0
- package/third_party/s2geometry/src/s2/s2error.h +147 -0
- package/third_party/s2geometry/src/s2/s2error_test.cc +31 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query.cc +117 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query.h +439 -0
- package/third_party/s2geometry/src/s2/s2furthest_edge_query_test.cc +487 -0
- package/third_party/s2geometry/src/s2/s2latlng.cc +90 -0
- package/third_party/s2geometry/src/s2/s2latlng.h +234 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect.cc +727 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect.h +434 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.cc +344 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.h +89 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_bounder_test.cc +306 -0
- package/third_party/s2geometry/src/s2/s2latlng_rect_test.cc +1030 -0
- package/third_party/s2geometry/src/s2/s2latlng_test.cc +165 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape.cc +104 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape.h +153 -0
- package/third_party/s2geometry/src/s2/s2lax_loop_shape_test.cc +101 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape.cc +348 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape.h +183 -0
- package/third_party/s2geometry/src/s2/s2lax_polygon_shape_test.cc +234 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape.cc +118 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape.h +124 -0
- package/third_party/s2geometry/src/s2/s2lax_polyline_shape_test.cc +62 -0
- package/third_party/s2geometry/src/s2/s2loop.cc +1509 -0
- package/third_party/s2geometry/src/s2/s2loop.h +711 -0
- package/third_party/s2geometry/src/s2/s2loop_measures.cc +313 -0
- package/third_party/s2geometry/src/s2/s2loop_measures.h +280 -0
- package/third_party/s2geometry/src/s2/s2loop_measures_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2loop_test.cc +1371 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets.cc +265 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets.h +241 -0
- package/third_party/s2geometry/src/s2/s2max_distance_targets_test.cc +367 -0
- package/third_party/s2geometry/src/s2/s2measures.cc +128 -0
- package/third_party/s2geometry/src/s2/s2measures.h +78 -0
- package/third_party/s2geometry/src/s2/s2measures_test.cc +135 -0
- package/third_party/s2geometry/src/s2/s2metrics.cc +122 -0
- package/third_party/s2geometry/src/s2/s2metrics.h +199 -0
- package/third_party/s2geometry/src/s2/s2metrics_test.cc +127 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets.cc +295 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets.h +273 -0
- package/third_party/s2geometry/src/s2/s2min_distance_targets_test.cc +239 -0
- package/third_party/s2geometry/src/s2/s2padded_cell.cc +162 -0
- package/third_party/s2geometry/src/s2/s2padded_cell.h +108 -0
- package/third_party/s2geometry/src/s2/s2padded_cell_test.cc +138 -0
- package/third_party/s2geometry/src/s2/s2point.h +38 -0
- package/third_party/s2geometry/src/s2/s2point_compression.cc +388 -0
- package/third_party/s2geometry/src/s2/s2point_compression.h +78 -0
- package/third_party/s2geometry/src/s2/s2point_compression_test.cc +305 -0
- package/third_party/s2geometry/src/s2/s2point_index.h +345 -0
- package/third_party/s2geometry/src/s2/s2point_index_test.cc +147 -0
- package/third_party/s2geometry/src/s2/s2point_region.cc +72 -0
- package/third_party/s2geometry/src/s2/s2point_region.h +76 -0
- package/third_party/s2geometry/src/s2/s2point_region_test.cc +100 -0
- package/third_party/s2geometry/src/s2/s2point_span.h +57 -0
- package/third_party/s2geometry/src/s2/s2point_test.cc +47 -0
- package/third_party/s2geometry/src/s2/s2point_vector_shape.h +127 -0
- package/third_party/s2geometry/src/s2/s2point_vector_shape_test.cc +59 -0
- package/third_party/s2geometry/src/s2/s2pointutil.cc +131 -0
- package/third_party/s2geometry/src/s2/s2pointutil.h +138 -0
- package/third_party/s2geometry/src/s2/s2pointutil_test.cc +157 -0
- package/third_party/s2geometry/src/s2/s2polygon.cc +1569 -0
- package/third_party/s2geometry/src/s2/s2polygon.h +934 -0
- package/third_party/s2geometry/src/s2/s2polygon_test.cc +3025 -0
- package/third_party/s2geometry/src/s2/s2polyline.cc +645 -0
- package/third_party/s2geometry/src/s2/s2polyline.h +379 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment.cc +414 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment.h +245 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment_internal.h +158 -0
- package/third_party/s2geometry/src/s2/s2polyline_alignment_test.cc +610 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures.cc +42 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures.h +53 -0
- package/third_party/s2geometry/src/s2/s2polyline_measures_test.cc +57 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier.cc +187 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier.h +109 -0
- package/third_party/s2geometry/src/s2/s2polyline_simplifier_test.cc +165 -0
- package/third_party/s2geometry/src/s2/s2polyline_test.cc +554 -0
- package/third_party/s2geometry/src/s2/s2predicates.cc +1486 -0
- package/third_party/s2geometry/src/s2/s2predicates.h +282 -0
- package/third_party/s2geometry/src/s2/s2predicates_internal.h +135 -0
- package/third_party/s2geometry/src/s2/s2predicates_test.cc +1427 -0
- package/third_party/s2geometry/src/s2/s2projections.cc +109 -0
- package/third_party/s2geometry/src/s2/s2projections.h +161 -0
- package/third_party/s2geometry/src/s2/s2projections_test.cc +78 -0
- package/third_party/s2geometry/src/s2/s2r2rect.cc +88 -0
- package/third_party/s2geometry/src/s2/s2r2rect.h +292 -0
- package/third_party/s2geometry/src/s2/s2r2rect_test.cc +312 -0
- package/third_party/s2geometry/src/s2/s2region.cc +26 -0
- package/third_party/s2geometry/src/s2/s2region.h +142 -0
- package/third_party/s2geometry/src/s2/s2region_coverer.cc +514 -0
- package/third_party/s2geometry/src/s2/s2region_coverer.h +356 -0
- package/third_party/s2geometry/src/s2/s2region_coverer_test.cc +509 -0
- package/third_party/s2geometry/src/s2/s2region_intersection.cc +84 -0
- package/third_party/s2geometry/src/s2/s2region_intersection.h +79 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer.cc +270 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer.h +299 -0
- package/third_party/s2geometry/src/s2/s2region_term_indexer_test.cc +209 -0
- package/third_party/s2geometry/src/s2/s2region_test.cc +370 -0
- package/third_party/s2geometry/src/s2/s2region_union.cc +90 -0
- package/third_party/s2geometry/src/s2/s2region_union.h +83 -0
- package/third_party/s2geometry/src/s2/s2region_union_test.cc +89 -0
- package/third_party/s2geometry/src/s2/s2shape.h +283 -0
- package/third_party/s2geometry/src/s2/s2shape_index.cc +321 -0
- package/third_party/s2geometry/src/s2/s2shape_index.h +781 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.cc +113 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.h +135 -0
- package/third_party/s2geometry/src/s2/s2shape_index_buffered_region_test.cc +162 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures.cc +92 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures.h +100 -0
- package/third_party/s2geometry/src/s2/s2shape_index_measures_test.cc +136 -0
- package/third_party/s2geometry/src/s2/s2shape_index_region.h +350 -0
- package/third_party/s2geometry/src/s2/s2shape_index_region_test.cc +161 -0
- package/third_party/s2geometry/src/s2/s2shape_index_test.cc +24 -0
- package/third_party/s2geometry/src/s2/s2shape_measures.cc +138 -0
- package/third_party/s2geometry/src/s2/s2shape_measures.h +95 -0
- package/third_party/s2geometry/src/s2/s2shape_measures_test.cc +139 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.cc +120 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.h +66 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries_test.cc +170 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding.cc +253 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding.h +283 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_coding_test.cc +54 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.cc +40 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.h +41 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force_test.cc +55 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_count_edges.h +57 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_count_edges_test.cc +43 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.cc +45 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.h +72 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator_test.cc +116 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.cc +107 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.h +48 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point_test.cc +104 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.cc +58 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.h +65 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator_test.cc +61 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge.h +58 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge_id.h +97 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_testing.cc +104 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_testing.h +36 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +440 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.h +72 -0
- package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs_test.cc +184 -0
- package/third_party/s2geometry/src/s2/s2testing.cc +464 -0
- package/third_party/s2geometry/src/s2/s2testing.h +385 -0
- package/third_party/s2geometry/src/s2/s2testing_test.cc +166 -0
- package/third_party/s2geometry/src/s2/s2text_format.cc +506 -0
- package/third_party/s2geometry/src/s2/s2text_format.h +289 -0
- package/third_party/s2geometry/src/s2/s2text_format_test.cc +417 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations.cc +80 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations.h +64 -0
- package/third_party/s2geometry/src/s2/s2wedge_relations_test.cc +89 -0
- package/third_party/s2geometry/src/s2/sequence_lexicon.h +296 -0
- package/third_party/s2geometry/src/s2/sequence_lexicon_test.cc +113 -0
- package/third_party/s2geometry/src/s2/strings/ostringstream.cc +35 -0
- package/third_party/s2geometry/src/s2/strings/ostringstream.h +105 -0
- package/third_party/s2geometry/src/s2/strings/serialize.cc +46 -0
- package/third_party/s2geometry/src/s2/strings/serialize.h +40 -0
- package/third_party/s2geometry/src/s2/third_party/absl/algorithm/algorithm.h +187 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/attributes.h +666 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/casts.h +189 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/config.h +462 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.cc +129 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.h +394 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/atomic_hook.h +168 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/identity.h +33 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/inline_variable.h +117 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/invoke.h +188 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.cc +254 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.h +205 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.cc +106 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.h +71 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/internal/unaligned_access.h +322 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/log_severity.h +77 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/macros.h +236 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/optimization.h +177 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/policy_checks.h +124 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/port.h +97 -0
- package/third_party/s2geometry/src/s2/third_party/absl/base/thread_annotations.h +277 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/fixed_array.h +523 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/inlined_vector.h +1453 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/compressed_tuple.h +191 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/container_memory.h +424 -0
- package/third_party/s2geometry/src/s2/third_party/absl/container/internal/layout.h +739 -0
- package/third_party/s2geometry/src/s2/third_party/absl/memory/memory.h +755 -0
- package/third_party/s2geometry/src/s2/third_party/absl/meta/type_traits.h +436 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.cc +232 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.h +656 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_have_intrinsic.inc +3 -0
- package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_no_intrinsic.inc +3 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.cc +198 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.h +239 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii_ctype.h +66 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/bits.h +53 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.cc +110 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.h +146 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/resize_uninitialized.h +72 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/match.cc +38 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/match.h +89 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.cc +909 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.h +187 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.cc +240 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.h +398 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_join.h +22 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.cc +47 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.h +43 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.cc +245 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.h +602 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.cc +42 -0
- package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.h +130 -0
- package/third_party/s2geometry/src/s2/third_party/absl/types/span.h +793 -0
- package/third_party/s2geometry/src/s2/third_party/absl/utility/utility.h +299 -0
- package/third_party/s2geometry/src/s2/util/bits/bit-interleave.cc +274 -0
- package/third_party/s2geometry/src/s2/util/bits/bit-interleave.h +53 -0
- package/third_party/s2geometry/src/s2/util/bits/bits.cc +155 -0
- package/third_party/s2geometry/src/s2/util/bits/bits.h +745 -0
- package/third_party/s2geometry/src/s2/util/coding/coder.cc +83 -0
- package/third_party/s2geometry/src/s2/util/coding/coder.h +553 -0
- package/third_party/s2geometry/src/s2/util/coding/nth-derivative.h +134 -0
- package/third_party/s2geometry/src/s2/util/coding/transforms.h +62 -0
- package/third_party/s2geometry/src/s2/util/coding/varint.cc +289 -0
- package/third_party/s2geometry/src/s2/util/coding/varint.h +476 -0
- package/third_party/s2geometry/src/s2/util/endian/endian.h +859 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree.h +2471 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_container.h +411 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_map.h +79 -0
- package/third_party/s2geometry/src/s2/util/gtl/btree_set.h +73 -0
- package/third_party/s2geometry/src/s2/util/gtl/compact_array.h +653 -0
- package/third_party/s2geometry/src/s2/util/gtl/container_logging.h +291 -0
- package/third_party/s2geometry/src/s2/util/gtl/dense_hash_set.h +358 -0
- package/third_party/s2geometry/src/s2/util/gtl/densehashtable.h +1493 -0
- package/third_party/s2geometry/src/s2/util/gtl/hashtable_common.h +253 -0
- package/third_party/s2geometry/src/s2/util/gtl/layout.h +28 -0
- package/third_party/s2geometry/src/s2/util/gtl/legacy_random_shuffle.h +77 -0
- package/third_party/s2geometry/src/s2/util/hash/mix.h +76 -0
- package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.cc +832 -0
- package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.h +646 -0
- package/third_party/s2geometry/src/s2/util/math/mathutil.cc +75 -0
- package/third_party/s2geometry/src/s2/util/math/mathutil.h +189 -0
- package/third_party/s2geometry/src/s2/util/math/matrix3x3.h +574 -0
- package/third_party/s2geometry/src/s2/util/math/vector.h +569 -0
- package/third_party/s2geometry/src/s2/util/math/vector3_hash.h +54 -0
- package/third_party/s2geometry/src/s2/util/units/length-units.cc +21 -0
- package/third_party/s2geometry/src/s2/util/units/length-units.h +135 -0
- package/third_party/s2geometry/src/s2/util/units/physical-units.h +313 -0
- package/third_party/s2geometry/src/s2/value_lexicon.h +234 -0
- package/third_party/s2geometry/src/s2/value_lexicon_test.cc +121 -0
- package/third_party/s2geometry/third_party/cmake/FindGFlags.cmake +48 -0
- 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
|
+
}
|