module Hasura.SQL.GeoJSON
  ( Position (..),
    Point (..),
    MultiPoint (..),
    LineString (..),
    LinearRing (..),
    MultiLineString (..),
    Polygon (..),
    MultiPolygon (..),
    Geometry (..),
    GeometryCollection (..),
    GeometryWithCRS (..),
  )
where

import Control.Monad
import Data.Aeson qualified as J
import Data.Aeson.Casing qualified as J
import Data.Aeson.Types qualified as J
import Data.Vector qualified as V
import Hasura.Prelude

-- Positions

data Position
  = Position !Double !Double !(Maybe Double)
  deriving (Int -> Position -> ShowS
[Position] -> ShowS
Position -> String
(Int -> Position -> ShowS)
-> (Position -> String) -> ([Position] -> ShowS) -> Show Position
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Position -> ShowS
showsPrec :: Int -> Position -> ShowS
$cshow :: Position -> String
show :: Position -> String
$cshowList :: [Position] -> ShowS
showList :: [Position] -> ShowS
Show, Position -> Position -> Bool
(Position -> Position -> Bool)
-> (Position -> Position -> Bool) -> Eq Position
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Position -> Position -> Bool
== :: Position -> Position -> Bool
$c/= :: Position -> Position -> Bool
/= :: Position -> Position -> Bool
Eq)

withParsedArray ::
  (J.FromJSON a) =>
  String ->
  (V.Vector a -> J.Parser b) ->
  J.Value ->
  J.Parser b
withParsedArray :: forall a b.
FromJSON a =>
String -> (Vector a -> Parser b) -> Value -> Parser b
withParsedArray String
s Vector a -> Parser b
fn =
  String -> (Array -> Parser b) -> Value -> Parser b
forall a. String -> (Array -> Parser a) -> Value -> Parser a
J.withArray String
s ((Value -> Parser a) -> Array -> Parser (Vector a)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
mapM Value -> Parser a
forall a. FromJSON a => Value -> Parser a
J.parseJSON (Array -> Parser (Vector a))
-> (Vector a -> Parser b) -> Array -> Parser b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Vector a -> Parser b
fn)

instance J.FromJSON Position where
  parseJSON :: Value -> Parser Position
parseJSON = String
-> (Vector Double -> Parser Position) -> Value -> Parser Position
forall a b.
FromJSON a =>
String -> (Vector a -> Parser b) -> Value -> Parser b
withParsedArray String
"Position" ((Vector Double -> Parser Position) -> Value -> Parser Position)
-> (Vector Double -> Parser Position) -> Value -> Parser Position
forall a b. (a -> b) -> a -> b
$ \Vector Double
arr ->
    if Vector Double -> Int
forall a. Vector a -> Int
V.length Vector Double
arr Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2
      then String -> Parser Position
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"A Position needs at least 2 elements"
      else -- here we are ignoring anything past 3 elements

        Position -> Parser Position
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return
          (Position -> Parser Position) -> Position -> Parser Position
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Maybe Double -> Position
Position
            (Vector Double
arr Vector Double -> Int -> Double
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
0)
            (Vector Double
arr Vector Double -> Int -> Double
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
1)
            (Vector Double
arr Vector Double -> Int -> Maybe Double
forall a. Vector a -> Int -> Maybe a
V.!? Int
2)

instance J.ToJSON Position where
  toJSON :: Position -> Value
toJSON (Position Double
a Double
b Maybe Double
c) =
    [Double] -> Value
forall a. ToJSON a => a -> Value
J.toJSON ([Double] -> Value) -> [Double] -> Value
forall a b. (a -> b) -> a -> b
$ Double
a Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
: Double
b Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
: Maybe Double -> [Double]
forall a. Maybe a -> [a]
maybeToList Maybe Double
c

-- Point, Multipoint

newtype Point = Point {Point -> Position
unPoint :: Position}
  deriving (Int -> Point -> ShowS
[Point] -> ShowS
Point -> String
(Int -> Point -> ShowS)
-> (Point -> String) -> ([Point] -> ShowS) -> Show Point
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Point -> ShowS
showsPrec :: Int -> Point -> ShowS
$cshow :: Point -> String
show :: Point -> String
$cshowList :: [Point] -> ShowS
showList :: [Point] -> ShowS
Show, Point -> Point -> Bool
(Point -> Point -> Bool) -> (Point -> Point -> Bool) -> Eq Point
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Point -> Point -> Bool
== :: Point -> Point -> Bool
$c/= :: Point -> Point -> Bool
/= :: Point -> Point -> Bool
Eq, [Point] -> Value
[Point] -> Encoding
Point -> Value
Point -> Encoding
(Point -> Value)
-> (Point -> Encoding)
-> ([Point] -> Value)
-> ([Point] -> Encoding)
-> ToJSON Point
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: Point -> Value
toJSON :: Point -> Value
$ctoEncoding :: Point -> Encoding
toEncoding :: Point -> Encoding
$ctoJSONList :: [Point] -> Value
toJSONList :: [Point] -> Value
$ctoEncodingList :: [Point] -> Encoding
toEncodingList :: [Point] -> Encoding
J.ToJSON, Value -> Parser [Point]
Value -> Parser Point
(Value -> Parser Point)
-> (Value -> Parser [Point]) -> FromJSON Point
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser Point
parseJSON :: Value -> Parser Point
$cparseJSONList :: Value -> Parser [Point]
parseJSONList :: Value -> Parser [Point]
J.FromJSON)

