Files
to-hen/onomastics-ng/web/Main.hs

104 lines
3.6 KiB
Haskell
Raw Normal View History

2022-04-19 23:11:06 +02:00
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Control.Monad (liftM2)
import Control.Monad.IO.Class (liftIO)
import Data.Aeson (ToJSON (..))
2022-10-07 02:21:34 +02:00
import qualified Data.Map as Map (fromList, lookup)
2022-04-19 23:11:06 +02:00
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import GHC.Generics (Generic)
import Network.HTTP.Client (Manager)
import Network.HTTP.Client.TLS (newTlsManager)
import Network.Wai.Handler.Warp (runEnv)
import Onomap.Stoepel
import Onomap.Svg (renderMap)
import Onomap.Types
import Servant
import Servant.HTML.Blaze (HTML)
import Text.Blaze (ToMarkup (..))
data Response = Response {color :: [Text], areas :: [Area], statistics :: [(Text, ByArea Double)], svgSettings :: SvgSettings}
2022-04-19 23:11:06 +02:00
deriving (Generic)
instance ToMarkup Response where
toMarkup response =
preEscapedToMarkup $
renderMap
(svgSettings response)
2022-04-19 23:11:06 +02:00
(color response)
(areas response)
(statistics response)
instance ToJSON Response where
toJSON response =
toJSON $
2022-10-07 02:21:34 +02:00
Map.fromList $
map
( \area ->
( name area
, Map.fromList $
("population", toJSON $ population area) :
map
( \(surname, stats) ->
( surname
, toJSON $ Map.lookup (key area) (getByArea stats)
)
)
(statistics response)
)
)
(areas response)
2022-04-19 23:11:06 +02:00
type OnomapApi =
Capture "mode" Mode
2022-10-07 02:21:34 +02:00
:> QueryParams "name" Text
2022-04-19 23:11:06 +02:00
:> QueryParam "by" AreaKind
2022-10-07 02:21:34 +02:00
:> QueryParams "color" Text
:> QueryParam "scale" ScaleToMaximum
2022-10-07 02:21:34 +02:00
:> Get '[HTML] Response
2022-04-19 23:11:06 +02:00
app :: Manager -> ([Area], [Area]) -> Application
app manager' (theDistricts, theStates) = serve onomapApi server
where
server :: Server OnomapApi
server = \mode (surnames :: [Text]) maybeAreaKind colors scaleTo ->
2022-04-19 23:11:06 +02:00
liftIO $
runStoepel manager' $ do
let areaMode = fromMaybe District maybeAreaKind
computeFunction =
case mode of
Relative -> relativeCount
Absolute -> absoluteCount
theAreas = case areaMode of
State -> theStates
District -> theDistricts
2022-10-07 02:21:34 +02:00
theNames = map Just surnames
theStats <- case areaMode of
State -> mapM stateStatistics theNames
District -> mapM districtStatistics theNames
let stats = map (computeAreaStatistics computeFunction theAreas) theStats
return
Response
2022-10-07 02:40:01 +02:00
{ color = colors ++ defaultColorPalette
2022-10-07 02:21:34 +02:00
, areas = theAreas
, svgSettings = SvgSettings{scaleToMaximum = fromMaybe Global scaleTo}
2022-10-07 02:21:34 +02:00
, statistics = zip surnames stats
}
2022-04-19 23:11:06 +02:00
onomapApi :: Proxy OnomapApi
onomapApi = Proxy
main :: IO ()
main = do
manager' <- newTlsManager
runEnv 8081 . app manager' =<< runStoepel manager' (liftM2 (,) districts states)