forked from micro/micro
/
main.go
95 lines (75 loc) · 1.98 KB
/
main.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
package main
import (
"encoding/json"
"log"
"github.com/hailocab/go-geoindex"
"github.com/micro/micro/examples/booking/data"
"github.com/micro/micro/examples/booking/srv/geo/proto"
"golang.org/x/net/context"
"golang.org/x/net/trace"
"github.com/micro/go-micro"
"github.com/micro/go-micro/metadata"
)
const (
maxSearchRadius = 10
maxSearchResults = 5
)
type point struct {
Pid string `json:"hotelId"`
Plat float64 `json:"lat"`
Plon float64 `json:"lon"`
}
// Implement Point interface
func (p *point) Lat() float64 { return p.Plat }
func (p *point) Lon() float64 { return p.Plon }
func (p *point) Id() string { return p.Pid }
type Geo struct {
index *geoindex.ClusteringIndex
}
// Nearby returns all hotels within a given distance.
func (s *Geo) Nearby(ctx context.Context, req *geo.Request, rsp *geo.Result) error {
md, _ := metadata.FromContext(ctx)
traceID := md["traceID"]
if tr, ok := trace.FromContext(ctx); ok {
tr.LazyPrintf("traceID %s", traceID)
}
// create center point for query
center := &geoindex.GeoPoint{
Pid: "",
Plat: float64(req.Lat),
Plon: float64(req.Lon),
}
// find points around center point
points := s.index.KNearest(center, maxSearchResults, geoindex.Km(maxSearchRadius), func(p geoindex.Point) bool {
return true
})
for _, p := range points {
rsp.HotelIds = append(rsp.HotelIds, p.Id())
}
return nil
}
// newGeoIndex returns a geo index with points loaded
func newGeoIndex(path string) *geoindex.ClusteringIndex {
file := data.MustAsset(path)
// unmarshal json points
var points []*point
if err := json.Unmarshal(file, &points); err != nil {
log.Fatalf("Failed to load hotels: %v", err)
}
// add points to index
index := geoindex.NewClusteringIndex()
for _, point := range points {
index.Add(point)
}
return index
}
func main() {
service := micro.NewService(
micro.Name("go.micro.srv.geo"),
)
service.Init()
geo.RegisterGeoHandler(service.Server(), &Geo{
index: newGeoIndex("data/locations.json"),
})
service.Run()
}