newtype MultiPoint = MultiPoint {MultiPoint -> [Position]
unMultiPoint :: [Position]}
  deriving (Int -> MultiPoint -> ShowS
[MultiPoint] -> ShowS
MultiPoint -> String
(Int -> MultiPoint -> ShowS)
-> (MultiPoint -> String)
-> ([MultiPoint] -> ShowS)
-> Show MultiPoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MultiPoint -> ShowS
showsPrec :: Int -> MultiPoint -> ShowS
$cshow :: MultiPoint -> String
show :: MultiPoint -> String
$cshowList :: [MultiPoint] -> ShowS
showList :: [MultiPoint] -> ShowS
Show, MultiPoint -> MultiPoint -> Bool
(MultiPoint -> MultiPoint -> Bool)
-> (MultiPoint -> MultiPoint -> Bool) -> Eq MultiPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MultiPoint -> MultiPoint -> Bool
== :: MultiPoint -> MultiPoint -> Bool
$c/= :: MultiPoint -> MultiPoint -> Bool
/= :: MultiPoint -> MultiPoint -> Bool
Eq, [MultiPoint] -> Value
[MultiPoint] -> Encoding
MultiPoint -> Value
MultiPoint -> Encoding
(MultiPoint -> Value)
-> (MultiPoint -> Encoding)
-> ([MultiPoint] -> Value)
-> ([MultiPoint] -> Encoding)
-> ToJSON MultiPoint
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: MultiPoint -> Value
toJSON :: MultiPoint -> Value
$ctoEncoding :: MultiPoint -> Encoding
toEncoding :: MultiPoint -> Encoding
$ctoJSONList :: [MultiPoint] -> Value
toJSONList :: [MultiPoint] -> Value
$ctoEncodingList :: [MultiPoint] -> Encoding
toEncodingList :: [MultiPoint] -> Encoding
J.ToJSON, Value -> Parser [MultiPoint]
Value -> Parser MultiPoint
(Value -> Parser MultiPoint)
-> (Value -> Parser [MultiPoint]) -> FromJSON MultiPoint
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser MultiPoint
parseJSON :: Value -> Parser MultiPoint
$cparseJSONList :: Value -> Parser [MultiPoint]
parseJSONList :: Value -> Parser [MultiPoint]
J.FromJSON)

-- LineString, MultiLineString

data LineString = LineString
  { LineString -> Position
_lsFirst :: !Position,
    LineString -> Position
_lsSecond :: !Position,
    LineString -> [Position]
_lsRest :: ![Position]
  }
  deriving (Int -> LineString -> ShowS
[LineString] -> ShowS
LineString -> String
(Int -> LineString -> ShowS)
-> (LineString -> String)
-> ([LineString] -> ShowS)
-> Show LineString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LineString -> ShowS
showsPrec :: Int -> LineString -> ShowS
$cshow :: LineString -> String
show :: LineString -> String
$cshowList :: [LineString] -> ShowS
showList :: [LineString] -> ShowS
Show, LineString -> LineString -> Bool
(LineString -> LineString -> Bool)
-> (LineString -> LineString -> Bool) -> Eq LineString
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LineString -> LineString -> Bool
== :: LineString -> LineString -> Bool
$c/= :: LineString -> LineString -> Bool
/= :: LineString -> LineString -> Bool
Eq)

instance J.ToJSON LineString where
  toJSON :: LineString -> Value
toJSON (LineString Position
a Position
b [Position]
rest) =
    [Position] -> Value
forall a. ToJSON a => a -> Value
J.toJSON ([Position] -> Value) -> [Position] -> Value
forall a b. (a -> b) -> a -> b
$ Position
a Position -> [Position] -> [Position]
forall a. a -> [a] -> [a]
: Position
b Position -> [Position] -> [Position]
forall a. a -> [a] -> [a]
: [Position]
rest

instance J.FromJSON LineString where
  parseJSON :: Value -> Parser LineString
parseJSON = String
-> (Vector Position -> Parser LineString)
-> Value
-> Parser LineString
forall a b.
FromJSON a =>
String -> (Vector a -> Parser b) -> Value -> Parser b
withParsedArray String
"LineString" ((Vector Position -> Parser LineString)
 -> Value -> Parser LineString)
