photoprism/location.go
2018-08-09 23:10:05 +02:00

105 lines
2.8 KiB
Go

package photoprism
import (
"fmt"
"encoding/json"
"net/http"
"github.com/jinzhu/gorm"
"strconv"
"errors"
)
type Location struct {
gorm.Model
DisplayName string
Lat float64
Long float64
City string
Postcode string
County string
State string
Country string
CountryCode string
LocationCategory string
LocationType string
Favorite bool
}
type OpenstreetmapAddress struct {
Town string `json:"town"`
City string `json:"city"`
Postcode string `json:"postcode"`
County string `json:"county"`
State string `json:"state"`
Country string `json:"country"`
CountryCode string `json:"country_code"`
}
type OpenstreetmapLocation struct {
PlaceId string `json:"place_id"`
Lat string `json:"lat"`
Lon string `json:"lon"`
Category string `json:"category"`
Type string `json:"type"`
DisplayName string `json:"display_name"`
Address *OpenstreetmapAddress `json:"address"`
}
// See https://wiki.openstreetmap.org/wiki/Nominatim#Reverse_Geocoding
func (m *MediaFile) GetLocation() (*Location, error) {
if m.location != nil {
return m.location, nil
}
location := &Location{}
openstreetmapLocation := &OpenstreetmapLocation{
Address: &OpenstreetmapAddress{},
}
if exifData, err := m.GetExifData(); err == nil {
url := fmt.Sprintf("https://nominatim.openstreetmap.org/reverse?lat=%f&lon=%f&format=jsonv2", exifData.Lat, exifData.Long)
if res, err := http.Get(url); err == nil {
json.NewDecoder(res.Body).Decode(openstreetmapLocation)
} else {
return nil, err
}
} else {
return nil, err
}
if id, err := strconv.Atoi(openstreetmapLocation.PlaceId); err == nil && id > 0 {
location.ID = uint(id)
} else {
return nil, errors.New("no location found")
}
if openstreetmapLocation.Address.City != "" {
location.City = openstreetmapLocation.Address.City
} else {
location.City = openstreetmapLocation.Address.Town
}
if lat, err := strconv.ParseFloat(openstreetmapLocation.Lat, 64); err == nil {
location.Lat = lat
}
if lon, err := strconv.ParseFloat(openstreetmapLocation.Lon, 64); err == nil {
location.Long = lon
}
location.Postcode = openstreetmapLocation.Address.Postcode
location.County = openstreetmapLocation.Address.County
location.State = openstreetmapLocation.Address.State
location.Country = openstreetmapLocation.Address.Country
location.CountryCode = openstreetmapLocation.Address.CountryCode
location.DisplayName = openstreetmapLocation.DisplayName
location.LocationCategory = openstreetmapLocation.Category
location.LocationType = openstreetmapLocation.Type
m.location = location
return m.location, nil
}