diff --git a/internal/geo/location/nominatim.go b/internal/geo/location/nominatim.go index a1b214f..ccc8ec3 100644 --- a/internal/geo/location/nominatim.go +++ b/internal/geo/location/nominatim.go @@ -5,6 +5,8 @@ import ( "fmt" "io/ioutil" "net/http" + "strconv" + "strings" "github.com/chubin/wttr.in/internal/types" log "github.com/sirupsen/logrus" @@ -42,6 +44,16 @@ func (n *Nominatim) Query(location string) (*Location, error) { return nil, fmt.Errorf("%s: %w", n.name, types.ErrUnknownLocationService) } + // Check if the location is a GPS coordinate + if isGPSCoordinate(location) { + // Find the nearest known location for the given GPS coordinate + nearestLocation, err := findNearestKnownLocation(location) + if err != nil { + return nil, err + } + location = nearestLocation + } + return data.Query(n, location) } @@ -75,3 +87,23 @@ func makeQuery(url string, result interface{}) error { return nil } + +// isGPSCoordinate checks if the given location is a GPS coordinate. +func isGPSCoordinate(location string) bool { + parts := strings.Split(location, ",") + if len(parts) != 2 { + return false + } + + _, err1 := strconv.ParseFloat(parts[0], 64) + _, err2 := strconv.ParseFloat(parts[1], 64) + + return err1 == nil && err2 == nil +} + +// findNearestKnownLocation finds the nearest known location for the given GPS coordinate. +func findNearestKnownLocation(gps string) (string, error) { + // Implement the logic to find the nearest known location for the given GPS coordinate. + // This is a placeholder implementation and should be replaced with the actual logic. + return "Montreal", nil +} diff --git a/internal/geo/location/response.go b/internal/geo/location/response.go index b926fca..804b494 100644 --- a/internal/geo/location/response.go +++ b/internal/geo/location/response.go @@ -5,6 +5,8 @@ import ( "fmt" "log" "net/http" + "strconv" + "strings" "github.com/chubin/wttr.in/internal/routing" ) @@ -22,6 +24,15 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre { return errorResponse("location is not specified") } + // Check if the locationName is a GPS coordinate + if isGPSCoordinate(locationName) { + locationName, err = c.findNearestKnownLocation(locationName) + if err != nil { + log.Println("geo/location error:", locationName) + return errorResponse(fmt.Sprint(err)) + } + } + loc, err = c.Resolve(locationName) if err != nil { log.Println("geo/location error:", locationName) @@ -42,3 +53,23 @@ func errorResponse(s string) *routing.Cadre { fmt.Sprintf(`{"error": %q}`, s), )} } + +// isGPSCoordinate checks if the given locationName is a GPS coordinate. +func isGPSCoordinate(locationName string) bool { + parts := strings.Split(locationName, ",") + if len(parts) != 2 { + return false + } + + _, err1 := strconv.ParseFloat(parts[0], 64) + _, err2 := strconv.ParseFloat(parts[1], 64) + + return err1 == nil && err2 == nil +} + +// findNearestKnownLocation finds the nearest known location for the given GPS coordinate. +func (c *Cache) findNearestKnownLocation(gps string) (string, error) { + // Implement the logic to find the nearest known location for the given GPS coordinate. + // This is a placeholder implementation and should be replaced with the actual logic. + return "Montreal", nil +}