-> (Vector Position -> Parser LineString)
-> Value
-> Parser LineString
forall a b. (a -> b) -> a -> b
$ \Vector Position
arr ->
    if Vector Position -> Int
forall a. Vector a -> Int
V.length Vector Position
arr Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2
      then String -> Parser LineString
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"A LineString needs at least 2 Positions"
      else -- here we are ignoring anything past 3 elements

        let fstPos :: Position
fstPos = Vector Position
arr Vector Position -> Int -> Position
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
0
            sndPos :: Position
sndPos = Vector Position
arr Vector Position -> Int -> Position
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
1
            rest :: [Position]
rest = Vector Position -> [Position]
forall a. Vector a -> [a]
V.toList (Vector Position -> [Position]) -> Vector Position -> [Position]
forall a b. (a -> b) -> a -> b
$ Int -> Vector Position -> Vector Position
forall a. Int -> Vector a -> Vector a
V.drop Int
2 Vector Position
arr
         in LineString -> Parser LineString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (LineString -> Parser LineString)
-> LineString -> Parser LineString
forall a b. (a -> b) -> a -> b
$ Position -> Position -> [Position] -> LineString
LineString Position
fstPos Position
sndPos [Position]
rest

newtype MultiLineString = MultiLineString {MultiLineString -> [LineString]
unMultiLineString :: [LineString]}
  deriving (Int -> MultiLineString -> ShowS
[MultiLineString] -> ShowS
MultiLineString -> String
(Int -> MultiLineString -> ShowS)
-> (MultiLineString -> String)
-> ([MultiLineString] -> ShowS)
-> Show MultiLineString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MultiLineString -> ShowS
showsPrec :: Int -> MultiLineString -> ShowS
$cshow :: MultiLineString -> String
show :: MultiLineString -> String
$cshowList :: [MultiLineString] -> ShowS
showList :: [MultiLineString] -> ShowS
Show, MultiLineString -> MultiLineString -> Bool
(MultiLineString -> MultiLineString -> Bool)
-> (MultiLineString -> MultiLineString -> Bool)
-> Eq MultiLineString
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MultiLineString -> MultiLineString -> Bool
== :: MultiLineString -> MultiLineString -> Bool
$c/= :: MultiLineString -> MultiLineString -> Bool
/= :: MultiLineString -> MultiLineString -> Bool
Eq, [MultiLineString] -> Value
[MultiLineString] -> Encoding
MultiLineString -> Value
MultiLineString -> Encoding
(MultiLineString -> Value)
-> (MultiLineString -> Encoding)
-> ([MultiLineString] -> Value)
-> ([MultiLineString] -> Encoding)
-> ToJSON MultiLineString
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: MultiLineString -> Value
toJSON :: MultiLineString -> Value
$ctoEncoding :: MultiLineString -> Encoding
toEncoding :: MultiLineString -> Encoding
$ctoJSONList :: [MultiLineString] -> Value
toJSONList :: [MultiLineString] -> Value
$ctoEncodingList :: [MultiLineString] -> Encoding
toEncodingList :: [MultiLineString] -> Encoding
J.ToJSON, Value -> Parser [MultiLineString]
Value -> Parser MultiLineString
(Value -> Parser MultiLineString)
-> (Value -> Parser [MultiLineString]) -> FromJSON MultiLineString
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser MultiLineString
parseJSON :: Value -> Parser MultiLineString
$cparseJSONList :: Value -> Parser [MultiLineString]
parseJSONList :: Value -> Parser [MultiLineString]
J.FromJSON)

-- Polygon, MultiPolygon

data LinearRing = LinearRing
  { LinearRing -> Position
_pFirst :: !Position,
    LinearRing -> Position
_pSecond :: !Position,
    LinearRing -> Position
_pThird :: !Position,
    LinearRing -> [Position]
_pRest :: ![Position]
  }
  deriving (Int -> LinearRing -> ShowS
[LinearRing] -> ShowS
LinearRing -> String
(Int -> LinearRing -> ShowS)
-> (LinearRing -> String)
-> ([LinearRing] -> ShowS)
-> Show LinearRing
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LinearRing -> ShowS
showsPrec :: Int -> LinearRing -> ShowS
$cshow :: LinearRing -> String
show :: LinearRing -> String
$cshowList :: [LinearRing] -> ShowS
showList :: [LinearRing] -> ShowS
Show, LinearRing -> LinearRing -> Bool
(LinearRing -> LinearRing -> Bool)
-> (LinearRing -> LinearRing -> Bool) -> Eq LinearRing
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LinearRing -> LinearRing -> Bool
== :: LinearRing -> LinearRing -> Bool
$c/= :: LinearRing -> LinearRing -> Bool
/= :: LinearRing -> LinearRing -> Bool
Eq)

instance J.FromJSON LinearRing where
  parseJSON :: Value -> Parser LinearRing
