
jbe@0: 
jbe@0: ----------------------------------------
jbe@0: -- forward declarations (shell types) --
jbe@0: ----------------------------------------
jbe@0: 
jbe@46: CREATE TYPE ekey_point;
jbe@46: CREATE TYPE ekey_area;
jbe@0: CREATE TYPE epoint;
jbe@46: CREATE TYPE epoint_with_sample_count;
jbe@0: CREATE TYPE ebox;
jbe@0: CREATE TYPE ecircle;
jbe@0: CREATE TYPE ecluster;
jbe@0: 
jbe@0: 
jbe@0: ------------------------------------------------------------
jbe@0: -- dummy input/output functions for dummy index key types --
jbe@0: ------------------------------------------------------------
jbe@0: 
jbe@0: CREATE FUNCTION ekey_point_in_dummy(cstring)
jbe@0:   RETURNS ekey_point
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_notimpl';
jbe@0: 
jbe@0: CREATE FUNCTION ekey_point_out_dummy(ekey_point)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_notimpl';
jbe@0: 
jbe@0: CREATE FUNCTION ekey_area_in_dummy(cstring)
jbe@0:   RETURNS ekey_area
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_notimpl';
jbe@0: 
jbe@0: CREATE FUNCTION ekey_area_out_dummy(ekey_area)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_notimpl';
jbe@0: 
jbe@0: 
jbe@0: --------------------------
jbe@0: -- text input functions --
jbe@0: --------------------------
jbe@0: 
jbe@0: CREATE FUNCTION epoint_in(cstring)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_in';
jbe@46: 
jbe@46: CREATE FUNCTION epoint_with_sample_count_in(cstring)
jbe@46:   RETURNS epoint_with_sample_count
jbe@46:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_with_sample_count_in';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_in(cstring)
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_in';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_in(cstring)
jbe@0:   RETURNS ecircle
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_in';
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_in(cstring)
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_in';
jbe@0: 
jbe@0: 
jbe@0: ---------------------------
jbe@0: -- text output functions --
jbe@0: ---------------------------
jbe@0: 
jbe@0: CREATE FUNCTION epoint_out(epoint)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_out';
jbe@46: 
jbe@46: CREATE FUNCTION epoint_with_sample_count_out(epoint_with_sample_count)
jbe@46:   RETURNS cstring
jbe@46:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_with_sample_count_out';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_out(ebox)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_out';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_out(ecircle)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_out';
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_out(ecluster)
jbe@0:   RETURNS cstring
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_out';
jbe@0: 
jbe@0: 
jbe@0: --------------------------
jbe@0: -- binary I/O functions --
jbe@0: --------------------------
jbe@0: 
jbe@0: CREATE FUNCTION epoint_recv(internal)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_recv';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_recv(internal)
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_recv';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_recv(internal)
jbe@0:   RETURNS ecircle
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_recv';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_send(epoint)
jbe@0:   RETURNS bytea
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_send';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_send(ebox)
jbe@0:   RETURNS bytea
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_send';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_send(ecircle)
jbe@0:   RETURNS bytea
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_send';
jbe@0: 
jbe@0: 
jbe@0: -----------------------------------------------
jbe@0: -- type definitions of dummy index key types --
jbe@0: -----------------------------------------------
jbe@0: 
jbe@0: CREATE TYPE ekey_point (
jbe@0:   internallength = 8,
jbe@0:   input = ekey_point_in_dummy,
jbe@0:   output = ekey_point_out_dummy,
jbe@0:   alignment = char );
jbe@0: 
jbe@0: CREATE TYPE ekey_area (
jbe@0:   internallength = 9,
jbe@0:   input = ekey_area_in_dummy,
jbe@0:   output = ekey_area_out_dummy,
jbe@0:   alignment = char );
jbe@0: 
jbe@0: 
jbe@0: ------------------------------------------
jbe@0: -- definitions of geographic data types --
jbe@0: ------------------------------------------
jbe@0: 
jbe@0: CREATE TYPE epoint (
jbe@0:   internallength = 16,
jbe@0:   input = epoint_in,
jbe@0:   output = epoint_out,
jbe@0:   receive = epoint_recv,
jbe@0:   send = epoint_send,
jbe@0:   alignment = double );
jbe@0: 
jbe@46: CREATE TYPE epoint_with_sample_count (
jbe@46:   internallength = 20,
jbe@46:   input = epoint_with_sample_count_in,
jbe@46:   output = epoint_with_sample_count_out,
jbe@46:   alignment = double );
jbe@46: 
jbe@0: CREATE TYPE ebox (
jbe@0:   internallength = 32,
jbe@0:   input = ebox_in,
jbe@0:   output = ebox_out,
jbe@0:   receive = ebox_recv,
jbe@0:   send = ebox_send,
jbe@0:   alignment = double );
jbe@0: 
jbe@0: CREATE TYPE ecircle (
jbe@0:   internallength = 24,
jbe@0:   input = ecircle_in,
jbe@0:   output = ecircle_out,
jbe@0:   receive = ecircle_recv,
jbe@0:   send = ecircle_send,
jbe@0:   alignment = double );
jbe@0: 
jbe@0: CREATE TYPE ecluster (
jbe@0:   internallength = VARIABLE,
jbe@0:   input = ecluster_in,
jbe@0:   output = ecluster_out,
jbe@0:   alignment = double,
jbe@0:   storage = external );
jbe@0: 
jbe@0: 
jbe@0: --------------------
jbe@0: -- B-tree support --
jbe@0: --------------------
jbe@0: 
jbe@0: -- begin of B-tree support for epoint
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_lt(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_lt';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_le(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_le';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_eq(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_eq';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_ne(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_ne';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_ge(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_ge';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_gt(epoint, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_gt';
jbe@0: 
jbe@0: CREATE OPERATOR <<< (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_btree_lt,
jbe@0:   commutator = >>>,
jbe@0:   negator = >>>=,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <<<= (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_btree_le,
jbe@0:   commutator = >>>=,
jbe@0:   negator = >>>,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR = (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_btree_eq,
jbe@0:   commutator = =,
jbe@0:   negator = <>,
jbe@0:   restrict = eqsel,
jbe@0:   join = eqjoinsel,
jbe@0:   merges
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <> (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@54:   procedure = epoint_btree_ne,
jbe@0:   commutator = <>,
jbe@0:   negator = =,
jbe@0:   restrict = neqsel,
jbe@0:   join = neqjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>>= (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_btree_ge,
jbe@0:   commutator = <<<=,
jbe@0:   negator = <<<,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>> (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_btree_gt,
jbe@0:   commutator = <<<,
jbe@0:   negator = <<<=,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_btree_cmp(epoint, epoint)
jbe@0:   RETURNS int4
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_epoint_cmp';
jbe@0: 
jbe@0: CREATE OPERATOR CLASS epoint_btree_ops
jbe@0:   DEFAULT FOR TYPE epoint USING btree AS
jbe@0:   OPERATOR 1 <<< ,
jbe@0:   OPERATOR 2 <<<= ,
jbe@0:   OPERATOR 3 = ,
jbe@0:   OPERATOR 4 >>>= ,
jbe@0:   OPERATOR 5 >>> ,
jbe@0:   FUNCTION 1 epoint_btree_cmp(epoint, epoint);
jbe@0: 
jbe@0: -- end of B-tree support for epoint
jbe@0: 
jbe@0: -- begin of B-tree support for ebox
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_lt(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_lt';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_le(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_le';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_eq(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_eq';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_ne(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_ne';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_ge(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_ge';
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_gt(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_gt';
jbe@0: 
jbe@0: CREATE OPERATOR <<< (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_btree_lt,
jbe@0:   commutator = >>>,
jbe@0:   negator = >>>=,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <<<= (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_btree_le,
jbe@0:   commutator = >>>=,
jbe@0:   negator = >>>,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR = (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_btree_eq,
jbe@0:   commutator = =,
jbe@0:   negator = <>,
jbe@0:   restrict = eqsel,
jbe@0:   join = eqjoinsel,
jbe@0:   merges
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <> (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@54:   procedure = ebox_btree_ne,
jbe@0:   commutator = <>,
jbe@0:   negator = =,
jbe@0:   restrict = neqsel,
jbe@0:   join = neqjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>>= (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_btree_ge,
jbe@0:   commutator = <<<=,
jbe@0:   negator = <<<,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>> (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_btree_gt,
jbe@0:   commutator = <<<,
jbe@0:   negator = <<<=,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION ebox_btree_cmp(ebox, ebox)
jbe@0:   RETURNS int4
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ebox_cmp';
jbe@0: 
jbe@0: CREATE OPERATOR CLASS ebox_btree_ops
jbe@0:   DEFAULT FOR TYPE ebox USING btree AS
jbe@0:   OPERATOR 1 <<< ,
jbe@0:   OPERATOR 2 <<<= ,
jbe@0:   OPERATOR 3 = ,
jbe@0:   OPERATOR 4 >>>= ,
jbe@0:   OPERATOR 5 >>> ,
jbe@0:   FUNCTION 1 ebox_btree_cmp(ebox, ebox);
jbe@0: 
jbe@0: -- end of B-tree support for ebox
jbe@0: 
jbe@0: -- begin of B-tree support for ecircle
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_lt(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_lt';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_le(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_le';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_eq(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_eq';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_ne(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_ne';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_ge(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_ge';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_gt(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_gt';
jbe@0: 
jbe@0: CREATE OPERATOR <<< (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_btree_lt,
jbe@0:   commutator = >>>,
jbe@0:   negator = >>>=,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <<<= (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_btree_le,
jbe@0:   commutator = >>>=,
jbe@0:   negator = >>>,
jbe@0:   restrict = scalarltsel,
jbe@0:   join = scalarltjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR = (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_btree_eq,
jbe@0:   commutator = =,
jbe@0:   negator = <>,
jbe@0:   restrict = eqsel,
jbe@0:   join = eqjoinsel,
jbe@0:   merges
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <> (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@54:   procedure = ecircle_btree_ne,
jbe@0:   commutator = <>,
jbe@0:   negator = =,
jbe@0:   restrict = neqsel,
jbe@0:   join = neqjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>>= (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_btree_ge,
jbe@0:   commutator = <<<=,
jbe@0:   negator = <<<,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR >>> (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_btree_gt,
jbe@0:   commutator = <<<,
jbe@0:   negator = <<<=,
jbe@0:   restrict = scalargtsel,
jbe@0:   join = scalargtjoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_btree_cmp(ecircle, ecircle)
jbe@0:   RETURNS int4
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_btree_ecircle_cmp';
jbe@0: 
jbe@0: CREATE OPERATOR CLASS ecircle_btree_ops
jbe@0:   DEFAULT FOR TYPE ecircle USING btree AS
jbe@0:   OPERATOR 1 <<< ,
jbe@0:   OPERATOR 2 <<<= ,
jbe@0:   OPERATOR 3 = ,
jbe@0:   OPERATOR 4 >>>= ,
jbe@0:   OPERATOR 5 >>> ,
jbe@0:   FUNCTION 1 ecircle_btree_cmp(ecircle, ecircle);
jbe@0: 
jbe@0: -- end of B-tree support for ecircle
jbe@0: 
jbe@0: 
jbe@0: ----------------
jbe@0: -- type casts --
jbe@0: ----------------
jbe@0: 
jbe@0: CREATE FUNCTION cast_epoint_to_ebox(epoint)
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_to_ebox';
jbe@0: 
jbe@0: CREATE CAST (epoint AS ebox) WITH FUNCTION cast_epoint_to_ebox(epoint);
jbe@0: 
jbe@0: CREATE FUNCTION cast_epoint_to_ecircle(epoint)
jbe@0:   RETURNS ecircle
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_to_ecircle';
jbe@0: 
jbe@0: CREATE CAST (epoint AS ecircle) WITH FUNCTION cast_epoint_to_ecircle(epoint);
jbe@0: 
jbe@0: CREATE FUNCTION cast_epoint_to_ecluster(epoint)
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_to_ecluster';
jbe@0: 
jbe@0: CREATE CAST (epoint AS ecluster) WITH FUNCTION cast_epoint_to_ecluster(epoint);
jbe@0: 
jbe@0: CREATE FUNCTION cast_ebox_to_ecluster(ebox)
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_to_ecluster';
jbe@0: 
jbe@0: CREATE CAST (ebox AS ecluster) WITH FUNCTION cast_ebox_to_ecluster(ebox);
jbe@0: 
jbe@0: 
jbe@0: ---------------------------
jbe@0: -- constructor functions --
jbe@0: ---------------------------
jbe@0: 
jbe@0: CREATE FUNCTION epoint(float8, float8)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_epoint';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_latlon(float8, float8)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE SQL IMMUTABLE STRICT AS $$
jbe@0:     SELECT epoint($1, $2)
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION epoint_lonlat(float8, float8)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE SQL IMMUTABLE STRICT AS $$
jbe@0:     SELECT epoint($2, $1)
jbe@0:   $$;
jbe@0: 
jbe@46: CREATE FUNCTION epoint_with_sample_count(epoint, int4)
jbe@46:   RETURNS epoint_with_sample_count
jbe@46:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_epoint_with_sample_count';
jbe@46: 
jbe@0: CREATE FUNCTION empty_ebox()
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_empty_ebox';
jbe@0: 
jbe@0: CREATE FUNCTION ebox(float8, float8, float8, float8)
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_ebox';
jbe@0: 
jbe@0: CREATE FUNCTION ebox(epoint, epoint)
jbe@0:   RETURNS ebox
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_ebox_from_epoints';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle(float8, float8, float8)
jbe@0:   RETURNS ecircle
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_ecircle';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle(epoint, float8)
jbe@0:   RETURNS ecircle
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_create_ecircle_from_epoint';
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_concat(ecluster[])
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT array_to_string($1, ' ')::ecluster
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_concat(ecluster, ecluster)
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT ($1::text || ' ' || $2::text)::ecluster
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_create_multipoint(epoint[])
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT
jbe@0:       array_to_string(array_agg('point (' || unnest || ')'), ' ')::ecluster
jbe@0:     FROM unnest($1)
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_create_path(epoint[])
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT CASE WHEN "str" = '' THEN 'empty'::ecluster ELSE
jbe@0:       ('path (' || array_to_string($1, ' ') || ')')::ecluster
jbe@0:     END
jbe@0:     FROM array_to_string($1, ' ') AS "str"
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_create_outline(epoint[])
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT CASE WHEN "str" = '' THEN 'empty'::ecluster ELSE
jbe@0:       ('outline (' || array_to_string($1, ' ') || ')')::ecluster
jbe@0:     END
jbe@0:     FROM array_to_string($1, ' ') AS "str"
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_create_polygon(epoint[])
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT CASE WHEN "str" = '' THEN 'empty'::ecluster ELSE
jbe@0:       ('polygon (' || array_to_string($1, ' ') || ')')::ecluster
jbe@0:     END
jbe@0:     FROM array_to_string($1, ' ') AS "str"
jbe@0:   $$;
jbe@0: 
jbe@0: 
jbe@0: ----------------------
jbe@0: -- getter functions --
jbe@0: ----------------------
jbe@0: 
jbe@0: CREATE FUNCTION latitude(epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_lat';
jbe@0: 
jbe@0: CREATE FUNCTION longitude(epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_lon';
jbe@0: 
jbe@0: CREATE FUNCTION min_latitude(ebox)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_lat_min';
jbe@0: 
jbe@0: CREATE FUNCTION max_latitude(ebox)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_lat_max';
jbe@0: 
jbe@0: CREATE FUNCTION min_longitude(ebox)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_lon_min';
jbe@0: 
jbe@0: CREATE FUNCTION max_longitude(ebox)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_lon_max';
jbe@0: 
jbe@0: CREATE FUNCTION center(ecircle)
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_center';
jbe@0: 
jbe@0: CREATE FUNCTION radius(ecircle)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_radius';
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_extract_points(ecluster)
jbe@0:   RETURNS SETOF epoint
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT "match"[2]::epoint
jbe@0:     FROM regexp_matches($1::text, e'(^| )point \\(([^)]+)\\)', 'g') AS "match"
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_extract_paths(ecluster)
jbe@0:   RETURNS SETOF epoint[]
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT (
jbe@0:       SELECT array_agg("m2"[1]::epoint)
jbe@0:       FROM regexp_matches("m1"[2], e'[^ ]+ [^ ]+', 'g') AS "m2"
jbe@0:     )
jbe@0:     FROM regexp_matches($1::text, e'(^| )path \\(([^)]+)\\)', 'g') AS "m1"
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_extract_outlines(ecluster)
jbe@0:   RETURNS SETOF epoint[]
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT (
jbe@0:       SELECT array_agg("m2"[1]::epoint)
jbe@0:       FROM regexp_matches("m1"[2], e'[^ ]+ [^ ]+', 'g') AS "m2"
jbe@0:     )
jbe@0:     FROM regexp_matches($1::text, e'(^| )outline \\(([^)]+)\\)', 'g') AS "m1"
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION ecluster_extract_polygons(ecluster)
jbe@0:   RETURNS SETOF epoint[]
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT (
jbe@0:       SELECT array_agg("m2"[1]::epoint)
jbe@0:       FROM regexp_matches("m1"[2], e'[^ ]+ [^ ]+', 'g') AS "m2"
jbe@0:     )
jbe@0:     FROM regexp_matches($1::text, e'(^| )polygon \\(([^)]+)\\)', 'g') AS "m1"
jbe@0:   $$;
jbe@0: 
jbe@0: 
jbe@0: ---------------
jbe@0: -- operators --
jbe@0: ---------------
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ebox_overlap_proc(epoint, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ebox_overlap';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecircle_overlap_proc(epoint, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ecircle_overlap';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecluster_overlap_proc(epoint, ecluster)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ecluster_overlap';
jbe@0: 
jbe@10: CREATE FUNCTION epoint_ecluster_may_overlap_proc(epoint, ecluster)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ecluster_may_overlap';
jbe@10: 
jbe@0: CREATE FUNCTION ebox_overlap_proc(ebox, ebox)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_overlap';
jbe@0: 
jbe@10: CREATE FUNCTION ebox_ecircle_may_overlap_proc(ebox, ecircle)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_ecircle_may_overlap';
jbe@10: 
jbe@10: CREATE FUNCTION ebox_ecluster_may_overlap_proc(ebox, ecluster)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ebox_ecluster_may_overlap';
jbe@10: 
jbe@0: CREATE FUNCTION ecircle_overlap_proc(ecircle, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_overlap';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_ecluster_overlap_proc(ecircle, ecluster)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_ecluster_overlap';
jbe@0: 
jbe@10: CREATE FUNCTION ecircle_ecluster_may_overlap_proc(ecircle, ecluster)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_ecluster_may_overlap';
jbe@10: 
jbe@16: CREATE FUNCTION ecluster_overlap_proc(ecluster, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_overlap';
jbe@16: 
jbe@10: CREATE FUNCTION ecluster_may_overlap_proc(ecluster, ecluster)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_may_overlap';
jbe@10: 
jbe@16: CREATE FUNCTION ecluster_contains_proc(ecluster, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_contains';
jbe@16: 
jbe@0: CREATE FUNCTION epoint_distance_proc(epoint, epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_distance';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecircle_distance_proc(epoint, ecircle)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ecircle_distance';
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecluster_distance_proc(epoint, ecluster)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_epoint_ecluster_distance';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_distance_proc(ecircle, ecircle)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_distance';
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_ecluster_distance_proc(ecircle, ecluster)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecircle_ecluster_distance';
jbe@0: 
jbe@16: CREATE FUNCTION ecluster_distance_proc(ecluster, ecluster)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_distance';
jbe@46: 
jbe@46: CREATE FUNCTION fair_distance_operator_proc(ecluster, epoint_with_sample_count)
jbe@46:   RETURNS float8
jbe@46:   LANGUAGE C IMMUTABLE STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_ecluster_epoint_sc_fair_distance';
jbe@16: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = epoint_ebox_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ebox_overlap_commutator(ebox, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 && $1';
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_ebox_overlap_commutator,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = epoint_ecircle_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecircle_overlap_commutator(ecircle, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 && $1';
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_ecircle_overlap_commutator,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = ecluster,
jbe@0:   procedure = epoint_ecluster_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecluster_overlap_commutator(ecluster, epoint)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 && $1';
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ecluster,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_ecluster_overlap_commutator,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ebox,
jbe@0:   rightarg = ebox,
jbe@0:   procedure = ebox_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecluster,
jbe@0:   procedure = ecircle_ecluster_overlap_proc,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_ecluster_overlap_commutator(ecluster, ecircle)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 && $1';
jbe@0: 
jbe@0: CREATE OPERATOR && (
jbe@0:   leftarg = ecluster,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_ecluster_overlap_commutator,
jbe@0:   commutator = &&,
jbe@0:   restrict = areasel,
jbe@0:   join = areajoinsel
jbe@0: );
jbe@0: 
jbe@16: CREATE OPERATOR && (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ecluster_overlap_proc,
jbe@16:   commutator = &&,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecircle_overlap_castwrap(ebox, ecircle)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster && $2';
jbe@16: 
jbe@16: CREATE OPERATOR && (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecircle,
jbe@16:   procedure = ebox_ecircle_overlap_castwrap,
jbe@16:   commutator = &&,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecircle_overlap_castwrap(ecircle, ebox)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 && $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR && (
jbe@16:   leftarg = ecircle,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_ecircle_overlap_castwrap,
jbe@16:   commutator = &&,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecluster_overlap_castwrap(ebox, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster && $2';
jbe@16: 
jbe@16: CREATE OPERATOR && (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ebox_ecluster_overlap_castwrap,
jbe@16:   commutator = &&,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecluster_overlap_castwrap(ecluster, ebox)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 && $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR && (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_ecluster_overlap_castwrap,
jbe@16:   commutator = &&,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = epoint,
jbe@10:   rightarg = ecluster,
jbe@10:   procedure = epoint_ecluster_may_overlap_proc,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE FUNCTION epoint_ecluster_may_overlap_commutator(ecluster, epoint)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 &&+ $1';
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecluster,
jbe@10:   rightarg = epoint,
jbe@10:   procedure = epoint_ecluster_may_overlap_commutator,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ebox,
jbe@10:   rightarg = ecircle,
jbe@10:   procedure = ebox_ecircle_may_overlap_proc,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE FUNCTION ebox_ecircle_may_overlap_commutator(ecircle, ebox)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 &&+ $1';
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecircle,
jbe@10:   rightarg = ebox,
jbe@10:   procedure = ebox_ecircle_may_overlap_commutator,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ebox,
jbe@10:   rightarg = ecluster,
jbe@10:   procedure = ebox_ecluster_may_overlap_proc,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE FUNCTION ebox_ecluster_may_overlap_commutator(ecluster, ebox)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 &&+ $1';
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecluster,
jbe@10:   rightarg = ebox,
jbe@10:   procedure = ebox_ecluster_may_overlap_commutator,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecircle,
jbe@10:   rightarg = ecluster,
jbe@10:   procedure = ecircle_ecluster_may_overlap_proc,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE FUNCTION ecircle_ecluster_may_overlap_commutator(ecluster, ecircle)
jbe@10:   RETURNS boolean
jbe@10:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 &&+ $1';
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecluster,
jbe@10:   rightarg = ecircle,
jbe@10:   procedure = ecircle_ecluster_may_overlap_commutator,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@10: CREATE OPERATOR &&+ (
jbe@10:   leftarg = ecluster,
jbe@10:   rightarg = ecluster,
jbe@10:   procedure = ecluster_may_overlap_proc,
jbe@10:   commutator = &&+,
jbe@10:   restrict = areasel,
jbe@10:   join = areajoinsel
jbe@10: );
jbe@10: 
jbe@16: CREATE OPERATOR @> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = epoint,
jbe@16:   procedure = epoint_ebox_overlap_commutator,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE OPERATOR <@ (
jbe@16:   leftarg = epoint,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = epoint_ebox_overlap_proc,
jbe@16:   commutator = @>,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE OPERATOR @> (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = epoint,
jbe@16:   procedure = epoint_ecluster_overlap_commutator,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE OPERATOR <@ (
jbe@16:   leftarg = epoint,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = epoint_ecluster_overlap_proc,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE OPERATOR @> (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ecluster_contains_proc,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ecluster_contains_commutator(ecluster, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 @> $1';
jbe@16: 
jbe@16: CREATE OPERATOR <@ (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ecluster_contains_commutator,
jbe@16:   commutator = @>,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@20: CREATE FUNCTION ebox_contains_castwrap(ebox, ebox)
jbe@20:   RETURNS boolean
jbe@20:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster @> $2::ecluster';
jbe@20: 
jbe@20: CREATE OPERATOR @> (
jbe@20:   leftarg = ebox,
jbe@20:   rightarg = ebox,
jbe@20:   procedure = ebox_contains_castwrap,
jbe@20:   commutator = <@,
jbe@20:   restrict = areasel,
jbe@20:   join = areajoinsel
jbe@20: );
jbe@20: 
jbe@20: CREATE FUNCTION ebox_contains_swapped_castwrap(ebox, ebox)
jbe@20:   RETURNS boolean
jbe@20:   LANGUAGE sql IMMUTABLE AS 'SELECT $2::ecluster @> $1::ecluster';
jbe@20: 
jbe@20: CREATE OPERATOR <@ (
jbe@20:   leftarg = ebox,
jbe@20:   rightarg = ebox,
jbe@20:   procedure = ebox_contains_swapped_castwrap,
jbe@20:   commutator = @>,
jbe@20:   restrict = areasel,
jbe@20:   join = areajoinsel
jbe@20: );
jbe@20: 
jbe@16: CREATE FUNCTION ebox_ecluster_contains_castwrap(ebox, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster @> $2';
jbe@16: 
jbe@16: CREATE OPERATOR @> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ebox_ecluster_contains_castwrap,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecluster_contains_castwrap(ecluster, ebox)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $2::ecluster @> $1';
jbe@16: 
jbe@16: CREATE OPERATOR <@ (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_ecluster_contains_castwrap,
jbe@16:   commutator = @>,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ecluster_ebox_contains_castwrap(ecluster, ebox)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 @> $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR @> (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ecluster_ebox_contains_castwrap,
jbe@16:   commutator = <@,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ecluster_ebox_contains_castwrap(ebox, ecluster)
jbe@16:   RETURNS boolean
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 @> $1::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR <@ (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ecluster_ebox_contains_castwrap,
jbe@16:   commutator = @>,
jbe@16:   restrict = areasel,
jbe@16:   join = areajoinsel
jbe@16: );
jbe@16: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_distance_proc,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = epoint_ecircle_distance_proc,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecircle_distance_commutator(ecircle, epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 <-> $1';
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_ecircle_distance_commutator,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = epoint,
jbe@0:   rightarg = ecluster,
jbe@0:   procedure = epoint_ecluster_distance_proc,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION epoint_ecluster_distance_commutator(ecluster, epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 <-> $1';
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = ecluster,
jbe@0:   rightarg = epoint,
jbe@0:   procedure = epoint_ecluster_distance_commutator,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_distance_proc,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = ecircle,
jbe@0:   rightarg = ecluster,
jbe@0:   procedure = ecircle_ecluster_distance_proc,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@0: CREATE FUNCTION ecircle_ecluster_distance_commutator(ecluster, ecircle)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $2 <-> $1';
jbe@0: 
jbe@0: CREATE OPERATOR <-> (
jbe@0:   leftarg = ecluster,
jbe@0:   rightarg = ecircle,
jbe@0:   procedure = ecircle_ecluster_distance_commutator,
jbe@0:   commutator = <->
jbe@0: );
jbe@0: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ecluster_distance_proc,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION epoint_ebox_distance_castwrap(epoint, ebox)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <-> $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = epoint,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = epoint_ebox_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION epoint_ebox_distance_castwrap(ebox, epoint)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster <-> $2';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = epoint,
jbe@16:   procedure = epoint_ebox_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_distance_castwrap(ebox, ebox)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster <-> $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecircle_distance_castwrap(ebox, ecircle)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster <-> $2';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecircle,
jbe@16:   procedure = ebox_ecircle_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecircle_distance_castwrap(ecircle, ebox)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <-> $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ecircle,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_ecircle_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecluster_distance_castwrap(ebox, ecluster)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1::ecluster <-> $2';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ebox,
jbe@16:   rightarg = ecluster,
jbe@16:   procedure = ebox_ecluster_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@16: CREATE FUNCTION ebox_ecluster_distance_castwrap(ecluster, ebox)
jbe@16:   RETURNS float8
jbe@16:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <-> $2::ecluster';
jbe@16: 
jbe@16: CREATE OPERATOR <-> (
jbe@16:   leftarg = ecluster,
jbe@16:   rightarg = ebox,
jbe@16:   procedure = ebox_ecluster_distance_castwrap,
jbe@16:   commutator = <->
jbe@16: );
jbe@16: 
jbe@46: CREATE OPERATOR <=> (
jbe@46:   leftarg = ecluster,
jbe@46:   rightarg = epoint_with_sample_count,
jbe@46:   procedure = fair_distance_operator_proc
jbe@46: );
jbe@42: 
jbe@42: 
jbe@0: ----------------
jbe@0: -- GiST index --
jbe@0: ----------------
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_consistent(internal, internal, smallint, oid, internal)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_consistent';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_union(internal, internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_union';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_compress_epoint(internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_compress_epoint';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_compress_ecircle(internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_compress_ecircle';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_compress_ecluster(internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_compress_ecluster';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_decompress(internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_decompress';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_penalty(internal, internal, internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_penalty';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_picksplit(internal, internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_picksplit';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_same(internal, internal, internal)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_same';
jbe@0: 
jbe@0: CREATE FUNCTION pgl_gist_distance(internal, internal, smallint, oid)
jbe@0:   RETURNS internal
jbe@0:   LANGUAGE C STRICT
jbe@46:   AS '$libdir/latlon-v0009', 'pgl_gist_distance';
jbe@0: 
jbe@0: CREATE OPERATOR CLASS epoint_ops
jbe@0:   DEFAULT FOR TYPE epoint USING gist AS
jbe@10:   OPERATOR  11 = ,
jbe@10:   OPERATOR  22 &&  (epoint, ebox),
jbe@16:   OPERATOR 222 <@  (epoint, ebox),
jbe@10:   OPERATOR  23 &&  (epoint, ecircle),
jbe@10:   OPERATOR  24 &&  (epoint, ecluster),
jbe@10:   OPERATOR 124 &&+ (epoint, ecluster),
jbe@16:   OPERATOR 224 <@  (epoint, ecluster),
jbe@10:   OPERATOR  31 <-> (epoint, epoint) FOR ORDER BY float_ops,
jbe@16:   OPERATOR  32 <-> (epoint, ebox) FOR ORDER BY float_ops,
jbe@10:   OPERATOR  33 <-> (epoint, ecircle) FOR ORDER BY float_ops,
jbe@10:   OPERATOR  34 <-> (epoint, ecluster) FOR ORDER BY float_ops,
jbe@0:   FUNCTION 1 pgl_gist_consistent(internal, internal, smallint, oid, internal),
jbe@0:   FUNCTION 2 pgl_gist_union(internal, internal),
jbe@0:   FUNCTION 3 pgl_gist_compress_epoint(internal),
jbe@0:   FUNCTION 4 pgl_gist_decompress(internal),
jbe@0:   FUNCTION 5 pgl_gist_penalty(internal, internal, internal),
jbe@0:   FUNCTION 6 pgl_gist_picksplit(internal, internal),
jbe@0:   FUNCTION 7 pgl_gist_same(internal, internal, internal),
jbe@0:   FUNCTION 8 pgl_gist_distance(internal, internal, smallint, oid),
jbe@0:   STORAGE ekey_point;
jbe@0: 
jbe@0: CREATE OPERATOR CLASS ecircle_ops
jbe@0:   DEFAULT FOR TYPE ecircle USING gist AS
jbe@10:   OPERATOR  13 = ,
jbe@10:   OPERATOR  21 &&  (ecircle, epoint),
jbe@16:   OPERATOR  22 &&  (ecircle, ebox),
jbe@10:   OPERATOR 122 &&+ (ecircle, ebox),
jbe@10:   OPERATOR  23 &&  (ecircle, ecircle),
jbe@10:   OPERATOR  24 &&  (ecircle, ecluster),
jbe@10:   OPERATOR 124 &&+ (ecircle, ecluster),
jbe@10:   OPERATOR  31 <-> (ecircle, epoint) FOR ORDER BY float_ops,
jbe@16:   OPERATOR  32 <-> (ecircle, ebox) FOR ORDER BY float_ops,
jbe@10:   OPERATOR  33 <-> (ecircle, ecircle) FOR ORDER BY float_ops,
jbe@10:   OPERATOR  34 <-> (ecircle, ecluster) FOR ORDER BY float_ops,
jbe@0:   FUNCTION 1 pgl_gist_consistent(internal, internal, smallint, oid, internal),
jbe@0:   FUNCTION 2 pgl_gist_union(internal, internal),
jbe@0:   FUNCTION 3 pgl_gist_compress_ecircle(internal),
jbe@0:   FUNCTION 4 pgl_gist_decompress(internal),
jbe@0:   FUNCTION 5 pgl_gist_penalty(internal, internal, internal),
jbe@0:   FUNCTION 6 pgl_gist_picksplit(internal, internal),
jbe@0:   FUNCTION 7 pgl_gist_same(internal, internal, internal),
jbe@0:   FUNCTION 8 pgl_gist_distance(internal, internal, smallint, oid),
jbe@0:   STORAGE ekey_area;
jbe@0: 
jbe@0: CREATE OPERATOR CLASS ecluster_ops
jbe@0:   DEFAULT FOR TYPE ecluster USING gist AS
jbe@10:   OPERATOR  21 &&  (ecluster, epoint),
jbe@10:   OPERATOR 121 &&+ (ecluster, epoint),
jbe@16:   OPERATOR 221 @>  (ecluster, epoint),
jbe@16:   OPERATOR  22 &&  (ecluster, ebox),
jbe@10:   OPERATOR 122 &&+ (ecluster, ebox),
jbe@16:   OPERATOR 222 @>  (ecluster, ebox),
jbe@16:   OPERATOR 322 <@  (ecluster, ebox),
jbe@10:   OPERATOR  23 &&  (ecluster, ecircle),
jbe@10:   OPERATOR 123 &&+ (ecluster, ecircle),
jbe@16:   OPERATOR  24 &&  (ecluster, ecluster),
jbe@10:   OPERATOR 124 &&+ (ecluster, ecluster),
jbe@16:   OPERATOR 224 @>  (ecluster, ecluster),
jbe@16:   OPERATOR 324 <@  (ecluster, ecluster),
jbe@16:   OPERATOR  31 <-> (ecluster, epoint) FOR ORDER BY float_ops,
jbe@16:   OPERATOR  32 <-> (ecluster, ebox) FOR ORDER BY float_ops,
jbe@16:   OPERATOR  33 <-> (ecluster, ecircle) FOR ORDER BY float_ops,
jbe@16:   OPERATOR  34 <-> (ecluster, ecluster) FOR ORDER BY float_ops,
jbe@46:   OPERATOR 131 <=> (ecluster, epoint_with_sample_count) FOR ORDER BY float_ops,
jbe@0:   FUNCTION 1 pgl_gist_consistent(internal, internal, smallint, oid, internal),
jbe@0:   FUNCTION 2 pgl_gist_union(internal, internal),
jbe@0:   FUNCTION 3 pgl_gist_compress_ecluster(internal),
jbe@0:   FUNCTION 4 pgl_gist_decompress(internal),
jbe@0:   FUNCTION 5 pgl_gist_penalty(internal, internal, internal),
jbe@0:   FUNCTION 6 pgl_gist_picksplit(internal, internal),
jbe@0:   FUNCTION 7 pgl_gist_same(internal, internal, internal),
jbe@0:   FUNCTION 8 pgl_gist_distance(internal, internal, smallint, oid),
jbe@0:   STORAGE ekey_area;
jbe@0: 
jbe@0: 
jbe@0: ---------------------
jbe@0: -- alias functions --
jbe@0: ---------------------
jbe@0: 
jbe@0: CREATE FUNCTION distance(epoint, epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <-> $2';
jbe@0: 
jbe@0: CREATE FUNCTION distance(ecluster, epoint)
jbe@0:   RETURNS float8
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <-> $2';
jbe@0: 
jbe@0: CREATE FUNCTION distance_within(epoint, epoint, float8)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 && ecircle($2, $3)';
jbe@0: 
jbe@0: CREATE FUNCTION distance_within(ecluster, epoint, float8)
jbe@0:   RETURNS boolean
jbe@0:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 && ecircle($2, $3)';
jbe@0: 
jbe@46: CREATE FUNCTION fair_distance(ecluster, epoint, int4 = 10000)
jbe@46:   RETURNS float8
jbe@46:   LANGUAGE sql IMMUTABLE AS 'SELECT $1 <=> epoint_with_sample_count($2, $3)';
jbe@46: 
jbe@0: 
jbe@0: --------------------------------
jbe@0: -- other data storage formats --
jbe@0: --------------------------------
jbe@0: 
jbe@39: CREATE FUNCTION coords_to_epoint(float8, float8, text = 'epoint')
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE plpgsql IMMUTABLE STRICT AS $$
jbe@0:     DECLARE
jbe@0:       "result" epoint;
jbe@0:     BEGIN
jbe@0:       IF $3 = 'epoint_lonlat' THEN
jbe@0:         -- avoid dynamic command execution for better performance
jbe@0:         RETURN epoint($2, $1);
jbe@0:       END IF;
jbe@0:       IF $3 = 'epoint' OR $3 = 'epoint_latlon' THEN
jbe@0:         -- avoid dynamic command execution for better performance
jbe@0:         RETURN epoint($1, $2);
jbe@0:       END IF;
jbe@0:       EXECUTE 'SELECT ' || $3 || '($1, $2)' INTO STRICT "result" USING $1, $2;
jbe@0:       RETURN "result";
jbe@0:     END;
jbe@0:   $$;
jbe@0: 
jbe@39: CREATE FUNCTION GeoJSON_LinearRing_vertices(jsonb, text = 'epoint_lonlat')
jbe@39:   RETURNS SETOF jsonb
jbe@39:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@39:     SELECT "result" FROM
jbe@39:       ( SELECT jsonb_array_length($1) - 1 ) AS "lastindex_row" ("lastindex")
jbe@39:       CROSS JOIN LATERAL jsonb_array_elements(
jbe@39:         CASE WHEN
jbe@39:           coords_to_epoint(
jbe@39:             ($1->0->>0)::float8,
jbe@39:             ($1->0->>1)::float8,
jbe@39:             $2
jbe@39:           ) = coords_to_epoint(
jbe@39:             ($1->"lastindex"->>0)::float8,
jbe@39:             ($1->"lastindex"->>1)::float8,
jbe@39:             $2
jbe@39:           )
jbe@39:         THEN
jbe@39:           $1 - "lastindex"
jbe@39:         ELSE
jbe@39:           $1
jbe@39:         END
jbe@39:       ) AS "result_row" ("result")
jbe@39:   $$;
jbe@39: 
jbe@0: CREATE FUNCTION GeoJSON_to_epoint(jsonb, text = 'epoint_lonlat')
jbe@0:   RETURNS epoint
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT CASE
jbe@0:     WHEN $1->>'type' = 'Point' THEN
jbe@0:       coords_to_epoint(
jbe@39:         ($1->'coordinates'->>0)::float8,
jbe@0:         ($1->'coordinates'->>1)::float8,
jbe@0:         $2
jbe@0:       )
jbe@0:     WHEN $1->>'type' = 'Feature' THEN
jbe@0:       GeoJSON_to_epoint($1->'geometry', $2)
jbe@0:     ELSE
jbe@0:       NULL
jbe@0:     END
jbe@0:   $$;
jbe@0: 
jbe@0: CREATE FUNCTION GeoJSON_to_ecluster(jsonb, text = 'epoint_lonlat')
jbe@0:   RETURNS ecluster
jbe@0:   LANGUAGE sql IMMUTABLE STRICT AS $$
jbe@0:     SELECT CASE $1->>'type'
jbe@0:     WHEN 'Point' THEN
jbe@0:       coords_to_epoint(
jbe@39:         ($1->'coordinates'->>0)::float8,
jbe@0:         ($1->'coordinates'->>1)::float8,
jbe@0:         $2
jbe@0:       )::ecluster
jbe@0:     WHEN 'MultiPoint' THEN
jbe@0:       ( SELECT ecluster_create_multipoint(array_agg(
jbe@0:           coords_to_epoint(
jbe@39:             ("coord"->>0)::float8,
jbe@0:             ("coord"->>1)::float8,
jbe@0:             $2
jbe@0:           )
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'coordinates') AS "coord"
jbe@0:       )
jbe@0:     WHEN 'LineString' THEN
jbe@0:       ( SELECT ecluster_create_path(array_agg(
jbe@0:           coords_to_epoint(
jbe@39:             ("coord"->>0)::float8,
jbe@0:             ("coord"->>1)::float8,
jbe@0:             $2
jbe@0:           )
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'coordinates') AS "coord"
jbe@0:       )
jbe@0:     WHEN 'MultiLineString' THEN
jbe@0:       ( SELECT ecluster_concat(array_agg(
jbe@0:           ( SELECT ecluster_create_path(array_agg(
jbe@0:               coords_to_epoint(
jbe@39:                 ("coord"->>0)::float8,
jbe@0:                 ("coord"->>1)::float8,
jbe@0:                 $2
jbe@0:               )
jbe@0:             ))
jbe@0:             FROM jsonb_array_elements("coord_array") AS "coord"
jbe@0:           )
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'coordinates') AS "coord_array"
jbe@0:       )
jbe@0:     WHEN 'Polygon' THEN
jbe@0:       ( SELECT ecluster_concat(array_agg(
jbe@0:           ( SELECT ecluster_create_polygon(array_agg(
jbe@0:               coords_to_epoint(
jbe@39:                 ("coord"->>0)::float8,
jbe@0:                 ("coord"->>1)::float8,
jbe@0:                 $2
jbe@0:               )
jbe@0:             ))
jbe@39:             FROM GeoJSON_LinearRing_vertices("coord_array", $2) AS "coord"
jbe@0:           )
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'coordinates') AS "coord_array"
jbe@0:       )
jbe@0:     WHEN 'MultiPolygon' THEN
jbe@0:       ( SELECT ecluster_concat(array_agg(
jbe@0:           ( SELECT ecluster_concat(array_agg(
jbe@0:               ( SELECT ecluster_create_polygon(array_agg(
jbe@0:                   coords_to_epoint(
jbe@39:                     ("coord"->>0)::float8,
jbe@0:                     ("coord"->>1)::float8,
jbe@0:                     $2
jbe@0:                   )
jbe@0:                 ))
jbe@39:                 FROM GeoJSON_LinearRing_vertices("coord_array", $2) AS "coord"
jbe@0:               )
jbe@0:             ))
jbe@0:             FROM jsonb_array_elements("coord_array_array") AS "coord_array"
jbe@0:           )
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'coordinates') AS "coord_array_array"
jbe@0:       )
jbe@39:     WHEN 'GeometryCollection' THEN
jbe@39:       ( SELECT ecluster_concat(array_agg(
jbe@39:           GeoJSON_to_ecluster("geometry", $2)
jbe@39:         ))
jbe@39:         FROM jsonb_array_elements($1->'geometries') AS "geometry"
jbe@39:       )
jbe@0:     WHEN 'Feature' THEN
jbe@0:       GeoJSON_to_ecluster($1->'geometry', $2)
jbe@0:     WHEN 'FeatureCollection' THEN
jbe@0:       ( SELECT ecluster_concat(array_agg(
jbe@0:           GeoJSON_to_ecluster("feature", $2)
jbe@0:         ))
jbe@0:         FROM jsonb_array_elements($1->'features') AS "feature"
jbe@0:       )
jbe@0:     ELSE
jbe@0:       NULL
jbe@0:     END
jbe@0:   $$;
jbe@0: 




