module Data.Internal.Wkt.Polygon
  ( polygon
  , multiPolygon
  , emptyPolygon
  , emptyMultiPolygon
  ) where

import           Control.Applicative      ((<|>))
import qualified Data.Geospatial          as Geospatial
import qualified Data.LinearRing          as LinearRing
import qualified Data.Sequence            as Sequence
import qualified Text.Trifecta            as Trifecta

import qualified Data.Internal.Wkt.Common as Wkt
import qualified Data.Internal.Wkt.Line   as Line
import qualified Data.Internal.Wkt.Point  as Point
import qualified Data.SeqHelper           as SeqHelper

polygon :: Trifecta.Parser Geospatial.GeoPolygon
polygon :: Parser GeoPolygon
polygon = do
  String
_ <- String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"polygon"
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (LinearRing GeoPositionWithoutCRS)
x <- Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall a. Parser (Seq a)
Wkt.emptySet Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Seq (LinearRing GeoPositionWithoutCRS))
nonEmptyPolygon
  GeoPolygon -> Parser GeoPolygon
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeoPolygon -> Parser GeoPolygon)
-> GeoPolygon -> Parser GeoPolygon
forall a b. (a -> b) -> a -> b
$ Seq (LinearRing GeoPositionWithoutCRS) -> GeoPolygon
Geospatial.GeoPolygon Seq (LinearRing GeoPositionWithoutCRS)
x

nonEmptyPolygon :: Trifecta.Parser (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS))
nonEmptyPolygon :: Parser (Seq (LinearRing GeoPositionWithoutCRS))
nonEmptyPolygon =
  (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"zm" Parser String
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
Point.justPointsXYZM)
  Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"z" Parser String
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
Point.justPointsXYZ)
  Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
Point.justPointsXY

multiPolygon :: Trifecta.Parser Geospatial.GeoMultiPolygon
multiPolygon :: Parser GeoMultiPolygon
multiPolygon = do
  String
_ <- String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"multipolygon"
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (Seq (LinearRing GeoPositionWithoutCRS))
xs <- Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall a. Parser (Seq a)
Wkt.emptySet Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
nonEmptyMultiPolygon
  GeoMultiPolygon -> Parser GeoMultiPolygon
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeoMultiPolygon -> Parser GeoMultiPolygon)
-> GeoMultiPolygon -> Parser GeoMultiPolygon
forall a b. (a -> b) -> a -> b
$ Seq (Seq (LinearRing GeoPositionWithoutCRS)) -> GeoMultiPolygon
Geospatial.GeoMultiPolygon Seq (Seq (LinearRing GeoPositionWithoutCRS))
xs

nonEmptyMultiPolygon :: Trifecta.Parser (Sequence.Seq (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS)))
nonEmptyMultiPolygon :: Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
nonEmptyMultiPolygon =
  (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"zm" Parser String
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
multiPolygon' Parser GeoPositionWithoutCRS
Point.justPointsXYZM)
  Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"z" Parser String
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
multiPolygon' Parser GeoPositionWithoutCRS
Point.justPointsXYZ)
  Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser GeoPositionWithoutCRS
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
multiPolygon' Parser GeoPositionWithoutCRS
Point.justPointsXY

polygon' :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS))
polygon' :: Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
pointParser = do
  Char
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser () -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
'('
  LinearRing GeoPositionWithoutCRS
x <- Parser GeoPositionWithoutCRS
-> Parser (LinearRing GeoPositionWithoutCRS)
linearRing Parser GeoPositionWithoutCRS
pointParser
  [LinearRing GeoPositionWithoutCRS]
xs <- Parser (LinearRing GeoPositionWithoutCRS)
-> Parser [LinearRing GeoPositionWithoutCRS]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Trifecta.many (Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
',' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser ()
-> Parser (LinearRing GeoPositionWithoutCRS)
-> Parser (LinearRing GeoPositionWithoutCRS)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (LinearRing GeoPositionWithoutCRS)
linearRing Parser GeoPositionWithoutCRS
pointParser)
  ()
_ <- Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
')' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (LinearRing GeoPositionWithoutCRS)
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Seq (LinearRing GeoPositionWithoutCRS)
 -> Parser (Seq (LinearRing GeoPositionWithoutCRS)))
-> Seq (LinearRing GeoPositionWithoutCRS)
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall a b. (a -> b) -> a -> b
$ LinearRing GeoPositionWithoutCRS
x LinearRing GeoPositionWithoutCRS
-> Seq (LinearRing GeoPositionWithoutCRS)
-> Seq (LinearRing GeoPositionWithoutCRS)
forall a. a -> Seq a -> Seq a
Sequence.:<| [LinearRing GeoPositionWithoutCRS]
-> Seq (LinearRing GeoPositionWithoutCRS)
forall a. [a] -> Seq a
Sequence.fromList [LinearRing GeoPositionWithoutCRS]
xs