parseJSON = String
-> (Vector Position -> Parser LinearRing)
-> Value
-> Parser LinearRing
forall a b.
FromJSON a =>
String -> (Vector a -> Parser b) -> Value -> Parser b
withParsedArray String
"LinearRing" ((Vector Position -> Parser LinearRing)
 -> Value -> Parser LinearRing)
-> (Vector Position -> Parser LinearRing)
-> Value
-> Parser LinearRing
forall a b. (a -> b) -> a -> b
$ \Vector Position
arr ->
    if Vector Position -> Int
forall a. Vector a -> Int
V.length Vector Position
arr Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
4
      then String -> Parser LinearRing
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"A LinearRing needs at least 4 Positions"
      else -- here we are ignoring anything past 3 elements
      do
        let fstPos :: Position
fstPos = Vector Position
arr Vector Position -> Int -> Position
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
0
            sndPos :: Position
sndPos = Vector Position
arr Vector Position -> Int -> Position
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
1
            thrPos :: Position
thrPos = Vector Position
arr Vector Position -> Int -> Position
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
2
            rest :: Vector Position
rest = Int -> Vector Position -> Vector Position
forall a. Int -> Vector a -> Vector a
V.drop Int
3 Vector Position
arr
        let lastPos :: Position
lastPos = Vector Position -> Position
forall a. Vector a -> a
V.last Vector Position
rest
        Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Position
fstPos Position -> Position -> Bool
forall a. Eq a => a -> a -> Bool
== Position
lastPos)
          (Parser () -> Parser ()) -> Parser () -> Parser ()
forall a b. (a -> b) -> a -> b
$ String -> Parser ()
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"the first and last locations have to be equal for a LinearRing"
        LinearRing -> Parser LinearRing
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (LinearRing -> Parser LinearRing)
-> LinearRing -> Parser LinearRing
forall a b. (a -> b) -> a -> b
$ Position -> Position -> Position -> [Position] -> LinearRing
LinearRing Position
fstPos Position
sndPos Position
thrPos ([Position] -> LinearRing) -> [Position] -> LinearRing
forall a b. (a -> b) -> a -> b
$ Vector Position -> [Position]
forall a. Vector a -> [a]
V.toList (Vector Position -> [Position]) -> Vector Position -> [Position]
forall a b. (a -> b) -> a -> b
$ Vector Position -> Vector Position
forall a. Vector a -> Vector a
V.init Vector Position
rest

instance J.ToJSON LinearRing where
  toJSON :: LinearRing -> Value
toJSON (LinearRing Position
a Position
b Position
c [Position]
rest) =
    Vector Position -> Value
forall a. ToJSON a => a -> Value
J.toJSON (Vector Position -> Value) -> Vector Position -> Value
forall a b. (a -> b) -> a -> b
$ ([Position] -> Vector Position
forall a. [a] -> Vector a
V.fromList [Position
a, Position
b, Position
c] Vector Position -> Vector Position -> Vector Position
forall a. Semigroup a => a -> a -> a
<> [Position] -> Vector Position
forall a. [a] -> Vector a
V.fromList [Position]
rest) Vector Position -> Position -> Vector Position
forall a. Vector a -> a -> Vector a
`V.snoc` Position
a

newtype Polygon = Polygon {Polygon -> [LinearRing]
unPolygon :: [LinearRing]}
  deriving (Int -> Polygon -> ShowS
[Polygon] -> ShowS
Polygon -> String
(Int -> Polygon -> ShowS)
-> (Polygon -> String) -> ([Polygon] -> ShowS) -> Show Polygon
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Polygon -> ShowS
showsPrec :: Int -> Polygon -> ShowS
$cshow :: Polygon -> String
show :: Polygon -> String
$cshowList :: [Polygon] -> ShowS
showList :: [Polygon] -> ShowS
Show, Polygon -> Polygon -> Bool
(Polygon -> Polygon -> Bool)
-> (Polygon -> Polygon -> Bool) -> Eq Polygon
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Polygon -> Polygon -> Bool
== :: Polygon -> Polygon -> Bool
$c/= :: Polygon -> Polygon -> Bool
/= :: Polygon -> Polygon -> Bool
Eq, [Polygon] -> Value
[Polygon] -> Encoding
Polygon -> Value
Polygon -> Encoding
(Polygon -> Value)
-> (Polygon -> Encoding)
-> ([Polygon] -> Value)
-> ([Polygon] -> Encoding)
-> ToJSON Polygon
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: Polygon -> Value
toJSON :: Polygon -> Value
$ctoEncoding :: Polygon -> Encoding
toEncoding :: Polygon -> Encoding
$ctoJSONList :: [Polygon] -> Value
toJSONList :: [Polygon] -> Value
$ctoEncodingList :: [Polygon] -> Encoding
toEncodingList :: [Polygon] -> Encoding
J.ToJSON, Value -> Parser [Polygon]
Value -> Parser Polygon
(Value -> Parser Polygon)
-> (Value -> Parser [Polygon]) -> FromJSON Polygon
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser Polygon
parseJSON :: Value -> Parser Polygon
$cparseJSONList :: Value -> Parser [Polygon]
parseJSONList :: Value -> Parser [Polygon]
J.FromJSON)

