Skip to content

Commit

Permalink
backend/feat : #70 OSM Reverse Geocode API Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
janhavi.soni committed Apr 7, 2023
1 parent ff1acd8 commit 8c6138a
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 4 deletions.
6 changes: 5 additions & 1 deletion lib/mobility-core/mobility-core.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.35.1.
--
-- see: https://github.com/sol/hpack

Expand Down Expand Up @@ -50,6 +50,7 @@ library
Kernel.External.Maps.Interface
Kernel.External.Maps.Interface.Google
Kernel.External.Maps.Interface.MMI
Kernel.External.Maps.Interface.OSM
Kernel.External.Maps.Interface.OSRM
Kernel.External.Maps.Interface.Types
Kernel.External.Maps.MMI.AutoSuggest
Expand All @@ -58,6 +59,9 @@ library
Kernel.External.Maps.MMI.MapsClient.Types
Kernel.External.Maps.MMI.MMIAuthToken
Kernel.External.Maps.MMI.Routes
Kernel.External.Maps.OSM.Config
Kernel.External.Maps.OSM.MapsClient.Types
Kernel.External.Maps.OSM.ReverseGeocode
Kernel.External.Maps.OSRM.Config
Kernel.External.Maps.OSRM.RoadsClient
Kernel.External.Maps.Types
Expand Down
35 changes: 35 additions & 0 deletions lib/mobility-core/src/Kernel/External/Maps/Interface.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ module Kernel.External.Maps.Interface
getPlaceDetails,
getPlaceNameProvided,
getPlaceName,
getPlaceDetailsFromLatLonProvided,
getPlaceDetailsFromLatLon,
)
where

Expand All @@ -35,6 +37,7 @@ import Kernel.External.Maps.Google.Config as Reexport
import Kernel.External.Maps.HasCoordinates as Reexport (HasCoordinates (..))
import qualified Kernel.External.Maps.Interface.Google as Google
import qualified Kernel.External.Maps.Interface.MMI as MMI
import qualified Kernel.External.Maps.Interface.OSM as OSM
import qualified Kernel.External.Maps.Interface.OSRM as OSRM
import Kernel.External.Maps.Interface.Types as Reexport
import Kernel.External.Maps.MMI.Config as Reexport
Expand Down Expand Up @@ -80,6 +83,7 @@ getDistancesProvided = \case
Google -> True
OSRM -> False
MMI -> True
OSM -> False

-- FIXME this logic is redundant, because we throw error always when getDistancesProvided service = False
getDistances ::
Expand All @@ -95,12 +99,14 @@ getDistances serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.getDistances cfg req
OSRMConfig cfg -> OSRM.getDistances cfg req
MMIConfig cfg -> MMI.getDistanceMatrix cfg req
OSMConfig _ -> throwNotProvidedError "autoComplete" OSM

getRoutesProvided :: MapsService -> Bool
getRoutesProvided = \case
Google -> True
OSRM -> False
MMI -> False
OSM -> False