multiPolygon' :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (Sequence.Seq (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS)))
multiPolygon' :: Parser GeoPositionWithoutCRS
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
multiPolygon' Parser GeoPositionWithoutCRS
pointParser = do
  Char
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser () -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
'('
  Seq (LinearRing GeoPositionWithoutCRS)
x <- Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
pointParser
  [Seq (LinearRing GeoPositionWithoutCRS)]
xs <- Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser [Seq (LinearRing GeoPositionWithoutCRS)]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Trifecta.many (Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
',' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser ()
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (LinearRing GeoPositionWithoutCRS))
polygon' Parser GeoPositionWithoutCRS
pointParser)
  ()
_ <- Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
')' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Seq (Seq (LinearRing GeoPositionWithoutCRS))
 -> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS))))
-> Seq (Seq (LinearRing GeoPositionWithoutCRS))
-> Parser (Seq (Seq (LinearRing GeoPositionWithoutCRS)))
forall a b. (a -> b) -> a -> b
$ Seq (LinearRing GeoPositionWithoutCRS)
x Seq (LinearRing GeoPositionWithoutCRS)
-> Seq (Seq (LinearRing GeoPositionWithoutCRS))
-> Seq (Seq (LinearRing GeoPositionWithoutCRS))
forall a. a -> Seq a -> Seq a
Sequence.:<| [Seq (LinearRing GeoPositionWithoutCRS)]
-> Seq (Seq (LinearRing GeoPositionWithoutCRS))
forall a. [a] -> Seq a
Sequence.fromList [Seq (LinearRing GeoPositionWithoutCRS)]
xs

linearRing :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS)
linearRing :: Parser GeoPositionWithoutCRS
-> Parser (LinearRing GeoPositionWithoutCRS)
linearRing Parser GeoPositionWithoutCRS
pointParser = do
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser () -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
'(' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  GeoPositionWithoutCRS
first <- Parser GeoPositionWithoutCRS
pointParser
  GeoPositionWithoutCRS
second <- Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
Line.commandPoint Parser GeoPositionWithoutCRS
pointParser
  GeoPositionWithoutCRS
third <- Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
Line.commandPoint Parser GeoPositionWithoutCRS
pointParser
  [GeoPositionWithoutCRS]
rest <- Parser GeoPositionWithoutCRS -> Parser [GeoPositionWithoutCRS]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Trifecta.many (Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
Line.commandPoint Parser GeoPositionWithoutCRS
pointParser)
  ()
_ <- Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
')' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  LinearRing GeoPositionWithoutCRS
-> Parser (LinearRing GeoPositionWithoutCRS)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LinearRing GeoPositionWithoutCRS
 -> Parser (LinearRing GeoPositionWithoutCRS))
-> LinearRing GeoPositionWithoutCRS
-> Parser (LinearRing GeoPositionWithoutCRS)
forall a b. (a -> b) -> a -> b
$ GeoPositionWithoutCRS
-> GeoPositionWithoutCRS
-> GeoPositionWithoutCRS
-> Seq GeoPositionWithoutCRS
-> LinearRing GeoPositionWithoutCRS
forall a. (Eq a, Show a) => a -> a -> a -> Seq a -> LinearRing a
LinearRing.makeLinearRing GeoPositionWithoutCRS
first GeoPositionWithoutCRS
second GeoPositionWithoutCRS
third (Seq GeoPositionWithoutCRS -> Seq GeoPositionWithoutCRS
forall a. Seq a -> Seq a
SeqHelper.sequenceHead (Seq GeoPositionWithoutCRS -> Seq GeoPositionWithoutCRS)
-> Seq GeoPositionWithoutCRS -> Seq GeoPositionWithoutCRS
forall a b. (a -> b) -> a -> b
$ [GeoPositionWithoutCRS] -> Seq GeoPositionWithoutCRS
forall a. [a] -> Seq a
Sequence.fromList [GeoPositionWithoutCRS]
rest)

emptyPolygon :: Geospatial.GeoPolygon
emptyPolygon :: GeoPolygon
emptyPolygon = Seq (LinearRing GeoPositionWithoutCRS) -> GeoPolygon
Geospatial.GeoPolygon Seq (LinearRing GeoPositionWithoutCRS)
forall a. Seq a
Sequence.empty

emptyMultiPolygon :: Geospatial.GeoMultiPolygon
emptyMultiPolygon :: GeoMultiPolygon
emptyMultiPolygon = Seq GeoPolygon -> GeoMultiPolygon
Geospatial.mergeGeoPolygons Seq GeoPolygon
forall a. Seq a
Sequence.empty