{-# LANGUAGE OverloadedStrings #-} -- | Here we define providers for the Reverse Geocoding feature, -- namely how to format the url, the key under which the results are returned, -- and how to parse the retrived data. -- -- Currently only Open Stree Map is provided, feel free to add others. -- module Data.Geolocation.Reverse.Providers ( ReverseGeoJsonKey , ReverseGeoParser , ReverseGeoProvider , openStreetMap ) where import Control.Applicative import Data.Monoid import Data.Aeson import Data.Aeson.Types import qualified Data.Text as T import Data.Geolocation.Reverse.Types type ReverseGeoJsonKey = T.Text type ReverseGeoUrl = Latitude -> Longitude -> Maybe String type ReverseGeoParser = Object -> Parser ParsedLocationInfo type ReverseGeoProvider = (ReverseGeoJsonKey, ReverseGeoUrl, ReverseGeoParser) openStreetMap :: ReverseGeoProvider openStreetMap = ("address", openStreetMapUrl, openStreetMapParser) openStreetMapUrl :: Latitude -> Longitude -> Maybe String openStreetMapUrl (Latitude mlat) (Longitude mlon) = do lat <- mlat lon <- mlon return $ "http://nominatim.openstreetmap.org/reverse" <> "?format=json" <> "&zoom=18" <> "&lat=" <> show lat <> "&lon=" <> show lon openStreetMapParser o = ParsedLocationInfo <$> o .: "country_code" <*> o .: "city" <*> o .:? "suburb" <*> ((o .:? "road") <|> (o .:? "street")) <*> o .:? "postcode"