-- **************************
--
-- spherical polygon functions
--
-- **************************

CREATE FUNCTION npoints(spoly)
   RETURNS INT4
   AS 'MODULE_PATHNAME', 'spherepoly_npts'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  npoints(spoly) IS
  'returns number of points of spherical polygon';

CREATE FUNCTION spoint(spoly, int4)
   RETURNS spoint
   AS 'MODULE_PATHNAME', 'spherepoly_get_point'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoint(spoly, int4) IS
  'returns n-th point of spherical polygon';

CREATE FUNCTION spoly_as_array(spoly)
   RETURNS spoint[]
   AS 'MODULE_PATHNAME', 'spherepoly_get_array'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_as_array(spoly) IS
  'returns spoly as array of points';

CREATE FUNCTION area(spoly)
   RETURNS FLOAT8
   AS 'MODULE_PATHNAME', 'spherepoly_area'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  area(spoly) IS
  'returns area of spherical polygon';



-- ****************************
--
-- spherical polygon operators
--
-- ****************************


--
-- equal
--

CREATE FUNCTION spoly_equal(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_equal'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_equal(spoly, spoly) IS
  'returns true, if spherical polygons are equal';


CREATE OPERATOR  = (
   LEFTARG    = spoly,
   RIGHTARG   = spoly,
   COMMUTATOR = =,
   NEGATOR    = <>,
   PROCEDURE  = spoly_equal,
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR = (spoly, spoly) IS
  'true, if spherical polygons are equal';

--
-- not equal
--

CREATE FUNCTION spoly_not_equal(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_equal_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_not_equal(spoly, spoly) IS
  'returns true, if spherical polygons are not equal';

CREATE OPERATOR  <> (
   LEFTARG    = spoly,
   RIGHTARG   = spoly,
   COMMUTATOR = <>,
   NEGATOR    = =,
   PROCEDURE  = spoly_not_equal,
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR <> (spoly, spoly) IS
  'true, if spherical polygons are not equal';

--
-- circumference
--

CREATE FUNCTION circum(spoly)
   RETURNS FLOAT8
   AS 'MODULE_PATHNAME', 'spherepoly_circ'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  circum(spoly) IS
  'returns circumference of spherical polygon';

CREATE OPERATOR  @-@ (
   RIGHTARG   = spoly,
   PROCEDURE  = circum
);

COMMENT ON OPERATOR @-@ (NONE, spoly) IS
  'returns circumference of spherical polygon';


--
-- polygon contains polygon
--

CREATE FUNCTION spoly_contains_polygon(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_poly'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_polygon(spoly, spoly) IS
  'true if spherical polygon contains spherical polygon';


--
-- polygon is contained by polygon
--

CREATE FUNCTION spoly_contains_polygon_com(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_poly_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_polygon_com(spoly, spoly) IS
  'true if spherical polygon is contained by spherical polygon';


--
-- polygon does not contain polygon
--

CREATE FUNCTION spoly_contains_polygon_neg(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_poly_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_polygon_neg(spoly, spoly) IS
  'true if spherical polygon does not contain spherical polygon';


--
-- polygon is not contained by polygon
--

CREATE FUNCTION spoly_contains_polygon_com_neg(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_poly_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_polygon_com_neg(spoly, spoly) IS
  'true if spherical polygon is not contained by spherical polygon';


--
-- polygons overlap
--

CREATE FUNCTION spoly_overlap_polygon(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_poly'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_polygon(spoly, spoly) IS
  'true if spherical polygon overlaps spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = spoly,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_polygon,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (spoly, spoly) IS
  'true if spherical polygons overlap';

--
-- polygons do not overlap
--

CREATE FUNCTION spoly_overlap_polygon_neg(spoly, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_poly_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_polygon_neg(spoly, spoly) IS
  'true if spherical polygon does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = spoly,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_polygon,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (spoly, spoly) IS
  'true if spherical polygon does not overlap spherical polygon';


--
-- polygon contains point
--

CREATE FUNCTION spoly_contains_point(spoly, spoint)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_point'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_point(spoly, spoint) IS
  'true if spherical polygon contains spherical point';

--
-- point is contained by polygon
--

CREATE FUNCTION spoly_contains_point_com(spoint, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_point_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_point_com(spoint, spoly) IS
  'true if spherical polygon contains spherical point';

--
-- polygon does not contain point
--

CREATE FUNCTION spoly_contains_point_neg(spoly, spoint)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_point_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_point_neg(spoly, spoint) IS
  'true if spherical polygon does not contain spherical point';

--
-- point is not contained by polygon
--

CREATE FUNCTION spoly_contains_point_com_neg(spoint, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_point_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_point_com_neg(spoint, spoly) IS
  'true if spherical polygon does not contain spherical point';

--
-- Transformation of polygon
--

CREATE FUNCTION strans_poly(spoly, strans)
   RETURNS spoly
   AS 'MODULE_PATHNAME', 'spheretrans_poly'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION strans_poly (spoly, strans) IS
  'returns a transformated spherical polygon';

CREATE OPERATOR + (
   LEFTARG    = spoly,
   RIGHTARG   = strans,
   PROCEDURE  = strans_poly
);

COMMENT ON OPERATOR + (spoly, strans) IS
  'transforms a spherical polygon';

CREATE FUNCTION strans_poly_inverse(spoly, strans)
   RETURNS spoly
   AS 'MODULE_PATHNAME', 'spheretrans_poly_inverse'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION strans_poly_inverse (spoly, strans) IS
  'returns a inverse transformated spherical polygon';

CREATE OPERATOR - (
   LEFTARG    = spoly,
   RIGHTARG   = strans,
   PROCEDURE  = strans_poly_inverse
);

COMMENT ON OPERATOR - (spoly, strans) IS
  'transforms inverse a spherical polygon';


--
-- polygon contains circle
--

CREATE FUNCTION spoly_contains_circle(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_circle'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_circle(spoly, scircle) IS
  'true if spherical polygon contains spherical circle';


--
-- circle is contained by polygon
--

CREATE FUNCTION spoly_contains_circle_com(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_circle_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_circle_com(scircle, spoly) IS
  'true if spherical polygon contains spherical circle';


--
-- polygon does not contain circle
--

CREATE FUNCTION spoly_contains_circle_neg(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_circle_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_circle_neg(spoly, scircle) IS
  'true if spherical polygon does not contain spherical circle';


--
-- circle is not contained by polygon
--

CREATE FUNCTION spoly_contains_circle_com_neg(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_circle_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_circle_com_neg(scircle, spoly) IS
  'true if spherical polygon does not contain spherical circle';


--
-- circle contains polygon
--

CREATE FUNCTION scircle_contains_polygon(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherecircle_cont_poly'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION scircle_contains_polygon(scircle, spoly) IS
  'true if spherical circle contains spherical polygon';


--
-- polygon is contained by circle
--

CREATE FUNCTION scircle_contains_polygon_com(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherecircle_cont_poly_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION scircle_contains_polygon_com(spoly, scircle) IS
  'true if spherical circle contains spherical polygon';


--
-- circle does not contain polygon
--

CREATE FUNCTION scircle_contains_polygon_neg(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherecircle_cont_poly_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION scircle_contains_polygon_neg(scircle, spoly) IS
  'true if spherical circle does not contain spherical polygon';


--
-- polygon is not contained by circle
--

CREATE FUNCTION scircle_contains_polygon_com_neg(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherecircle_cont_poly_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION scircle_contains_polygon_com_neg(spoly, scircle) IS
  'true if spherical circle does not contain spherical polygon';


--
-- circle overlaps polygon
--

CREATE FUNCTION spoly_overlap_circle(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_circle'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_overlap_circle(spoly, scircle) IS
  'true if spherical circle overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = spoly,
   RIGHTARG   = scircle,
   PROCEDURE  = spoly_overlap_circle,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (spoly, scircle) IS
  'true if spherical circle overlap spherical polygon';

--
-- polygon overlaps circle
--

CREATE FUNCTION spoly_overlap_circle_com(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_circle_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_circle_com(scircle, spoly) IS
  'true if spherical circle overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = scircle,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_circle_com,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (scircle, spoly) IS
  'true if spherical circle overlap spherical polygon';


--
-- circle does not overlap polygon
--

CREATE FUNCTION spoly_overlap_circle_neg(spoly, scircle)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_circle_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_circle_neg(spoly, scircle) IS
  'true if spherical circle does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = spoly,
   RIGHTARG   = scircle,
   PROCEDURE  = spoly_overlap_circle_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (spoly, scircle) IS
  'true if spherical circle does not overlap spherical polygon';

--
-- polygon does not overlap circle
--

CREATE FUNCTION spoly_overlap_circle_com_neg(scircle, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_circle_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_circle_com_neg(scircle, spoly) IS
  'true if spherical circle does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = scircle,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_circle_com_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (scircle, spoly) IS
  'true if spherical circle does not overlap spherical polygon';


--
-- polygon contains line
--

CREATE FUNCTION spoly_contains_line(spoly, sline)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_line'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_line(spoly, sline) IS
  'true if spherical polygon contains spherical line';

--
-- line is contained by polygon
--

CREATE FUNCTION spoly_contains_line_com(sline, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_line_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_line_com(sline, spoly) IS
  'true if spherical polygon contains spherical line';

--
-- polygon does not contain line
--

CREATE FUNCTION spoly_contains_line_neg(spoly, sline)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_line_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_line_neg(spoly, sline) IS
  'true if spherical polygon does not contain spherical line';

--
-- line is not contained by polygon
--

CREATE FUNCTION spoly_contains_line_com_neg(sline, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_line_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_line_com_neg(sline, spoly) IS
  'true if spherical polygon does not contain spherical line';

--
-- line overlaps polygon
--

CREATE FUNCTION spoly_overlap_line(spoly, sline)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_line'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_overlap_line(spoly, sline) IS
  'true if spherical line overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = spoly,
   RIGHTARG   = sline,
   PROCEDURE  = spoly_overlap_line,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (spoly, sline) IS
  'true if spherical line overlap spherical polygon';

--
-- polygon overlaps line
--

CREATE FUNCTION spoly_overlap_line_com(sline, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_line_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_line_com(sline, spoly) IS
  'true if spherical line overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = sline,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_line_com,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (sline, spoly) IS
  'true if spherical line overlap spherical polygon';


--
-- line does not overlap polygon
--

CREATE FUNCTION spoly_overlap_line_neg(spoly, sline)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_line_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_line_neg(spoly, sline) IS
  'true if spherical line does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = spoly,
   RIGHTARG   = sline,
   PROCEDURE  = spoly_overlap_line_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (spoly, sline) IS
  'true if spherical line does not overlap spherical polygon';

--
-- polygon does not overlap line
--

CREATE FUNCTION spoly_overlap_line_com_neg(sline, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_line_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_line_com_neg(sline, spoly) IS
  'true if spherical line does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = sline,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_line_com_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (sline, spoly) IS
  'true if spherical line does not overlap spherical polygon';



--
-- polygon contains ellipse
--

CREATE FUNCTION spoly_contains_ellipse(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_ellipse'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_ellipse(spoly, sellipse) IS
  'true if spherical polygon contains spherical ellipse';


--
-- ellipse is contained by polygon
--

CREATE FUNCTION spoly_contains_ellipse_com(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_ellipse_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_ellipse_com(sellipse, spoly) IS
  'true if spherical polygon contains spherical ellipse';


--
-- polygon does not contain ellipse
--

CREATE FUNCTION spoly_contains_ellipse_neg(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_ellipse_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_ellipse_neg(spoly, sellipse) IS
  'true if spherical polygon does not contain spherical ellipse';


--
-- ellipse is not contained by polygon
--

CREATE FUNCTION spoly_contains_ellipse_com_neg(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_cont_ellipse_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_contains_ellipse_com_neg(sellipse, spoly) IS
  'true if spherical polygon does not contain spherical ellipse';


--
-- ellipse contains polygon
--

CREATE FUNCTION sellipse_contains_polygon(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'sphereellipse_cont_poly'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION sellipse_contains_polygon(sellipse, spoly) IS
  'true if spherical ellipse contains spherical polygon';


--
-- polygon is contained by ellipse
--

CREATE FUNCTION sellipse_contains_polygon_com(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'sphereellipse_cont_poly_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION sellipse_contains_polygon_com(spoly, sellipse) IS
  'true if spherical ellipse contains spherical polygon';


--
-- ellipse does not contain polygon
--

CREATE FUNCTION sellipse_contains_polygon_neg(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'sphereellipse_cont_poly_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION sellipse_contains_polygon_neg(sellipse, spoly) IS
  'true if spherical ellipse does not contain spherical polygon';


--
-- polygon is not contained by ellipse
--

CREATE FUNCTION sellipse_contains_polygon_com_neg(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'sphereellipse_cont_poly_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION sellipse_contains_polygon_com_neg(spoly, sellipse) IS
  'true if spherical ellipse does not contain spherical polygon';


--
-- ellipse overlaps polygon
--

CREATE FUNCTION spoly_overlap_ellipse(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_ellipse'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_overlap_ellipse(spoly, sellipse) IS
  'true if spherical ellipse overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = spoly,
   RIGHTARG   = sellipse,
   PROCEDURE  = spoly_overlap_ellipse,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (spoly, sellipse) IS
  'true if spherical ellipse overlap spherical polygon';

--
-- polygon overlaps ellipse
--

CREATE FUNCTION spoly_overlap_ellipse_com(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_ellipse_com'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_ellipse_com(sellipse, spoly) IS
  'true if spherical ellipse overlap spherical polygon';


CREATE OPERATOR && (
   LEFTARG    = sellipse,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_ellipse_com,
   COMMUTATOR = '&&',
   NEGATOR    = '!&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR && (sellipse, spoly) IS
  'true if spherical ellipse overlap spherical polygon';


--
-- ellipse does not overlap polygon
--

CREATE FUNCTION spoly_overlap_ellipse_neg(spoly, sellipse)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_ellipse_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_ellipse_neg(spoly, sellipse) IS
  'true if spherical ellipse does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = spoly,
   RIGHTARG   = sellipse,
   PROCEDURE  = spoly_overlap_ellipse_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (spoly, sellipse) IS
  'true if spherical ellipse does not overlap spherical polygon';

--
-- polygon does not overlap ellipse
--

CREATE FUNCTION spoly_overlap_ellipse_com_neg(sellipse, spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_overlap_ellipse_com_neg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_overlap_ellipse_com_neg(sellipse, spoly) IS
  'true if spherical ellipse does not overlap spherical polygon';


CREATE OPERATOR !&& (
   LEFTARG    = sellipse,
   RIGHTARG   = spoly,
   PROCEDURE  = spoly_overlap_ellipse_com_neg,
   COMMUTATOR = '!&&',
   NEGATOR    = '&&',
   RESTRICT   = contsel,
   JOIN       = contjoinsel
);

COMMENT ON OPERATOR !&& (sellipse, spoly) IS
  'true if spherical ellipse does not overlap spherical polygon';


--
-- Functions to create a polygon from arrays
--

CREATE FUNCTION spoly(float8[])
   RETURNS spoly
   AS 'MODULE_PATHNAME', 'spherepoly_rad'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly(float8[]) IS
   'creates spoly from array of numbers in radians';

CREATE FUNCTION spoly(spoint[])
  RETURNS spoly
  AS 'MODULE_PATHNAME', 'spherepoly_from_point_array'
  LANGUAGE 'c'
  IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly(spoint[]) IS
  'creates spoly from an array of points';

CREATE FUNCTION spoly_deg(float8[])
   RETURNS spoly
   AS 'MODULE_PATHNAME', 'spherepoly_deg'
   LANGUAGE 'c'
   IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION spoly_deg(float8[]) IS
   'creates spoly from array of numbers in degrees';


--
-- Aggregate functions to add points to polygon
--

CREATE FUNCTION spoly_add_point_aggr (spoly, spoint)
  RETURNS spoly
  AS 'MODULE_PATHNAME', 'spherepoly_add_point'
  LANGUAGE 'c'
  IMMUTABLE PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_add_point_aggr (spoly, spoint) IS
  'adds a spherical point to spherical polygon. Do not use it standalone!';

CREATE FUNCTION spoly_add_points_fin_aggr (spoly)
  RETURNS spoly
  AS 'MODULE_PATHNAME', 'spherepoly_add_points_finalize'
  LANGUAGE 'c'
  IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION  spoly_add_points_fin_aggr (spoly) IS
  'Finalize spherical point adding to spherical polygon. Do not use it standalone!';

CREATE AGGREGATE spoly (
    sfunc     = spoly_add_point_aggr,
    basetype  = spoint,
    stype     = spoly,
    finalfunc = spoly_add_points_fin_aggr
);

--
-- polygon is convex
--

CREATE FUNCTION spoly_is_convex(spoly)
   RETURNS BOOL
   AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
   LANGUAGE 'c'
   IMMUTABLE PARALLEL SAFE;

COMMENT ON FUNCTION spoly_is_convex(spoly) IS
  'true if spherical polygon is convex';
