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 (..))
|
|
|
|
|
|
2022-10-09 06:58:39 +02:00
|
|
|
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
|
2022-10-09 06:58:39 +02:00
|
|
|
(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
|
2022-10-09 06:58:39 +02:00
|
|
|
:> 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
|
2022-10-09 06:58:39 +02:00
|
|
|
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
|
2022-10-09 06:58:39 +02:00
|
|
|
, 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)
|