@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,261 @@
|
|
|
1
|
+
// Copyright 2017 Google Inc. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
// Author: ericv@google.com (Eric Veach)
|
|
17
|
+
|
|
18
|
+
#include "s2/s2builderutil_closed_set_normalizer.h"
|
|
19
|
+
|
|
20
|
+
#include <memory>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
#include <gtest/gtest.h>
|
|
24
|
+
#include "s2/third_party/absl/memory/memory.h"
|
|
25
|
+
#include "s2/mutable_s2shape_index.h"
|
|
26
|
+
#include "s2/s2boolean_operation.h"
|
|
27
|
+
#include "s2/s2builder.h"
|
|
28
|
+
#include "s2/s2builder_graph.h"
|
|
29
|
+
#include "s2/s2builder_layer.h"
|
|
30
|
+
#include "s2/s2builderutil_s2point_vector_layer.h"
|
|
31
|
+
#include "s2/s2builderutil_s2polygon_layer.h"
|
|
32
|
+
#include "s2/s2builderutil_s2polyline_vector_layer.h"
|
|
33
|
+
#include "s2/s2builderutil_testing.h"
|
|
34
|
+
#include "s2/s2text_format.h"
|
|
35
|
+
|
|
36
|
+
using absl::make_unique;
|
|
37
|
+
using std::unique_ptr;
|
|
38
|
+
using std::vector;
|
|
39
|
+
|
|
40
|
+
using EdgeType = S2Builder::EdgeType;
|
|
41
|
+
using Graph = S2Builder::Graph;
|
|
42
|
+
using GraphOptions = S2Builder::GraphOptions;
|
|
43
|
+
|
|
44
|
+
using DegenerateEdges = GraphOptions::DegenerateEdges;
|
|
45
|
+
using DuplicateEdges = GraphOptions::DuplicateEdges;
|
|
46
|
+
using SiblingPairs = GraphOptions::SiblingPairs;
|
|
47
|
+
|
|
48
|
+
using Edge = Graph::Edge;
|
|
49
|
+
|
|
50
|
+
namespace s2builderutil {
|
|
51
|
+
|
|
52
|
+
// A test harness that sets default values for ClosedSetNormalizer::Options
|
|
53
|
+
// and the S2Builder::GraphOptions for each of the three output layers.
|
|
54
|
+
class NormalizeTest : public testing::Test {
|
|
55
|
+
public:
|
|
56
|
+
NormalizeTest() : suppress_lower_dimensions_(true) {
|
|
57
|
+
// Set the default GraphOptions for building S2Points, S2Polylines, and
|
|
58
|
+
// S2Polygons. Tests can modify these options as necessary. Most of the
|
|
59
|
+
// defaults are KEEP so that we can verify edge counts in some cases.
|
|
60
|
+
//
|
|
61
|
+
// Polyline edges are undirected by default because (1) this case is
|
|
62
|
+
// slightly more challenging and (2) it is expected to be common.
|
|
63
|
+
graph_options_out_.push_back( // Points
|
|
64
|
+
GraphOptions(EdgeType::DIRECTED, DegenerateEdges::KEEP,
|
|
65
|
+
DuplicateEdges::KEEP, SiblingPairs::KEEP));
|
|
66
|
+
graph_options_out_.push_back( // Polylines
|
|
67
|
+
GraphOptions(EdgeType::UNDIRECTED, DegenerateEdges::KEEP,
|
|
68
|
+
DuplicateEdges::KEEP, SiblingPairs::KEEP));
|
|
69
|
+
graph_options_out_.push_back( // Polygons
|
|
70
|
+
GraphOptions(EdgeType::DIRECTED, DegenerateEdges::KEEP,
|
|
71
|
+
DuplicateEdges::KEEP, SiblingPairs::KEEP));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void Run(const string& input_str, const string& expected_str);
|
|
75
|
+
|
|
76
|
+
protected:
|
|
77
|
+
bool suppress_lower_dimensions_;
|
|
78
|
+
vector<GraphOptions> graph_options_out_;
|
|
79
|
+
|
|
80
|
+
private:
|
|
81
|
+
static string ToString(const Graph& g);
|
|
82
|
+
void AddLayers(const string& str, const vector<GraphOptions>& graph_options,
|
|
83
|
+
vector<Graph>* graphs_out, S2Builder* builder);
|
|
84
|
+
|
|
85
|
+
vector<unique_ptr<GraphClone>> graph_clones_;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
void NormalizeTest::Run(const string& input_str,
|
|
89
|
+
const string& expected_str) {
|
|
90
|
+
ClosedSetNormalizer::Options options;
|
|
91
|
+
options.set_suppress_lower_dimensions(suppress_lower_dimensions_);
|
|
92
|
+
ClosedSetNormalizer normalizer(options, graph_options_out_);
|
|
93
|
+
|
|
94
|
+
S2Builder builder{S2Builder::Options()};
|
|
95
|
+
vector<Graph> input, expected;
|
|
96
|
+
AddLayers(input_str, normalizer.graph_options(), &input, &builder);
|
|
97
|
+
AddLayers(expected_str, graph_options_out_, &expected, &builder);
|
|
98
|
+
S2Error error;
|
|
99
|
+
// Populate the "input" and "expected" vectors.
|
|
100
|
+
EXPECT_TRUE(builder.Build(&error)) << error;
|
|
101
|
+
|
|
102
|
+
const vector<Graph>& actual = normalizer.Run(input, &error);
|
|
103
|
+
for (int dim = 0; dim < 3; ++dim) {
|
|
104
|
+
EXPECT_TRUE(expected[dim].options() == actual[dim].options());
|
|
105
|
+
EXPECT_EQ(ToString(expected[dim]), ToString(actual[dim])) << "dim=" << dim;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void NormalizeTest::AddLayers(
|
|
110
|
+
const string& str, const vector<GraphOptions>& graph_options,
|
|
111
|
+
vector<Graph>* graphs_out, S2Builder* builder) {
|
|
112
|
+
auto index = s2textformat::MakeIndex(str);
|
|
113
|
+
for (int dim = 0; dim < 3; ++dim) {
|
|
114
|
+
builder->StartLayer(make_unique<GraphAppendingLayer>(
|
|
115
|
+
graph_options[dim], graphs_out, &graph_clones_));
|
|
116
|
+
for (S2Shape* shape : *index) {
|
|
117
|
+
if (shape->dimension() != dim) continue;
|
|
118
|
+
int n = shape->num_edges();
|
|
119
|
+
for (int e = 0; e < n; ++e) {
|
|
120
|
+
S2Shape::Edge edge = shape->edge(e);
|
|
121
|
+
builder->AddEdge(edge.v0, edge.v1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
string NormalizeTest::ToString(const Graph& g) {
|
|
128
|
+
string msg;
|
|
129
|
+
for (const auto& edge : g.edges()) {
|
|
130
|
+
vector<S2Point> vertices = { g.vertex(edge.first),
|
|
131
|
+
g.vertex(edge.second) };
|
|
132
|
+
msg += s2textformat::ToString(vertices);
|
|
133
|
+
msg += "; ";
|
|
134
|
+
}
|
|
135
|
+
return msg;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
TEST_F(NormalizeTest, EmptyGraphs) {
|
|
139
|
+
Run("# #", "# #");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
TEST_F(NormalizeTest, NonDegenerateInputs) {
|
|
143
|
+
Run("0:0 # 1:0, 1:1 | 1:2, 1:3 # 2:2, 2:3, 3:2",
|
|
144
|
+
"0:0 # 1:0, 1:1 | 1:2, 1:3 # 2:2, 2:3, 3:2");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
TEST_F(NormalizeTest, PointShell) {
|
|
148
|
+
Run("# # 0:0", "0:0 # #");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
TEST_F(NormalizeTest, PointHole) {
|
|
152
|
+
Run("# # 0:0, 0:3, 3:0 | 1:1", "# # 0:0, 0:3, 3:0");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
TEST_F(NormalizeTest, PointPolyline) {
|
|
156
|
+
// Verify that a single degenerate polyline edge is transformed into a
|
|
157
|
+
// single point. Note that since the polyline layer is undirected while the
|
|
158
|
+
// point layer is not, this tests that the edge count is halved when the
|
|
159
|
+
// edge is demoted.
|
|
160
|
+
Run("# 0:0, 0:0 #", "0:0 # #");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
TEST_F(NormalizeTest, SiblingPairShell) {
|
|
164
|
+
Run("# # 0:0, 1:0 ", "# 0:0, 1:0 #");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
TEST_F(NormalizeTest, SiblingPairHole) {
|
|
168
|
+
Run("# # 0:0, 0:3, 3:0; 0:0, 1:1",
|
|
169
|
+
"# # 0:0, 0:3, 3:0");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
TEST_F(NormalizeTest, PointSuppressedByPolygonVertex) {
|
|
173
|
+
Run("0:0 | 0:1 | 1:0 # # 0:0, 0:1, 1:0",
|
|
174
|
+
"# # 0:0, 0:1, 1:0");
|
|
175
|
+
suppress_lower_dimensions_ = false;
|
|
176
|
+
Run("0:0 | 0:1 | 1:0 # # 0:0, 0:1, 1:0",
|
|
177
|
+
"0:0 | 0:1 | 1:0 # # 0:0, 0:1, 1:0");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
TEST_F(NormalizeTest, PointSuppressedByPolylineVertex) {
|
|
181
|
+
Run("0:0 | 0:1 # 0:0, 0:1 #", "# 0:0, 0:1 #");
|
|
182
|
+
suppress_lower_dimensions_ = false;
|
|
183
|
+
Run("0:0 | 0:1 # 0:0, 0:1 #", "0:0 | 0:1 # 0:0, 0:1 #");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
TEST_F(NormalizeTest, PointShellSuppressedByPolylineEdge) {
|
|
187
|
+
// This tests the case where a single-point shell is demoted to a point
|
|
188
|
+
// which is then suppressed by a matching polyline vertex.
|
|
189
|
+
Run("# 0:0, 1:0 # 0:0; 1:0", "# 0:0, 1:0 #");
|
|
190
|
+
suppress_lower_dimensions_ = false;
|
|
191
|
+
Run("# 0:0, 1:0 # 0:0; 1:0", "0:0 | 1:0 # 0:0, 1:0 #");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
TEST_F(NormalizeTest, PolylineEdgeSuppressedByPolygonEdge) {
|
|
195
|
+
Run("# 0:0, 0:1 # 0:0, 0:1, 1:0", "# # 0:0, 0:1, 1:0");
|
|
196
|
+
suppress_lower_dimensions_ = false;
|
|
197
|
+
Run("# 0:0, 0:1 # 0:0, 0:1, 1:0", "# 0:0, 0:1 # 0:0, 0:1, 1:0");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
TEST_F(NormalizeTest, PolylineEdgeSuppressedByReversePolygonEdge) {
|
|
201
|
+
graph_options_out_[1].set_edge_type(EdgeType::DIRECTED);
|
|
202
|
+
Run("# 1:0, 0:0 # 0:0, 0:1, 1:0", "# # 0:0, 0:1, 1:0");
|
|
203
|
+
suppress_lower_dimensions_ = false;
|
|
204
|
+
Run("# 1:0, 0:0 # 0:0, 0:1, 1:0", "# 1:0, 0:0 # 0:0, 0:1, 1:0");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
TEST_F(NormalizeTest, DuplicateEdgeMerging) {
|
|
208
|
+
// Verify that when DuplicateEdges::KEEP is specified, demoted edges are
|
|
209
|
+
// added as new edges rather than being merged with existing ones.
|
|
210
|
+
// (Note that NormalizeTest specifies DuplicateEdges::KEEP by default.)
|
|
211
|
+
Run("0:0 | 0:0 # 0:0, 0:0 | 0:1, 0:2 # 0:0; 0:1, 0:2",
|
|
212
|
+
"0:0 | 0:0 | 0:0 | 0:0 # 0:1, 0:2 | 0:1, 0:2 #");
|
|
213
|
+
// Now verify that the duplicate edges are merged if requested.
|
|
214
|
+
graph_options_out_[0].set_duplicate_edges(DuplicateEdges::MERGE);
|
|
215
|
+
graph_options_out_[1].set_duplicate_edges(DuplicateEdges::MERGE);
|
|
216
|
+
Run("0:0 | 0:0 # 0:0, 0:0 | 0:1, 0:2 # 0:0; 0:1, 0:2",
|
|
217
|
+
"0:0 # 0:1, 0:2 #");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// If this code changes, please update the header file comments to match.
|
|
221
|
+
bool ComputeUnion(const S2ShapeIndex& a, const S2ShapeIndex& b,
|
|
222
|
+
MutableS2ShapeIndex* index, S2Error* error) {
|
|
223
|
+
IndexedS2PolylineVectorLayer::Options polyline_options;
|
|
224
|
+
polyline_options.set_edge_type(EdgeType::UNDIRECTED);
|
|
225
|
+
polyline_options.set_polyline_type(Graph::PolylineType::WALK);
|
|
226
|
+
polyline_options.set_duplicate_edges(DuplicateEdges::MERGE);
|
|
227
|
+
LayerVector layers(3);
|
|
228
|
+
layers[0] = make_unique<IndexedS2PointVectorLayer>(index);
|
|
229
|
+
layers[1] = make_unique<IndexedS2PolylineVectorLayer>(
|
|
230
|
+
index, polyline_options);
|
|
231
|
+
layers[2] = make_unique<IndexedS2PolygonLayer>(index);
|
|
232
|
+
S2BooleanOperation op(S2BooleanOperation::OpType::UNION,
|
|
233
|
+
NormalizeClosedSet(std::move(layers)));
|
|
234
|
+
return op.Build(a, b, error);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
TEST(ComputeUnion, MixedGeometry) {
|
|
238
|
+
// Verifies that the code above works. Features tested include:
|
|
239
|
+
// - Points and polylines in the interior of the other polygon are removed
|
|
240
|
+
// - Degenerate polygon shells are converted to points/polylines
|
|
241
|
+
// - Degenerate polygon holes are removed
|
|
242
|
+
// - Points coincident with polyline or polygon edges are removed
|
|
243
|
+
// - Polyline edges coincident with polygon edges are removed
|
|
244
|
+
auto a = s2textformat::MakeIndex(
|
|
245
|
+
"0:0 | 10:10 | 20:20 # "
|
|
246
|
+
"0:0, 0:10 | 0:0, 10:0 | 15:15, 16:16 # "
|
|
247
|
+
"0:0, 0:10, 10:10, 10:0; 0:0, 1:1; 2:2; 10:10, 11:11; 12:12");
|
|
248
|
+
auto b = s2textformat::MakeIndex(
|
|
249
|
+
"0:10 | 10:0 | 3:3 | 16:16 # "
|
|
250
|
+
"10:10, 0:10 | 10:10, 10:0 | 5:5, 6:6 # "
|
|
251
|
+
"19:19, 19:21, 21:21, 21:19");
|
|
252
|
+
MutableS2ShapeIndex result;
|
|
253
|
+
S2Error error;
|
|
254
|
+
ASSERT_TRUE(ComputeUnion(*a, *b, &result, &error));
|
|
255
|
+
EXPECT_EQ("12:12 # "
|
|
256
|
+
"15:15, 16:16 | 10:10, 11:11 # "
|
|
257
|
+
"0:0, 0:10, 10:10, 10:0; 19:19, 19:21, 21:21, 21:19",
|
|
258
|
+
s2textformat::ToString(result));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
} // namespace s2builderutil
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
// Copyright 2017 Google Inc. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
// Author: ericv@google.com (Eric Veach)
|
|
17
|
+
|
|
18
|
+
#include "s2/s2builderutil_find_polygon_degeneracies.h"
|
|
19
|
+
|
|
20
|
+
#include <cstdlib>
|
|
21
|
+
#include <utility>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
#include "s2/third_party/absl/memory/memory.h"
|
|
25
|
+
#include "s2/mutable_s2shape_index.h"
|
|
26
|
+
#include "s2/s2builder_graph.h"
|
|
27
|
+
#include "s2/s2builderutil_graph_shape.h"
|
|
28
|
+
#include "s2/s2contains_vertex_query.h"
|
|
29
|
+
#include "s2/s2crossing_edge_query.h"
|
|
30
|
+
#include "s2/s2edge_crosser.h"
|
|
31
|
+
#include "s2/s2pointutil.h"
|
|
32
|
+
#include "s2/s2predicates.h"
|
|
33
|
+
|
|
34
|
+
using absl::make_unique;
|
|
35
|
+
using std::make_pair;
|
|
36
|
+
using std::pair;
|
|
37
|
+
using std::vector;
|
|
38
|
+
|
|
39
|
+
using EdgeType = S2Builder::EdgeType;
|
|
40
|
+
using Graph = S2Builder::Graph;
|
|
41
|
+
using GraphOptions = S2Builder::GraphOptions;
|
|
42
|
+
|
|
43
|
+
using Edge = Graph::Edge;
|
|
44
|
+
using EdgeId = Graph::EdgeId;
|
|
45
|
+
using VertexId = Graph::VertexId;
|
|
46
|
+
|
|
47
|
+
using DegenerateEdges = GraphOptions::DegenerateEdges;
|
|
48
|
+
using SiblingPairs = GraphOptions::SiblingPairs;
|
|
49
|
+
|
|
50
|
+
using ShapeEdgeId = s2shapeutil::ShapeEdgeId;
|
|
51
|
+
|
|
52
|
+
namespace s2builderutil {
|
|
53
|
+
|
|
54
|
+
namespace {
|
|
55
|
+
|
|
56
|
+
// The algorithm builds a set of connected components containing all edges
|
|
57
|
+
// that form degeneracies. The shell/hole status of each degeneracy is
|
|
58
|
+
// initially unknown, and is expressed relative to the root vertex: "is_hole"
|
|
59
|
+
// means that the degeneracy is a hole if and only if the root vertex turns
|
|
60
|
+
// out to be inside the polygon.
|
|
61
|
+
struct Component {
|
|
62
|
+
// The root vertex from which this component was built.
|
|
63
|
+
VertexId root;
|
|
64
|
+
|
|
65
|
+
// +1 if "root" inside the polygon, -1 if outside, and 0 if unknown.
|
|
66
|
+
int root_sign = 0;
|
|
67
|
+
|
|
68
|
+
// The degeneracies found in this component. "is_hole" is expressed
|
|
69
|
+
// relative to the root vertex: the degeneracy is a hole iff the root vertex
|
|
70
|
+
// turns out to be inside the polygon (i.e., root_sign > 0).
|
|
71
|
+
vector<PolygonDegeneracy> degeneracies;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// The actual implementation of FindPolygonDegeneracies.
|
|
75
|
+
class DegeneracyFinder {
|
|
76
|
+
public:
|
|
77
|
+
explicit DegeneracyFinder(const S2Builder::Graph* g)
|
|
78
|
+
: g_(*g), in_(g_), out_(g_) {
|
|
79
|
+
}
|
|
80
|
+
vector<PolygonDegeneracy> Run(S2Error* error);
|
|
81
|
+
|
|
82
|
+
private:
|
|
83
|
+
// Methods are documented below.
|
|
84
|
+
int ComputeDegeneracies();
|
|
85
|
+
Component BuildComponent(VertexId root);
|
|
86
|
+
bool CrossingParity(VertexId v0, VertexId v1, bool include_same) const;
|
|
87
|
+
VertexId FindUnbalancedVertex() const;
|
|
88
|
+
int ContainsVertexSign(VertexId v0) const;
|
|
89
|
+
void ComputeUnknownSignsBruteForce(VertexId known_vertex,
|
|
90
|
+
int known_vertex_sign,
|
|
91
|
+
vector<Component>* components) const;
|
|
92
|
+
void ComputeUnknownSignsIndexed(VertexId known_vertex, int known_vertex_sign,
|
|
93
|
+
vector<Component>* components) const;
|
|
94
|
+
vector<PolygonDegeneracy> MergeDegeneracies(
|
|
95
|
+
const vector<Component>& components) const;
|
|
96
|
+
|
|
97
|
+
const Graph& g_;
|
|
98
|
+
Graph::VertexInMap in_;
|
|
99
|
+
Graph::VertexOutMap out_;
|
|
100
|
+
vector<bool> is_vertex_used_; // Has vertex been visited?
|
|
101
|
+
vector<bool> is_edge_degeneracy_; // Belongs to a degeneracy?
|
|
102
|
+
vector<bool> is_vertex_unbalanced_; // Has unbalanced sibling pairs?
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
vector<PolygonDegeneracy> DegeneracyFinder::Run(S2Error* error) {
|
|
106
|
+
// Mark all degenerate edges and sibling pairs in the "is_edge_degeneracy_"
|
|
107
|
+
// vector, and mark any vertices with unbalanced edges in the
|
|
108
|
+
// "is_vertex_unbalanced_" vector.
|
|
109
|
+
int num_degeneracies = ComputeDegeneracies();
|
|
110
|
+
if (num_degeneracies == 0) return {};
|
|
111
|
+
|
|
112
|
+
// If all edges are degenerate, then use IsFullPolygon() to classify the
|
|
113
|
+
// degeneracies (they are necessarily all the same type).
|
|
114
|
+
if (num_degeneracies == g_.num_edges()) {
|
|
115
|
+
bool is_hole = g_.IsFullPolygon(error);
|
|
116
|
+
vector<PolygonDegeneracy> result(g_.num_edges());
|
|
117
|
+
for (int e = 0; e < g_.num_edges(); ++e) {
|
|
118
|
+
result[e] = PolygonDegeneracy(e, is_hole);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Otherwise repeatedly build components starting from an unvisited
|
|
124
|
+
// degeneracy. (This avoids building components that don't contain any
|
|
125
|
+
// degeneracies.) Each component records the "is_hole" status of each
|
|
126
|
+
// degeneracy relative to the root vertex of that component. If the
|
|
127
|
+
// component contains any non-degenerate portions, then we also determine
|
|
128
|
+
// whether the root vertex is contained by the component (root_sign).
|
|
129
|
+
// In addition we keep track of the number of components that were
|
|
130
|
+
// completely degenerate (to help us decide whether to build an index).
|
|
131
|
+
vector<Component> components;
|
|
132
|
+
VertexId known_vertex = -1;
|
|
133
|
+
int known_vertex_sign = 0;
|
|
134
|
+
int num_unknown_signs = 0;
|
|
135
|
+
is_vertex_used_.resize(g_.num_vertices());
|
|
136
|
+
for (int e = 0; e < g_.num_edges(); ++e) {
|
|
137
|
+
if (is_edge_degeneracy_[e]) {
|
|
138
|
+
VertexId root = g_.edge(e).first;
|
|
139
|
+
if (is_vertex_used_[root]) continue;
|
|
140
|
+
Component component = BuildComponent(root);
|
|
141
|
+
if (component.root_sign == 0) {
|
|
142
|
+
++num_unknown_signs;
|
|
143
|
+
} else {
|
|
144
|
+
known_vertex = root;
|
|
145
|
+
known_vertex_sign = component.root_sign;
|
|
146
|
+
}
|
|
147
|
+
components.push_back(component);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// If some components have an unknown root_sign (i.e., it is unknown whether
|
|
152
|
+
// the root vertex is contained by the polygon or not), we determine the
|
|
153
|
+
// sign of those root vertices by counting crossings starting from a vertex
|
|
154
|
+
// whose sign is known. Depending on how many components we need to do this
|
|
155
|
+
// for, it may be worthwhile to build an index first.
|
|
156
|
+
if (num_unknown_signs > 0) {
|
|
157
|
+
if (known_vertex_sign == 0) {
|
|
158
|
+
known_vertex = FindUnbalancedVertex();
|
|
159
|
+
known_vertex_sign = ContainsVertexSign(known_vertex);
|
|
160
|
+
}
|
|
161
|
+
const int kMaxUnindexedContainsCalls = 20; // Tuned using benchmarks.
|
|
162
|
+
if (num_unknown_signs <= kMaxUnindexedContainsCalls) {
|
|
163
|
+
ComputeUnknownSignsBruteForce(known_vertex, known_vertex_sign,
|
|
164
|
+
&components);
|
|
165
|
+
} else {
|
|
166
|
+
ComputeUnknownSignsIndexed(known_vertex, known_vertex_sign,
|
|
167
|
+
&components);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Finally we convert the "is_hole" status of each degeneracy from a
|
|
171
|
+
// relative value (compared to the component's root vertex) to an absolute
|
|
172
|
+
// one, and sort all the degeneracies by EdgeId.
|
|
173
|
+
return MergeDegeneracies(components);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
int DegeneracyFinder::ComputeDegeneracies() {
|
|
177
|
+
is_edge_degeneracy_.resize(g_.num_edges());
|
|
178
|
+
is_vertex_unbalanced_.resize(g_.num_vertices());
|
|
179
|
+
int num_degeneracies = 0;
|
|
180
|
+
const vector<EdgeId>& in_edge_ids = in_.in_edge_ids();
|
|
181
|
+
int n = g_.num_edges();
|
|
182
|
+
for (int in = 0, out = 0; out < n; ++out) {
|
|
183
|
+
Edge out_edge = g_.edge(out);
|
|
184
|
+
if (out_edge.first == out_edge.second) {
|
|
185
|
+
is_edge_degeneracy_[out] = true;
|
|
186
|
+
++num_degeneracies;
|
|
187
|
+
} else {
|
|
188
|
+
while (in < n && Graph::reverse(g_.edge(in_edge_ids[in])) < out_edge) {
|
|
189
|
+
++in;
|
|
190
|
+
}
|
|
191
|
+
if (in < n && Graph::reverse(g_.edge(in_edge_ids[in])) == out_edge) {
|
|
192
|
+
is_edge_degeneracy_[out] = true;
|
|
193
|
+
++num_degeneracies;
|
|
194
|
+
} else {
|
|
195
|
+
// This edge does not have a sibling, which mean that we can determine
|
|
196
|
+
// whether either vertex is contained by the polygon (using semi-open
|
|
197
|
+
// boundaries) by examining only the edges incident to that vertex.
|
|
198
|
+
// We only mark the first vertex since there is no advantage to
|
|
199
|
+
// finding more than one unbalanced vertex per connected component.
|
|
200
|
+
is_vertex_unbalanced_[out_edge.first] = true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return num_degeneracies;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Build a connected component starting at the given root vertex. The
|
|
208
|
+
// information returned includes: the root vertex, whether the containment
|
|
209
|
+
// status of the root vertex could be determined using only the edges in this
|
|
210
|
+
// component, and a vector of the edges that belong to degeneracies along with
|
|
211
|
+
// the shell/hole status of each such edge relative to the root vertex.
|
|
212
|
+
Component DegeneracyFinder::BuildComponent(VertexId root) {
|
|
213
|
+
Component result;
|
|
214
|
+
result.root = root;
|
|
215
|
+
// We keep track of the frontier of unexplored vertices, and whether each
|
|
216
|
+
// vertex is on the same side of the polygon boundary as the root vertex.
|
|
217
|
+
vector<pair<VertexId, bool>> frontier;
|
|
218
|
+
frontier.push_back(make_pair(root, true));
|
|
219
|
+
is_vertex_used_[root] = true;
|
|
220
|
+
while (!frontier.empty()) {
|
|
221
|
+
VertexId v0 = frontier.back().first;
|
|
222
|
+
bool v0_same_inside = frontier.back().second; // Same as root vertex?
|
|
223
|
+
frontier.pop_back();
|
|
224
|
+
if (result.root_sign == 0 && is_vertex_unbalanced_[v0]) {
|
|
225
|
+
int v0_sign = ContainsVertexSign(v0);
|
|
226
|
+
S2_DCHECK_NE(v0_sign, 0);
|
|
227
|
+
result.root_sign = v0_same_inside ? v0_sign : -v0_sign;
|
|
228
|
+
}
|
|
229
|
+
for (EdgeId e : out_.edge_ids(v0)) {
|
|
230
|
+
VertexId v1 = g_.edge(e).second;
|
|
231
|
+
bool same_inside = v0_same_inside ^ CrossingParity(v0, v1, false);
|
|
232
|
+
if (is_edge_degeneracy_[e]) {
|
|
233
|
+
result.degeneracies.push_back(PolygonDegeneracy(e, same_inside));
|
|
234
|
+
}
|
|
235
|
+
if (is_vertex_used_[v1]) continue;
|
|
236
|
+
same_inside ^= CrossingParity(v1, v0, true);
|
|
237
|
+
frontier.push_back(make_pair(v1, same_inside));
|
|
238
|
+
is_vertex_used_[v1] = true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Counts the number of times that (v0, v1) crosses the edges incident to v0,
|
|
245
|
+
// and returns the result modulo 2. This is equivalent to calling
|
|
246
|
+
// S2::VertexCrossing for the edges incident to v0, except that this
|
|
247
|
+
// implementation is more efficient (since it doesn't need to determine which
|
|
248
|
+
// two edge vertices are the same).
|
|
249
|
+
//
|
|
250
|
+
// If "include_same" is false, then the edge (v0, v1) and its sibling (v1, v0)
|
|
251
|
+
// (if any) are excluded from the parity calculation.
|
|
252
|
+
bool DegeneracyFinder::CrossingParity(VertexId v0, VertexId v1,
|
|
253
|
+
bool include_same) const {
|
|
254
|
+
int crossings = 0;
|
|
255
|
+
S2Point p0 = g_.vertex(v0);
|
|
256
|
+
S2Point p1 = g_.vertex(v1);
|
|
257
|
+
S2Point p0_ref = S2::Ortho(p0);
|
|
258
|
+
for (const Edge& edge : out_.edges(v0)) {
|
|
259
|
+
if (edge.second == v1) {
|
|
260
|
+
if (include_same) ++crossings;
|
|
261
|
+
} else if (s2pred::OrderedCCW(p0_ref, g_.vertex(edge.second), p1, p0)) {
|
|
262
|
+
++crossings;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
for (EdgeId e : in_.edge_ids(v0)) {
|
|
266
|
+
Edge edge = g_.edge(e);
|
|
267
|
+
if (edge.first == v1) {
|
|
268
|
+
if (include_same) ++crossings;
|
|
269
|
+
} else if (s2pred::OrderedCCW(p0_ref, g_.vertex(edge.first), p1, p0)) {
|
|
270
|
+
++crossings;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return crossings & 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
VertexId DegeneracyFinder::FindUnbalancedVertex() const {
|
|
277
|
+
for (VertexId v = 0; v < g_.num_vertices(); ++v) {
|
|
278
|
+
if (is_vertex_unbalanced_[v]) return v;
|
|
279
|
+
}
|
|
280
|
+
S2_LOG(DFATAL) << "Could not find previously marked unbalanced vertex";
|
|
281
|
+
return -1;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
int DegeneracyFinder::ContainsVertexSign(VertexId v0) const {
|
|
285
|
+
S2ContainsVertexQuery query(g_.vertex(v0));
|
|
286
|
+
for (const Edge& edge : out_.edges(v0)) {
|
|
287
|
+
query.AddEdge(g_.vertex(edge.second), 1);
|
|
288
|
+
}
|
|
289
|
+
for (EdgeId e : in_.edge_ids(v0)) {
|
|
290
|
+
query.AddEdge(g_.vertex(g_.edge(e).first), -1);
|
|
291
|
+
}
|
|
292
|
+
return query.ContainsSign();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Determines any unknown signs of component root vertices by counting
|
|
296
|
+
// crossings starting from a vertex whose sign is known. This version simply
|
|
297
|
+
// tests all edges for crossings.
|
|
298
|
+
void DegeneracyFinder::ComputeUnknownSignsBruteForce(
|
|
299
|
+
VertexId known_vertex, int known_vertex_sign,
|
|
300
|
+
vector<Component>* components) const {
|
|
301
|
+
S2EdgeCrosser crosser;
|
|
302
|
+
for (Component& component : *components) {
|
|
303
|
+
if (component.root_sign != 0) continue;
|
|
304
|
+
bool inside = known_vertex_sign > 0;
|
|
305
|
+
crosser.Init(&g_.vertex(known_vertex), &g_.vertex(component.root));
|
|
306
|
+
for (EdgeId e = 0; e < g_.num_edges(); ++e) {
|
|
307
|
+
if (is_edge_degeneracy_[e]) continue;
|
|
308
|
+
const Edge& edge = g_.edge(e);
|
|
309
|
+
inside ^= crosser.EdgeOrVertexCrossing(&g_.vertex(edge.first),
|
|
310
|
+
&g_.vertex(edge.second));
|
|
311
|
+
}
|
|
312
|
+
component.root_sign = inside ? 1 : -1;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Like ComputeUnknownSignsBruteForce, except that this method uses an index
|
|
317
|
+
// to find the set of edges that cross a given edge.
|
|
318
|
+
void DegeneracyFinder::ComputeUnknownSignsIndexed(
|
|
319
|
+
VertexId known_vertex, int known_vertex_sign,
|
|
320
|
+
vector<Component>* components) const {
|
|
321
|
+
MutableS2ShapeIndex index;
|
|
322
|
+
index.Add(make_unique<GraphShape>(&g_));
|
|
323
|
+
S2CrossingEdgeQuery query(&index);
|
|
324
|
+
vector<ShapeEdgeId> crossing_edges;
|
|
325
|
+
S2EdgeCrosser crosser;
|
|
326
|
+
for (Component& component : *components) {
|
|
327
|
+
if (component.root_sign != 0) continue;
|
|
328
|
+
bool inside = known_vertex_sign > 0;
|
|
329
|
+
crosser.Init(&g_.vertex(known_vertex), &g_.vertex(component.root));
|
|
330
|
+
query.GetCandidates(g_.vertex(known_vertex), g_.vertex(component.root),
|
|
331
|
+
*index.shape(0), &crossing_edges);
|
|
332
|
+
for (ShapeEdgeId id : crossing_edges) {
|
|
333
|
+
int e = id.edge_id;
|
|
334
|
+
if (is_edge_degeneracy_[e]) continue;
|
|
335
|
+
inside ^= crosser.EdgeOrVertexCrossing(&g_.vertex(g_.edge(e).first),
|
|
336
|
+
&g_.vertex(g_.edge(e).second));
|
|
337
|
+
}
|
|
338
|
+
component.root_sign = inside ? 1 : -1;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Merges the degeneracies from all components together, and computes the
|
|
343
|
+
// final "is_hole" status of each edge (since up to this point, the "is_hole"
|
|
344
|
+
// value has been expressed relative to the root vertex of each component).
|
|
345
|
+
vector<PolygonDegeneracy> DegeneracyFinder::MergeDegeneracies(
|
|
346
|
+
const vector<Component>& components) const {
|
|
347
|
+
vector<PolygonDegeneracy> result;
|
|
348
|
+
for (const Component& component : components) {
|
|
349
|
+
S2_DCHECK_NE(component.root_sign, 0);
|
|
350
|
+
bool invert = component.root_sign < 0;
|
|
351
|
+
for (const auto& d : component.degeneracies) {
|
|
352
|
+
result.push_back(PolygonDegeneracy(d.edge_id, d.is_hole ^ invert));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
std::sort(result.begin(), result.end());
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
void CheckGraphOptions(const Graph& g) {
|
|
360
|
+
S2_DCHECK(g.options().edge_type() == EdgeType::DIRECTED);
|
|
361
|
+
S2_DCHECK(g.options().degenerate_edges() == DegenerateEdges::DISCARD ||
|
|
362
|
+
g.options().degenerate_edges() == DegenerateEdges::DISCARD_EXCESS);
|
|
363
|
+
S2_DCHECK(g.options().sibling_pairs() == SiblingPairs::DISCARD ||
|
|
364
|
+
g.options().sibling_pairs() == SiblingPairs::DISCARD_EXCESS);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
} // namespace
|
|
368
|
+
|
|
369
|
+
vector<PolygonDegeneracy> FindPolygonDegeneracies(const Graph& g,
|
|
370
|
+
S2Error* error) {
|
|
371
|
+
CheckGraphOptions(g);
|
|
372
|
+
if (g.options().degenerate_edges() == DegenerateEdges::DISCARD &&
|
|
373
|
+
g.options().sibling_pairs() == SiblingPairs::DISCARD) {
|
|
374
|
+
return {}; // All degeneracies have already been discarded.
|
|
375
|
+
}
|
|
376
|
+
return DegeneracyFinder(&g).Run(error);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
bool IsFullyDegenerate(const S2Builder::Graph& g) {
|
|
380
|
+
CheckGraphOptions(g);
|
|
381
|
+
const vector<Edge>& edges = g.edges();
|
|
382
|
+
for (int e = 0; e < g.num_edges(); ++e) {
|
|
383
|
+
Edge edge = edges[e];
|
|
384
|
+
if (edge.first == edge.second) continue;
|
|
385
|
+
if (!std::binary_search(edges.begin(), edges.end(), Graph::reverse(edge))) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
} // namespace s2builderutil
|