/
githubmirror
/
photoprism
Обзор
Документация
Войти
/
githubmirror
/
photoprism
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
pkg/clean/gps.go
140 строк
4 KB
Michael Mayer
Search: Parse lat,lng string into float64 coordinates #4930 #4812
19 апр 2025, 17:04
19 апр 2025, 17:04
27b72aa
Код
Авторство
О чём код?
package clean import ( "fmt" "strings" "github.com/photoprism/photoprism/pkg/geo" "github.com/photoprism/photoprism/pkg/txt" ) // GPSBoundsDefaultPadding specifies the default padding of the GPS coordinates in meters. const GPSBoundsDefaultPadding = 5.0 // GPSBounds parses the GPS bounds (Lat N, Lng E, Lat S, Lng W) // and returns the coordinates with default padding. func GPSBounds(bounds string) (latN, lngE, latS, lngW float64, err error) { return GPSBoundsWithPadding(bounds, GPSBoundsDefaultPadding) } // GPSBoundsWithPadding parses the GPS bounds (Lat N, Lng E, Lat S, Lng W) // and returns the coordinates with a custom padding in meters. func GPSBoundsWithPadding(bounds string, padding float64) (latN, lngE, latS, lngW float64, err error) { // Bounds string not long enough? if len(bounds) < 7 { return 0, 0, 0, 0, fmt.Errorf("no coordinates found") } // Trim whitespace and invalid characters. bounds = strings.Trim(bounds, " |\\<>\n\r\t\"'#$%!^*()[]{}") // Split bounding box string into coordinate values. values := strings.SplitN(bounds, ",", 5) found := len(values) // Return error if number of coordinates is invalid. if found != 4 { return 0, 0, 0, 0, fmt.Errorf("invalid number of coordinates") } // Convert coordinate strings to floating point values. latNorth, lngEast, latSouth, lngWest := txt.Float64(values[0]), txt.Float64(values[1]), txt.Float64(values[2]), txt.Float64(values[3]) // Latitudes have a valid range of +90 to -90 degrees. if latNorth > 90 { latNorth = 90 } else if latNorth < -90 { latNorth = -90 } if latSouth > 90 { latSouth = 90 } else if latSouth < -90 { latSouth = -90 } // Make sure latSouth is smaller than latNorth. if latSouth > latNorth { latNorth, latSouth = latSouth, latNorth } // Longitudes have a valid range of -180 to +180 degrees. if lngEast > 180 { lngEast = 180 } else if lngEast < -180 { lngEast = -180 } if lngWest > 180 { lngWest = 180 } else if lngWest < -180 { lngWest = -180 } // Make sure lngWest is smaller than lngEast. if lngWest > lngEast { lngEast, lngWest = lngWest, lngEast } // Calculate the latitude and longitude padding in degrees. dLat, dLng := geo.Deg((latNorth+latSouth)/2.0, padding) // Return the coordinates of the bounding box with padding applied. return latNorth + dLat, lngEast + dLng, latSouth - dLat, lngWest - dLng, nil } // GPSLatRange returns a range based on the specified latitude and distance in km, or an error otherwise. func GPSLatRange(lat float64, km float64) (latN, latS float64, err error) { // Latitude (from +90 to -90 degrees). if lat == 0 || lat < -90 || lat > 90 { return 0, 0, fmt.Errorf("invalid latitude") } // Approximate range radius. r := km * 0.75 // Approximate longitude range, // see https://en.wikipedia.org/wiki/Decimal_degrees dLat, _ := geo.DegKm(lat, r) latN = lat + dLat latS = lat - dLat if latN > 90 { latN = 90 } if latS < -90 { latS = -90 } return latN, latS, nil } // GPSLngRange returns a range based on the specified longitude and distance in km, or an error otherwise. func GPSLngRange(lat, lng float64, km float64) (lngE, lngW float64, err error) { // Longitude (from -180 to +180 degrees). if lng == 0 || lng < -180 || lng > 180 { return 0, 0, fmt.Errorf("invalid longitude") } // Approximate range radius. r := km * 0.75 // Approximate longitude range, // see https://en.wikipedia.org/wiki/Decimal_degrees _, dLng := geo.DegKm(lat, r) lngE = lng + dLng lngW = lng - dLng if lngE > 180 { lngE = 180 } if lngW < -180 { lngW = -180 } return lngE, lngW, nil }