-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
tzf_fuzzy.go
69 lines (62 loc) · 1.65 KB
/
tzf_fuzzy.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
package tzf
import (
"github.com/paulmach/orb"
"github.com/paulmach/orb/maptile"
"github.com/ringsaturn/tzf/pb"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)
// FuzzyFinder use a tile map to store timezone name. Data are made by
// [github.com/ringsaturn/tzf/cmd/preindextzpb] which powerd by
// [github.com/ringsaturn/tzf/preindex.PreIndexTimezones].
type FuzzyFinder struct {
idxZoom int
aggZoom int
m map[maptile.Tile][]string // timezones may have common area
version string
names []string
}
func NewFuzzyFinderFromPB(input *pb.PreindexTimezones) (F, error) {
f := &FuzzyFinder{
m: make(map[maptile.Tile][]string),
idxZoom: int(input.IdxZoom),
aggZoom: int(input.AggZoom),
version: input.Version,
}
namesMap := map[string]bool{}
for _, item := range input.Keys {
tile := maptile.New(uint32(item.X), uint32(item.Y), maptile.Zoom(item.Z))
if _, ok := f.m[tile]; !ok {
f.m[tile] = make([]string, 0)
}
f.m[tile] = append(f.m[tile], item.Name)
namesMap[item.Name] = true
}
f.names = maps.Keys(namesMap)
slices.Sort(f.names)
return f, nil
}
func (f *FuzzyFinder) GetTimezoneName(lng float64, lat float64) string {
names, err := f.GetTimezoneNames(lng, lat)
if err != nil {
return ""
}
return names[0]
}
func (f *FuzzyFinder) GetTimezoneNames(lng float64, lat float64) ([]string, error) {
p := orb.Point{lng, lat}
for z := f.aggZoom; z <= f.idxZoom; z++ {
key := maptile.At(p, maptile.Zoom(z))
v, ok := f.m[key]
if ok {
return v, nil
}
}
return nil, ErrNoTimezoneFound
}
func (f *FuzzyFinder) TimezoneNames() []string {
return f.names
}
func (f *FuzzyFinder) DataVersion() string {
return f.version
}