module Hasura.SQL.WKT ( ToWKT (..), WKT (..), ) where import Data.List (intersperse) import Hasura.Base.Error qualified as E import Hasura.Prelude import Hasura.SQL.GeoJSON qualified as G newtype WKT = WKT {WKT -> Text getWKT :: Text} class ToWKT a where toWKT :: a -> Either E.QErr WKT instance ToWKT G.Point where toWKT :: Point -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "POINT" (Either QErr Text -> Either QErr WKT) -> (Point -> Either QErr Text) -> Point -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . Position -> Either QErr Text positionToText (Position -> Either QErr Text) -> (Point -> Position) -> Point -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Point -> Position G.unPoint instance ToWKT G.MultiPoint where toWKT :: MultiPoint -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "MULTIPOINT" (Either QErr Text -> Either QErr WKT) -> (MultiPoint -> Either QErr Text) -> MultiPoint -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . [Position] -> Either QErr Text commaSeparated ([Position] -> Either QErr Text) -> (MultiPoint -> [Position]) -> MultiPoint -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . MultiPoint -> [Position] G.unMultiPoint instance ToWKT G.LineString where toWKT :: LineString -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "LINESTRING" (Either QErr Text -> Either QErr WKT) -> (LineString -> Either QErr Text) -> LineString -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . LineString -> Either QErr Text lineStringToText instance ToWKT G.MultiLineString where toWKT :: MultiLineString -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "MULTILINESTRING" (Either QErr Text -> Either QErr WKT) -> (MultiLineString -> Either QErr Text) -> MultiLineString -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ([Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> (MultiLineString -> Either QErr [Text]) -> MultiLineString -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (LineString -> Either QErr Text) -> [LineString] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse ((Text -> Text) -> Either QErr Text -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Text -> Text parens (Either QErr Text -> Either QErr Text) -> (LineString -> Either QErr Text) -> LineString -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . LineString -> Either QErr Text lineStringToText) ([LineString] -> Either QErr [Text]) -> (MultiLineString -> [LineString]) -> MultiLineString -> Either QErr [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . MultiLineString -> [LineString] G.unMultiLineString instance ToWKT G.Polygon where toWKT :: Polygon -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "POLYGON" (Either QErr Text -> Either QErr WKT) -> (Polygon -> Either QErr Text) -> Polygon -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ([Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> (Polygon -> Either QErr [Text]) -> Polygon -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (LinearRing -> Either QErr Text) -> [LinearRing] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse ((Text -> Text) -> Either QErr Text -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Text -> Text parens (Either QErr Text -> Either QErr Text) -> (LinearRing -> Either QErr Text) -> LinearRing -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . LinearRing -> Either QErr Text linearRingToText) ([LinearRing] -> Either QErr [Text]) -> (Polygon -> [LinearRing]) -> Polygon -> Either QErr [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . Polygon -> [LinearRing] G.unPolygon instance ToWKT G.MultiPolygon where toWKT :: MultiPolygon -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "MULTIPOLYGON" (Either QErr Text -> Either QErr WKT) -> (MultiPolygon -> Either QErr Text) -> MultiPolygon -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ([Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> (MultiPolygon -> Either QErr [Text]) -> MultiPolygon -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (Polygon -> Either QErr Text) -> [Polygon] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse ( ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Text -> Text parens (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . [Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> (Polygon -> Either QErr [Text]) -> Polygon -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (LinearRing -> Either QErr Text) -> [LinearRing] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse ((Text -> Text) -> Either QErr Text -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Text -> Text parens (Either QErr Text -> Either QErr Text) -> (LinearRing -> Either QErr Text) -> LinearRing -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . LinearRing -> Either QErr Text linearRingToText) ([LinearRing] -> Either QErr [Text]) -> (Polygon -> [LinearRing]) -> Polygon -> Either QErr [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . Polygon -> [LinearRing] G.unPolygon ) ([Polygon] -> Either QErr [Text]) -> (MultiPolygon -> [Polygon]) -> MultiPolygon -> Either QErr [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . MultiPolygon -> [Polygon] G.unMultiPolygon instance ToWKT G.GeometryCollection where toWKT :: GeometryCollection -> Either QErr WKT toWKT = Text -> Either QErr Text -> Either QErr WKT mkWKT Text "GEOMETRYCOLLECTION" (Either QErr Text -> Either QErr WKT) -> (GeometryCollection -> Either QErr Text) -> GeometryCollection -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ([Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> (GeometryCollection -> Either QErr [Text]) -> GeometryCollection -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (GeometryWithCRS -> Either QErr Text) -> [GeometryWithCRS] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse ((WKT -> Text) -> Either QErr WKT -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap WKT -> Text getWKT (Either QErr WKT -> Either QErr Text) -> (GeometryWithCRS -> Either QErr WKT) -> GeometryWithCRS -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Geometry -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT (Geometry -> Either QErr WKT) -> (GeometryWithCRS -> Geometry) -> GeometryWithCRS -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . GeometryWithCRS -> Geometry G._gwcGeom) ([GeometryWithCRS] -> Either QErr [Text]) -> (GeometryCollection -> [GeometryWithCRS]) -> GeometryCollection -> Either QErr [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . GeometryCollection -> [GeometryWithCRS] G.unGeometryCollection instance ToWKT G.Geometry where toWKT :: Geometry -> Either QErr WKT toWKT = \case G.GPoint Point p -> Point -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT Point p G.GMultiPoint MultiPoint m -> MultiPoint -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT MultiPoint m G.GLineString LineString l -> LineString -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT LineString l G.GMultiLineString MultiLineString m -> MultiLineString -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT MultiLineString m G.GPolygon Polygon p -> Polygon -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT Polygon p G.GMultiPolygon MultiPolygon m -> MultiPolygon -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT MultiPolygon m G.GGeometryCollection GeometryCollection g -> GeometryCollection -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT GeometryCollection g instance ToWKT G.GeometryWithCRS where toWKT :: GeometryWithCRS -> Either QErr WKT toWKT = Geometry -> Either QErr WKT forall a. ToWKT a => a -> Either QErr WKT toWKT (Geometry -> Either QErr WKT) -> (GeometryWithCRS -> Geometry) -> GeometryWithCRS -> Either QErr WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . GeometryWithCRS -> Geometry G._gwcGeom mkWKT :: Text -> Either E.QErr Text -> Either E.QErr WKT mkWKT :: Text -> Either QErr Text -> Either QErr WKT mkWKT Text name Either QErr Text args = Text -> WKT WKT (Text -> WKT) -> (Text -> Text) -> Text -> WKT forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> Text wktFormat (Text -> WKT) -> Either QErr Text -> Either QErr WKT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Either QErr Text args where wktFormat :: Text -> Text wktFormat :: Text -> Text wktFormat Text a = Text name Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text -> Text parens Text a parens :: Text -> Text parens :: Text -> Text parens Text t = Text "(" Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text t Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text ")" commaSeparated :: [G.Position] -> Either E.QErr Text commaSeparated :: [Position] -> Either QErr Text commaSeparated = ([Text] -> Text) -> Either QErr [Text] -> Either QErr Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ([Text] -> Text forall a. Monoid a => [a] -> a mconcat ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> [Text] forall a. a -> [a] -> [a] intersperse Text ", ") (Either QErr [Text] -> Either QErr Text) -> ([Position] -> Either QErr [Text]) -> [Position] -> Either QErr Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (Position -> Either QErr Text) -> [Position] -> Either QErr [Text] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse Position -> Either QErr Text positionToText positionToText :: G.Position -> Either E.QErr Text positionToText :: Position -> Either QErr Text positionToText (G.Position Double x Double y Maybe Double mz) = case Maybe Double mz of Maybe Double Nothing -> Text -> Either QErr Text forall (f :: * -> *) a. Applicative f => a -> f a pure (Text -> Either QErr Text) -> Text -> Either QErr Text forall a b. (a -> b) -> a -> b $ Double -> Text forall a. Show a => a -> Text tshow Double x Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Double -> Text forall a. Show a => a -> Text tshow Double y Just Double _ -> QErr -> Either QErr Text forall a b. a -> Either a b Left (QErr -> Either QErr Text) -> QErr -> Either QErr Text forall a b. (a -> b) -> a -> b $ Code -> Text -> QErr E.err400 Code E.ParseFailed Text "3 dimmensional coordinates are not supported" lineStringToText :: G.LineString -> Either E.QErr Text lineStringToText :: LineString -> Either QErr Text lineStringToText (G.LineString Position ls1 Position ls2 [Position] lsRest) = [Position] -> Either QErr Text commaSeparated (Position ls1 Position -> [Position] -> [Position] forall a. a -> [a] -> [a] : Position ls2 Position -> [Position] -> [Position] forall a. a -> [a] -> [a] : [Position] lsRest) linearRingToText :: G.LinearRing -> Either E.QErr Text linearRingToText :: LinearRing -> Either QErr Text linearRingToText (G.LinearRing Position p1 Position p2 Position p3 [Position] pRest) = [Position] -> Either QErr Text commaSeparated (Position p1 Position -> [Position] -> [Position] forall a. a -> [a] -> [a] : Position p2 Position -> [Position] -> [Position] forall a. a -> [a] -> [a] : Position p3 Position -> [Position] -> [Position] forall a. a -> [a] -> [a] : [Position] pRest [Position] -> [Position] -> [Position] forall a. Semigroup a => a -> a -> a <> [Position p1])