diff --git a/CMakeLists.txt b/CMakeLists.txt index 4044cd90..a5049901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,185 +260,193 @@ endif() # list(APPEND CMAKE_MODULE_PATH "/third_party/cmake") # add_subdirectory( s2geometry) # target_link_libraries( s2) -target_include_directories(s2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +if (S2_SYSTEM_HEADERS) + # it's useful to avoid warnings from s2 headers + # because it's impossible to pass same settings to target_link_libraries + target_include_directories(s2 SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +else () + target_include_directories(s2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +endif () # Add version information to the target set_target_properties(s2 PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION}) -# We don't need to install all headers, only those -# transitively included by s2 headers we are exporting. -install(FILES src/s2/_fp_contract_off.h - src/s2/encoded_s2cell_id_vector.h - src/s2/encoded_s2point_vector.h - src/s2/encoded_s2shape_index.h - src/s2/encoded_string_vector.h - src/s2/encoded_uint_vector.h - src/s2/id_set_lexicon.h - src/s2/mutable_s2shape_index.h - src/s2/r1interval.h - src/s2/r2.h - src/s2/r2rect.h - src/s2/s1angle.h - src/s2/s1chord_angle.h - src/s2/s1interval.h - src/s2/s2boolean_operation.h - src/s2/s2buffer_operation.h - src/s2/s2builder.h - src/s2/s2builder_graph.h - src/s2/s2builder_layer.h - src/s2/s2builderutil_closed_set_normalizer.h - src/s2/s2builderutil_find_polygon_degeneracies.h - src/s2/s2builderutil_get_snapped_winding_delta.h - src/s2/s2builderutil_graph_shape.h - src/s2/s2builderutil_lax_polygon_layer.h - src/s2/s2builderutil_lax_polyline_layer.h - src/s2/s2builderutil_s2point_vector_layer.h - src/s2/s2builderutil_s2polygon_layer.h - src/s2/s2builderutil_s2polyline_layer.h - src/s2/s2builderutil_s2polyline_vector_layer.h - src/s2/s2builderutil_snap_functions.h - src/s2/s2builderutil_testing.h - src/s2/s2cap.h - src/s2/s2cell.h - src/s2/s2cell_id.h - src/s2/s2cell_index.h - src/s2/s2cell_union.h - src/s2/s2centroids.h - src/s2/s2closest_cell_query.h - src/s2/s2closest_cell_query_base.h - src/s2/s2closest_edge_query.h - src/s2/s2closest_edge_query_base.h - src/s2/s2closest_point_query.h - src/s2/s2closest_point_query_base.h - src/s2/s2contains_point_query.h - src/s2/s2contains_vertex_query.h - src/s2/s2convex_hull_query.h - src/s2/s2coords_internal.h - src/s2/s2coords.h - src/s2/s2crossing_edge_query.h - src/s2/s2debug.h - src/s2/s2distance_target.h - src/s2/s2earth.h - src/s2/s2edge_clipping.h - src/s2/s2edge_crosser.h - src/s2/s2edge_crossings.h - src/s2/s2edge_crossings_internal.h - src/s2/s2edge_distances.h - src/s2/s2edge_tessellator.h - src/s2/s2edge_vector_shape.h - src/s2/s2error.h - src/s2/s2furthest_edge_query.h - src/s2/s2hausdorff_distance_query.h - src/s2/s2latlng.h - src/s2/s2latlng_rect.h - src/s2/s2latlng_rect_bounder.h - src/s2/s2lax_loop_shape.h - src/s2/s2lax_polygon_shape.h - src/s2/s2lax_polyline_shape.h - src/s2/s2loop.h - src/s2/s2loop_measures.h - src/s2/s2measures.h - src/s2/s2memory_tracker.h - src/s2/s2metrics.h - src/s2/s2max_distance_targets.h - src/s2/s2min_distance_targets.h - src/s2/s2padded_cell.h - src/s2/s2point.h - src/s2/s2point_vector_shape.h - src/s2/s2point_compression.h - src/s2/s2point_index.h - src/s2/s2point_region.h - src/s2/s2point_span.h - src/s2/s2pointutil.h - src/s2/s2polygon.h - src/s2/s2polyline.h - src/s2/s2polyline_alignment.h - src/s2/s2polyline_measures.h - src/s2/s2polyline_simplifier.h - src/s2/s2predicates.h - src/s2/s2predicates_internal.h - src/s2/s2projections.h - src/s2/s2r2rect.h - src/s2/s2region.h - src/s2/s2region_term_indexer.h - src/s2/s2region_coverer.h - src/s2/s2region_intersection.h - src/s2/s2region_union.h - src/s2/s2shape.h - src/s2/s2shape_index.h - src/s2/s2shape_index_buffered_region.h - src/s2/s2shape_index_region.h - src/s2/s2shape_measures.h - src/s2/s2shape_nesting_query.h - src/s2/s2shapeutil_build_polygon_boundaries.h - src/s2/s2shapeutil_coding.h - src/s2/s2shapeutil_contains_brute_force.h - src/s2/s2shapeutil_conversion.h - src/s2/s2shapeutil_count_edges.h - src/s2/s2shapeutil_edge_iterator.h - src/s2/s2shapeutil_get_reference_point.h - src/s2/s2shapeutil_range_iterator.h - src/s2/s2shapeutil_shape_edge.h - src/s2/s2shapeutil_shape_edge_id.h - src/s2/s2shapeutil_testing.h - src/s2/s2shapeutil_visit_crossing_edge_pairs.h - src/s2/s2testing.h - src/s2/s2text_format.h - src/s2/s2wedge_relations.h - src/s2/s2winding_operation.h - src/s2/s2wrapped_shape.h - src/s2/sequence_lexicon.h - src/s2/thread_testing.h - src/s2/value_lexicon.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2") -install(FILES src/s2/base/casts.h - src/s2/base/commandlineflags.h - src/s2/base/integral_types.h - src/s2/base/log_severity.h - src/s2/base/logging.h - src/s2/base/port.h - src/s2/base/spinlock.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/base") -install(FILES src/s2/util/bitmap/bitmap.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/bitmap") -install(FILES src/s2/util/bits/bits.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/bits") -install(FILES src/s2/util/coding/coder.h - src/s2/util/coding/varint.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/coding") -install(FILES src/s2/util/endian/endian.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/endian") -install(FILES src/s2/util/gtl/compact_array.h - src/s2/util/gtl/container_logging.h - src/s2/util/gtl/dense_hash_set.h - src/s2/util/gtl/densehashtable.h - src/s2/util/gtl/hashtable_common.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/gtl") -install(FILES src/s2/util/hash/mix.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/hash") -install(FILES src/s2/util/math/mathutil.h - src/s2/util/math/matrix3x3.h - src/s2/util/math/vector.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/math") -install(FILES src/s2/util/math/exactfloat/exactfloat.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/math/exactfloat") -install(FILES src/s2/util/units/length-units.h - src/s2/util/units/physical-units.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/units") - -if (GTEST_ROOT) - set(S2_TARGETS s2 s2testing) -else() - set(S2_TARGETS s2) +if (NOT S2_DO_NOT_INSTALL) + # We don't need to install all headers, only those + # transitively included by s2 headers we are exporting. + install(FILES src/s2/_fp_contract_off.h + src/s2/encoded_s2cell_id_vector.h + src/s2/encoded_s2point_vector.h + src/s2/encoded_s2shape_index.h + src/s2/encoded_string_vector.h + src/s2/encoded_uint_vector.h + src/s2/id_set_lexicon.h + src/s2/mutable_s2shape_index.h + src/s2/r1interval.h + src/s2/r2.h + src/s2/r2rect.h + src/s2/s1angle.h + src/s2/s1chord_angle.h + src/s2/s1interval.h + src/s2/s2boolean_operation.h + src/s2/s2buffer_operation.h + src/s2/s2builder.h + src/s2/s2builder_graph.h + src/s2/s2builder_layer.h + src/s2/s2builderutil_closed_set_normalizer.h + src/s2/s2builderutil_find_polygon_degeneracies.h + src/s2/s2builderutil_get_snapped_winding_delta.h + src/s2/s2builderutil_graph_shape.h + src/s2/s2builderutil_lax_polygon_layer.h + src/s2/s2builderutil_lax_polyline_layer.h + src/s2/s2builderutil_s2point_vector_layer.h + src/s2/s2builderutil_s2polygon_layer.h + src/s2/s2builderutil_s2polyline_layer.h + src/s2/s2builderutil_s2polyline_vector_layer.h + src/s2/s2builderutil_snap_functions.h + src/s2/s2builderutil_testing.h + src/s2/s2cap.h + src/s2/s2cell.h + src/s2/s2cell_id.h + src/s2/s2cell_index.h + src/s2/s2cell_union.h + src/s2/s2centroids.h + src/s2/s2closest_cell_query.h + src/s2/s2closest_cell_query_base.h + src/s2/s2closest_edge_query.h + src/s2/s2closest_edge_query_base.h + src/s2/s2closest_point_query.h + src/s2/s2closest_point_query_base.h + src/s2/s2contains_point_query.h + src/s2/s2contains_vertex_query.h + src/s2/s2convex_hull_query.h + src/s2/s2coords_internal.h + src/s2/s2coords.h + src/s2/s2crossing_edge_query.h + src/s2/s2debug.h + src/s2/s2distance_target.h + src/s2/s2earth.h + src/s2/s2edge_clipping.h + src/s2/s2edge_crosser.h + src/s2/s2edge_crossings.h + src/s2/s2edge_crossings_internal.h + src/s2/s2edge_distances.h + src/s2/s2edge_tessellator.h + src/s2/s2edge_vector_shape.h + src/s2/s2error.h + src/s2/s2furthest_edge_query.h + src/s2/s2hausdorff_distance_query.h + src/s2/s2latlng.h + src/s2/s2latlng_rect.h + src/s2/s2latlng_rect_bounder.h + src/s2/s2lax_loop_shape.h + src/s2/s2lax_polygon_shape.h + src/s2/s2lax_polyline_shape.h + src/s2/s2loop.h + src/s2/s2loop_measures.h + src/s2/s2measures.h + src/s2/s2memory_tracker.h + src/s2/s2metrics.h + src/s2/s2max_distance_targets.h + src/s2/s2min_distance_targets.h + src/s2/s2padded_cell.h + src/s2/s2point.h + src/s2/s2point_vector_shape.h + src/s2/s2point_compression.h + src/s2/s2point_index.h + src/s2/s2point_region.h + src/s2/s2point_span.h + src/s2/s2pointutil.h + src/s2/s2polygon.h + src/s2/s2polyline.h + src/s2/s2polyline_alignment.h + src/s2/s2polyline_measures.h + src/s2/s2polyline_simplifier.h + src/s2/s2predicates.h + src/s2/s2predicates_internal.h + src/s2/s2projections.h + src/s2/s2r2rect.h + src/s2/s2region.h + src/s2/s2region_term_indexer.h + src/s2/s2region_coverer.h + src/s2/s2region_intersection.h + src/s2/s2region_union.h + src/s2/s2shape.h + src/s2/s2shape_index.h + src/s2/s2shape_index_buffered_region.h + src/s2/s2shape_index_region.h + src/s2/s2shape_measures.h + src/s2/s2shape_nesting_query.h + src/s2/s2shapeutil_build_polygon_boundaries.h + src/s2/s2shapeutil_coding.h + src/s2/s2shapeutil_contains_brute_force.h + src/s2/s2shapeutil_conversion.h + src/s2/s2shapeutil_count_edges.h + src/s2/s2shapeutil_edge_iterator.h + src/s2/s2shapeutil_get_reference_point.h + src/s2/s2shapeutil_range_iterator.h + src/s2/s2shapeutil_shape_edge.h + src/s2/s2shapeutil_shape_edge_id.h + src/s2/s2shapeutil_testing.h + src/s2/s2shapeutil_visit_crossing_edge_pairs.h + src/s2/s2testing.h + src/s2/s2text_format.h + src/s2/s2wedge_relations.h + src/s2/s2winding_operation.h + src/s2/s2wrapped_shape.h + src/s2/sequence_lexicon.h + src/s2/thread_testing.h + src/s2/value_lexicon.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2") + install(FILES src/s2/base/casts.h + src/s2/base/commandlineflags.h + src/s2/base/integral_types.h + src/s2/base/log_severity.h + src/s2/base/logging.h + src/s2/base/port.h + src/s2/base/spinlock.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/base") + install(FILES src/s2/util/bitmap/bitmap.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/bitmap") + install(FILES src/s2/util/bits/bits.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/bits") + install(FILES src/s2/util/coding/coder.h + src/s2/util/coding/varint.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/coding") + install(FILES src/s2/util/endian/endian.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/endian") + install(FILES src/s2/util/gtl/compact_array.h + src/s2/util/gtl/container_logging.h + src/s2/util/gtl/dense_hash_set.h + src/s2/util/gtl/densehashtable.h + src/s2/util/gtl/hashtable_common.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/gtl") + install(FILES src/s2/util/hash/mix.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/hash") + install(FILES src/s2/util/math/mathutil.h + src/s2/util/math/matrix3x3.h + src/s2/util/math/vector.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/math") + install(FILES src/s2/util/math/exactfloat/exactfloat.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/math/exactfloat") + install(FILES src/s2/util/units/length-units.h + src/s2/util/units/physical-units.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/s2/util/units") + + if (GTEST_ROOT) + set(S2_TARGETS s2 s2testing) + else() + set(S2_TARGETS s2) + endif() + + install(TARGETS ${S2_TARGETS} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() -install(TARGETS ${S2_TARGETS} - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") - message("GTEST_ROOT: ${GTEST_ROOT}") if (GTEST_ROOT) add_subdirectory(${GTEST_ROOT} build_gtest) diff --git a/src/s2/s2polygon.h b/src/s2/s2polygon.h index 9981ae0f..82f1619e 100644 --- a/src/s2/s2polygon.h +++ b/src/s2/s2polygon.h @@ -701,6 +701,9 @@ class S2Polygon final : public S2Region { S2Polygon* Clone() const override; S2Cap GetCapBound() const override; // Cap surrounding rect bound. S2LatLngRect GetRectBound() const override { return bound_; } + // It's useful for external Contains operation. + // (see subregion_bound_ definition for details) + S2LatLngRect GetSubRegionBound() const { return subregion_bound_; } void GetCellUnionBound(std::vector *cell_ids) const override; bool Contains(const S2Cell& cell) const override; diff --git a/src/s2/s2region_term_indexer.cc b/src/s2/s2region_term_indexer.cc index 5c73e66d..39b2c6e1 100644 --- a/src/s2/s2region_term_indexer.cc +++ b/src/s2/s2region_term_indexer.cc @@ -126,6 +126,14 @@ string S2RegionTermIndexer::GetTerm(TermType term_type, const S2CellId id, vector S2RegionTermIndexer::GetIndexTerms(const S2Point& point, string_view prefix) { + vector terms; + GetIndexTerms(point, prefix, &terms); + return terms; +} + +void S2RegionTermIndexer::GetIndexTerms(const S2Point& point, + string_view prefix, + vector* terms) { // See the top of this file for an overview of the indexing strategy. // // The last cell generated by this loop is effectively the covering for @@ -136,12 +144,13 @@ vector S2RegionTermIndexer::GetIndexTerms(const S2Point& point, // max_level() != true_max_level() (see S2RegionCoverer::Options). const S2CellId id(point); - vector terms; - for (int level = options_.min_level(); level <= options_.max_level(); - level += options_.level_mod()) { - terms.push_back(GetTerm(TermType::ANCESTOR, id.parent(level), prefix)); + int level = options_.min_level(); + if (options_.query_contains_points_only()) { + level = options_.true_max_level(); + } + for (; level <= options_.max_level(); level += options_.level_mod()) { + terms->push_back(GetTerm(TermType::ANCESTOR, id.parent(level), prefix)); } - return terms; } vector S2RegionTermIndexer::GetIndexTerms(const S2Region& region, @@ -154,6 +163,13 @@ vector S2RegionTermIndexer::GetIndexTerms(const S2Region& region, vector S2RegionTermIndexer::GetIndexTermsForCanonicalCovering( const S2CellUnion& covering, string_view prefix) { + vector terms; + GetIndexTermsForCanonicalCovering(covering, prefix, &terms); + return terms; +} + +void S2RegionTermIndexer::GetIndexTermsForCanonicalCovering( + const S2CellUnion& covering, string_view prefix, vector* terms) { // See the top of this file for an overview of the indexing strategy. // // Cells in the covering are normally indexed as covering terms. If we are @@ -168,7 +184,6 @@ vector S2RegionTermIndexer::GetIndexTermsForCanonicalCovering( *coverer_.mutable_options() = options_; S2_CHECK(coverer_.IsCanonical(covering)); } - vector terms; S2CellId prev_id = S2CellId::None(); int true_max_level = options_.true_max_level(); for (S2CellId id : covering) { @@ -178,14 +193,20 @@ vector S2RegionTermIndexer::GetIndexTermsForCanonicalCovering( S2_DCHECK_GE(level, options_.min_level()); S2_DCHECK_LE(level, options_.max_level()); S2_DCHECK_EQ(0, (level - options_.min_level()) % options_.level_mod()); + // assume level <= options_.true_max_level() - if (level < true_max_level) { - // Add a covering term for this cell. - terms.push_back(GetTerm(TermType::COVERING, id, prefix)); - } - if (level == true_max_level || !options_.optimize_for_space()) { - // Add an ancestor term for this cell at the constrained level. - terms.push_back(GetTerm(TermType::ANCESTOR, id.parent(level), prefix)); + const bool is_max_level_cell = level == true_max_level; + // Add a term for this cell, max_level cell ANCESTOR is optimization + terms->push_back(GetTerm(is_max_level_cell ? TermType::ANCESTOR + : TermType::COVERING, + id, prefix)); + + // If query only contains points, there are no need other terms. + if (options_.query_contains_points_only()) continue; + + if (!options_.optimize_for_space() && !is_max_level_cell) { + // Add an ancestor term for this cell. + terms->push_back(GetTerm(TermType::ANCESTOR, id, prefix)); } // Finally, add ancestor terms for all the ancestors of this cell. while ((level -= options_.level_mod()) >= options_.min_level()) { @@ -194,29 +215,34 @@ vector S2RegionTermIndexer::GetIndexTermsForCanonicalCovering( prev_id.parent(level) == ancestor_id) { break; // We have already processed this cell and its ancestors. } - terms.push_back(GetTerm(TermType::ANCESTOR, ancestor_id, prefix)); + terms->push_back(GetTerm(TermType::ANCESTOR, ancestor_id, prefix)); } prev_id = id; } - return terms; } vector S2RegionTermIndexer::GetQueryTerms(const S2Point& point, string_view prefix) { + vector terms; + GetQueryTerms(point, prefix, &terms); + return terms; +} + +void S2RegionTermIndexer::GetQueryTerms(const S2Point& point, + string_view prefix, + vector* terms) { // See the top of this file for an overview of the indexing strategy. const S2CellId id(point); - vector terms; // Recall that all true_max_level() cells are indexed only as ancestor terms. int level = options_.true_max_level(); - terms.push_back(GetTerm(TermType::ANCESTOR, id.parent(level), prefix)); - if (options_.index_contains_points_only()) return terms; + terms->push_back(GetTerm(TermType::ANCESTOR, id.parent(level), prefix)); + if (options_.index_contains_points_only()) return; // Add covering terms for all the ancestor cells. for (; level >= options_.min_level(); level -= options_.level_mod()) { - terms.push_back(GetTerm(TermType::COVERING, id.parent(level), prefix)); + terms->push_back(GetTerm(TermType::COVERING, id.parent(level), prefix)); } - return terms; } vector S2RegionTermIndexer::GetQueryTerms(const S2Region& region, @@ -229,13 +255,20 @@ vector S2RegionTermIndexer::GetQueryTerms(const S2Region& region, vector S2RegionTermIndexer::GetQueryTermsForCanonicalCovering( const S2CellUnion& covering, string_view prefix) { + vector terms; + GetQueryTermsForCanonicalCovering(covering, prefix, &terms); + return terms; +} + +void S2RegionTermIndexer::GetQueryTermsForCanonicalCovering( + const S2CellUnion& covering, string_view prefix, vector* terms) { // See the top of this file for an overview of the indexing strategy. + S2_CHECK(!options_.query_contains_points_only()); if (google::DEBUG_MODE) { *coverer_.mutable_options() = options_; S2_CHECK(coverer_.IsCanonical(covering)); } - vector terms; S2CellId prev_id = S2CellId::None(); int true_max_level = options_.true_max_level(); for (S2CellId id : covering) { @@ -245,9 +278,10 @@ vector S2RegionTermIndexer::GetQueryTermsForCanonicalCovering( S2_DCHECK_GE(level, options_.min_level()); S2_DCHECK_LE(level, options_.max_level()); S2_DCHECK_EQ(0, (level - options_.min_level()) % options_.level_mod()); + // assume level <= options_.true_max_level() // Cells in the covering are always queried as ancestor terms. - terms.push_back(GetTerm(TermType::ANCESTOR, id, prefix)); + terms->push_back(GetTerm(TermType::ANCESTOR, id, prefix)); // If the index only contains points, there are no covering terms. if (options_.index_contains_points_only()) continue; @@ -255,8 +289,8 @@ vector S2RegionTermIndexer::GetQueryTermsForCanonicalCovering( // If we are optimizing for index space rather than query time, cells are // also queried as covering terms (except for true_max_level() cells, // which are indexed and queried as ancestor cells only). - if (options_.optimize_for_space() && level < true_max_level) { - terms.push_back(GetTerm(TermType::COVERING, id, prefix)); + if (options_.optimize_for_space() && level != true_max_level) { + terms->push_back(GetTerm(TermType::COVERING, id, prefix)); } // Finally, add covering terms for all the ancestors of this cell. while ((level -= options_.level_mod()) >= options_.min_level()) { @@ -265,9 +299,8 @@ vector S2RegionTermIndexer::GetQueryTermsForCanonicalCovering( prev_id.parent(level) == ancestor_id) { break; // We have already processed this cell and its ancestors. } - terms.push_back(GetTerm(TermType::COVERING, ancestor_id, prefix)); + terms->push_back(GetTerm(TermType::COVERING, ancestor_id, prefix)); } prev_id = id; } - return terms; } diff --git a/src/s2/s2region_term_indexer.h b/src/s2/s2region_term_indexer.h index 44650799..13210de5 100644 --- a/src/s2/s2region_term_indexer.h +++ b/src/s2/s2region_term_indexer.h @@ -196,8 +196,21 @@ class S2RegionTermIndexer { // this flag if your index consists entirely of points.) // // DEFAULT: false - bool index_contains_points_only() const { return points_only_; } - void set_index_contains_points_only(bool value) { points_only_ = value; } + bool index_contains_points_only() const { return index_points_only_; } + void set_index_contains_points_only(bool value) { index_points_only_ = value; } + + // If your query will only contain points (rather than regions), be sure + // to set this flag. This will generate smaller and faster index that + // are specialized for the points-only case. + // + // With the default quality settings, this flag reduces the number of + // index terms by about a factor of two. (The improvement gets smaller + // as max_cells() is increased, but there is really no reason not to use + // this flag if your query consist entirely of points.) + // + // DEFAULT: false + bool query_contains_points_only() const { return query_points_only_; } + void set_query_contains_points_only(bool value) { query_points_only_ = value; } // If true, the index will be optimized for space rather than for query // time. With the default quality settings, this flag reduces the number @@ -221,7 +234,8 @@ class S2RegionTermIndexer { void set_marker_character(char ch); private: - bool points_only_ = false; + bool index_points_only_ = false; + bool query_points_only_ = false; bool optimize_for_space_ = false; std::string marker_ = std::string(1, '$'); }; @@ -243,6 +257,12 @@ class S2RegionTermIndexer { const Options& options() const { return options_; } Options* mutable_options() { return &options_; } + // Returns the current coverer. + // It's useful if for some data you use GetIndexTerms + // and for another GetIndexTermsForCanonicalCovering but still need coverer. + const S2RegionCoverer& coverer() const { return coverer_; } + S2RegionCoverer* mutable_coverer() { return &coverer_; } + // Converts the given region into a set of terms for indexing. Terms // consist of lowercase letters, numbers, '$', and an optional prefix. // @@ -287,6 +307,21 @@ class S2RegionTermIndexer { std::vector GetQueryTermsForCanonicalCovering( const S2CellUnion& covering, absl::string_view prefix); + // Same as above but allows to reuse same buffer for different points or use + // single buffer for multiple points (common case is GeoJson MultiPoint) + void GetIndexTerms(const S2Point& point, absl::string_view prefix, + std::vector* terms); + void GetQueryTerms(const S2Point& point, absl::string_view prefix, + std::vector* terms); + + // Same as above but allows to reuse same buffer for different covering + void GetIndexTermsForCanonicalCovering(const S2CellUnion &covering, + absl::string_view prefix, + std::vector *terms); + void GetQueryTermsForCanonicalCovering(const S2CellUnion &covering, + absl::string_view prefix, + std::vector *terms); + private: enum TermType { ANCESTOR, COVERING };