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 = do _ <- Trifecta.string "polygon" _ <- Trifecta.spaces x <- Wkt.emptySet <|> nonEmptyPolygon pure $ Geospatial.GeoPolygon x nonEmptyPolygon :: Trifecta.Parser (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS)) nonEmptyPolygon = (Trifecta.string "zm" >> polygon' Point.justPointsXYZM) <|> (Trifecta.string "z" >> polygon' Point.justPointsXYZ) <|> polygon' Point.justPointsXY multiPolygon :: Trifecta.Parser Geospatial.GeoMultiPolygon multiPolygon = do _ <- Trifecta.string "multipolygon" _ <- Trifecta.spaces xs <- Wkt.emptySet <|> nonEmptyMultiPolygon pure $ Geospatial.GeoMultiPolygon xs nonEmptyMultiPolygon :: Trifecta.Parser (Sequence.Seq (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS))) nonEmptyMultiPolygon = (Trifecta.string "zm" >> multiPolygon' Point.justPointsXYZM) <|> (Trifecta.string "z" >> multiPolygon' Point.justPointsXYZ) <|> multiPolygon' Point.justPointsXY polygon' :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS)) polygon' pointParser = do _ <- Trifecta.spaces >> Trifecta.char '(' x <- linearRing pointParser xs <- Trifecta.many (Trifecta.char ',' >> Trifecta.spaces >> linearRing pointParser) _ <- Trifecta.char ')' >> Trifecta.spaces pure $ x Sequence.:<| Sequence.fromList xs multiPolygon' :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (Sequence.Seq (Sequence.Seq (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS))) multiPolygon' pointParser = do _ <- Trifecta.spaces >> Trifecta.char '(' x <- polygon' pointParser xs <- Trifecta.many (Trifecta.char ',' >> Trifecta.spaces >> polygon' pointParser) _ <- Trifecta.char ')' >> Trifecta.spaces pure $ x Sequence.:<| Sequence.fromList xs linearRing :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (LinearRing.LinearRing Geospatial.GeoPositionWithoutCRS) linearRing pointParser = do _ <- Trifecta.spaces >> Trifecta.char '(' >> Trifecta.spaces first <- pointParser second <- Line.commandPoint pointParser third <- Line.commandPoint pointParser rest <- Trifecta.many (Line.commandPoint pointParser) _ <- Trifecta.char ')' >> Trifecta.spaces pure $ LinearRing.makeLinearRing first second third (SeqHelper.sequenceHead $ Sequence.fromList rest) emptyPolygon :: Geospatial.GeoPolygon emptyPolygon = Geospatial.GeoPolygon Sequence.empty emptyMultiPolygon :: Geospatial.GeoMultiPolygon emptyMultiPolygon = Geospatial.mergeGeoPolygons Sequence.empty