refactoring
This commit is contained in:
96
cmd/maps.go
Normal file
96
cmd/maps.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
"googlemaps.github.io/maps"
|
||||
)
|
||||
|
||||
type Maps struct {
|
||||
around Location
|
||||
}
|
||||
|
||||
func NewMapsOf(ctx context.Context, town string) (*Maps, error) {
|
||||
m := &Maps{}
|
||||
var err error
|
||||
m.around, err = m.textSearchOne(ctx, town)
|
||||
return m, err
|
||||
}
|
||||
|
||||
var rps = 2
|
||||
var limit = 200
|
||||
var mapsLimiter = rate.NewLimiter(rate.Limit(rps), 1)
|
||||
|
||||
type Location struct {
|
||||
Name string
|
||||
Lat float64
|
||||
Lng float64
|
||||
Address string
|
||||
}
|
||||
|
||||
func (m *Maps) textSearchOne(ctx context.Context, query string) (Location, error) {
|
||||
results, err := m.textSearch(ctx, query)
|
||||
if err != nil {
|
||||
return Location{}, err
|
||||
} else if len(results) < 1 {
|
||||
return Location{}, fmt.Errorf("no results for %q", query)
|
||||
}
|
||||
return results[0], nil
|
||||
}
|
||||
|
||||
func (m *Maps) textSearch(ctx context.Context, query string) ([]Location, error) {
|
||||
locations := []Location{}
|
||||
nextToken := ""
|
||||
for {
|
||||
results, err := m._textSearch(ctx, query, nextToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, result := range results.Results {
|
||||
locations = append(locations, Location{
|
||||
Name: result.Name,
|
||||
Lat: result.Geometry.Location.Lat,
|
||||
Lng: result.Geometry.Location.Lng,
|
||||
Address: result.FormattedAddress,
|
||||
})
|
||||
}
|
||||
nextToken = results.NextPageToken
|
||||
if nextToken == "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
return locations, ctx.Err()
|
||||
}
|
||||
|
||||
func (m *Maps) _textSearch(ctx context.Context, query string, nextToken string) (maps.PlacesSearchResponse, error) {
|
||||
mapsLimiter.Wait(ctx)
|
||||
|
||||
var location *maps.LatLng
|
||||
radius := uint(0)
|
||||
if m.around == (Location{}) {
|
||||
radius = 250
|
||||
} else {
|
||||
location = &maps.LatLng{
|
||||
Lat: m.around.Lat,
|
||||
Lng: m.around.Lng,
|
||||
}
|
||||
}
|
||||
|
||||
return m.client().TextSearch(ctx, &maps.TextSearchRequest{
|
||||
Query: query,
|
||||
Location: location,
|
||||
Radius: radius,
|
||||
PageToken: nextToken,
|
||||
})
|
||||
}
|
||||
|
||||
func (*Maps) client() *maps.Client {
|
||||
c, err := maps.NewClient(maps.WithAPIKey(os.Getenv("GOOGLE_PLACES_API_KEY")))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
Reference in New Issue
Block a user