photoprism/internal/maps/places/location.go

122 lines
2.4 KiB
Go
Raw Normal View History

package places
import (
"encoding/json"
"fmt"
"net/http"
gc "github.com/patrickmn/go-cache"
"github.com/photoprism/photoprism/internal/s2"
"github.com/photoprism/photoprism/internal/util"
)
// Location
type Location struct {
ID string `json:"id"`
LocLat float64 `json:"lat"`
LocLng float64 `json:"lng"`
LocName string `json:"name"`
LocCategory string `json:"category"`
LocSuburb string `json:"suburb"`
Place Place `json:"place"`
Cached bool `json:"-"`
}
var ReverseLookupURL = "https://places.photoprism.org/v1/location/%s"
func FindLocation(id string) (result Location, err error) {
if len(id) > 16 || len(id) == 0 {
return result, fmt.Errorf("places: invalid location id %s", id)
}
lat, lng := s2.LatLng(id)
if lat == 0.0 || lng == 0.0 {
return result, fmt.Errorf("places: skipping lat %f, lng %f", lat, lng)
}
if hit, ok := cache.Get(id); ok {
log.Debugf("places: cache hit for lat %f, lng %f", lat, lng)
result = hit.(Location)
result.Cached = true
return result, nil
}
url := fmt.Sprintf(ReverseLookupURL, id)
log.Debugf("places: query %s", url)
r, err := http.Get(url)
if err != nil {
log.Errorf("places: %s", err.Error())
return result, err
}
err = json.NewDecoder(r.Body).Decode(&result)
if err != nil {
log.Errorf("places: %s", err.Error())
return result, err
}
if result.ID == "" {
log.Debugf("result: %+v", result)
return result, fmt.Errorf("places: no result for %s", id)
}
cache.Set(id, result, gc.DefaultExpiration)
result.Cached = false
return result, nil
}
func (l Location) CellID() (result string) {
return l.ID
}
func (l Location) Name() (result string) {
return l.LocName
}
func (l Location) Category() (result string) {
return l.LocCategory
}
func (l Location) Label() (result string) {
return l.Place.LocLabel
}
func (l Location) State() (result string) {
return l.Place.LocState
}
func (l Location) City() (result string) {
return l.Place.LocCity
}
func (l Location) Suburb() (result string) {
return l.LocSuburb
}
func (l Location) CountryCode() (result string) {
return l.Place.LocCountry
}
func (l Location) Latitude() (result float64) {
return l.LocLat
}
func (l Location) Longitude() (result float64) {
return l.LocLng
}
func (l Location) Keywords() (result []string) {
return util.Keywords(l.Label())
}
func (l Location) Source() string {
return "places"
}