newtype MultiPolygon = MultiPolygon {MultiPolygon -> [Polygon]
unMultiPolygon :: [Polygon]}
  deriving (Int -> MultiPolygon -> ShowS
[MultiPolygon] -> ShowS
MultiPolygon -> String
(Int -> MultiPolygon -> ShowS)
-> (MultiPolygon -> String)
-> ([MultiPolygon] -> ShowS)
-> Show MultiPolygon
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MultiPolygon -> ShowS
showsPrec :: Int -> MultiPolygon -> ShowS
$cshow :: MultiPolygon -> String
show :: MultiPolygon -> String
$cshowList :: [MultiPolygon] -> ShowS
showList :: [MultiPolygon] -> ShowS
Show, MultiPolygon -> MultiPolygon -> Bool
(MultiPolygon -> MultiPolygon -> Bool)
-> (MultiPolygon -> MultiPolygon -> Bool) -> Eq MultiPolygon
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MultiPolygon -> MultiPolygon -> Bool
== :: MultiPolygon -> MultiPolygon -> Bool
$c/= :: MultiPolygon -> MultiPolygon -> Bool
/= :: MultiPolygon -> MultiPolygon -> Bool
Eq, [MultiPolygon] -> Value
[MultiPolygon] -> Encoding
MultiPolygon -> Value
MultiPolygon -> Encoding
(MultiPolygon -> Value)
-> (MultiPolygon -> Encoding)
-> ([MultiPolygon] -> Value)
-> ([MultiPolygon] -> Encoding)
-> ToJSON MultiPolygon
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: MultiPolygon -> Value
toJSON :: MultiPolygon -> Value
$ctoEncoding :: MultiPolygon -> Encoding
toEncoding :: MultiPolygon -> Encoding
$ctoJSONList :: [MultiPolygon] -> Value
toJSONList :: [MultiPolygon] -> Value
$ctoEncodingList :: [MultiPolygon] -> Encoding
toEncodingList :: [MultiPolygon] -> Encoding
J.ToJSON, Value -> Parser [MultiPolygon]
Value -> Parser MultiPolygon
(Value -> Parser MultiPolygon)
-> (Value -> Parser [MultiPolygon]) -> FromJSON MultiPolygon
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser MultiPolygon
parseJSON :: Value -> Parser MultiPolygon
$cparseJSONList :: Value -> Parser [MultiPolygon]
parseJSONList :: Value -> Parser [MultiPolygon]
J.FromJSON)

-- GeometryCollection

data CRSNameProps = CRSNameProps
  { CRSNameProps -> Text
_cnpName :: !Text
  }
  deriving (Int -> CRSNameProps -> ShowS
[CRSNameProps] -> ShowS
CRSNameProps -> String
(Int -> CRSNameProps -> ShowS)
-> (CRSNameProps -> String)
-> ([CRSNameProps] -> ShowS)
-> Show CRSNameProps
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CRSNameProps -> ShowS
showsPrec :: Int -> CRSNameProps -> ShowS
$cshow :: CRSNameProps -> String
show :: CRSNameProps -> String
$cshowList :: [CRSNameProps] -> ShowS
showList :: [CRSNameProps] -> ShowS
Show, CRSNameProps -> CRSNameProps -> Bool
(CRSNameProps -> CRSNameProps -> Bool)
-> (CRSNameProps -> CRSNameProps -> Bool) -> Eq CRSNameProps
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CRSNameProps -> CRSNameProps -> Bool
== :: CRSNameProps -> CRSNameProps -> Bool
$c/= :: CRSNameProps -> CRSNameProps -> Bool
/= :: CRSNameProps -> CRSNameProps -> Bool
Eq, (forall x. CRSNameProps -> Rep CRSNameProps x)
-> (forall x. Rep CRSNameProps x -> CRSNameProps)
-> Generic CRSNameProps
forall x. Rep CRSNameProps x -> CRSNameProps
forall x. CRSNameProps -> Rep CRSNameProps x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CRSNameProps -> Rep CRSNameProps x
from :: forall x. CRSNameProps -> Rep CRSNameProps x
$cto :: forall x. Rep CRSNameProps x -> CRSNameProps
to :: forall x. Rep CRSNameProps x -> CRSNameProps
Generic)

