{-# LANGUAGE DataKinds #-}

module Database.Esqueleto.Postgis.Accessor
  ( st_x
  , st_y
  , st_npoints
  , st_numgeometries
  , st_dimension
  , st_issimple
  , st_isclosed
  , st_isvalid
  , st_srid
  , st_boundary
  , st_coorddim
  , st_endpoint
  , st_exteriorring
  , st_geometryn
  , st_geometrytype
  , st_interiorringn
  , st_iscollection
  , st_isempty
  , st_ispolygonccw
  , st_ispolygoncw
  , st_isring
  , st_m
  , st_ndims
  , st_nrings
  , st_numinteriorrings
  , st_numpoints
  , st_pointn
  , st_startpoint
  , st_z
  ) where

import Database.Esqueleto.Postgis.Geometry (Postgis, SpatialType(..))
import Database.Esqueleto.Experimental (SqlExpr, Value)
import Database.Esqueleto.Internal.Internal (unsafeSqlFunction)
import Data.Text (Text)

-- | Returns the X coordinate of a point geometry.
--   Only works on points; other geometry types will error.
--   https://postgis.net/docs/ST_X.html
st_x ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Double)
st_x :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
st_x SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_X" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the Y coordinate of a point geometry.
--   Only works on points; other geometry types will error.
--   https://postgis.net/docs/ST_Y.html
st_y ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Double)
st_y :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
st_y SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_Y" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of points (vertices) in a geometry.
--   Works on any geometry type.
--   https://postgis.net/docs/ST_NPoints.html
st_npoints ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_npoints :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_npoints SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NPoints" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of sub-geometries in a geometry collection or multi-type.
--   Returns 1 for single geometries.
--   https://postgis.net/docs/ST_NumGeometries.html
st_numgeometries ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_numgeometries :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_numgeometries SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NumGeometries" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the topological dimension of a geometry.
--   0 for points, 1 for lines, 2 for polygons.
--   https://postgis.net/docs/ST_Dimension.html
st_dimension ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_dimension :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_dimension SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_Dimension" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if the geometry has no self-intersections.
--   Points and properly-formed polygons are always simple.
--   https://postgis.net/docs/ST_IsSimple.html
st_issimple ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_issimple :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_issimple SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsSimple" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if the linestring's start and end points are coincident.
--   For polyhedral surfaces, reports if the surface is areal (open) or volumetric (closed).
--   https://postgis.net/docs/ST_IsClosed.html
st_isclosed ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_isclosed :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_isclosed SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsClosed" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if the geometry is well-formed and valid per the OGC rules.
--   Points and lines are always valid; polygons need correct ring structure.
--   https://postgis.net/docs/ST_IsValid.html
st_isvalid ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_isvalid :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_isvalid SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsValid" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the spatial reference identifier (SRID) of the geometry.
--   0 means no SRID is set.
--   https://postgis.net/docs/ST_SRID.html
st_srid ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_srid :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_srid SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_SRID" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the boundary of a geometry.
--   https://postgis.net/docs/ST_Boundary.html
st_boundary ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_boundary :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
st_boundary SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_Boundary" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the coordinate dimension of a geometry (2, 3, or 4).
--   https://postgis.net/docs/ST_CoordDim.html
st_coorddim ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_coorddim :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_coorddim SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_CoordDim" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the last point of a linestring.
--   https://postgis.net/docs/ST_EndPoint.html
st_endpoint ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_endpoint :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
st_endpoint SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_EndPoint" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the exterior ring of a polygon geometry.
--   https://postgis.net/docs/ST_ExteriorRing.html
st_exteriorring ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_exteriorring :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
st_exteriorring SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_ExteriorRing" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the Nth sub-geometry of a geometry collection (1-indexed).
--   https://postgis.net/docs/ST_GeometryN.html
st_geometryn ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_geometryn :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value Int) -> SqlExpr (Value (Postgis 'Geometry a))
st_geometryn SqlExpr (Value (Postgis 'Geometry a))
a SqlExpr (Value Int)
n = Builder
-> (SqlExpr (Value (Postgis 'Geometry a)), SqlExpr (Value Int))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_GeometryN" (SqlExpr (Value (Postgis 'Geometry a))
a, SqlExpr (Value Int)
n)

-- | Returns the geometry type as a string (e.g. "ST_Polygon").
--   https://postgis.net/docs/ST_GeometryType.html
st_geometrytype ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Text)
st_geometrytype :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Text)
st_geometrytype SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Text)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_GeometryType" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the Nth interior ring of a polygon (1-indexed).
--   https://postgis.net/docs/ST_InteriorRingN.html
st_interiorringn ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_interiorringn :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value Int) -> SqlExpr (Value (Postgis 'Geometry a))
st_interiorringn SqlExpr (Value (Postgis 'Geometry a))
a SqlExpr (Value Int)
n = Builder
-> (SqlExpr (Value (Postgis 'Geometry a)), SqlExpr (Value Int))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_InteriorRingN" (SqlExpr (Value (Postgis 'Geometry a))
a, SqlExpr (Value Int)
n)

-- | Returns TRUE if the geometry is a geometry collection type.
--   https://postgis.net/docs/ST_IsCollection.html
st_iscollection ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_iscollection :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_iscollection SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsCollection" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if the geometry is an empty geometry.
--   https://postgis.net/docs/ST_IsEmpty.html
st_isempty ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_isempty :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_isempty SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsEmpty" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if all polygon rings are oriented counter-clockwise.
--   https://postgis.net/docs/ST_IsPolygonCCW.html
st_ispolygonccw ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_ispolygonccw :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_ispolygonccw SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsPolygonCCW" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if all polygon rings are oriented clockwise.
--   https://postgis.net/docs/ST_IsPolygonCW.html
st_ispolygoncw ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_ispolygoncw :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_ispolygoncw SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsPolygonCW" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns TRUE if the linestring is closed and simple (a ring).
--   https://postgis.net/docs/ST_IsRing.html
st_isring ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Bool)
st_isring :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
st_isring SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_IsRing" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the M coordinate of a point.
--   https://postgis.net/docs/ST_M.html
st_m ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Double)
st_m :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
st_m SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_M" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of dimensions of a geometry's coordinates (2, 3, or 4).
--   https://postgis.net/docs/ST_NDims.html
st_ndims ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_ndims :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_ndims SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NDims" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of rings in a polygon (exterior + interior).
--   https://postgis.net/docs/ST_NRings.html
st_nrings ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_nrings :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_nrings SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NRings" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of interior rings of a polygon.
--   https://postgis.net/docs/ST_NumInteriorRings.html
st_numinteriorrings ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_numinteriorrings :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_numinteriorrings SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NumInteriorRings" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the number of points in a linestring.
--   https://postgis.net/docs/ST_NumPoints.html
st_numpoints ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int)
st_numpoints :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
st_numpoints SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Int)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_NumPoints" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the Nth point in a linestring (1-indexed).
--   https://postgis.net/docs/ST_PointN.html
st_pointn ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Int) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_pointn :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value Int) -> SqlExpr (Value (Postgis 'Geometry a))
st_pointn SqlExpr (Value (Postgis 'Geometry a))
a SqlExpr (Value Int)
n = Builder
-> (SqlExpr (Value (Postgis 'Geometry a)), SqlExpr (Value Int))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_PointN" (SqlExpr (Value (Postgis 'Geometry a))
a, SqlExpr (Value Int)
n)

-- | Returns the first point of a linestring.
--   https://postgis.net/docs/ST_StartPoint.html
st_startpoint ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value (Postgis 'Geometry a))
st_startpoint :: forall a.
SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
st_startpoint SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a))
-> SqlExpr (Value (Postgis 'Geometry a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_StartPoint" SqlExpr (Value (Postgis 'Geometry a))
a

-- | Returns the Z coordinate of a point.
--   https://postgis.net/docs/ST_Z.html
st_z ::
  SqlExpr (Value (Postgis 'Geometry a)) ->
  SqlExpr (Value Double)
st_z :: forall a.
SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
st_z SqlExpr (Value (Postgis 'Geometry a))
a = Builder
-> SqlExpr (Value (Postgis 'Geometry a)) -> SqlExpr (Value Double)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ST_Z" SqlExpr (Value (Postgis 'Geometry a))
a