diff --git a/defaults.yaml b/defaults.yaml index 17a2005..5095719 100644 --- a/defaults.yaml +++ b/defaults.yaml @@ -55,6 +55,16 @@ tags: # exif: # enable: true +geo: + # Reverse geocode coordinates to location names. Runs fully locally + # via the "rgeo" Golang library. Currently only supported in the + # timeline layout. + # + # Can delay startup by up to a minute as the local geolocation + # database is loaded. + # + # reverse_geocode: true + media: # Extract metadata from this many files concurrently concurrent_meta_loads: 8 diff --git a/internal/image/source.go b/internal/image/source.go index 09892f0..73dd114 100644 --- a/internal/image/source.go +++ b/internal/image/source.go @@ -30,6 +30,7 @@ import ( var ErrNotFound = errors.New("not found") var ErrNotAnImage = errors.New("not a supported image extension, might be video") +var ErrUnavailable = errors.New("unavailable") type ImageId uint32 @@ -109,9 +110,14 @@ type Caches struct { Image CacheConfig } +type Geo struct { + ReverseGeocode bool `json:"reverse_geocode"` +} + type Config struct { DataDir string AI clip.AI + Geo Geo TagConfig tag.Config `json:"-"` ExifToolCount int `json:"exif_tool_count"` @@ -169,12 +175,12 @@ func NewSource(config Config, migrations embed.FS, migrationsThumbs embed.FS) *S source.imageInfoCache = newInfoCache() source.pathCache = newPathCache() - r, err := rgeo.New(rgeo.Provinces10, rgeo.Cities10) - - if err != nil { - // Handle error - fmt.Println("RGEO ERR", err) - } else { + if config.Geo.ReverseGeocode { + log.Println("rgeo loading") + r, err := rgeo.New(rgeo.Provinces10, rgeo.Cities10) + if err != nil { + log.Fatalf("failed to initialize rgeo: %s", err) + } source.rg = r } @@ -285,6 +291,9 @@ func NewSource(config Config, migrations embed.FS, migrationsThumbs embed.FS) *S } func (source *Source) ReverseGeocode(l s2.LatLng) (string, error) { + if source.rg == nil { + return "", ErrUnavailable + } location, err := source.rg.ReverseGeocode([]float64{l.Lng.Degrees(), l.Lat.Degrees()}) if err != nil { return "", err diff --git a/main.go b/main.go index 30a146c..ee898fd 100644 --- a/main.go +++ b/main.go @@ -997,6 +997,7 @@ type AppConfig struct { Render render.Render `json:"render"` Media image.Config `json:"media"` AI clip.AI `json:"ai"` + Geo image.Geo `json:"geo"` Tags tag.Config `json:"tags"` TileRequests TileRequestConfig `json:"tile_requests"` } @@ -1065,6 +1066,7 @@ func loadConfiguration(path string) AppConfig { } appConfig.Media.AI = appConfig.AI + appConfig.Media.Geo = appConfig.Geo appConfig.Tags.Enable = appConfig.Tags.Enable || appConfig.Tags.Enabled return appConfig