@@ -34,7 +34,7 @@ type cellIndexNode struct {
34
34
// newCellIndexNode returns a node with the appropriate default values.
35
35
func newCellIndexNode () cellIndexNode {
36
36
return cellIndexNode {
37
- cellID : 0 ,
37
+ cellID : CellID ( 0 ) ,
38
38
label : cellIndexDoneContents ,
39
39
parent : - 1 ,
40
40
}
@@ -49,15 +49,52 @@ type rangeNode struct {
49
49
contents int32 // Contents of this node (an index within the cell tree).
50
50
}
51
51
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
+
52
69
// CellIndexIterator is an iterator that visits the entire set of indexed
53
70
// (CellID, label) pairs in an unspecified order.
54
71
type CellIndexIterator struct {
55
- // TODO(roberts): Implement
72
+ nodes []cellIndexNode
73
+ pos int
56
74
}
57
75
58
76
// NewCellIndexIterator creates an iterator for the given CellIndex.
59
77
func 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 ++
61
98
}
62
99
63
100
// CellIndexRangeIterator is an iterator that seeks and iterates over a set of
@@ -202,7 +239,6 @@ func (c *CellIndexRangeIterator) Seek(target CellID) {
202
239
203
240
// Nonempty needs to find the next non-empty entry.
204
241
for c .nonEmpty && c .IsEmpty () && ! c .Done () {
205
- // c.Next()
206
242
c .pos ++
207
243
}
208
244
}
@@ -246,7 +282,7 @@ type CellIndexContentsIterator struct {
246
282
func NewCellIndexContentsIterator (index * CellIndex ) * CellIndexContentsIterator {
247
283
it := & CellIndexContentsIterator {
248
284
cellTree : index .cellTree ,
249
- prevStartID : 0 ,
285
+ prevStartID : CellID ( 0 ) ,
250
286
nodeCutoff : - 1 ,
251
287
nextNodeCutoff : - 1 ,
252
288
node : cellIndexNode {label : cellIndexDoneContents },
@@ -256,7 +292,7 @@ func NewCellIndexContentsIterator(index *CellIndex) *CellIndexContentsIterator {
256
292
257
293
// Clear clears all state with respect to which range(s) have been visited.
258
294
func (c * CellIndexContentsIterator ) Clear () {
259
- c .prevStartID = 0
295
+ c .prevStartID = CellID ( 0 )
260
296
c .nodeCutoff = - 1
261
297
c .nextNodeCutoff = - 1
262
298
c .node .label = cellIndexDoneContents
@@ -343,7 +379,7 @@ func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) {
343
379
// There is also a helper method that adds all elements of CellUnion with the
344
380
// same label:
345
381
//
346
- // index.AddCellUnion(cellUnion, label)
382
+ // index.AddCellUnion(cellUnion, label)
347
383
//
348
384
// Note that the index is not dynamic; the contents of the index cannot be
349
385
// changed once it has been built. Adding more after calling Build results in
@@ -353,7 +389,7 @@ func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) {
353
389
// is to use a built-in method such as IntersectingLabels (which returns
354
390
// the labels of all cells that intersect a given target CellUnion):
355
391
//
356
- // labels := index.IntersectingLabels(targetUnion);
392
+ // labels := index.IntersectingLabels(targetUnion);
357
393
//
358
394
// Alternatively, you can use a ClosestCellQuery which computes the cell(s)
359
395
// that are closest to a given target geometry.
@@ -482,7 +518,8 @@ func (c *CellIndex) Build() {
482
518
c .cellTree = append (c .cellTree , cellIndexNode {
483
519
cellID : deltas [i ].cellID ,
484
520
label : deltas [i ].label ,
485
- parent : contents })
521
+ parent : contents ,
522
+ })
486
523
contents = int32 (len (c .cellTree ) - 1 )
487
524
} else if deltas [i ].cellID == SentinelCellID {
488
525
contents = c .cellTree [contents ].parent
@@ -492,7 +529,48 @@ func (c *CellIndex) Build() {
492
529
}
493
530
}
494
531
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