forked from holizz/go-tile-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paths2.go
103 lines (80 loc) · 2.01 KB
/
s2.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
package tiles
import (
//"fmt"
"github.com/golang/geo/s2"
)
type S2Index map[s2.CellID]([]FeatureRef)
func (si S2Index) AddWay(w Way, fname string, data *OsmData) {
c := s2.EmptyCap()
for _, node := range w.GetNodes(data.Nodes) {
c = c.AddPoint(s2.PointFromLatLng(s2.LatLngFromDegrees(node.Lat(), node.Lon())))
}
if c.IsEmpty() {
return
}
rc := &s2.RegionCoverer{MaxLevel: 30, MaxCells: 10}
cu := rc.FastCovering(c)
for _, cid := range cu {
si[cid] = append(si[cid], FeatureRef{w.Id, ItemTypeWay, fname})
for l := cid.Level(); l > 0; l-- {
cid = cid.Parent(l - 1)
if _, ok := si[cid]; !ok {
si[cid] = make([]FeatureRef, 0)
}
}
}
}
func (si S2Index) GetFeatures(nwPt, sePt Pointer, zoom int64) []FeatureRef {
r := s2.RectFromLatLng(s2.LatLngFromDegrees(nwPt.Lat(), nwPt.Lon()))
r = r.AddPoint(s2.LatLngFromDegrees(sePt.Lat(), sePt.Lon()))
rc := &s2.RegionCoverer{MaxLevel: 30, MaxCells: 10}
cu := rc.Covering(r)
visitCid := make(map[s2.CellID]bool)
visitF := make(map[int64]bool)
ret := make([]FeatureRef, 0)
for _, cid := range cu {
if v, ok := si[cid]; ok {
ret = si.VisitDown(cid, v, visitF, ret)
}
for l := cid.Level(); l > 0; l-- {
cid = cid.Parent(l - 1)
ret = si.VisitUp(cid, visitCid, visitF, ret)
}
}
//fmt.Println( len(ret))
return ret
}
func (si S2Index) VisitUp(cid s2.CellID, visitCid map[s2.CellID]bool, visitF map[int64]bool, ret []FeatureRef) []FeatureRef {
v, ok := si[cid]
if !ok {
return ret
}
if visitCid[cid] {
return ret
}
visitCid[cid] = true
for _, f := range v {
if !visitF[f.Id] {
ret = append(ret, f)
visitF[f.Id] = true
}
}
return ret
}
func (si S2Index) VisitDown(cid s2.CellID, fr []FeatureRef, visitF map[int64]bool, ret []FeatureRef) []FeatureRef {
for _, f := range fr {
if !visitF[f.Id] {
ret = append(ret, f)
visitF[f.Id] = true
}
}
if !cid.IsLeaf() {
chs := cid.Children()
for i := 0; i < 4; i++ {
if v, ok := si[chs[i]]; ok {
ret = si.VisitDown(chs[i], v, visitF, ret)
}
}
}
return ret
}