@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,716 @@
|
|
|
1
|
+
// Copyright 2016 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
|
+
// The bulk of this file consists of "tests" that attempt to construct worst
|
|
19
|
+
// cases for the various constants used in S2CellIdSnapFunction and
|
|
20
|
+
// IntLatLngSnapFunction implementations. For all of these constants I have
|
|
21
|
+
// done hand analysis of the planar configurations, but sometimes the
|
|
22
|
+
// spherical case is slightly better or worse because of the spherical
|
|
23
|
+
// distortion.
|
|
24
|
+
|
|
25
|
+
#include "s2/s2builderutil_snap_functions.h"
|
|
26
|
+
|
|
27
|
+
#include <algorithm>
|
|
28
|
+
#include <cinttypes>
|
|
29
|
+
#include <cmath>
|
|
30
|
+
#include <cstdint>
|
|
31
|
+
#include <cstdio>
|
|
32
|
+
#include <map>
|
|
33
|
+
#include <set>
|
|
34
|
+
#include <string>
|
|
35
|
+
#include <utility>
|
|
36
|
+
#include <vector>
|
|
37
|
+
#include "s2/base/integral_types.h"
|
|
38
|
+
#include "s2/base/logging.h"
|
|
39
|
+
#include <gtest/gtest.h>
|
|
40
|
+
#include "s2/r2.h"
|
|
41
|
+
#include "s2/s1angle.h"
|
|
42
|
+
#include "s2/s2cell.h"
|
|
43
|
+
#include "s2/s2cell_id.h"
|
|
44
|
+
#include "s2/s2edge_distances.h"
|
|
45
|
+
#include "s2/s2latlng.h"
|
|
46
|
+
#include "s2/s2measures.h"
|
|
47
|
+
#include "s2/s2metrics.h"
|
|
48
|
+
#include "s2/s2testing.h"
|
|
49
|
+
#include "s2/s2text_format.h"
|
|
50
|
+
#include "s2/util/math/mathutil.h"
|
|
51
|
+
|
|
52
|
+
using std::abs;
|
|
53
|
+
using std::fabs;
|
|
54
|
+
using std::make_pair;
|
|
55
|
+
using std::map;
|
|
56
|
+
using std::min;
|
|
57
|
+
using std::max;
|
|
58
|
+
using std::pair;
|
|
59
|
+
using std::set;
|
|
60
|
+
using std::vector;
|
|
61
|
+
using s2builderutil::S2CellIdSnapFunction;
|
|
62
|
+
using s2builderutil::IntLatLngSnapFunction;
|
|
63
|
+
|
|
64
|
+
TEST(S2CellIdSnapFunction, LevelToFromSnapRadius) {
|
|
65
|
+
for (int level = 0; level <= S2CellId::kMaxLevel; ++level) {
|
|
66
|
+
S1Angle radius = S2CellIdSnapFunction::MinSnapRadiusForLevel(level);
|
|
67
|
+
EXPECT_EQ(level, S2CellIdSnapFunction::LevelForMaxSnapRadius(radius));
|
|
68
|
+
EXPECT_EQ(min(level + 1, S2CellId::kMaxLevel),
|
|
69
|
+
S2CellIdSnapFunction::LevelForMaxSnapRadius(0.999 * radius));
|
|
70
|
+
}
|
|
71
|
+
EXPECT_EQ(0,
|
|
72
|
+
S2CellIdSnapFunction::LevelForMaxSnapRadius(
|
|
73
|
+
S1Angle::Radians(5)));
|
|
74
|
+
EXPECT_EQ(S2CellId::kMaxLevel,
|
|
75
|
+
S2CellIdSnapFunction::LevelForMaxSnapRadius(
|
|
76
|
+
S1Angle::Radians(1e-30)));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
TEST(S2CellIdSnapFunction, SnapPoint) {
|
|
80
|
+
for (int iter = 0; iter < 1000; ++iter) {
|
|
81
|
+
for (int level = 0; level <= S2CellId::kMaxLevel; ++level) {
|
|
82
|
+
// This checks that points are snapped to the correct level, since
|
|
83
|
+
// S2CellId centers at different levels are always different.
|
|
84
|
+
S2CellIdSnapFunction f(level);
|
|
85
|
+
S2Point p = S2Testing::GetRandomCellId(level).ToPoint();
|
|
86
|
+
EXPECT_EQ(p, f.SnapPoint(p));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
TEST(IntLatLngSnapFunction, ExponentToFromSnapRadius) {
|
|
92
|
+
for (int exponent = IntLatLngSnapFunction::kMinExponent;
|
|
93
|
+
exponent <= IntLatLngSnapFunction::kMaxExponent; ++exponent) {
|
|
94
|
+
S1Angle radius = IntLatLngSnapFunction::MinSnapRadiusForExponent(exponent);
|
|
95
|
+
EXPECT_EQ(exponent,
|
|
96
|
+
IntLatLngSnapFunction::ExponentForMaxSnapRadius(radius));
|
|
97
|
+
EXPECT_EQ(min(exponent + 1, IntLatLngSnapFunction::kMaxExponent),
|
|
98
|
+
IntLatLngSnapFunction::ExponentForMaxSnapRadius(0.999 * radius));
|
|
99
|
+
}
|
|
100
|
+
EXPECT_EQ(IntLatLngSnapFunction::kMinExponent,
|
|
101
|
+
IntLatLngSnapFunction::ExponentForMaxSnapRadius(
|
|
102
|
+
S1Angle::Radians(5)));
|
|
103
|
+
EXPECT_EQ(IntLatLngSnapFunction::kMaxExponent,
|
|
104
|
+
IntLatLngSnapFunction::ExponentForMaxSnapRadius(
|
|
105
|
+
S1Angle::Radians(1e-30)));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
TEST(IntLatLngSnapFunction, SnapPoint) {
|
|
109
|
+
for (int iter = 0; iter < 1000; ++iter) {
|
|
110
|
+
// Test that IntLatLngSnapFunction does not modify points that were
|
|
111
|
+
// generated using the S2LatLng::From{E5,E6,E7} methods. This ensures
|
|
112
|
+
// that both functions are using bitwise-compatible conversion methods.
|
|
113
|
+
S2Point p = S2Testing::RandomPoint();
|
|
114
|
+
S2LatLng ll(p);
|
|
115
|
+
S2Point p5 = S2LatLng::FromE5(ll.lat().e5(), ll.lng().e5()).ToPoint();
|
|
116
|
+
EXPECT_EQ(p5, IntLatLngSnapFunction(5).SnapPoint(p5));
|
|
117
|
+
S2Point p6 = S2LatLng::FromE6(ll.lat().e6(), ll.lng().e6()).ToPoint();
|
|
118
|
+
EXPECT_EQ(p6, IntLatLngSnapFunction(6).SnapPoint(p6));
|
|
119
|
+
S2Point p7 = S2LatLng::FromE7(ll.lat().e7(), ll.lng().e7()).ToPoint();
|
|
120
|
+
EXPECT_EQ(p7, IntLatLngSnapFunction(7).SnapPoint(p7));
|
|
121
|
+
|
|
122
|
+
// Make sure that we're not snapping using some lower exponent.
|
|
123
|
+
S2Point p7not6 = S2LatLng::FromE7(10 * ll.lat().e6() + 1,
|
|
124
|
+
10 * ll.lng().e6() + 1).ToPoint();
|
|
125
|
+
EXPECT_NE(p7not6, IntLatLngSnapFunction(6).SnapPoint(p7not6));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static S2CellId kSearchRootId = S2CellId::FromFace(0);
|
|
130
|
+
static S2CellId kSearchFocusId = S2CellId::FromFace(0).child(3);
|
|
131
|
+
|
|
132
|
+
static S1Angle GetMaxVertexDistance(const S2Point& p, S2CellId id) {
|
|
133
|
+
S2Cell cell(id);
|
|
134
|
+
return max(max(S1Angle(p, cell.GetVertex(0)),
|
|
135
|
+
S1Angle(p, cell.GetVertex(1))),
|
|
136
|
+
max(S1Angle(p, cell.GetVertex(2)),
|
|
137
|
+
S1Angle(p, cell.GetVertex(3))));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Helper function that computes the vertex separation between "id0" and its
|
|
141
|
+
// neighbors.
|
|
142
|
+
static void UpdateS2CellIdMinVertexSeparation(
|
|
143
|
+
S2CellId id0, vector<pair<double, S2CellId>>* scores) {
|
|
144
|
+
S2Point site0 = id0.ToPoint();
|
|
145
|
+
vector<S2CellId> nbrs;
|
|
146
|
+
id0.AppendAllNeighbors(id0.level(), &nbrs);
|
|
147
|
+
for (S2CellId id1 : nbrs) {
|
|
148
|
+
S2Point site1 = id1.ToPoint();
|
|
149
|
+
S1Angle vertex_sep(site0, site1);
|
|
150
|
+
S1Angle max_snap_radius = GetMaxVertexDistance(site0, id1);
|
|
151
|
+
S2_DCHECK_GE(max_snap_radius,
|
|
152
|
+
S2CellIdSnapFunction::MinSnapRadiusForLevel(id0.level()));
|
|
153
|
+
double r = vertex_sep / max_snap_radius;
|
|
154
|
+
scores->push_back(make_pair(r, id0));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static double GetS2CellIdMinVertexSeparation(int level,
|
|
159
|
+
set<S2CellId>* best_cells) {
|
|
160
|
+
// The worst-case separation ratios always occur when the snap_radius is not
|
|
161
|
+
// much larger than the minimum, since this allows the site spacing to be
|
|
162
|
+
// reduced by as large a fraction as possible.
|
|
163
|
+
//
|
|
164
|
+
// For the minimum vertex separation ratio, we choose a site and one of its
|
|
165
|
+
// 8-way neighbors, then look at the ratio of the distance to the center of
|
|
166
|
+
// that neighbor to the distance to the furthest corner of that neighbor
|
|
167
|
+
// (which is the largest possible snap radius for this configuration).
|
|
168
|
+
vector<pair<double, S2CellId>> scores;
|
|
169
|
+
if (level == 0) {
|
|
170
|
+
UpdateS2CellIdMinVertexSeparation(kSearchRootId, &scores);
|
|
171
|
+
} else {
|
|
172
|
+
for (S2CellId parent : *best_cells) {
|
|
173
|
+
for (S2CellId id0 = parent.child_begin();
|
|
174
|
+
id0 != parent.child_end(); id0 = id0.next()) {
|
|
175
|
+
UpdateS2CellIdMinVertexSeparation(id0, &scores);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Now sort the entries, print out the "num_to_print" best ones, and keep
|
|
180
|
+
// the best "num_to_keep" of them to seed the next round.
|
|
181
|
+
std::sort(scores.begin(), scores.end());
|
|
182
|
+
scores.erase(std::unique(scores.begin(), scores.end()), scores.end());
|
|
183
|
+
best_cells->clear();
|
|
184
|
+
int num_to_keep = 300;
|
|
185
|
+
int num_to_print = 1;
|
|
186
|
+
for (const auto& entry : scores) {
|
|
187
|
+
S2CellId id = entry.second;
|
|
188
|
+
if (--num_to_print >= 0) {
|
|
189
|
+
R2Point uv = id.GetCenterUV();
|
|
190
|
+
printf("Level %2d: min_vertex_sep_ratio = %.15f u=%.6f v=%.6f %s\n",
|
|
191
|
+
level, entry.first, uv[0], uv[1], id.ToToken().c_str());
|
|
192
|
+
}
|
|
193
|
+
if (kSearchFocusId.contains(id) || id.contains(kSearchFocusId)) {
|
|
194
|
+
if (best_cells->insert(id).second && --num_to_keep <= 0) break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return scores[0].first;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
TEST(S2CellIdSnapFunction, MinVertexSeparationSnapRadiusRatio) {
|
|
201
|
+
// The purpose of this "test" is to compute a lower bound to the fraction
|
|
202
|
+
// (min_vertex_separation() / snap_radius()). Essentially this involves
|
|
203
|
+
// searching for two adjacent cells A and B such when one of the corner
|
|
204
|
+
// vertices of B is snapped to the center of B, the distance to the center
|
|
205
|
+
// of A decreases as much as possible. In other words, we want the ratio
|
|
206
|
+
//
|
|
207
|
+
// distance(center(A), center(B)) / distance(center(A), vertex(B))
|
|
208
|
+
//
|
|
209
|
+
// to be as small as possible. We do this by considering one cell level at
|
|
210
|
+
// a time, and remembering the cells that had the lowest ratios. When we
|
|
211
|
+
// proceed from one level to the next, we consider all the children of those
|
|
212
|
+
// cells and keep the best ones.
|
|
213
|
+
//
|
|
214
|
+
// The reason we can restrict the search to children of cells at the
|
|
215
|
+
// previous level is that the ratio above is essentially a function of the
|
|
216
|
+
// local distortions created by projecting the S2 cube space onto the
|
|
217
|
+
// sphere. These distortions change smoothly over the sphere, so by keeping
|
|
218
|
+
// a fairly large number of candidates ("num_to_keep"), we are essentially
|
|
219
|
+
// keeping all the neighbors of the optimal cell as well.
|
|
220
|
+
double best_score = 1e10;
|
|
221
|
+
set<S2CellId> best_cells;
|
|
222
|
+
for (int level = 0; level <= S2CellId::kMaxLevel; ++level) {
|
|
223
|
+
double score = GetS2CellIdMinVertexSeparation(level, &best_cells);
|
|
224
|
+
best_score = min(best_score, score);
|
|
225
|
+
}
|
|
226
|
+
printf("min_vertex_sep / snap_radius ratio: %.15f\n", best_score);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
static S1Angle GetCircumRadius(const S2Point& a, const S2Point& b,
|
|
230
|
+
const S2Point& c) {
|
|
231
|
+
// We return this value is the circumradius is very large.
|
|
232
|
+
S1Angle kTooBig = S1Angle::Radians(M_PI);
|
|
233
|
+
double turn_angle = S2::TurnAngle(a, b, c);
|
|
234
|
+
if (fabs(remainder(turn_angle, M_PI)) < 1e-2) return kTooBig;
|
|
235
|
+
|
|
236
|
+
long double a2 = (b - c).Norm2();
|
|
237
|
+
long double b2 = (c - a).Norm2();
|
|
238
|
+
long double c2 = (a - b).Norm2();
|
|
239
|
+
if (a2 > 2 || b2 > 2 || c2 > 2) return kTooBig;
|
|
240
|
+
long double ma = a2 * (b2 + c2 - a2);
|
|
241
|
+
long double mb = b2 * (c2 + a2 - b2);
|
|
242
|
+
long double mc = c2 * (a2 + b2 - c2);
|
|
243
|
+
S2Point p = (ma * a + mb * b + mc * c) / (ma + mb + mc);
|
|
244
|
+
return S1Angle(p, a);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static vector<S2CellId> GetNeighbors(S2CellId id) {
|
|
248
|
+
const int kNumLayers = 2;
|
|
249
|
+
vector<S2CellId> nbrs;
|
|
250
|
+
nbrs.push_back(id);
|
|
251
|
+
for (int layer = 0; layer < kNumLayers; ++layer) {
|
|
252
|
+
vector<S2CellId> new_nbrs;
|
|
253
|
+
for (S2CellId nbr : nbrs) {
|
|
254
|
+
nbr.AppendAllNeighbors(id.level(), &new_nbrs);
|
|
255
|
+
}
|
|
256
|
+
nbrs.insert(nbrs.end(), new_nbrs.begin(), new_nbrs.end());
|
|
257
|
+
nbrs.erase(std::remove(nbrs.begin(), nbrs.end(), id), nbrs.end());
|
|
258
|
+
std::sort(nbrs.begin(), nbrs.end());
|
|
259
|
+
nbrs.erase(std::unique(nbrs.begin(), nbrs.end()), nbrs.end());
|
|
260
|
+
}
|
|
261
|
+
return nbrs;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// S2CellIdMinEdgeSeparationFunction defines an objective function that will
|
|
265
|
+
// be optimized by GetS2CellIdMinEdgeSeparation() by finding worst-case
|
|
266
|
+
// configurations of S2CellIds. We use this to find the worst cases under
|
|
267
|
+
// various conditions (e.g., when the minimum snap radius at a given level is
|
|
268
|
+
// being used). The objective function is called for a specific configuration
|
|
269
|
+
// of vertices that are snapped at the given S2CellId level. "edge_sep" is
|
|
270
|
+
// the edge-vertex distance that is achieved by this configuration, and
|
|
271
|
+
// "min_snap_radius" and "max_snap_radius" are the minimum and maximum snap
|
|
272
|
+
// radii for which this configuration is valid (i.e., where the desired
|
|
273
|
+
// snapping will take place).
|
|
274
|
+
typedef double S2CellIdMinEdgeSeparationFunction(int level, S1Angle edge_sep,
|
|
275
|
+
S1Angle min_snap_radius,
|
|
276
|
+
S1Angle max_snap_radius);
|
|
277
|
+
|
|
278
|
+
// Returns the minimum value of the given objective function over sets of
|
|
279
|
+
// nearby vertices that are designed to minimize the edge-vertex separation
|
|
280
|
+
// when an edge is snapped.
|
|
281
|
+
static double GetS2CellIdMinEdgeSeparation(
|
|
282
|
+
const char* label, S2CellIdMinEdgeSeparationFunction objective,
|
|
283
|
+
int level, set<S2CellId>* best_cells) {
|
|
284
|
+
// To find minimum edge separations, we choose a cell ("id0") and two nearby
|
|
285
|
+
// cells ("id1" and "id2"), where "nearby" is defined by GetNeighbors().
|
|
286
|
+
// Let "site0", "site1", and "site2" be the centers of these cells. The
|
|
287
|
+
// idea is to consider an input edge E that intersects the Voronoi regions
|
|
288
|
+
// of "site1" and "site2" (and therefore snaps to an edge E' between these
|
|
289
|
+
// sites) but does not not intersect the Voronoi region of "site0" (and
|
|
290
|
+
// therefore can't be snapped to site0). The goal is to search for snapped
|
|
291
|
+
// edges E' that approach site0 as closely as possible.
|
|
292
|
+
//
|
|
293
|
+
// To do this, we first compute the circumradius of the three cell centers
|
|
294
|
+
// ("site0", "site1", and "site2"); this is the minimum snap radius in order
|
|
295
|
+
// for it to be possible to construct an edge E that snaps to "site1" and
|
|
296
|
+
// "site2" but not to "site0". We also compute the distance from "site0" to
|
|
297
|
+
// the snapped edge. Next we find the corner vertex of "id1" and "id2" that
|
|
298
|
+
// is furthest from "site0"; the smaller of these two distances is the
|
|
299
|
+
// maximum snap radius such that "site1" and "site2" can be chosen as
|
|
300
|
+
// sites after choosing "site0". If the maximum is less than the minimum,
|
|
301
|
+
// then this configuration is rejected; otherwise we evaluate the given
|
|
302
|
+
// objective function and keep the configurations that result in the
|
|
303
|
+
// smallest values.
|
|
304
|
+
//
|
|
305
|
+
// The optimization process works by keeping track of the set of S2CellIds
|
|
306
|
+
// that yielded the best results at the previous level, and exploring all
|
|
307
|
+
// the nearby neighbor combinations of the children of those cells at the
|
|
308
|
+
// next level. In order to get better coverage, we keep track of the best
|
|
309
|
+
// score and configuration (i.e. the two neighboring cells "id1" and "id2")
|
|
310
|
+
// for each initial cell "id0".
|
|
311
|
+
map<S2CellId, double> best_scores;
|
|
312
|
+
map<S2CellId, pair<S2CellId, S2CellId>> best_configs;
|
|
313
|
+
for (S2CellId parent : *best_cells) {
|
|
314
|
+
for (S2CellId id0 = parent.child_begin(level);
|
|
315
|
+
id0 != parent.child_end(level); id0 = id0.next()) {
|
|
316
|
+
S2Point site0 = id0.ToPoint();
|
|
317
|
+
vector<S2CellId> nbrs = GetNeighbors(id0);
|
|
318
|
+
for (S2CellId id1 : nbrs) {
|
|
319
|
+
S2Point site1 = id1.ToPoint();
|
|
320
|
+
S1Angle max_v1 = GetMaxVertexDistance(site0, id1);
|
|
321
|
+
for (S2CellId id2 : nbrs) {
|
|
322
|
+
if (id2 <= id1) continue;
|
|
323
|
+
S2Point site2 = id2.ToPoint();
|
|
324
|
+
S1Angle min_snap_radius = GetCircumRadius(site0, site1, site2);
|
|
325
|
+
if (min_snap_radius > S2Builder::SnapFunction::kMaxSnapRadius()) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
// Note that it is only the original points *before* snapping that
|
|
329
|
+
// need to be at least "snap_radius" away from "site0". The points
|
|
330
|
+
// after snapping ("site1" and "site2") may be closer.
|
|
331
|
+
S1Angle max_v2 = GetMaxVertexDistance(site0, id2);
|
|
332
|
+
S1Angle max_snap_radius = min(max_v1, max_v2);
|
|
333
|
+
if (min_snap_radius > max_snap_radius) continue;
|
|
334
|
+
S2_DCHECK_GE(max_snap_radius,
|
|
335
|
+
S2CellIdSnapFunction::MinSnapRadiusForLevel(level));
|
|
336
|
+
|
|
337
|
+
// This is a valid configuration, so evaluate it.
|
|
338
|
+
S1Angle edge_sep = S2::GetDistance(site0, site1, site2);
|
|
339
|
+
double score = objective(level, edge_sep,
|
|
340
|
+
min_snap_radius, max_snap_radius);
|
|
341
|
+
double& best_score = best_scores[id0];
|
|
342
|
+
if (best_score == 0 || best_score > score) {
|
|
343
|
+
best_score = score;
|
|
344
|
+
best_configs[id0] = make_pair(id1, id2);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Now sort the entries, print out the "num_to_print" best ones, and
|
|
351
|
+
// generate a set of candidates for the next round by generating all the
|
|
352
|
+
// 8-way neighbors of the best candidates, and keeping up to"num_to_keep" of
|
|
353
|
+
// them. The results vary slightly according to how many candidates we
|
|
354
|
+
// keep, but the variations are much smaller than the conservative
|
|
355
|
+
// assumptions made by the S2CellIdSnapFunction implementation.
|
|
356
|
+
int num_to_keep = google::DEBUG_MODE ? 20 : 100;
|
|
357
|
+
int num_to_print = 3;
|
|
358
|
+
vector<pair<double, S2CellId>> sorted;
|
|
359
|
+
for (const auto& entry : best_scores) {
|
|
360
|
+
sorted.push_back(make_pair(entry.second, entry.first));
|
|
361
|
+
}
|
|
362
|
+
std::sort(sorted.begin(), sorted.end());
|
|
363
|
+
best_cells->clear();
|
|
364
|
+
printf("Level %d:\n", level);
|
|
365
|
+
for (const auto& entry : sorted) {
|
|
366
|
+
S2CellId id = entry.second;
|
|
367
|
+
if (--num_to_print >= 0) {
|
|
368
|
+
R2Point uv = id.GetCenterUV();
|
|
369
|
+
const pair<S2CellId, S2CellId>& nbrs = best_configs.find(id)->second;
|
|
370
|
+
printf(" %s = %.15f u=%7.4f v=%7.4f %s %s %s\n",
|
|
371
|
+
label, entry.first, uv[0], uv[1], id.ToToken().c_str(),
|
|
372
|
+
nbrs.first.ToToken().c_str(), nbrs.second.ToToken().c_str());
|
|
373
|
+
}
|
|
374
|
+
vector<S2CellId> nbrs(1, id);
|
|
375
|
+
id.AppendAllNeighbors(id.level(), &nbrs);
|
|
376
|
+
for (S2CellId nbr : nbrs) {
|
|
377
|
+
// The S2Cell hierarchy has many regions that are symmetrical. We can
|
|
378
|
+
// eliminate most of the "duplicates" by restricting the search to cells
|
|
379
|
+
// in kS2CellIdFocus.
|
|
380
|
+
if (kSearchFocusId.contains(nbr) || nbr.contains(kSearchFocusId)) {
|
|
381
|
+
if (best_cells->insert(nbr).second && --num_to_keep <= 0) {
|
|
382
|
+
return sorted[0].first;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return sorted[0].first;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
static double GetS2CellIdMinEdgeSeparation(
|
|
391
|
+
const char* label, S2CellIdMinEdgeSeparationFunction objective) {
|
|
392
|
+
double best_score = 1e10;
|
|
393
|
+
set<S2CellId> best_cells;
|
|
394
|
+
best_cells.insert(kSearchRootId);
|
|
395
|
+
for (int level = 0; level <= S2CellId::kMaxLevel; ++level) {
|
|
396
|
+
double score = GetS2CellIdMinEdgeSeparation(label, objective, level,
|
|
397
|
+
&best_cells);
|
|
398
|
+
best_score = min(best_score, score);
|
|
399
|
+
}
|
|
400
|
+
return best_score;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
TEST(S2CellIdSnapFunction, MinEdgeVertexSeparationForLevel) {
|
|
404
|
+
// Computes the minimum edge separation (as a fraction of kMinDiag) for any
|
|
405
|
+
// snap radius at each level.
|
|
406
|
+
double score = GetS2CellIdMinEdgeSeparation("min_sep_for_level",
|
|
407
|
+
[](int level, S1Angle edge_sep,
|
|
408
|
+
S1Angle min_snap_radius,
|
|
409
|
+
S1Angle max_snap_radius) {
|
|
410
|
+
return edge_sep.radians() / S2::kMinDiag.GetValue(level);
|
|
411
|
+
});
|
|
412
|
+
printf("min_edge_vertex_sep / kMinDiag ratio: %.15f\n", score);
|
|
413
|
+
}
|
|
414
|
+
TEST(S2CellIdSnapFunction, MinEdgeVertexSeparationAtMinSnapRadius) {
|
|
415
|
+
// Computes the minimum edge separation (as a fraction of kMinDiag) for the
|
|
416
|
+
// special case where the minimum snap radius is being used.
|
|
417
|
+
double score = GetS2CellIdMinEdgeSeparation("min_sep_at_min_radius",
|
|
418
|
+
[](int level, S1Angle edge_sep,
|
|
419
|
+
S1Angle min_snap_radius,
|
|
420
|
+
S1Angle max_snap_radius) {
|
|
421
|
+
double min_radius_at_level = S2::kMaxDiag.GetValue(level) / 2;
|
|
422
|
+
return (min_snap_radius.radians() <= (1 + 1e-10) * min_radius_at_level) ?
|
|
423
|
+
(edge_sep.radians() / S2::kMinDiag.GetValue(level)) : 100.0;
|
|
424
|
+
});
|
|
425
|
+
printf("min_edge_vertex_sep / kMinDiag at MinSnapRadiusForLevel: %.15f\n",
|
|
426
|
+
score);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
TEST(S2CellIdSnapFunction, MinEdgeVertexSeparationSnapRadiusRatio) {
|
|
430
|
+
// Computes the minimum edge separation expressed as a fraction of the
|
|
431
|
+
// maximum snap radius that could yield that edge separation.
|
|
432
|
+
double score = GetS2CellIdMinEdgeSeparation("min_sep_snap_radius_ratio",
|
|
433
|
+
[](int level, S1Angle edge_sep,
|
|
434
|
+
S1Angle min_snap_radius,
|
|
435
|
+
S1Angle max_snap_radius) {
|
|
436
|
+
return edge_sep.radians() / max_snap_radius.radians();
|
|
437
|
+
});
|
|
438
|
+
printf("min_edge_vertex_sep / snap_radius ratio: %.15f\n", score);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// A scaled S2LatLng with integer coordinates, similar to E7 coordinates,
|
|
442
|
+
// except that the scale is variable (see LatLngConfig below).
|
|
443
|
+
using IntLatLng = Vector2<int64>;
|
|
444
|
+
|
|
445
|
+
static bool IsValid(const IntLatLng& ll, int64 scale) {
|
|
446
|
+
// A coordinate value of "scale" corresponds to 180 degrees.
|
|
447
|
+
return (abs(ll[0]) <= scale / 2 && abs(ll[1]) <= scale);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
static bool HasValidVertices(const IntLatLng& ll, int64 scale) {
|
|
451
|
+
// Like IsValid, but excludes latitudes of 90 and longitudes of 180.
|
|
452
|
+
// A coordinate value of "scale" corresponds to 180 degrees.
|
|
453
|
+
return (abs(ll[0]) < scale / 2 && abs(ll[1]) < scale);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
static IntLatLng Rescale(const IntLatLng&ll, double scale_factor) {
|
|
457
|
+
return IntLatLng(MathUtil::FastInt64Round(scale_factor * ll[0]),
|
|
458
|
+
MathUtil::FastInt64Round(scale_factor * ll[1]));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
static S2Point ToPoint(const IntLatLng& ll, int64 scale) {
|
|
462
|
+
return S2LatLng::FromRadians(ll[0] * (M_PI / scale),
|
|
463
|
+
ll[1] * (M_PI / scale)).ToPoint();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
static S2Point GetVertex(const IntLatLng& ll, int64 scale, int i) {
|
|
467
|
+
// Return the points in CCW order starting from the lower left.
|
|
468
|
+
int dlat = (i == 0 || i == 3) ? -1 : 1;
|
|
469
|
+
int dlng = (i == 0 || i == 1) ? -1 : 1;
|
|
470
|
+
return ToPoint(2 * ll + IntLatLng(dlat, dlng), 2 * scale);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
static S1Angle GetMaxVertexDistance(const S2Point& p,
|
|
474
|
+
const IntLatLng& ll, int64 scale) {
|
|
475
|
+
return max(max(S1Angle(p, GetVertex(ll, scale, 0)),
|
|
476
|
+
S1Angle(p, GetVertex(ll, scale, 1))),
|
|
477
|
+
max(S1Angle(p, GetVertex(ll, scale, 2)),
|
|
478
|
+
S1Angle(p, GetVertex(ll, scale, 3))));
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
static double GetLatLngMinVertexSeparation(int64 old_scale, int64 scale,
|
|
482
|
+
set<IntLatLng>* best_configs) {
|
|
483
|
+
// The worst-case separation ratios always occur when the snap_radius is not
|
|
484
|
+
// much larger than the minimum, since this allows the site spacing to be
|
|
485
|
+
// reduced by as large a fraction as possible.
|
|
486
|
+
//
|
|
487
|
+
// For the minimum vertex separation ratio, we choose a site and one of its
|
|
488
|
+
// 8-way neighbors, then look at the ratio of the distance to the center of
|
|
489
|
+
// that neighbor to the distance to the furthest corner of that neighbor
|
|
490
|
+
// (which is the largest possible snap radius for this configuration).
|
|
491
|
+
S1Angle min_snap_radius_at_scale = S1Angle::Radians(M_SQRT1_2 * M_PI / scale);
|
|
492
|
+
vector<pair<double, IntLatLng>> scores;
|
|
493
|
+
double scale_factor = static_cast<double>(scale) / old_scale;
|
|
494
|
+
for (const IntLatLng& parent : *best_configs) {
|
|
495
|
+
IntLatLng new_parent = Rescale(parent, scale_factor);
|
|
496
|
+
for (int dlat0 = -7; dlat0 <= 7; ++dlat0) {
|
|
497
|
+
IntLatLng ll0 = new_parent + IntLatLng(dlat0, 0);
|
|
498
|
+
if (!IsValid(ll0, scale) || ll0[0] < 0) continue;
|
|
499
|
+
S2Point site0 = ToPoint(ll0, scale);
|
|
500
|
+
for (int dlat1 = 0; dlat1 <= 2; ++dlat1) {
|
|
501
|
+
for (int dlng1 = 0; dlng1 <= 5; ++dlng1) {
|
|
502
|
+
IntLatLng ll1 = ll0 + IntLatLng(dlat1, dlng1);
|
|
503
|
+
if (ll1 == ll0 || !HasValidVertices(ll1, scale)) continue;
|
|
504
|
+
S1Angle max_snap_radius = GetMaxVertexDistance(site0, ll1, scale);
|
|
505
|
+
if (max_snap_radius < min_snap_radius_at_scale) continue;
|
|
506
|
+
S2Point site1 = ToPoint(ll1, scale);
|
|
507
|
+
S1Angle vertex_sep(site0, site1);
|
|
508
|
+
double r = vertex_sep / max_snap_radius;
|
|
509
|
+
scores.push_back(make_pair(r, ll0));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// Now sort the entries, print out the "num_to_print" best ones, and keep
|
|
515
|
+
// the best "num_to_keep" of them to seed the next round.
|
|
516
|
+
std::sort(scores.begin(), scores.end());
|
|
517
|
+
scores.erase(std::unique(scores.begin(), scores.end()), scores.end());
|
|
518
|
+
best_configs->clear();
|
|
519
|
+
int num_to_keep = 100;
|
|
520
|
+
int num_to_print = 1;
|
|
521
|
+
for (const auto& entry : scores) {
|
|
522
|
+
if (--num_to_print >= 0) {
|
|
523
|
+
printf("Scale %14" PRId64 ": min_vertex_sep_ratio = %.15f, %s\n",
|
|
524
|
+
int64_t{scale}, entry.first,
|
|
525
|
+
s2textformat::ToString(ToPoint(entry.second, scale)).c_str());
|
|
526
|
+
}
|
|
527
|
+
if (best_configs->insert(entry.second).second && --num_to_keep <= 0) break;
|
|
528
|
+
}
|
|
529
|
+
return scores[0].first;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
TEST(IntLatLngSnapFunction, MinVertexSeparationSnapRadiusRatio) {
|
|
533
|
+
double best_score = 1e10;
|
|
534
|
+
set<IntLatLng> best_configs;
|
|
535
|
+
int64 scale = 18;
|
|
536
|
+
for (int lat0 = 0; lat0 <= 9; ++lat0) {
|
|
537
|
+
best_configs.insert(IntLatLng(lat0, 0));
|
|
538
|
+
}
|
|
539
|
+
for (int exp = 0; exp <= 10; ++exp, scale *= 10) {
|
|
540
|
+
double score = GetLatLngMinVertexSeparation(scale, 10 * scale,
|
|
541
|
+
&best_configs);
|
|
542
|
+
best_score = min(best_score, score);
|
|
543
|
+
}
|
|
544
|
+
printf("min_vertex_sep / snap_radius ratio: %.15f\n", best_score);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// A triple of scaled S2LatLng coordinates. The coordinates are multiplied by
|
|
548
|
+
// (M_PI / scale) to convert them to radians.
|
|
549
|
+
struct LatLngConfig {
|
|
550
|
+
int64 scale;
|
|
551
|
+
IntLatLng ll0, ll1, ll2;
|
|
552
|
+
|
|
553
|
+
LatLngConfig(int64 _scale, const IntLatLng& _ll0,
|
|
554
|
+
const IntLatLng& _ll1, const IntLatLng& _ll2) :
|
|
555
|
+
scale(_scale), ll0(_ll0), ll1(_ll1), ll2(_ll2) {
|
|
556
|
+
}
|
|
557
|
+
bool operator<(const LatLngConfig& other) const {
|
|
558
|
+
S2_DCHECK_EQ(scale, other.scale);
|
|
559
|
+
return (make_pair(ll0, make_pair(ll1, ll2)) <
|
|
560
|
+
make_pair(other.ll0, make_pair(other.ll1, other.ll2)));
|
|
561
|
+
}
|
|
562
|
+
bool operator==(const LatLngConfig& other) const {
|
|
563
|
+
return (ll0 == other.ll0 && ll1 == other.ll1 && ll2 == other.ll2);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
typedef double LatLngMinEdgeSeparationFunction(int64 scale, S1Angle edge_sep,
|
|
568
|
+
S1Angle max_snap_radius);
|
|
569
|
+
|
|
570
|
+
static double GetLatLngMinEdgeSeparation(
|
|
571
|
+
const char* label, LatLngMinEdgeSeparationFunction objective,
|
|
572
|
+
int64 scale, vector<LatLngConfig>* best_configs) {
|
|
573
|
+
S1Angle min_snap_radius_at_scale = S1Angle::Radians(M_SQRT1_2 * M_PI / scale);
|
|
574
|
+
vector<pair<double, LatLngConfig>> scores;
|
|
575
|
+
for (LatLngConfig parent : *best_configs) {
|
|
576
|
+
// To reduce duplicates, we require that site0 always has longitude 0.
|
|
577
|
+
S2_DCHECK_EQ(0, parent.ll0[1]);
|
|
578
|
+
double scale_factor = static_cast<double>(scale) / parent.scale;
|
|
579
|
+
parent.ll0 = Rescale(parent.ll0, scale_factor);
|
|
580
|
+
parent.ll1 = Rescale(parent.ll1, scale_factor);
|
|
581
|
+
parent.ll2 = Rescale(parent.ll2, scale_factor);
|
|
582
|
+
for (int dlat0 = -1; dlat0 <= 1; ++dlat0) {
|
|
583
|
+
IntLatLng ll0 = parent.ll0 + IntLatLng(dlat0, 0);
|
|
584
|
+
// To reduce duplicates, we require that site0.latitude >= 0.
|
|
585
|
+
if (!IsValid(ll0, scale) || ll0[0] < 0) continue;
|
|
586
|
+
S2Point site0 = ToPoint(ll0, scale);
|
|
587
|
+
for (int dlat1 = -1; dlat1 <= 1; ++dlat1) {
|
|
588
|
+
for (int dlng1 = -2; dlng1 <= 2; ++dlng1) {
|
|
589
|
+
IntLatLng ll1 = parent.ll1 + IntLatLng(dlat0 + dlat1, dlng1);
|
|
590
|
+
if (ll1 == ll0 || !HasValidVertices(ll1, scale)) continue;
|
|
591
|
+
// Only consider neighbors within 2 latitude units of site0.
|
|
592
|
+
if (abs(ll1[0] - ll0[0]) > 2) continue;
|
|
593
|
+
|
|
594
|
+
S2Point site1 = ToPoint(ll1, scale);
|
|
595
|
+
S1Angle max_v1 = GetMaxVertexDistance(site0, ll1, scale);
|
|
596
|
+
for (int dlat2 = -1; dlat2 <= 1; ++dlat2) {
|
|
597
|
+
for (int dlng2 = -2; dlng2 <= 2; ++dlng2) {
|
|
598
|
+
IntLatLng ll2 = parent.ll2 + IntLatLng(dlat0 + dlat2, dlng2);
|
|
599
|
+
if (!HasValidVertices(ll2, scale)) continue;
|
|
600
|
+
// Only consider neighbors within 2 latitude units of site0.
|
|
601
|
+
if (abs(ll2[0] - ll0[0]) > 2) continue;
|
|
602
|
+
// To reduce duplicates, we require ll1 < ll2 lexicographically
|
|
603
|
+
// and site2.longitude >= 0. (It's *not* okay to
|
|
604
|
+
// require site1.longitude >= 0, because then some configurations
|
|
605
|
+
// with site1.latitude == site2.latitude would be missed.)
|
|
606
|
+
if (ll2 <= ll1 || ll2[1] < 0) continue;
|
|
607
|
+
|
|
608
|
+
S2Point site2 = ToPoint(ll2, scale);
|
|
609
|
+
S1Angle min_snap_radius = GetCircumRadius(site0, site1, site2);
|
|
610
|
+
if (min_snap_radius > S2Builder::SnapFunction::kMaxSnapRadius()) {
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
// Only the original points *before* snapping that need to be at
|
|
614
|
+
// least "snap_radius" away from "site0". The points after
|
|
615
|
+
// snapping ("site1" and "site2") may be closer.
|
|
616
|
+
S1Angle max_v2 = GetMaxVertexDistance(site0, ll2, scale);
|
|
617
|
+
S1Angle max_snap_radius = min(max_v1, max_v2);
|
|
618
|
+
if (min_snap_radius > max_snap_radius) continue;
|
|
619
|
+
if (max_snap_radius < min_snap_radius_at_scale) continue;
|
|
620
|
+
|
|
621
|
+
// This is a valid configuration, so evaluate it.
|
|
622
|
+
S1Angle edge_sep = S2::GetDistance(site0, site1, site2);
|
|
623
|
+
double score = objective(scale, edge_sep, max_snap_radius);
|
|
624
|
+
LatLngConfig config(scale, ll0, ll1, ll2);
|
|
625
|
+
scores.push_back(make_pair(score, config));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
// Now sort the entries, print out the "num_to_print" best ones, and keep
|
|
633
|
+
// the best "num_to_keep" of them to seed the next round.
|
|
634
|
+
std::sort(scores.begin(), scores.end());
|
|
635
|
+
scores.erase(std::unique(scores.begin(), scores.end()), scores.end());
|
|
636
|
+
best_configs->clear();
|
|
637
|
+
int num_to_keep = google::DEBUG_MODE ? 50 : 200;
|
|
638
|
+
int num_to_print = 3;
|
|
639
|
+
printf("Scale %" PRId64 ":\n", int64_t{scale});
|
|
640
|
+
for (const auto& entry : scores) {
|
|
641
|
+
const LatLngConfig& config = entry.second;
|
|
642
|
+
int64 scale = config.scale;
|
|
643
|
+
if (--num_to_print >= 0) {
|
|
644
|
+
printf(" %s = %.15f %s %s %s\n",
|
|
645
|
+
label, entry.first,
|
|
646
|
+
s2textformat::ToString(ToPoint(config.ll0, scale)).c_str(),
|
|
647
|
+
s2textformat::ToString(ToPoint(config.ll1, scale)).c_str(),
|
|
648
|
+
s2textformat::ToString(ToPoint(config.ll2, scale)).c_str());
|
|
649
|
+
}
|
|
650
|
+
// Optional: filter the candidates to concentrate on a specific region
|
|
651
|
+
// (e.g., the north pole).
|
|
652
|
+
best_configs->push_back(config);
|
|
653
|
+
if (--num_to_keep <= 0) break;
|
|
654
|
+
}
|
|
655
|
+
return scores[0].first;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
static double GetLatLngMinEdgeSeparation(
|
|
659
|
+
const char* label, LatLngMinEdgeSeparationFunction objective) {
|
|
660
|
+
double best_score = 1e10;
|
|
661
|
+
vector<LatLngConfig> best_configs;
|
|
662
|
+
int64 scale = 6; // Initially points are 30 degrees apart.
|
|
663
|
+
int max_lng = scale;
|
|
664
|
+
int max_lat = scale / 2;
|
|
665
|
+
for (int lat0 = 0; lat0 <= max_lat; ++lat0) {
|
|
666
|
+
for (int lat1 = lat0 - 2; lat1 <= min(max_lat, lat0 + 2); ++lat1) {
|
|
667
|
+
for (int lng1 = 0; lng1 <= max_lng; ++lng1) {
|
|
668
|
+
for (int lat2 = lat1; lat2 <= min(max_lat, lat0 + 2); ++lat2) {
|
|
669
|
+
for (int lng2 = 0; lng2 <= max_lng; ++lng2) {
|
|
670
|
+
IntLatLng ll0(lat0, 0);
|
|
671
|
+
IntLatLng ll1(lat1, lng1);
|
|
672
|
+
IntLatLng ll2(lat2, lng2);
|
|
673
|
+
if (ll2 <= ll1) continue;
|
|
674
|
+
best_configs.push_back(LatLngConfig(scale, ll0, ll1, ll2));
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
S2_LOG(INFO) << "Starting with " << best_configs.size() << " configurations";
|
|
681
|
+
int64 target_scale = 180;
|
|
682
|
+
for (int exp = 0; exp <= 10; ++exp, target_scale *= 10) {
|
|
683
|
+
while (scale < target_scale) {
|
|
684
|
+
scale = min(static_cast<int64>(1.8 * scale), target_scale);
|
|
685
|
+
double score = GetLatLngMinEdgeSeparation(label, objective, scale,
|
|
686
|
+
&best_configs);
|
|
687
|
+
if (scale == target_scale) {
|
|
688
|
+
best_score = min(best_score, score);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return best_score;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
TEST(IntLatLngSnapFunction, MinEdgeVertexSeparationForLevel) {
|
|
696
|
+
// Computes the minimum edge separation (as a fraction of kMinDiag) for any
|
|
697
|
+
// snap radius at each level.
|
|
698
|
+
double score = GetLatLngMinEdgeSeparation("min_sep_for_level",
|
|
699
|
+
[](int64 scale, S1Angle edge_sep,
|
|
700
|
+
S1Angle max_snap_radius) {
|
|
701
|
+
double e_unit = M_PI / scale;
|
|
702
|
+
return edge_sep.radians() / e_unit;
|
|
703
|
+
});
|
|
704
|
+
printf("min_edge_vertex_sep / e_unit ratio: %.15f\n", score);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
TEST(IntLatLngSnapFunction, MinEdgeVertexSeparationSnapRadiusRatio) {
|
|
708
|
+
// Computes the minimum edge separation expressed as a fraction of the
|
|
709
|
+
// maximum snap radius that could yield that edge separation.
|
|
710
|
+
double score = GetLatLngMinEdgeSeparation("min_sep_snap_radius_ratio",
|
|
711
|
+
[](int64 scale, S1Angle edge_sep,
|
|
712
|
+
S1Angle max_snap_radius) {
|
|
713
|
+
return edge_sep.radians() / max_snap_radius.radians();
|
|
714
|
+
});
|
|
715
|
+
printf("min_edge_vertex_sep / snap_radius ratio: %.15f\n", score);
|
|
716
|
+
}
|