@@ -305,8 +305,6 @@ class S2ClosestEdgeQueryBase {
305305 void FindClosestEdgesOptimized (std::optional<ResultVisitor> visitor = {});
306306 void InitQueue ();
307307 void InitCovering ();
308- void AddInitialRange (const S2ShapeIndex::Iterator& first,
309- const S2ShapeIndex::Iterator& last);
310308 void MaybeAddResult (const S2Shape& shape, int shape_id, int edge_id);
311309 void AddResult (const Result& result);
312310 void ProcessEdges (const QueueEntry& entry);
@@ -921,53 +919,55 @@ void S2ClosestEdgeQueryBase<Distance>::InitCovering() {
921919 // Don't need to reserve index_cells_ since it is an InlinedVector.
922920 index_covering_.reserve (6 );
923921
924- // TODO(ericv): Use a single iterator (iter_) below and save position
925- // information using pair<S2CellId, const S2ShapeIndexCell*> type.
926- S2ShapeIndex::Iterator next (index_, S2ShapeIndex::BEGIN);
927- S2ShapeIndex::Iterator last (index_, S2ShapeIndex::END);
928- last.Prev ();
929- if (next.id () != last.id ()) {
930- // The index has at least two cells. Choose a level such that the entire
931- // index can be spanned with at most 6 cells (if the index spans multiple
932- // faces) or 4 cells (it the index spans a single face).
933- int level = next.id ().GetCommonAncestorLevel (last.id ()) + 1 ;
934-
935- // Visit each potential top-level cell except the last (handled below).
936- S2CellId last_id = last.id ().parent (level);
937- for (S2CellId id = next.id ().parent (level); id != last_id; id = id.next ()) {
938- // Skip any top-level cells that don't contain any index cells.
939- if (id.range_max () < next.id ()) continue ;
940-
941- // Find the range of index cells contained by this top-level cell and
942- // then shrink the cell if necessary so that it just covers them.
943- S2ShapeIndex::Iterator cell_first = next;
944- next.Seek (id.range_max ().next ());
945- S2ShapeIndex::Iterator cell_last = next;
946- cell_last.Prev ();
947- AddInitialRange (cell_first, cell_last);
948- }
922+ S2ShapeIndex::Iterator iter (index_, S2ShapeIndex::BEGIN);
923+
924+ using IndexPosition = std::pair<S2CellId, const S2ShapeIndexCell*>;
925+
926+ IndexPosition first = {iter.id (), &iter.cell ()};
927+ iter.Finish ();
928+ iter.Prev ();
929+ IndexPosition last = {iter.id (), &iter.cell ()};
930+
931+ if (first.first == last.first ) {
932+ index_covering_.push_back (first.first );
933+ index_cells_.push_back (first.second );
934+ return ;
949935 }
950- AddInitialRange (next, last);
951- }
952936
953- // Add an entry to index_covering_ and index_cells_ that covers the given
954- // inclusive range of cells.
955- //
956- // REQUIRES: "first" and "last" have a common ancestor.
957- template <class Distance >
958- void S2ClosestEdgeQueryBase<Distance>::AddInitialRange(
959- const S2ShapeIndex::Iterator& first,
960- const S2ShapeIndex::Iterator& last) {
961- if (first.id () == last.id ()) {
962- // The range consists of a single index cell.
963- index_covering_.push_back (first.id ());
964- index_cells_.push_back (&first.cell ());
965- } else {
966- // Add the lowest common ancestor of the given range.
967- int level = first.id ().GetCommonAncestorLevel (last.id ());
968- ABSL_DCHECK_GE (level, 0 );
969- index_covering_.push_back (first.id ().parent (level));
970- index_cells_.push_back (nullptr );
937+ // The index has at least two cells. Choose a level such that the entire
938+ // index can be spanned with at most 6 cells (if the index spans multiple
939+ // faces) or 4 cells (if the index spans a single face).
940+ int level = first.first .GetCommonAncestorLevel (last.first ) + 1 ;
941+
942+ // Visit each top-level cell.
943+ iter.Begin ();
944+ S2CellId last_top_level = last.first .parent (level);
945+ for (S2CellId id = first.first .parent (level); ; id = id.next ()) {
946+ // Skip any top-level cells that don't contain any index cells.
947+ if (id.range_max () < iter.id ()) {
948+ if (id == last_top_level) break ;
949+ continue ;
950+ }
951+
952+ // Find the range of index cells contained by this top-level cell and
953+ // then shrink the cell if necessary so that it just covers them.
954+ IndexPosition cell_first = {iter.id (), &iter.cell ()};
955+ iter.Seek (id.range_max ().next ());
956+ iter.Prev ();
957+ IndexPosition cell_last = {iter.id (), &iter.cell ()};
958+
959+ if (cell_first.first == cell_last.first ) {
960+ index_covering_.push_back (cell_first.first );
961+ index_cells_.push_back (cell_first.second );
962+ } else {
963+ int ancestor_level = cell_first.first .GetCommonAncestorLevel (cell_last.first );
964+ ABSL_DCHECK_GE (ancestor_level, 0 );
965+ index_covering_.push_back (cell_first.first .parent (ancestor_level));
966+ index_cells_.push_back (nullptr );
967+ }
968+
969+ if (id == last_top_level) break ;
970+ iter.Next ();
971971 }
972972}
973973
0 commit comments