@@ -34,7 +34,7 @@ type cellIndexNode struct {
3434// newCellIndexNode returns a node with the appropriate default values.
3535func newCellIndexNode () cellIndexNode {
3636 return cellIndexNode {
37- cellID : 0 ,
37+ cellID : CellID ( 0 ) ,
3838 label : cellIndexDoneContents ,
3939 parent : - 1 ,
4040 }
@@ -49,15 +49,52 @@ type rangeNode struct {
4949 contents int32 // Contents of this node (an index within the cell tree).
5050}
5151
52+ type labels []int32
53+
54+ func (l * labels ) Normalize () {
55+ encountered := make (map [int32 ]struct {})
56+
57+ for i := range * l {
58+ encountered [(* l )[i ]] = struct {}{}
59+ }
60+
61+ * l = (* l )[:0 ]
62+ for key := range encountered {
63+ * l = append (* l , key )
64+ }
65+ }
66+
67+ type cellVisitor func (cellID CellID , label int32 ) bool
68+
5269// CellIndexIterator is an iterator that visits the entire set of indexed
5370// (CellID, label) pairs in an unspecified order.
5471type CellIndexIterator struct {
55- // TODO(roberts): Implement
72+ nodes []cellIndexNode
73+ pos int
5674}
5775
5876// NewCellIndexIterator creates an iterator for the given CellIndex.
5977func NewCellIndexIterator (index * CellIndex ) * CellIndexIterator {
60- return & CellIndexIterator {}
78+ return & CellIndexIterator {
79+ nodes : index .cellTree ,
80+ pos : 0 ,
81+ }
82+ }
83+
84+ func (c * CellIndexIterator ) CellID () CellID {
85+ return c .nodes [c .pos ].cellID
86+ }
87+
88+ func (c * CellIndexIterator ) Label () int32 {
89+ return c .nodes [c .pos ].label
90+ }
91+
92+ func (c * CellIndexIterator ) Done () bool {
93+ return c .pos == len (c .nodes )
94+ }
95+
96+ func (c * CellIndexIterator ) Next () {
97+ c .pos ++
6198}
6299
63100// CellIndexRangeIterator is an iterator that seeks and iterates over a set of
@@ -202,7 +239,6 @@ func (c *CellIndexRangeIterator) Seek(target CellID) {
202239
203240 // Nonempty needs to find the next non-empty entry.
204241 for c .nonEmpty && c .IsEmpty () && ! c .Done () {
205- // c.Next()
206242 c .pos ++
207243 }
208244}
@@ -246,7 +282,7 @@ type CellIndexContentsIterator struct {
246282func NewCellIndexContentsIterator (index * CellIndex ) * CellIndexContentsIterator {
247283 it := & CellIndexContentsIterator {
248284 cellTree : index .cellTree ,
249- prevStartID : 0 ,
285+ prevStartID : CellID ( 0 ) ,
250286 nodeCutoff : - 1 ,
251287 nextNodeCutoff : - 1 ,
252288 node : cellIndexNode {label : cellIndexDoneContents },
@@ -256,7 +292,7 @@ func NewCellIndexContentsIterator(index *CellIndex) *CellIndexContentsIterator {
256292
257293// Clear clears all state with respect to which range(s) have been visited.
258294func (c * CellIndexContentsIterator ) Clear () {
259- c .prevStartID = 0
295+ c .prevStartID = CellID ( 0 )
260296 c .nodeCutoff = - 1
261297 c .nextNodeCutoff = - 1
262298 c .node .label = cellIndexDoneContents
@@ -343,7 +379,7 @@ func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) {
343379// There is also a helper method that adds all elements of CellUnion with the
344380// same label:
345381//
346- // index.AddCellUnion(cellUnion, label)
382+ // index.AddCellUnion(cellUnion, label)
347383//
348384// Note that the index is not dynamic; the contents of the index cannot be
349385// changed once it has been built. Adding more after calling Build results in
@@ -353,7 +389,7 @@ func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) {
353389// is to use a built-in method such as IntersectingLabels (which returns
354390// the labels of all cells that intersect a given target CellUnion):
355391//
356- // labels := index.IntersectingLabels(targetUnion);
392+ // labels := index.IntersectingLabels(targetUnion);
357393//
358394// Alternatively, you can use a ClosestCellQuery which computes the cell(s)
359395// that are closest to a given target geometry.
@@ -482,7 +518,8 @@ func (c *CellIndex) Build() {
482518 c .cellTree = append (c .cellTree , cellIndexNode {
483519 cellID : deltas [i ].cellID ,
484520 label : deltas [i ].label ,
485- parent : contents })
521+ parent : contents ,
522+ })
486523 contents = int32 (len (c .cellTree ) - 1 )
487524 } else if deltas [i ].cellID == SentinelCellID {
488525 contents = c .cellTree [contents ].parent
@@ -492,7 +529,48 @@ func (c *CellIndex) Build() {
492529 }
493530}
494531
495- // TODO(roberts): Differences from C++
496- // IntersectingLabels
497- // VisitIntersectingCells
498- // CellIndexIterator
532+ func (c * CellIndex ) IntersectingLabels (target CellUnion ) []int32 {
533+ var labels labels
534+ c .VisitIntersectingCells (target , func (cellID CellID , label int32 ) bool {
535+ labels = append (labels , label )
536+ return true
537+ })
538+
539+ labels .Normalize ()
540+ return labels
541+ }
542+
543+ func (c * CellIndex ) VisitIntersectingCells (target CellUnion , visitor cellVisitor ) bool {
544+ if len (target ) == 0 {
545+ return true
546+ }
547+
548+ pos := 0
549+ contents := NewCellIndexContentsIterator (c )
550+ rangeIter := NewCellIndexRangeIterator (c )
551+ rangeIter .Begin ()
552+
553+ for ok := true ; ok ; ok = pos != len (target ) {
554+ if rangeIter .LimitID () <= target [pos ].RangeMin () {
555+ rangeIter .Seek (target [pos ].RangeMin ())
556+ }
557+
558+ for ; rangeIter .StartID () <= target [pos ].RangeMax (); rangeIter .Next () {
559+ for contents .StartUnion (rangeIter ); ! contents .Done (); contents .Next () {
560+ if ! visitor (contents .CellID (), contents .Label ()) {
561+ return false
562+ }
563+ }
564+ }
565+
566+ pos ++
567+ if pos != len (target ) && target [pos ].RangeMax () < rangeIter .StartID () {
568+ pos = target .lowerBound (pos + 1 , len (target ), rangeIter .StartID ())
569+ if target [pos - 1 ].RangeMax () >= rangeIter .StartID () {
570+ pos --
571+ }
572+ }
573+ }
574+
575+ return true
576+ }
0 commit comments