Skip to content

Commit

Permalink
Add location search to metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
zach-capalbo committed Apr 29, 2023
1 parent b4c4faf commit 65a6148
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 5 deletions.
3 changes: 3 additions & 0 deletions db/migrations/000012_add_gps_coords.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE infos DROP COLUMN "longitude" text;
ALTER TABLE infos DROP COLUMN "latitude" text;
ALTER TABLE infos DROP COLUMN "location" text;
3 changes: 3 additions & 0 deletions db/migrations/000012_add_gps_coords.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE infos ADD COLUMN "longitude" numeric;
ALTER TABLE infos ADD COLUMN "latitude" numeric;
ALTER TABLE infos ADD COLUMN "location" text;
15 changes: 12 additions & 3 deletions internal/image/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,21 +179,27 @@ func (source *Database) writePendingInfosSqlite() {
defer upsertPrefix.Finalize()

updateMeta := conn.Prep(`
INSERT INTO infos(path_prefix_id, filename, width, height, orientation, created_at_unix, created_at_tz_offset)
INSERT INTO infos(path_prefix_id, filename, width, height, orientation, created_at_unix, created_at_tz_offset, latitude, longitude, location)
SELECT
id as path_prefix_id,
? as filename,
? as width,
? as height,
? orientation,
? as created_at_unix,
? as created_at_tz_offset
? as created_at_tz_offset,
? as latitude,
? as longitude,
? as location
FROM prefix
WHERE str == ?
ON CONFLICT(path_prefix_id, filename) DO UPDATE SET
width=excluded.width,
height=excluded.height,
orientation=excluded.orientation,
latitude=excluded.latitude,
longitude=excluded.longitude,
location=excluded.location,
created_at_unix=excluded.created_at_unix,
created_at_tz_offset=excluded.created_at_tz_offset;`)
defer updateMeta.Finalize()
Expand Down Expand Up @@ -297,7 +303,10 @@ func (source *Database) writePendingInfosSqlite() {
updateMeta.BindInt64(4, (int64)(imageInfo.Orientation))
updateMeta.BindInt64(5, imageInfo.DateTime.Unix())
updateMeta.BindInt64(6, int64(timezoneOffsetSeconds/60))
updateMeta.BindText(7, dir)
updateMeta.BindFloat(7, imageInfo.Latitude)
updateMeta.BindFloat(8, imageInfo.Longitude)
updateMeta.BindText(9, imageInfo.Location)
updateMeta.BindText(10, dir)

_, err := updateMeta.Step()
if err != nil {
Expand Down
27 changes: 26 additions & 1 deletion internal/image/exiftool-mostlygeek.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"time"
"math"

"github.com/mostlygeek/go-exiftool"
)
Expand Down Expand Up @@ -54,6 +55,9 @@ func (decoder *ExifToolMostlyGeekLoader) DecodeInfo(path string, info *Info) err
"-TimeStamp",
"-FileModifyDate",
"-FileCreateDate",
// Location Info
"-GPSLatitude",
"-GPSLongitude",
)
if err != nil {
return err
Expand All @@ -63,6 +67,8 @@ func (decoder *ExifToolMostlyGeekLoader) DecodeInfo(path string, info *Info) err
rotation := ""
imageWidth := ""
imageHeight := ""
latitude := ""
longitude := ""

// var gpsTime time.Time

Expand All @@ -86,6 +92,11 @@ func (decoder *ExifToolMostlyGeekLoader) DecodeInfo(path string, info *Info) err
imageWidth = value
case "ImageHeight":
imageHeight = value
case "GPSLatitude":
latitude = value
case "GPSLongitude":
longitude = value

// case "GPSDateTime":
// gpsTime, _ = parseDateTime(value)
default:
Expand Down Expand Up @@ -131,11 +142,25 @@ func (decoder *ExifToolMostlyGeekLoader) DecodeInfo(path string, info *Info) err
info.Orientation = getOrientationFromRotation(rotation)
}

if latitude != "" {
info.Latitude, err = strconv.ParseFloat(latitude, 64)
if err != nil {
info.Latitude = math.NaN()
}
}

if longitude != "" {
info.Longitude, err = strconv.ParseFloat(longitude, 64)
if err != nil {
info.Longitude = math.NaN()
}
}

if info.Orientation.SwapsDimensions() {
info.Width, info.Height = info.Height, info.Width
}

// println(path, info.Width, info.Height, info.DateTime.String())
println(path, info.Width, info.Height, info.DateTime.String(), info.Latitude, info.Longitude)

return nil
}
Expand Down
18 changes: 18 additions & 0 deletions internal/image/indexMetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package image

import (
"fmt"
"math"


)

func (source *Source) indexMetadata(in <-chan interface{}) {
Expand All @@ -16,6 +19,21 @@ func (source *Source) indexMetadata(in <-chan interface{}) {
fmt.Println("Unable to load image info meta", err, path)
continue
}

if !math.IsNaN(info.Latitude) {
loc, err := source.rg.ReverseGeocode([]float64{info.Longitude, info.Latitude})
if err != nil {
// Handle error
fmt.Println("RGEO ERR", err)
}
fmt.Println("RGeo", loc.City, loc.Province, loc.Country)
if loc.City != "" {
info.Location = fmt.Sprintf("%s, %s, %s", loc.City, loc.Province, loc.Country)
} else {
info.Location = fmt.Sprintf("%s, %s", loc.Province, loc.Country)
}
}

source.database.Write(path, info, UpdateMeta)
source.imageInfoCache.Delete(id)
}
Expand Down
6 changes: 5 additions & 1 deletion internal/image/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ type Info struct {
DateTime time.Time
Color uint32
Orientation Orientation
Latitude float64
Longitude float64
Location string
}

func (info *Info) Size() Size {
return Size{X: info.Width, Y: info.Height}
}

func (info *Info) String() string {
return fmt.Sprintf("width: %v, height: %v, date: %v, color: %08x, orientation: %s",
return fmt.Sprintf("width: %v, height: %v, date: %v, color: %08x, orientation: %s, location: %s",
info.Width,
info.Height,
info.DateTime.String(),
info.Color,
info.Orientation,
info.Location,
)
}

Expand Down
12 changes: 12 additions & 0 deletions internal/image/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"github.com/docker/go-units"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/sams96/rgeo"
)

var ErrNotFound = errors.New("not found")
Expand Down Expand Up @@ -140,6 +142,7 @@ type Source struct {

decoder *Decoder
database *Database
rg *rgeo.Rgeo

imageInfoCache InfoCache
pathCache PathCache
Expand All @@ -161,6 +164,15 @@ func NewSource(config Config, migrations embed.FS, migrationsThumbs embed.FS) *S
source.database = NewDatabase(filepath.Join(config.DataDir, "photofield.cache.db"), migrations)
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 {
source.rg = r
}

source.SourceLatencyHistogram = promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: metrics.Namespace,
Expand Down

0 comments on commit 65a6148

Please sign in to comment.