data CRSLinkProps = CRSLinkProps
  { CRSLinkProps -> Text
_clpHref :: !Text,
    CRSLinkProps -> Maybe Text
_clpType :: !(Maybe Text)
  }
  deriving (Int -> CRSLinkProps -> ShowS
[CRSLinkProps] -> ShowS
CRSLinkProps -> String
(Int -> CRSLinkProps -> ShowS)
-> (CRSLinkProps -> String)
-> ([CRSLinkProps] -> ShowS)
-> Show CRSLinkProps
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CRSLinkProps -> ShowS
showsPrec :: Int -> CRSLinkProps -> ShowS
$cshow :: CRSLinkProps -> String
show :: CRSLinkProps -> String
$cshowList :: [CRSLinkProps] -> ShowS
showList :: [CRSLinkProps] -> ShowS
Show, CRSLinkProps -> CRSLinkProps -> Bool
(CRSLinkProps -> CRSLinkProps -> Bool)
-> (CRSLinkProps -> CRSLinkProps -> Bool) -> Eq CRSLinkProps
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CRSLinkProps -> CRSLinkProps -> Bool
== :: CRSLinkProps -> CRSLinkProps -> Bool
$c/= :: CRSLinkProps -> CRSLinkProps -> Bool
/= :: CRSLinkProps -> CRSLinkProps -> Bool
Eq, (forall x. CRSLinkProps -> Rep CRSLinkProps x)
-> (forall x. Rep CRSLinkProps x -> CRSLinkProps)
-> Generic CRSLinkProps
forall x. Rep CRSLinkProps x -> CRSLinkProps
forall x. CRSLinkProps -> Rep CRSLinkProps x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CRSLinkProps -> Rep CRSLinkProps x
from :: forall x. CRSLinkProps -> Rep CRSLinkProps x
$cto :: forall x. Rep CRSLinkProps x -> CRSLinkProps
to :: forall x. Rep CRSLinkProps x -> CRSLinkProps
Generic)

data CRS
  = CRSName !CRSNameProps
  | CRSLink !CRSLinkProps
  deriving (Int -> CRS -> ShowS
[CRS] -> ShowS
CRS -> String
(Int -> CRS -> ShowS)
-> (CRS -> String) -> ([CRS] -> ShowS) -> Show CRS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CRS -> ShowS
showsPrec :: Int -> CRS -> ShowS
$cshow :: CRS -> String
show :: CRS -> String
$cshowList :: [CRS] -> ShowS
showList :: [CRS] -> ShowS
Show, CRS -> CRS -> Bool
(CRS -> CRS -> Bool) -> (CRS -> CRS -> Bool) -> Eq CRS
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CRS -> CRS -> Bool
== :: CRS -> CRS -> Bool
$c/= :: CRS -> CRS -> Bool
/= :: CRS -> CRS -> Bool
Eq, (forall x. CRS -> Rep CRS x)
-> (forall x. Rep CRS x -> CRS) -> Generic CRS
forall x. Rep CRS x -> CRS
forall x. CRS -> Rep CRS x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CRS -> Rep CRS x
from :: forall x. CRS -> Rep CRS x
$cto :: forall x. Rep CRS x -> CRS
to :: forall x. Rep CRS x -> CRS
Generic)

instance J.FromJSON CRSNameProps where
  parseJSON :: Value -> Parser CRSNameProps
parseJSON = Options -> Value -> Parser CRSNameProps
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
J.genericParseJSON (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)

instance J.ToJSON CRSNameProps where
  toJSON :: CRSNameProps -> Value
toJSON = Options -> CRSNameProps -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
J.genericToJSON (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)
  toEncoding :: CRSNameProps -> Encoding
toEncoding = Options -> CRSNameProps -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
J.genericToEncoding (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)

instance J.FromJSON CRSLinkProps where
  parseJSON :: Value -> Parser CRSLinkProps
parseJSON = Options -> Value -> Parser CRSLinkProps
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
J.genericParseJSON (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)

instance J.ToJSON CRSLinkProps where
  toJSON :: CRSLinkProps -> Value
toJSON = Options -> CRSLinkProps -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
J.genericToJSON (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)
  toEncoding :: CRSLinkProps -> Encoding
toEncoding = Options -> CRSLinkProps -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
J.genericToEncoding (ShowS -> Options
J.aesonPrefix ShowS
J.camelCase)

instance J.FromJSON CRS where
  parseJSON :: Value -> Parser CRS
parseJSON =
    Options -> Value -> Parser CRS
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
J.genericParseJSON
      Options
J.defaultOptions
        { constructorTagModifier :: ShowS
J.constructorTagModifier = ShowS
J.camelCase ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3,
          sumEncoding :: SumEncoding
J.sumEncoding = String -> String -> SumEncoding
J.TaggedObject String
"type" String
"properties"
        }

instance J.ToJSON CRS where
  toJSON :: CRS -> Value
toJSON =
    Options -> CRS -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
J.genericToJSON
      Options
J.defaultOptions
        { constructorTagModifier :: ShowS
J.constructorTagModifier = ShowS
J.camelCase ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3,
          sumEncoding :: SumEncoding
J.sumEncoding = String -> String -> SumEncoding
J.TaggedObject String
"type" String
"properties"
        }
  toEncoding :: CRS -> Encoding
toEncoding =
    Options -> CRS -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
