Search: improve radius approximation for "lat" and "lng" filters #3558

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-09-20 17:42:38 +02:00
parent c2e38f942b
commit 295fe0e6fa
5 changed files with 25 additions and 16 deletions

View file

@ -639,7 +639,7 @@ func TestPhotos(t *testing.T) {
})
t.Run("form.Lat and form.Lng", func(t *testing.T) {
var f form.SearchPhotos
f.Query = "Lat:33.45343166666667 Lng:25.764711666666667 Dist:2000"
f.Query = "Lat:33.45343166666667 Lng:25.764711666666667 Dist:4000"
f.Count = 10
f.Offset = 0
f.Order = "imported"

View file

@ -88,9 +88,13 @@ func GPSLatRange(lat float64, km uint) (latN, latS float32, err error) {
return 0, 0, fmt.Errorf("invalid latitude")
}
// Approximate range.
latN = gpsCeil(lat + geo.KmToDeg(km))
latS = gpsFloor(lat - geo.KmToDeg(km))
// Approximate range radius.
r := float64(km) * 0.75
// Approximate longitude range,
// see https://en.wikipedia.org/wiki/Decimal_degrees
latN = gpsCeil(lat + geo.Deg(r))
latS = gpsFloor(lat - geo.Deg(r))
if latN > 90 {
latN = 90
@ -110,9 +114,13 @@ func GPSLngRange(lng float64, km uint) (lngE, lngW float32, err error) {
return 0, 0, fmt.Errorf("invalid longitude")
}
// Approximate range.
lngE = gpsCeil(lng + geo.KmToDeg(km))
lngW = gpsFloor(lng - geo.KmToDeg(km))
// Approximate range radius.
r := float64(km) * 0.75
// Approximate longitude range,
// see https://en.wikipedia.org/wiki/Decimal_degrees
lngE = gpsCeil(lng + geo.Deg(r))
lngW = gpsFloor(lng - geo.Deg(r))
if lngE > 180 {
lngE = 180

View file

@ -68,8 +68,8 @@ func TestGPSBounds(t *testing.T) {
func TestGPSLatRange(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
latNorth, latSouth, err := GPSLatRange(41.87760543823242, 2)
assert.Equal(t, float32(41.8958), latNorth)
assert.Equal(t, float32(41.8594), latSouth)
assert.Equal(t, float32(41.8913), latNorth)
assert.Equal(t, float32(41.8639), latSouth)
assert.NoError(t, err)
})
t.Run("Zero", func(t *testing.T) {
@ -83,8 +83,8 @@ func TestGPSLatRange(t *testing.T) {
func TestGPSLngRange(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
lngEast, lngWest, err := GPSLngRange(-87.62521362304688, 2)
assert.Equal(t, float32(-87.6434), lngWest)
assert.Equal(t, float32(-87.607), lngEast)
assert.Equal(t, float32(-87.6389), lngWest)
assert.Equal(t, float32(-87.6116), lngEast)
assert.NoError(t, err)
})
t.Run("Zero", func(t *testing.T) {

View file

@ -10,9 +10,10 @@ const (
DefaultDist uint = 2
)
// KmToDeg returns the approximate distance in decimal degrees.
func KmToDeg(km uint) float64 {
return 0.009009009 * float64(km)
// Deg returns the approximate distance in decimal degrees,
// see https://en.wikipedia.org/wiki/Decimal_degrees.
func Deg(km float64) float64 {
return 0.009009009 * km
}
// DegToRad converts a value from degrees to radians.

View file

@ -6,9 +6,9 @@ import (
"github.com/stretchr/testify/assert"
)
func TestKmToDeg(t *testing.T) {
func TestDeg(t *testing.T) {
t.Run("10km", func(t *testing.T) {
assert.Equal(t, 0.09009009, KmToDeg(10))
assert.Equal(t, 0.09009009, Deg(10))
})
}