getRoutes ::
( EncFlow m r,
Expand All @@ -114,12 +120,14 @@ getRoutes serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.getRoutes cfg req
OSRMConfig osrmCfg -> OSRM.getRoutes osrmCfg req
MMIConfig cfg -> MMI.getRoutes cfg req
OSMConfig _ -> throwNotProvidedError "getRoutes" OSM

snapToRoadProvided :: MapsService -> Bool
snapToRoadProvided = \case
Google -> True
OSRM -> True
MMI -> False
OSM -> False

snapToRoad ::
( EncFlow m r,
Expand All @@ -133,12 +141,14 @@ snapToRoad serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.snapToRoad cfg req
OSRMConfig osrmCfg -> OSRM.callOsrmMatch osrmCfg req
MMIConfig _ -> throwNotProvidedError "snapToRoad" MMI
OSMConfig _ -> throwNotProvidedError "snapToRoad" OSM

autoCompleteProvided :: MapsService -> Bool
autoCompleteProvided = \case
Google -> True
OSRM -> False
MMI -> True
OSM -> False

autoComplete ::
( EncFlow m r,
Expand All @@ -152,12 +162,14 @@ autoComplete serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.autoComplete cfg req
OSRMConfig _ -> throwNotProvidedError "autoComplete" OSRM
MMIConfig cfg -> MMI.autoSuggest cfg req
OSMConfig _ -> throwNotProvidedError "autoComplete" OSM

getPlaceDetailsProvided :: MapsService -> Bool
getPlaceDetailsProvided = \case
Google -> True
OSRM -> False
MMI -> False
OSM -> False

getPlaceDetails ::
( EncFlow m r,
Expand All @@ -170,12 +182,14 @@ getPlaceDetails serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.getPlaceDetails cfg req
OSRMConfig _ -> throwNotProvidedError "getPlaceDetails" OSRM
MMIConfig _ -> throwNotProvidedError "getPlaceDetails" MMI
OSMConfig _ -> throwNotProvidedError "getPlaceDetails" OSM

getPlaceNameProvided :: MapsService -> Bool
getPlaceNameProvided = \case
Google -> True
OSRM -> False
MMI -> False
OSM -> False

getPlaceName ::
( EncFlow m r,
Expand All @@ -188,3 +202,24 @@ getPlaceName serviceConfig req = case serviceConfig of
GoogleConfig cfg -> Google.getPlaceName cfg req
OSRMConfig _ -> throwNotProvidedError "getPlaceName" OSRM
MMIConfig _ -> throwNotProvidedError "getPlaceName" MMI
OSMConfig _ -> throwNotProvidedError "getPlaceName" OSM

getPlaceDetailsFromLatLonProvided :: MapsService -> Bool
getPlaceDetailsFromLatLonProvided = \case
Google -> False
OSRM -> False
MMI -> False
OSM -> True

getPlaceDetailsFromLatLon ::
( EncFlow m r,
CoreMetrics m
) =>
MapsServiceConfig ->
GetPlaceDetailsFromLatLonReq ->
m GetPlaceDetailsFromLatLonResp
getPlaceDetailsFromLatLon serviceConfig req = case serviceConfig of
GoogleConfig _ -> throwNotProvidedError "getPlaceDetailsFromLatLon" OSM
OSRMConfig _ -> throwNotProvidedError "getPlaceDetailsFromLatLon" OSRM
MMIConfig _ -> throwNotProvidedError "getPlaceDetailsFromLatLon" MMI
OSMConfig cfg -> OSM.getPlaceDetailsFromLatLon cfg req
47 changes: 47 additions & 0 deletions lib/mobility-core/src/Kernel/External/Maps/Interface/OSM.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{-
Copyright 2022-23, Juspay India Pvt Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero
General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-}

module Kernel.External.Maps.Interface.OSM where

import Kernel.External.Maps.Interface.Types
import Kernel.External.Maps.OSM.Config
import qualified Kernel.External.Maps.OSM.ReverseGeocode as OSM
import Kernel.Prelude
import Kernel.Tools.Metrics.CoreMetrics (CoreMetrics)
import Kernel.Types.App

getPlaceDetailsFromLatLon ::
( CoreMetrics m,
MonadFlow m
) =>
OSMCfg ->
GetPlaceDetailsFromLatLonReq ->
m GetPlaceDetailsFromLatLonResp
getPlaceDetailsFromLatLon osmCfg req = do
reverseGeocodeRes <- OSM.getPlaceDetailsFromLatLon osmCfg.osmUrl req.responseFormat req.location.lat req.location.lon
return
GetPlaceDetailsFromLatLonResp
{ placeId = reverseGeocodeRes.place_id,
displayName = reverseGeocodeRes.display_name,
address =
PlaceDetails
{ city = reverseGeocodeRes.address.state_district,
state_ = reverseGeocodeRes.address.state,
country = reverseGeocodeRes.address.country,
street = reverseGeocodeRes.address.road,
building = Nothing,
areaCode = reverseGeocodeRes.address.postcode,
area = reverseGeocodeRes.address.neighbourhood
}
}
24 changes: 23 additions & 1 deletion lib/mobility-core/src/Kernel/External/Maps/Interface/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ import Deriving.Aeson
import EulerHS.Prelude
import qualified Kernel.External.Maps.Google.Config as Google
import qualified Kernel.External.Maps.MMI.Config as MMI
import qualified Kernel.External.Maps.OSM.Config as OSM
import qualified Kernel.External.Maps.OSRM.Config as OSRM
import Kernel.External.Maps.Types
import Kernel.External.Types (Language)
import Kernel.Types.Common
import Kernel.Utils.GenericPretty (PrettyShow)

data MapsServiceConfig = GoogleConfig Google.GoogleCfg | OSRMConfig OSRM.OSRMCfg | MMIConfig MMI.MMICfg
data MapsServiceConfig = GoogleConfig Google.GoogleCfg | OSRMConfig OSRM.OSRMCfg | MMIConfig MMI.MMICfg | OSMConfig OSM.OSMCfg
deriving stock (Show, Eq, Generic)
deriving (FromJSON, ToJSON) via CustomJSON '[SumTaggedObject "tag" "content"] MapsServiceConfig

Expand Down Expand Up @@ -181,3 +182,24 @@ data AddressResp = AddressResp
}
deriving stock (Generic)
deriving anyclass (ToJSON, FromJSON, ToSchema)

data GetPlaceDetailsFromLatLonReq = GetPlaceDetailsFromLatLonReq
{ location :: LatLong,
responseFormat :: Text
}

data GetPlaceDetailsFromLatLonResp = GetPlaceDetailsFromLatLonResp
{ placeId :: Text,
displayName :: Text,
address :: PlaceDetails
}

data PlaceDetails = PlaceDetails
{ city :: Text,
state_ :: Text,
country :: Text,
street :: Text,
building :: Maybe Text,
areaCode :: Text,
area :: Text
}
22 changes: 22 additions & 0 deletions lib/mobility-core/src/Kernel/External/Maps/OSM/Config.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{-
Copyright 2022-23, Juspay India Pvt Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero
General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-}

module Kernel.External.Maps.OSM.Config where

import Kernel.Prelude

data OSMCfg = OSRMCfg
{ osmUrl :: BaseUrl
}
deriving (Show, Eq, Generic, FromJSON, ToJSON)
38 changes: 38 additions & 0 deletions lib/mobility-core/src/Kernel/External/Maps/OSM/MapsClient/Types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{-
Copyright 2022-23, Juspay India Pvt Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero
General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-}
{-# LANGUAGE DerivingVia #-}

module Kernel.External.Maps.OSM.MapsClient.Types where

import Kernel.Prelude

data ReverseGeocodeRes = ReverseGeocodeRes
{ place_id :: Text,
lat :: Double,
lon :: Double,
display_name :: Text,
address :: AddressInfo
}
deriving (Generic, ToJSON, FromJSON, ToSchema)

data AddressInfo = AddressInfo
{ road :: Text,
neighbourhood :: Text,
state_district :: Text,
state :: Text,
postcode :: Text,
country :: Text,
country_code :: Maybe Text
}
deriving (Generic, ToJSON, FromJSON, ToSchema)
50 changes: 50 additions & 0 deletions lib/mobility-core/src/Kernel/External/Maps/OSM/ReverseGeocode.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{-
Copyright 2022-23, Juspay India Pvt Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero
General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-}

module Kernel.External.Maps.OSM.ReverseGeocode where

import EulerHS.Types (EulerClient, client)
import Kernel.External.Maps.OSM.MapsClient.Types as OSM
import Kernel.Prelude
import Kernel.Tools.Metrics.CoreMetrics (CoreMetrics)
import Kernel.Types.Common
import Kernel.Types.Error
import Kernel.Utils.Common
import Servant hiding (throwError)

type OSMReverseGeocodeAPI =
"reverse"
:> MandatoryQueryParam "format" Text
:> MandatoryQueryParam "lat" Double
:> MandatoryQueryParam "lon" Double
:> Get '[JSON] OSM.ReverseGeocodeRes

osmReverseGeocodeAPI :: Proxy OSMReverseGeocodeAPI
osmReverseGeocodeAPI = Proxy

getPlaceDetailsFromLatLonClient :: Text -> Double -> Double -> EulerClient OSM.ReverseGeocodeRes
getPlaceDetailsFromLatLonClient = client osmReverseGeocodeAPI

getPlaceDetailsFromLatLon ::
( CoreMetrics m,
MonadFlow m
) =>
BaseUrl ->
Text ->
Double ->
Double ->
m OSM.ReverseGeocodeRes
getPlaceDetailsFromLatLon osmUrl format latitude longitude = do
callAPI osmUrl (getPlaceDetailsFromLatLonClient format latitude longitude) "osm-getPlaceDetails"
>>= fromEitherM (\err -> InternalError $ "Failed to call OSM Reverse Geocode API" <> show err)
4 changes: 2 additions & 2 deletions lib/mobility-core/src/Kernel/External/Maps/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ import Kernel.Storage.Esqueleto (derivePersistField)
import Kernel.Utils.GenericPretty (PrettyShow)
import Servant.API (FromHttpApiData (..), ToHttpApiData (..))

data MapsService = Google | OSRM | MMI
data MapsService = Google | OSRM | MMI | OSM
deriving (Show, Read, Eq, Ord, Generic, ToJSON, FromJSON, ToSchema)

availableMapsServices :: [MapsService]
availableMapsServices = [Google, OSRM, MMI]
availableMapsServices = [Google, OSRM, MMI, OSM]

derivePersistField "MapsService"

Expand Down

0 comments on commit 8c6138a

Please sign in to comment.