J.genericToEncoding
      Options
J.defaultOptions
        { constructorTagModifier :: ShowS
J.constructorTagModifier = ShowS
J.camelCase ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3,
          sumEncoding :: SumEncoding
J.sumEncoding = String -> String -> SumEncoding
J.TaggedObject String
"type" String
"properties"
        }

data GeometryWithCRS = GeometryWithCRS
  { GeometryWithCRS -> Geometry
_gwcGeom :: !Geometry,
    GeometryWithCRS -> Maybe CRS
_gwcCrs :: !(Maybe CRS)
  }
  deriving (Int -> GeometryWithCRS -> ShowS
[GeometryWithCRS] -> ShowS
GeometryWithCRS -> String
(Int -> GeometryWithCRS -> ShowS)
-> (GeometryWithCRS -> String)
-> ([GeometryWithCRS] -> ShowS)
-> Show GeometryWithCRS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GeometryWithCRS -> ShowS
showsPrec :: Int -> GeometryWithCRS -> ShowS
$cshow :: GeometryWithCRS -> String
show :: GeometryWithCRS -> String
$cshowList :: [GeometryWithCRS] -> ShowS
showList :: [GeometryWithCRS] -> ShowS
Show, GeometryWithCRS -> GeometryWithCRS -> Bool
(GeometryWithCRS -> GeometryWithCRS -> Bool)
-> (GeometryWithCRS -> GeometryWithCRS -> Bool)
-> Eq GeometryWithCRS
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GeometryWithCRS -> GeometryWithCRS -> Bool
== :: GeometryWithCRS -> GeometryWithCRS -> Bool
$c/= :: GeometryWithCRS -> GeometryWithCRS -> Bool
/= :: GeometryWithCRS -> GeometryWithCRS -> Bool
Eq)

encToCoords :: (J.ToJSON a) => Text -> a -> Maybe CRS -> J.Value
encToCoords :: forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
ty a
a Maybe CRS
Nothing =
  [Pair] -> Value
J.object [Key
"type" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= Text
ty, Key
"coordinates" Key -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= a
a]
encToCoords Text
ty a
a (Just CRS
crs) =
  [Pair] -> Value
J.object [Key
"type" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= Text
ty, Key
"coordinates" Key -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= a
a, Key
"crs" Key -> CRS -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= CRS
crs]

instance J.ToJSON GeometryWithCRS where
  toJSON :: GeometryWithCRS -> Value
toJSON (GeometryWithCRS Geometry
geom Maybe CRS
crsM) = case Geometry
geom of
    GPoint Point
o -> Text -> Point -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"Point" Point
o Maybe CRS
crsM
    GMultiPoint MultiPoint
o -> Text -> MultiPoint -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"MultiPoint" MultiPoint
o Maybe CRS
crsM
    GLineString LineString
o -> Text -> LineString -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"LineString" LineString
o Maybe CRS
crsM
    GMultiLineString MultiLineString
o -> Text -> MultiLineString -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"MultiLineString" MultiLineString
o Maybe CRS
crsM
    GPolygon Polygon
o -> Text -> Polygon -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"Polygon" Polygon
o Maybe CRS
crsM
    GMultiPolygon MultiPolygon
o -> Text -> MultiPolygon -> Maybe CRS -> Value
forall a. ToJSON a => Text -> a -> Maybe CRS -> Value
encToCoords Text
"MultiPolygon" MultiPolygon
o Maybe CRS
crsM
    GGeometryCollection GeometryCollection
o ->
      [Pair] -> Value
J.object
        [ Key
"type" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= (Text
"GeometryCollection" :: Text),
          Key
"geometries" Key -> GeometryCollection -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
J..= GeometryCollection
o
        ]

instance J.FromJSON GeometryWithCRS where
  parseJSON :: Value -> Parser GeometryWithCRS
parseJSON = String
-> (Object -> Parser GeometryWithCRS)
-> Value
-> Parser GeometryWithCRS
forall a. String -> (Object -> Parser a) -> Value -> Parser a
J.withObject String
"Geometry" ((Object -> Parser GeometryWithCRS)
 -> Value -> Parser GeometryWithCRS)
-> (Object -> Parser GeometryWithCRS)
-> Value
-> Parser GeometryWithCRS
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    String
ty <- Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"type"
    Geometry
geom <- case String
ty of
      String
"Point" -> Point -> Geometry
GPoint (Point -> Geometry) -> Parser Point -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Point
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"MultiPoint" -> MultiPoint -> Geometry
GMultiPoint (MultiPoint -> Geometry) -> Parser MultiPoint -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser MultiPoint
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"LineString" -> LineString -> Geometry
GLineString (LineString -> Geometry) -> Parser LineString -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser LineString
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"MultiLineString" -> MultiLineString -> Geometry
GMultiLineString (MultiLineString -> Geometry)
-> Parser MultiLineString -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser MultiLineString
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"Polygon" -> Polygon -> Geometry
GPolygon (Polygon -> Geometry) -> Parser Polygon -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Polygon
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"MultiPolygon" -> MultiPolygon -> Geometry
GMultiPolygon (MultiPolygon -> Geometry)
-> Parser MultiPolygon -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser MultiPolygon
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"coordinates"
      String
