forked from go-spatial/tegola
-
Notifications
You must be signed in to change notification settings - Fork 0
/
walker.go
133 lines (116 loc) · 2.67 KB
/
walker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package intersect
import (
"github.com/terranodo/tegola/container/singlelist/point/list"
"github.com/terranodo/tegola/maths"
)
type Inbound struct {
pt *Point
seen map[list.Elementer]bool
iseen map[*Point]bool
}
func NewInbound(pt *Point) *Inbound {
if pt == nil {
return nil
}
seen := make(map[list.Elementer]bool)
iseen := make(map[*Point]bool)
return &Inbound{pt: pt, seen: seen, iseen: iseen}
}
func (ib *Inbound) Next() (nib *Inbound) {
var pt *Point
var ok bool
for p := ib.pt.Next(); ib.pt != p; p = p.Next() {
if p == nil {
return
}
// skip elements that are not points.
if pt, ok = p.(*Point); !ok {
continue
}
ipp := asIntersect(p)
if pt.Inward && !ib.iseen[ipp] {
nib := NewInbound(pt)
nib.seen = ib.seen
nib.iseen = ib.iseen
return nib
}
}
return nil
}
func next(p list.Elementer) list.Elementer {
switch ppt := p.(type) {
case *Point:
return ppt.NextWalk()
case *SubjectPoint:
ipt := ppt.AsIntersectPoint()
return ipt.NextWalk()
case *RegionPoint:
ipt := ppt.AsIntersectPoint()
return ipt.NextWalk()
case list.ElementerPointer:
return ppt.Next()
default:
return nil
}
}
func asIntersect(p list.Elementer) *Point {
switch ppt := p.(type) {
case *Point:
return ppt
case *SubjectPoint:
return ppt.AsIntersectPoint()
case *RegionPoint:
return ppt.AsIntersectPoint()
default:
return nil
}
}
func (ib *Inbound) Walk(fn func(idx int, pt maths.Pt) bool) {
firstInboundPoint := ib.pt
if ib.iseen[firstInboundPoint] {
// we already saw this point, let's move on.
//log.Printf("Already saw (%.3v) at (%p)%[2]#v upping count(%v).", 0, firstInboundPoint, 0)
return
}
//log.Printf("Walk Looking at %#v", firstInboundPoint)
if !fn(0, firstInboundPoint.Point()) {
// log.Printf("Bailing after first point.")
return
}
ib.seen[firstInboundPoint] = true
ib.iseen[firstInboundPoint] = true
//count := 0
//log.Println("\n\nStarting walk:\n\n")
//defer log.Println("\nEnding Walk\n")
for i, p := 1, next(firstInboundPoint); ; i, p = i+1, next(p) {
// We have found the original point.
ipp := asIntersect(p)
if ipp == firstInboundPoint {
//log.Println("Back to the begining.\n\n\n")
return
}
//log.Printf("(%.3v)Walk Looking at %#v", i, p)
if ib.seen[p] {
/*
count++
log.Printf("Already saw (%.3v) at (%p)%[2]#v upping count(%v).", i, p, count)
if count > 10 {
*/
return
// }
}
ib.seen[p] = true
if ipp != nil {
ib.iseen[ipp] = true
}
pter, ok := p.(list.ElementerPointer)
if !ok {
// skip entries that are not points.
continue
}
//log.Printf("Looking at Point(%.3v) looking at pt(%p)%[2]v", i, p)
if !fn(i, pter.Point()) {
return
}
}
}