"GeometryCollection" -> GeometryCollection -> Geometry
GGeometryCollection (GeometryCollection -> Geometry)
-> Parser GeometryCollection -> Parser Geometry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser GeometryCollection
forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"geometries"
      String
_ -> String -> Parser Geometry
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Geometry) -> String -> Parser Geometry
forall a b. (a -> b) -> a -> b
$ String
"unexpected geometry type: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
ty
    Maybe CRS
crsM <- Object
o Object -> Key -> Parser (Maybe CRS)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
J..:? Key
"crs"
    GeometryWithCRS -> Parser GeometryWithCRS
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (GeometryWithCRS -> Parser GeometryWithCRS)
-> GeometryWithCRS -> Parser GeometryWithCRS
forall a b. (a -> b) -> a -> b
$ Geometry -> Maybe CRS -> GeometryWithCRS
GeometryWithCRS Geometry
geom Maybe CRS
crsM

newtype GeometryCollection = GeometryCollection {GeometryCollection -> [GeometryWithCRS]
unGeometryCollection :: [GeometryWithCRS]}
  deriving (Int -> GeometryCollection -> ShowS
[GeometryCollection] -> ShowS
GeometryCollection -> String
(Int -> GeometryCollection -> ShowS)
-> (GeometryCollection -> String)
-> ([GeometryCollection] -> ShowS)
-> Show GeometryCollection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GeometryCollection -> ShowS
showsPrec :: Int -> GeometryCollection -> ShowS
$cshow :: GeometryCollection -> String
show :: GeometryCollection -> String
$cshowList :: [GeometryCollection] -> ShowS
showList :: [GeometryCollection] -> ShowS
Show, GeometryCollection -> GeometryCollection -> Bool
(GeometryCollection -> GeometryCollection -> Bool)
-> (GeometryCollection -> GeometryCollection -> Bool)
-> Eq GeometryCollection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GeometryCollection -> GeometryCollection -> Bool
== :: GeometryCollection -> GeometryCollection -> Bool
$c/= :: GeometryCollection -> GeometryCollection -> Bool
/= :: GeometryCollection -> GeometryCollection -> Bool
Eq, [GeometryCollection] -> Value
[GeometryCollection] -> Encoding
GeometryCollection -> Value
GeometryCollection -> Encoding
(GeometryCollection -> Value)
-> (GeometryCollection -> Encoding)
-> ([GeometryCollection] -> Value)
-> ([GeometryCollection] -> Encoding)
-> ToJSON GeometryCollection
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: GeometryCollection -> Value
toJSON :: GeometryCollection -> Value
$ctoEncoding :: GeometryCollection -> Encoding
toEncoding :: GeometryCollection -> Encoding
$ctoJSONList :: [GeometryCollection] -> Value
toJSONList :: [GeometryCollection] -> Value
$ctoEncodingList :: [GeometryCollection] -> Encoding
toEncodingList :: [GeometryCollection] -> Encoding
J.ToJSON, Value -> Parser [GeometryCollection]
Value -> Parser GeometryCollection
(Value -> Parser GeometryCollection)
-> (Value -> Parser [GeometryCollection])
-> FromJSON GeometryCollection
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser GeometryCollection
parseJSON :: Value -> Parser GeometryCollection
$cparseJSONList :: Value -> Parser [GeometryCollection]
parseJSONList :: Value -> Parser [GeometryCollection]
J.FromJSON)

-- Geometry

data Geometry
  = GPoint !Point
  | GMultiPoint !MultiPoint
  | GLineString !LineString
  | GMultiLineString !MultiLineString
  | GPolygon !Polygon
  | GMultiPolygon !MultiPolygon
  | GGeometryCollection !GeometryCollection
  deriving (Int -> Geometry -> ShowS
[Geometry] -> ShowS
Geometry -> String
(Int -> Geometry -> ShowS)
-> (Geometry -> String) -> ([Geometry] -> ShowS) -> Show Geometry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Geometry -> ShowS
showsPrec :: Int -> Geometry -> ShowS
$cshow :: Geometry -> String
show :: Geometry -> String
$cshowList :: [Geometry] -> ShowS
showList :: [Geometry] -> ShowS
Show, Geometry -> Geometry -> Bool
(Geometry -> Geometry -> Bool)
-> (Geometry -> Geometry -> Bool) -> Eq Geometry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Geometry -> Geometry -> Bool
== :: Geometry -> Geometry -> Bool
$c/= :: Geometry -> Geometry -> Bool
/= :: Geometry -> Geometry -> Bool
Eq)