Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Functions

geo_decls.h File Reference

#include <math.h>
#include "fmgr.h"
Include dependency graph for geo_decls.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Point
struct  LSEG
struct  PATH
struct  LINE
struct  BOX
struct  POLYGON
struct  CIRCLE

Defines

#define EPSILON   1.0E-06
#define FPzero(A)   (fabs(A) <= EPSILON)
#define FPeq(A, B)   (fabs((A) - (B)) <= EPSILON)
#define FPne(A, B)   (fabs((A) - (B)) > EPSILON)
#define FPlt(A, B)   ((B) - (A) > EPSILON)
#define FPle(A, B)   ((A) - (B) <= EPSILON)
#define FPgt(A, B)   ((A) - (B) > EPSILON)
#define FPge(A, B)   ((B) - (A) <= EPSILON)
#define HYPOT(A, B)   pg_hypot(A, B)
#define DatumGetPointP(X)   ((Point *) DatumGetPointer(X))
#define PointPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_POINT_P(n)   DatumGetPointP(PG_GETARG_DATUM(n))
#define PG_RETURN_POINT_P(x)   return PointPGetDatum(x)
#define DatumGetLsegP(X)   ((LSEG *) DatumGetPointer(X))
#define LsegPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_LSEG_P(n)   DatumGetLsegP(PG_GETARG_DATUM(n))
#define PG_RETURN_LSEG_P(x)   return LsegPGetDatum(x)
#define DatumGetPathP(X)   ((PATH *) PG_DETOAST_DATUM(X))
#define DatumGetPathPCopy(X)   ((PATH *) PG_DETOAST_DATUM_COPY(X))
#define PathPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_PATH_P(n)   DatumGetPathP(PG_GETARG_DATUM(n))
#define PG_GETARG_PATH_P_COPY(n)   DatumGetPathPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_PATH_P(x)   return PathPGetDatum(x)
#define DatumGetLineP(X)   ((LINE *) DatumGetPointer(X))
#define LinePGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_LINE_P(n)   DatumGetLineP(PG_GETARG_DATUM(n))
#define PG_RETURN_LINE_P(x)   return LinePGetDatum(x)
#define DatumGetBoxP(X)   ((BOX *) DatumGetPointer(X))
#define BoxPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_BOX_P(n)   DatumGetBoxP(PG_GETARG_DATUM(n))
#define PG_RETURN_BOX_P(x)   return BoxPGetDatum(x)
#define DatumGetPolygonP(X)   ((POLYGON *) PG_DETOAST_DATUM(X))
#define DatumGetPolygonPCopy(X)   ((POLYGON *) PG_DETOAST_DATUM_COPY(X))
#define PolygonPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_POLYGON_P(n)   DatumGetPolygonP(PG_GETARG_DATUM(n))
#define PG_GETARG_POLYGON_P_COPY(n)   DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_POLYGON_P(x)   return PolygonPGetDatum(x)
#define DatumGetCircleP(X)   ((CIRCLE *) DatumGetPointer(X))
#define CirclePGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_CIRCLE_P(n)   DatumGetCircleP(PG_GETARG_DATUM(n))
#define PG_RETURN_CIRCLE_P(x)   return CirclePGetDatum(x)

Functions

Datum point_in (PG_FUNCTION_ARGS)
Datum point_out (PG_FUNCTION_ARGS)
Datum point_recv (PG_FUNCTION_ARGS)
Datum point_send (PG_FUNCTION_ARGS)
Datum construct_point (PG_FUNCTION_ARGS)
Datum point_left (PG_FUNCTION_ARGS)
Datum point_right (PG_FUNCTION_ARGS)
Datum point_above (PG_FUNCTION_ARGS)
Datum point_below (PG_FUNCTION_ARGS)
Datum point_vert (PG_FUNCTION_ARGS)
Datum point_horiz (PG_FUNCTION_ARGS)
Datum point_eq (PG_FUNCTION_ARGS)
Datum point_ne (PG_FUNCTION_ARGS)
Datum point_distance (PG_FUNCTION_ARGS)
Datum point_slope (PG_FUNCTION_ARGS)
Datum point_add (PG_FUNCTION_ARGS)
Datum point_sub (PG_FUNCTION_ARGS)
Datum point_mul (PG_FUNCTION_ARGS)
Datum point_div (PG_FUNCTION_ARGS)
double point_dt (Point *pt1, Point *pt2)
double point_sl (Point *pt1, Point *pt2)
double pg_hypot (double x, double y)
Datum lseg_in (PG_FUNCTION_ARGS)
Datum lseg_out (PG_FUNCTION_ARGS)
Datum lseg_recv (PG_FUNCTION_ARGS)
Datum lseg_send (PG_FUNCTION_ARGS)
Datum lseg_intersect (PG_FUNCTION_ARGS)
Datum lseg_parallel (PG_FUNCTION_ARGS)
Datum lseg_perp (PG_FUNCTION_ARGS)
Datum lseg_vertical (PG_FUNCTION_ARGS)
Datum lseg_horizontal (PG_FUNCTION_ARGS)
Datum lseg_eq (PG_FUNCTION_ARGS)
Datum lseg_ne (PG_FUNCTION_ARGS)
Datum lseg_lt (PG_FUNCTION_ARGS)
Datum lseg_le (PG_FUNCTION_ARGS)
Datum lseg_gt (PG_FUNCTION_ARGS)
Datum lseg_ge (PG_FUNCTION_ARGS)
Datum lseg_construct (PG_FUNCTION_ARGS)
Datum lseg_length (PG_FUNCTION_ARGS)
Datum lseg_distance (PG_FUNCTION_ARGS)
Datum lseg_center (PG_FUNCTION_ARGS)
Datum lseg_interpt (PG_FUNCTION_ARGS)
Datum dist_pl (PG_FUNCTION_ARGS)
Datum dist_ps (PG_FUNCTION_ARGS)
Datum dist_ppath (PG_FUNCTION_ARGS)
Datum dist_pb (PG_FUNCTION_ARGS)
Datum dist_sl (PG_FUNCTION_ARGS)
Datum dist_sb (PG_FUNCTION_ARGS)
Datum dist_lb (PG_FUNCTION_ARGS)
Datum close_lseg (PG_FUNCTION_ARGS)
Datum close_pl (PG_FUNCTION_ARGS)
Datum close_ps (PG_FUNCTION_ARGS)
Datum close_pb (PG_FUNCTION_ARGS)
Datum close_sl (PG_FUNCTION_ARGS)
Datum close_sb (PG_FUNCTION_ARGS)
Datum close_ls (PG_FUNCTION_ARGS)
Datum close_lb (PG_FUNCTION_ARGS)
Datum on_pl (PG_FUNCTION_ARGS)
Datum on_ps (PG_FUNCTION_ARGS)
Datum on_pb (PG_FUNCTION_ARGS)
Datum on_ppath (PG_FUNCTION_ARGS)
Datum on_sl (PG_FUNCTION_ARGS)
Datum on_sb (PG_FUNCTION_ARGS)
Datum inter_sl (PG_FUNCTION_ARGS)
Datum inter_sb (PG_FUNCTION_ARGS)
Datum inter_lb (PG_FUNCTION_ARGS)
Datum line_in (PG_FUNCTION_ARGS)
Datum line_out (PG_FUNCTION_ARGS)
Datum line_recv (PG_FUNCTION_ARGS)
Datum line_send (PG_FUNCTION_ARGS)
Datum line_interpt (PG_FUNCTION_ARGS)
Datum line_distance (PG_FUNCTION_ARGS)
Datum line_construct_pp (PG_FUNCTION_ARGS)
Datum line_intersect (PG_FUNCTION_ARGS)
Datum line_parallel (PG_FUNCTION_ARGS)
Datum line_perp (PG_FUNCTION_ARGS)
Datum line_vertical (PG_FUNCTION_ARGS)
Datum line_horizontal (PG_FUNCTION_ARGS)
Datum line_eq (PG_FUNCTION_ARGS)
Datum box_in (PG_FUNCTION_ARGS)
Datum box_out (PG_FUNCTION_ARGS)
Datum box_recv (PG_FUNCTION_ARGS)
Datum box_send (PG_FUNCTION_ARGS)
Datum box_same (PG_FUNCTION_ARGS)
Datum box_overlap (PG_FUNCTION_ARGS)
Datum box_left (PG_FUNCTION_ARGS)
Datum box_overleft (PG_FUNCTION_ARGS)
Datum box_right (PG_FUNCTION_ARGS)
Datum box_overright (PG_FUNCTION_ARGS)
Datum box_below (PG_FUNCTION_ARGS)
Datum box_overbelow (PG_FUNCTION_ARGS)
Datum box_above (PG_FUNCTION_ARGS)
Datum box_overabove (PG_FUNCTION_ARGS)
Datum box_contained (PG_FUNCTION_ARGS)
Datum box_contain (PG_FUNCTION_ARGS)
Datum box_contain_pt (PG_FUNCTION_ARGS)
Datum box_below_eq (PG_FUNCTION_ARGS)
Datum box_above_eq (PG_FUNCTION_ARGS)
Datum box_lt (PG_FUNCTION_ARGS)
Datum box_gt (PG_FUNCTION_ARGS)
Datum box_eq (PG_FUNCTION_ARGS)
Datum box_le (PG_FUNCTION_ARGS)
Datum box_ge (PG_FUNCTION_ARGS)
Datum box_area (PG_FUNCTION_ARGS)
Datum box_width (PG_FUNCTION_ARGS)
Datum box_height (PG_FUNCTION_ARGS)
Datum box_distance (PG_FUNCTION_ARGS)
Datum box_center (PG_FUNCTION_ARGS)
Datum box_intersect (PG_FUNCTION_ARGS)
Datum box_diagonal (PG_FUNCTION_ARGS)
Datum points_box (PG_FUNCTION_ARGS)
Datum box_add (PG_FUNCTION_ARGS)
Datum box_sub (PG_FUNCTION_ARGS)
Datum box_mul (PG_FUNCTION_ARGS)
Datum box_div (PG_FUNCTION_ARGS)
Datum path_area (PG_FUNCTION_ARGS)
Datum path_in (PG_FUNCTION_ARGS)
Datum path_out (PG_FUNCTION_ARGS)
Datum path_recv (PG_FUNCTION_ARGS)
Datum path_send (PG_FUNCTION_ARGS)
Datum path_n_lt (PG_FUNCTION_ARGS)
Datum path_n_gt (PG_FUNCTION_ARGS)
Datum path_n_eq (PG_FUNCTION_ARGS)
Datum path_n_le (PG_FUNCTION_ARGS)
Datum path_n_ge (PG_FUNCTION_ARGS)
Datum path_inter (PG_FUNCTION_ARGS)
Datum path_distance (PG_FUNCTION_ARGS)
Datum path_length (PG_FUNCTION_ARGS)
Datum path_isclosed (PG_FUNCTION_ARGS)
Datum path_isopen (PG_FUNCTION_ARGS)
Datum path_npoints (PG_FUNCTION_ARGS)
Datum path_close (PG_FUNCTION_ARGS)
Datum path_open (PG_FUNCTION_ARGS)
Datum path_add (PG_FUNCTION_ARGS)
Datum path_add_pt (PG_FUNCTION_ARGS)
Datum path_sub_pt (PG_FUNCTION_ARGS)
Datum path_mul_pt (PG_FUNCTION_ARGS)
Datum path_div_pt (PG_FUNCTION_ARGS)
Datum path_center (PG_FUNCTION_ARGS)
Datum path_poly (PG_FUNCTION_ARGS)
Datum poly_in (PG_FUNCTION_ARGS)
Datum poly_out (PG_FUNCTION_ARGS)
Datum poly_recv (PG_FUNCTION_ARGS)
Datum poly_send (PG_FUNCTION_ARGS)
Datum poly_left (PG_FUNCTION_ARGS)
Datum poly_overleft (PG_FUNCTION_ARGS)
Datum poly_right (PG_FUNCTION_ARGS)
Datum poly_overright (PG_FUNCTION_ARGS)
Datum poly_below (PG_FUNCTION_ARGS)
Datum poly_overbelow (PG_FUNCTION_ARGS)
Datum poly_above (PG_FUNCTION_ARGS)
Datum poly_overabove (PG_FUNCTION_ARGS)
Datum poly_same (PG_FUNCTION_ARGS)
Datum poly_overlap (PG_FUNCTION_ARGS)
Datum poly_contain (PG_FUNCTION_ARGS)
Datum poly_contained (PG_FUNCTION_ARGS)
Datum poly_contain_pt (PG_FUNCTION_ARGS)
Datum pt_contained_poly (PG_FUNCTION_ARGS)
Datum poly_distance (PG_FUNCTION_ARGS)
Datum poly_npoints (PG_FUNCTION_ARGS)
Datum poly_center (PG_FUNCTION_ARGS)
Datum poly_box (PG_FUNCTION_ARGS)
Datum poly_path (PG_FUNCTION_ARGS)
Datum box_poly (PG_FUNCTION_ARGS)
Datum circle_in (PG_FUNCTION_ARGS)
Datum circle_out (PG_FUNCTION_ARGS)
Datum circle_recv (PG_FUNCTION_ARGS)
Datum circle_send (PG_FUNCTION_ARGS)
Datum circle_same (PG_FUNCTION_ARGS)
Datum circle_overlap (PG_FUNCTION_ARGS)
Datum circle_overleft (PG_FUNCTION_ARGS)
Datum circle_left (PG_FUNCTION_ARGS)
Datum circle_right (PG_FUNCTION_ARGS)
Datum circle_overright (PG_FUNCTION_ARGS)
Datum circle_contained (PG_FUNCTION_ARGS)
Datum circle_contain (PG_FUNCTION_ARGS)
Datum circle_below (PG_FUNCTION_ARGS)
Datum circle_above (PG_FUNCTION_ARGS)
Datum circle_overbelow (PG_FUNCTION_ARGS)
Datum circle_overabove (PG_FUNCTION_ARGS)
Datum circle_eq (PG_FUNCTION_ARGS)
Datum circle_ne (PG_FUNCTION_ARGS)
Datum circle_lt (PG_FUNCTION_ARGS)
Datum circle_gt (PG_FUNCTION_ARGS)
Datum circle_le (PG_FUNCTION_ARGS)
Datum circle_ge (PG_FUNCTION_ARGS)
Datum circle_contain_pt (PG_FUNCTION_ARGS)
Datum pt_contained_circle (PG_FUNCTION_ARGS)
Datum circle_add_pt (PG_FUNCTION_ARGS)
Datum circle_sub_pt (PG_FUNCTION_ARGS)
Datum circle_mul_pt (PG_FUNCTION_ARGS)
Datum circle_div_pt (PG_FUNCTION_ARGS)
Datum circle_diameter (PG_FUNCTION_ARGS)
Datum circle_radius (PG_FUNCTION_ARGS)
Datum circle_distance (PG_FUNCTION_ARGS)
Datum dist_pc (PG_FUNCTION_ARGS)
Datum dist_cpoly (PG_FUNCTION_ARGS)
Datum circle_center (PG_FUNCTION_ARGS)
Datum cr_circle (PG_FUNCTION_ARGS)
Datum box_circle (PG_FUNCTION_ARGS)
Datum circle_box (PG_FUNCTION_ARGS)
Datum poly_circle (PG_FUNCTION_ARGS)
Datum circle_poly (PG_FUNCTION_ARGS)
Datum circle_area (PG_FUNCTION_ARGS)
Datum gist_box_compress (PG_FUNCTION_ARGS)
Datum gist_box_decompress (PG_FUNCTION_ARGS)
Datum gist_box_union (PG_FUNCTION_ARGS)
Datum gist_box_picksplit (PG_FUNCTION_ARGS)
Datum gist_box_consistent (PG_FUNCTION_ARGS)
Datum gist_box_penalty (PG_FUNCTION_ARGS)
Datum gist_box_same (PG_FUNCTION_ARGS)
Datum gist_poly_compress (PG_FUNCTION_ARGS)
Datum gist_poly_consistent (PG_FUNCTION_ARGS)
Datum gist_circle_compress (PG_FUNCTION_ARGS)
Datum gist_circle_consistent (PG_FUNCTION_ARGS)
Datum gist_point_compress (PG_FUNCTION_ARGS)
Datum gist_point_consistent (PG_FUNCTION_ARGS)
Datum gist_point_distance (PG_FUNCTION_ARGS)
Datum areasel (PG_FUNCTION_ARGS)
Datum areajoinsel (PG_FUNCTION_ARGS)
Datum positionsel (PG_FUNCTION_ARGS)
Datum positionjoinsel (PG_FUNCTION_ARGS)
Datum contsel (PG_FUNCTION_ARGS)
Datum contjoinsel (PG_FUNCTION_ARGS)

Define Documentation

#define BoxPGetDatum (   X  )     PointerGetDatum(X)
#define CirclePGetDatum (   X  )     PointerGetDatum(X)

Definition at line 181 of file geo_decls.h.

Referenced by gist_point_consistent(), and poly_center().

#define DatumGetBoxP (   X  )     ((BOX *) DatumGetPointer(X))
#define DatumGetCircleP (   X  )     ((CIRCLE *) DatumGetPointer(X))

Definition at line 180 of file geo_decls.h.

Referenced by gist_circle_compress(), and poly_center().

#define DatumGetLineP (   X  )     ((LINE *) DatumGetPointer(X))

Definition at line 163 of file geo_decls.h.

#define DatumGetLsegP (   X  )     ((LSEG *) DatumGetPointer(X))

Definition at line 151 of file geo_decls.h.

#define DatumGetPathP (   X  )     ((PATH *) PG_DETOAST_DATUM(X))

Definition at line 156 of file geo_decls.h.

Referenced by poly2path().

#define DatumGetPathPCopy (   X  )     ((PATH *) PG_DETOAST_DATUM_COPY(X))

Definition at line 157 of file geo_decls.h.

#define DatumGetPointP (   X  )     ((Point *) DatumGetPointer(X))
#define DatumGetPolygonP (   X  )     ((POLYGON *) PG_DETOAST_DATUM(X))

Definition at line 173 of file geo_decls.h.

Referenced by gist_poly_compress().

#define DatumGetPolygonPCopy (   X  )     ((POLYGON *) PG_DETOAST_DATUM_COPY(X))

Definition at line 174 of file geo_decls.h.

#define EPSILON   1.0E-06

Definition at line 33 of file geo_decls.h.

#define FPeq (   A,
  B 
)    (fabs((A) - (B)) <= EPSILON)
#define FPge (   A,
  B 
)    ((B) - (A) <= EPSILON)
#define FPgt (   A,
  B 
)    ((A) - (B) > EPSILON)
#define FPle (   A,
  B 
)    ((A) - (B) <= EPSILON)
#define FPlt (   A,
  B 
)    ((B) - (A) > EPSILON)
#define FPne (   A,
  B 
)    (fabs((A) - (B)) > EPSILON)

Definition at line 38 of file geo_decls.h.

Referenced by circle_ne(), and point_ne().

#define FPzero (   A  )     (fabs(A) <= EPSILON)
#define HYPOT (   A,
  B 
)    pg_hypot(A, B)
#define LinePGetDatum (   X  )     PointerGetDatum(X)

Definition at line 164 of file geo_decls.h.

Referenced by line_distance(), line_interpt_internal(), line_intersect(), and on_sl().

#define LsegPGetDatum (   X  )     PointerGetDatum(X)
#define PathPGetDatum (   X  )     PointerGetDatum(X)

Definition at line 158 of file geo_decls.h.

#define PG_GETARG_BOX_P (   n  )     DatumGetBoxP(PG_GETARG_DATUM(n))
#define PG_GETARG_CIRCLE_P (   n  )     DatumGetCircleP(PG_GETARG_DATUM(n))
#define PG_GETARG_LINE_P (   n  )     DatumGetLineP(PG_GETARG_DATUM(n))
#define PG_GETARG_LSEG_P (   n  )     DatumGetLsegP(PG_GETARG_DATUM(n))
#define PG_GETARG_PATH_P (   n  )     DatumGetPathP(PG_GETARG_DATUM(n))
#define PG_GETARG_PATH_P_COPY (   n  )     DatumGetPathPCopy(PG_GETARG_DATUM(n))

Definition at line 160 of file geo_decls.h.

Referenced by path_add_pt(), path_close(), path_div_pt(), path_mul_pt(), path_open(), and path_sub_pt().

#define PG_GETARG_POINT_P (   n  )     DatumGetPointP(PG_GETARG_DATUM(n))
#define PG_GETARG_POLYGON_P (   n  )     DatumGetPolygonP(PG_GETARG_DATUM(n))
#define PG_GETARG_POLYGON_P_COPY (   n  )     DatumGetPolygonPCopy(PG_GETARG_DATUM(n))

Definition at line 177 of file geo_decls.h.

#define PG_RETURN_BOX_P (   x  )     return BoxPGetDatum(x)
#define PG_RETURN_CIRCLE_P (   x  )     return CirclePGetDatum(x)
#define PG_RETURN_LINE_P (   x  )     return LinePGetDatum(x)

Definition at line 166 of file geo_decls.h.

Referenced by line_construct_pp(), and line_in().

#define PG_RETURN_LSEG_P (   x  )     return LsegPGetDatum(x)

Definition at line 154 of file geo_decls.h.

Referenced by box_diagonal(), lseg_construct(), lseg_in(), and lseg_recv().

#define PG_RETURN_PATH_P (   x  )     return PathPGetDatum(x)
#define PG_RETURN_POINT_P (   x  )     return PointPGetDatum(x)
#define PG_RETURN_POLYGON_P (   x  )     return PolygonPGetDatum(x)

Definition at line 178 of file geo_decls.h.

Referenced by box_poly(), circle_poly(), path_poly(), poly_in(), and poly_recv().

#define PointPGetDatum (   X  )     PointerGetDatum(X)
#define PolygonPGetDatum (   X  )     PointerGetDatum(X)

Definition at line 175 of file geo_decls.h.

Referenced by gist_point_consistent(), and poly_center().


Function Documentation

Datum areajoinsel ( PG_FUNCTION_ARGS   ) 

Definition at line 54 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.005);
}

Datum areasel ( PG_FUNCTION_ARGS   ) 

Definition at line 48 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.005);
}

Datum box_above ( PG_FUNCTION_ARGS   ) 

Definition at line 645 of file geo_ops.c.

References FPgt, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));
}

Datum box_above_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 712 of file geo_ops.c.

References FPge, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
}

Datum box_add ( PG_FUNCTION_ARGS   ) 

Definition at line 4150 of file geo_ops.c.

References box_construct(), BOX::high, BOX::low, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, Point::x, and Point::y.

{
    BOX        *box = PG_GETARG_BOX_P(0);
    Point      *p = PG_GETARG_POINT_P(1);

    PG_RETURN_BOX_P(box_construct((box->high.x + p->x),
                                  (box->low.x + p->x),
                                  (box->high.y + p->y),
                                  (box->low.y + p->y)));
}

Datum box_area ( PG_FUNCTION_ARGS   ) 

Definition at line 777 of file geo_ops.c.

References box_ar(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

Datum box_below ( PG_FUNCTION_ARGS   ) 

Definition at line 622 of file geo_ops.c.

References FPlt, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));
}

Datum box_below_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 703 of file geo_ops.c.

References FPle, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
}

Datum box_center ( PG_FUNCTION_ARGS   ) 

Definition at line 830 of file geo_ops.c.

References box_cn(), palloc(), PG_GETARG_BOX_P, and PG_RETURN_POINT_P.

{
    BOX        *box = PG_GETARG_BOX_P(0);
    Point      *result = (Point *) palloc(sizeof(Point));

    box_cn(result, box);

    PG_RETURN_POINT_P(result);
}

Datum box_circle ( PG_FUNCTION_ARGS   ) 

Definition at line 5122 of file geo_ops.c.

References CIRCLE::center, BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_RETURN_CIRCLE_P, point_dt(), CIRCLE::radius, Point::x, and Point::y.

{
    BOX        *box = PG_GETARG_BOX_P(0);
    CIRCLE     *circle;

    circle = (CIRCLE *) palloc(sizeof(CIRCLE));

    circle->center.x = (box->high.x + box->low.x) / 2;
    circle->center.y = (box->high.y + box->low.y) / 2;

    circle->radius = point_dt(&circle->center, &box->high);

    PG_RETURN_CIRCLE_P(circle);
}

Datum box_contain ( PG_FUNCTION_ARGS   ) 

Definition at line 682 of file geo_ops.c.

References FPge, FPle, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by gist_box_leaf_consistent(), poly_contain(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPge(box1->high.x, box2->high.x) &&
                   FPle(box1->low.x, box2->low.x) &&
                   FPge(box1->high.y, box2->high.y) &&
                   FPle(box1->low.y, box2->low.y));
}

Datum box_contain_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 3210 of file geo_ops.c.

References BOX::high, BOX::low, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

{
    BOX        *box = PG_GETARG_BOX_P(0);
    Point      *pt = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x &&
                   pt->y <= box->high.y && pt->y >= box->low.y);
}

Datum box_contained ( PG_FUNCTION_ARGS   ) 

Definition at line 668 of file geo_ops.c.

References FPge, FPle, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by gist_box_leaf_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x) &&
                   FPge(box1->low.x, box2->low.x) &&
                   FPle(box1->high.y, box2->high.y) &&
                   FPge(box1->low.y, box2->low.y));
}

Datum box_diagonal ( PG_FUNCTION_ARGS   ) 

Definition at line 914 of file geo_ops.c.

References BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_RETURN_LSEG_P, and statlseg_construct().

{
    BOX        *box = PG_GETARG_BOX_P(0);
    LSEG       *result = (LSEG *) palloc(sizeof(LSEG));

    statlseg_construct(result, &box->high, &box->low);

    PG_RETURN_LSEG_P(result);
}

Datum box_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 813 of file geo_ops.c.

References box_cn(), HYPOT, PG_GETARG_BOX_P, PG_RETURN_FLOAT8, Point::x, and Point::y.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);
    Point       a,
                b;

    box_cn(&a, box1);
    box_cn(&b, box2);

    PG_RETURN_FLOAT8(HYPOT(a.x - b.x, a.y - b.y));
}

Datum box_div ( PG_FUNCTION_ARGS   ) 
Datum box_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 743 of file geo_ops.c.

References box_ar(), FPeq, PG_GETARG_BOX_P, and PG_RETURN_BOOL.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPeq(box_ar(box1), box_ar(box2)));
}

Datum box_ge ( PG_FUNCTION_ARGS   ) 

Definition at line 761 of file geo_ops.c.

References box_ar(), FPge, PG_GETARG_BOX_P, and PG_RETURN_BOOL.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPge(box_ar(box1), box_ar(box2)));
}

Datum box_gt ( PG_FUNCTION_ARGS   ) 

Definition at line 734 of file geo_ops.c.

References box_ar(), FPgt, PG_GETARG_BOX_P, and PG_RETURN_BOOL.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPgt(box_ar(box1), box_ar(box2)));
}

Datum box_height ( PG_FUNCTION_ARGS   ) 

Definition at line 801 of file geo_ops.c.

References BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_FLOAT8, and Point::y.

{
    BOX        *box = PG_GETARG_BOX_P(0);

    PG_RETURN_FLOAT8(box->high.y - box->low.y);
}

Datum box_in ( PG_FUNCTION_ARGS   ) 

Definition at line 379 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, FALSE, BOX::high, BOX::low, palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_BOX_P, Point::x, and Point::y.

{
    char       *str = PG_GETARG_CSTRING(0);
    BOX        *box = (BOX *) palloc(sizeof(BOX));
    int         isopen;
    char       *s;
    double      x,
                y;

    if ((!path_decode(FALSE, 2, str, &isopen, &s, &(box->high)))
        || (*s != '\0'))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type box: \"%s\"", str)));

    /* reorder corners if necessary... */
    if (box->high.x < box->low.x)
    {
        x = box->high.x;
        box->high.x = box->low.x;
        box->low.x = x;
    }
    if (box->high.y < box->low.y)
    {
        y = box->high.y;
        box->high.y = box->low.y;
        box->low.y = y;
    }

    PG_RETURN_BOX_P(box);
}

Datum box_intersect ( PG_FUNCTION_ARGS   ) 

Definition at line 889 of file geo_ops.c.

References box_ov(), BOX::high, BOX::low, Max, Min, palloc(), PG_GETARG_BOX_P, PG_RETURN_BOX_P, PG_RETURN_NULL, Point::x, and Point::y.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);
    BOX        *result;

    if (!box_ov(box1, box2))
        PG_RETURN_NULL();

    result = (BOX *) palloc(sizeof(BOX));

    result->high.x = Min(box1->high.x, box2->high.x);
    result->low.x = Max(box1->low.x, box2->low.x);
    result->high.y = Min(box1->high.y, box2->high.y);
    result->low.y = Max(box1->low.y, box2->low.y);

    PG_RETURN_BOX_P(result);
}

Datum box_le ( PG_FUNCTION_ARGS   ) 

Definition at line 752 of file geo_ops.c.

References box_ar(), FPle, PG_GETARG_BOX_P, and PG_RETURN_BOOL.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPle(box_ar(box1), box_ar(box2)));
}

Datum box_left ( PG_FUNCTION_ARGS   ) 

Definition at line 570 of file geo_ops.c.

References FPlt, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::x.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x));
}

Datum box_lt ( PG_FUNCTION_ARGS   ) 

Definition at line 725 of file geo_ops.c.

References box_ar(), FPlt, PG_GETARG_BOX_P, and PG_RETURN_BOOL.

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPlt(box_ar(box1), box_ar(box2)));
}

Datum box_mul ( PG_FUNCTION_ARGS   ) 
Datum box_out ( PG_FUNCTION_ARGS   ) 

Definition at line 414 of file geo_ops.c.

References BOX::high, path_encode(), PG_GETARG_BOX_P, and PG_RETURN_CSTRING.

{
    BOX        *box = PG_GETARG_BOX_P(0);

    PG_RETURN_CSTRING(path_encode(-1, 2, &(box->high)));
}

Datum box_overabove ( PG_FUNCTION_ARGS   ) 

Definition at line 657 of file geo_ops.c.

References FPge, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));
}

Datum box_overbelow ( PG_FUNCTION_ARGS   ) 

Definition at line 634 of file geo_ops.c.

References FPle, BOX::high, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::y.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));
}

Datum box_overlap ( PG_FUNCTION_ARGS   ) 

Definition at line 550 of file geo_ops.c.

References box_ov(), PG_GETARG_BOX_P, and PG_RETURN_BOOL.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(box_ov(box1, box2));
}

Datum box_overleft ( PG_FUNCTION_ARGS   ) 

Definition at line 585 of file geo_ops.c.

References FPle, BOX::high, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::x.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x));
}

Datum box_overright ( PG_FUNCTION_ARGS   ) 

Definition at line 611 of file geo_ops.c.

References FPge, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::x.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));
}

Datum box_poly ( PG_FUNCTION_ARGS   ) 

Definition at line 4445 of file geo_ops.c.

References POLYGON::boundbox, box_fill(), BOX::high, BOX::low, POLYGON::npts, offsetof, POLYGON::p, palloc(), PG_GETARG_BOX_P, PG_RETURN_POLYGON_P, SET_VARSIZE, Point::x, and Point::y.

{
    BOX        *box = PG_GETARG_BOX_P(0);
    POLYGON    *poly;
    int         size;

    /* map four corners of the box to a polygon */
    size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * 4;
    poly = (POLYGON *) palloc(size);

    SET_VARSIZE(poly, size);
    poly->npts = 4;

    poly->p[0].x = box->low.x;
    poly->p[0].y = box->low.y;
    poly->p[1].x = box->low.x;
    poly->p[1].y = box->high.y;
    poly->p[2].x = box->high.x;
    poly->p[2].y = box->high.y;
    poly->p[3].x = box->high.x;
    poly->p[3].y = box->low.y;

    box_fill(&poly->boundbox, box->high.x, box->low.x,
             box->high.y, box->low.y);

    PG_RETURN_POLYGON_P(poly);
}

Datum box_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 425 of file geo_ops.c.

References buf, BOX::high, BOX::low, palloc(), PG_GETARG_POINTER, PG_RETURN_BOX_P, pq_getmsgfloat8(), Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    BOX        *box;
    double      x,
                y;

    box = (BOX *) palloc(sizeof(BOX));

    box->high.x = pq_getmsgfloat8(buf);
    box->high.y = pq_getmsgfloat8(buf);
    box->low.x = pq_getmsgfloat8(buf);
    box->low.y = pq_getmsgfloat8(buf);

    /* reorder corners if necessary... */
    if (box->high.x < box->low.x)
    {
        x = box->high.x;
        box->high.x = box->low.x;
        box->low.x = x;
    }
    if (box->high.y < box->low.y)
    {
        y = box->high.y;
        box->high.y = box->low.y;
        box->low.y = y;
    }

    PG_RETURN_BOX_P(box);
}

Datum box_right ( PG_FUNCTION_ARGS   ) 

Definition at line 596 of file geo_ops.c.

References FPgt, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, and Point::x.

Referenced by gist_box_leaf_consistent(), and rtree_internal_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));
}

Datum box_same ( PG_FUNCTION_ARGS   ) 

Definition at line 536 of file geo_ops.c.

References FPeq, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by gist_box_leaf_consistent().

{
    BOX        *box1 = PG_GETARG_BOX_P(0);
    BOX        *box2 = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(FPeq(box1->high.x, box2->high.x) &&
                   FPeq(box1->low.x, box2->low.x) &&
                   FPeq(box1->high.y, box2->high.y) &&
                   FPeq(box1->low.y, box2->low.y));
}

Datum box_send ( PG_FUNCTION_ARGS   ) 
Datum box_sub ( PG_FUNCTION_ARGS   ) 

Definition at line 4162 of file geo_ops.c.

References box_construct(), BOX::high, BOX::low, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, Point::x, and Point::y.

{
    BOX        *box = PG_GETARG_BOX_P(0);
    Point      *p = PG_GETARG_POINT_P(1);

    PG_RETURN_BOX_P(box_construct((box->high.x - p->x),
                                  (box->low.x - p->x),
                                  (box->high.y - p->y),
                                  (box->low.y - p->y)));
}

Datum box_width ( PG_FUNCTION_ARGS   ) 

Definition at line 789 of file geo_ops.c.

References BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_FLOAT8, and Point::x.

{
    BOX        *box = PG_GETARG_BOX_P(0);

    PG_RETURN_FLOAT8(box->high.x - box->low.x);
}

Datum circle_above ( PG_FUNCTION_ARGS   ) 

Definition at line 4772 of file geo_ops.c.

References CIRCLE::center, FPgt, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPgt((circle1->center.y - circle1->radius),
                        (circle2->center.y + circle2->radius)));
}

Datum circle_add_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4888 of file geo_ops.c.

References CIRCLE::center, circle_copy(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, Point::x, and Point::y.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    Point      *point = PG_GETARG_POINT_P(1);
    CIRCLE     *result;

    result = circle_copy(circle);

    result->center.x += point->x;
    result->center.y += point->y;

    PG_RETURN_CIRCLE_P(result);
}

Datum circle_area ( PG_FUNCTION_ARGS   ) 

Definition at line 4965 of file geo_ops.c.

References circle_ar(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

Datum circle_below ( PG_FUNCTION_ARGS   ) 

Definition at line 4760 of file geo_ops.c.

References CIRCLE::center, FPlt, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPlt((circle1->center.y + circle1->radius),
                        (circle2->center.y - circle2->radius)));
}

Datum circle_box ( PG_FUNCTION_ARGS   ) 

Definition at line 5100 of file geo_ops.c.

References CIRCLE::center, BOX::high, BOX::low, palloc(), PG_GETARG_CIRCLE_P, PG_RETURN_BOX_P, CIRCLE::radius, Point::x, and Point::y.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    BOX        *box;
    double      delta;

    box = (BOX *) palloc(sizeof(BOX));

    delta = circle->radius / sqrt(2.0);

    box->high.x = circle->center.x + delta;
    box->low.x = circle->center.x - delta;
    box->high.y = circle->center.y + delta;
    box->low.y = circle->center.y - delta;

    PG_RETURN_BOX_P(box);
}

Datum circle_center ( PG_FUNCTION_ARGS   ) 

Definition at line 5057 of file geo_ops.c.

References CIRCLE::center, palloc(), PG_GETARG_CIRCLE_P, PG_RETURN_POINT_P, Point::x, and Point::y.

Referenced by poly_center().

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    Point      *result;

    result = (Point *) palloc(sizeof(Point));
    result->x = circle->center.x;
    result->y = circle->center.y;

    PG_RETURN_POINT_P(result);
}

Datum circle_contain ( PG_FUNCTION_ARGS   ) 

Definition at line 4748 of file geo_ops.c.

References CIRCLE::center, FPle, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, point_dt(), and CIRCLE::radius.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle2->radius), circle1->radius));
}

Datum circle_contain_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 5014 of file geo_ops.c.

References CIRCLE::center, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_dt().

Referenced by gist_point_consistent().

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    Point      *point = PG_GETARG_POINT_P(1);
    double      d;

    d = point_dt(&circle->center, point);
    PG_RETURN_BOOL(d <= circle->radius);
}

Datum circle_contained ( PG_FUNCTION_ARGS   ) 

Definition at line 4737 of file geo_ops.c.

References CIRCLE::center, FPle, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, point_dt(), and CIRCLE::radius.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle1->radius), circle2->radius));
}

Datum circle_diameter ( PG_FUNCTION_ARGS   ) 

Definition at line 4976 of file geo_ops.c.

References PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, and CIRCLE::radius.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);

    PG_RETURN_FLOAT8(2 * circle->radius);
}

Datum circle_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 4999 of file geo_ops.c.

References CIRCLE::center, PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, point_dt(), and CIRCLE::radius.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);
    float8      result;

    result = point_dt(&circle1->center, &circle2->center)
        - (circle1->radius + circle2->radius);
    if (result < 0)
        result = 0;
    PG_RETURN_FLOAT8(result);
}

Datum circle_div_pt ( PG_FUNCTION_ARGS   ) 
Datum circle_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 4812 of file geo_ops.c.

References circle_ar(), FPeq, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPeq(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_ge ( PG_FUNCTION_ARGS   ) 

Definition at line 4857 of file geo_ops.c.

References circle_ar(), FPge, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPge(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_gt ( PG_FUNCTION_ARGS   ) 

Definition at line 4839 of file geo_ops.c.

References circle_ar(), FPgt, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPgt(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_in ( PG_FUNCTION_ARGS   ) 

Definition at line 4518 of file geo_ops.c.

References CIRCLE::center, DELIM, ereport, errcode(), errmsg(), ERROR, LDELIM, LDELIM_C, pair_decode(), palloc(), PG_GETARG_CSTRING, PG_RETURN_CIRCLE_P, CIRCLE::radius, RDELIM, single_decode(), Point::x, and Point::y.

{
    char       *str = PG_GETARG_CSTRING(0);
    CIRCLE     *circle;
    char       *s,
               *cp;
    int         depth = 0;

    circle = (CIRCLE *) palloc(sizeof(CIRCLE));

    s = str;
    while (isspace((unsigned char) *s))
        s++;
    if ((*s == LDELIM_C) || (*s == LDELIM))
    {
        depth++;
        cp = (s + 1);
        while (isspace((unsigned char) *cp))
            cp++;
        if (*cp == LDELIM)
            s = cp;
    }

    if (!pair_decode(s, &circle->center.x, &circle->center.y, &s))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
               errmsg("invalid input syntax for type circle: \"%s\"", str)));

    if (*s == DELIM)
        s++;
    while (isspace((unsigned char) *s))
        s++;

    if ((!single_decode(s, &circle->radius, &s)) || (circle->radius < 0))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
               errmsg("invalid input syntax for type circle: \"%s\"", str)));

    while (depth > 0)
    {
        if ((*s == RDELIM)
            || ((*s == RDELIM_C) && (depth == 1)))
        {
            depth--;
            s++;
            while (isspace((unsigned char) *s))
                s++;
        }
        else
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
               errmsg("invalid input syntax for type circle: \"%s\"", str)));
    }

    if (*s != '\0')
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
               errmsg("invalid input syntax for type circle: \"%s\"", str)));

    PG_RETURN_CIRCLE_P(circle);
}

Datum circle_le ( PG_FUNCTION_ARGS   ) 

Definition at line 4848 of file geo_ops.c.

References circle_ar(), FPle, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_left ( PG_FUNCTION_ARGS   ) 

Definition at line 4700 of file geo_ops.c.

References CIRCLE::center, FPlt, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPlt((circle1->center.x + circle1->radius),
                        (circle2->center.x - circle2->radius)));
}

Datum circle_lt ( PG_FUNCTION_ARGS   ) 

Definition at line 4830 of file geo_ops.c.

References circle_ar(), FPlt, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPlt(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_mul_pt ( PG_FUNCTION_ARGS   ) 
Datum circle_ne ( PG_FUNCTION_ARGS   ) 

Definition at line 4821 of file geo_ops.c.

References circle_ar(), FPne, PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPne(circle_ar(circle1), circle_ar(circle2)));
}

Datum circle_out ( PG_FUNCTION_ARGS   ) 

Definition at line 4583 of file geo_ops.c.

References CIRCLE::center, ereport, errcode(), errmsg(), ERROR, P_MAXLEN, pair_encode(), palloc(), PG_GETARG_CIRCLE_P, PG_RETURN_CSTRING, CIRCLE::radius, single_encode(), Point::x, and Point::y.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    char       *result;
    char       *cp;

    result = palloc(2 * P_MAXLEN + 6);

    cp = result;
    *cp++ = LDELIM_C;
    *cp++ = LDELIM;
    if (!pair_encode(circle->center.x, circle->center.y, cp))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("could not format \"circle\" value")));

    cp += strlen(cp);
    *cp++ = RDELIM;
    *cp++ = DELIM;
    if (!single_encode(circle->radius, cp))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("could not format \"circle\" value")));

    cp += strlen(cp);
    *cp++ = RDELIM_C;
    *cp = '\0';

    PG_RETURN_CSTRING(result);
}

Datum circle_overabove ( PG_FUNCTION_ARGS   ) 

Definition at line 4798 of file geo_ops.c.

References CIRCLE::center, FPge, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPge((circle1->center.y - circle1->radius),
                        (circle2->center.y - circle2->radius)));
}

Datum circle_overbelow ( PG_FUNCTION_ARGS   ) 

Definition at line 4785 of file geo_ops.c.

References CIRCLE::center, FPle, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle((circle1->center.y + circle1->radius),
                        (circle2->center.y + circle2->radius)));
}

Datum circle_overlap ( PG_FUNCTION_ARGS   ) 

Definition at line 4675 of file geo_ops.c.

References CIRCLE::center, FPle, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, point_dt(), and CIRCLE::radius.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center),
                        circle1->radius + circle2->radius));
}

Datum circle_overleft ( PG_FUNCTION_ARGS   ) 

Definition at line 4688 of file geo_ops.c.

References CIRCLE::center, FPle, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPle((circle1->center.x + circle1->radius),
                        (circle2->center.x + circle2->radius)));
}

Datum circle_overright ( PG_FUNCTION_ARGS   ) 

Definition at line 4725 of file geo_ops.c.

References CIRCLE::center, FPge, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPge((circle1->center.x - circle1->radius),
                        (circle2->center.x - circle2->radius)));
}

Datum circle_poly ( PG_FUNCTION_ARGS   ) 

Definition at line 5139 of file geo_ops.c.

References CIRCLE::center, ereport, errcode(), errmsg(), ERROR, FPzero, i, make_bound_box(), POLYGON::npts, offsetof, POLYGON::p, palloc0(), PG_GETARG_CIRCLE_P, PG_GETARG_INT32, PG_RETURN_POLYGON_P, CIRCLE::radius, SET_VARSIZE, Point::x, and Point::y.

{
    int32       npts = PG_GETARG_INT32(0);
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(1);
    POLYGON    *poly;
    int         base_size,
                size;
    int         i;
    double      angle;
    double      anglestep;

    if (FPzero(circle->radius))
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
               errmsg("cannot convert circle with radius zero to polygon")));

    if (npts < 2)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("must request at least 2 points")));

    base_size = sizeof(poly->p[0]) * npts;
    size = offsetof(POLYGON, p[0]) +base_size;

    /* Check for integer overflow */
    if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
        ereport(ERROR,
                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                 errmsg("too many points requested")));

    poly = (POLYGON *) palloc0(size);   /* zero any holes */
    SET_VARSIZE(poly, size);
    poly->npts = npts;

    anglestep = (2.0 * M_PI) / npts;

    for (i = 0; i < npts; i++)
    {
        angle = i * anglestep;
        poly->p[i].x = circle->center.x - (circle->radius * cos(angle));
        poly->p[i].y = circle->center.y + (circle->radius * sin(angle));
    }

    make_bound_box(poly);

    PG_RETURN_POLYGON_P(poly);
}

Datum circle_radius ( PG_FUNCTION_ARGS   ) 

Definition at line 4987 of file geo_ops.c.

References PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, and CIRCLE::radius.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);

    PG_RETURN_FLOAT8(circle->radius);
}

Datum circle_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 4618 of file geo_ops.c.

References buf, CIRCLE::center, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_POINTER, PG_RETURN_CIRCLE_P, pq_getmsgfloat8(), CIRCLE::radius, Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    CIRCLE     *circle;

    circle = (CIRCLE *) palloc(sizeof(CIRCLE));

    circle->center.x = pq_getmsgfloat8(buf);
    circle->center.y = pq_getmsgfloat8(buf);
    circle->radius = pq_getmsgfloat8(buf);

    if (circle->radius < 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("invalid radius in external \"circle\" value")));

    PG_RETURN_CIRCLE_P(circle);
}

Datum circle_right ( PG_FUNCTION_ARGS   ) 

Definition at line 4712 of file geo_ops.c.

References CIRCLE::center, FPgt, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPgt((circle1->center.x - circle1->radius),
                        (circle2->center.x + circle2->radius)));
}

Datum circle_same ( PG_FUNCTION_ARGS   ) 

Definition at line 4662 of file geo_ops.c.

References CIRCLE::center, FPeq, PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, Point::x, and Point::y.

{
    CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
    CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);

    PG_RETURN_BOOL(FPeq(circle1->radius, circle2->radius) &&
                   FPeq(circle1->center.x, circle2->center.x) &&
                   FPeq(circle1->center.y, circle2->center.y));
}

Datum circle_send ( PG_FUNCTION_ARGS   ) 
Datum circle_sub_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4903 of file geo_ops.c.

References CIRCLE::center, circle_copy(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, Point::x, and Point::y.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    Point      *point = PG_GETARG_POINT_P(1);
    CIRCLE     *result;

    result = circle_copy(circle);

    result->center.x -= point->x;
    result->center.y -= point->y;

    PG_RETURN_CIRCLE_P(result);
}

Datum close_lb ( PG_FUNCTION_ARGS   ) 

Definition at line 3146 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_BOX_P, PG_GETARG_LINE_P, and PG_RETURN_NULL.

{
#ifdef NOT_USED
    LINE       *line = PG_GETARG_LINE_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
#endif

    /* think about this one for a while */
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("function \"close_lb\" not implemented")));

    PG_RETURN_NULL();
}

Datum close_ls ( PG_FUNCTION_ARGS   ) 

Definition at line 3063 of file geo_ops.c.

References dist_pl_internal(), interpt_sl(), LSEG::p, PG_GETARG_LINE_P, PG_GETARG_LSEG_P, PG_RETURN_POINT_P, and point_copy().

{
    LINE       *line = PG_GETARG_LINE_P(0);
    LSEG       *lseg = PG_GETARG_LSEG_P(1);
    Point      *result;
    float8      d1,
                d2;

    result = interpt_sl(lseg, line);
    if (result)
        PG_RETURN_POINT_P(result);

    d1 = dist_pl_internal(&lseg->p[0], line);
    d2 = dist_pl_internal(&lseg->p[1], line);
    if (d1 < d2)
        result = point_copy(&lseg->p[0]);
    else
        result = point_copy(&lseg->p[1]);

    PG_RETURN_POINT_P(result);
}

Datum close_lseg ( PG_FUNCTION_ARGS   ) 

Definition at line 2927 of file geo_ops.c.

References close_ps(), DatumGetPointP, DirectFunctionCall2, dist_ps_internal(), LsegPGetDatum, NULL, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_POINT_P, point_copy(), and PointPGetDatum.

Referenced by close_sb().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);
    Point      *result = NULL;
    Point       point;
    double      dist;
    double      d;

    d = dist_ps_internal(&l1->p[0], l2);
    dist = d;
    memcpy(&point, &l1->p[0], sizeof(Point));

    if ((d = dist_ps_internal(&l1->p[1], l2)) < dist)
    {
        dist = d;
        memcpy(&point, &l1->p[1], sizeof(Point));
    }

    if (dist_ps_internal(&l2->p[0], l1) < dist)
    {
        result = DatumGetPointP(DirectFunctionCall2(close_ps,
                                                    PointPGetDatum(&l2->p[0]),
                                                    LsegPGetDatum(l1)));
        memcpy(&point, result, sizeof(Point));
        result = DatumGetPointP(DirectFunctionCall2(close_ps,
                                                    PointPGetDatum(&point),
                                                    LsegPGetDatum(l2)));
    }

    if (dist_ps_internal(&l2->p[1], l1) < dist)
    {
        result = DatumGetPointP(DirectFunctionCall2(close_ps,
                                                    PointPGetDatum(&l2->p[1]),
                                                    LsegPGetDatum(l1)));
        memcpy(&point, result, sizeof(Point));
        result = DatumGetPointP(DirectFunctionCall2(close_ps,
                                                    PointPGetDatum(&point),
                                                    LsegPGetDatum(l2)));
    }

    if (result == NULL)
        result = point_copy(&point);

    PG_RETURN_POINT_P(result);
}

Datum close_pb ( PG_FUNCTION_ARGS   ) 

Definition at line 2978 of file geo_ops.c.

References BoxPGetDatum, close_ps(), DatumGetBool, DirectFunctionCall2, dist_ps_internal(), BOX::high, BOX::low, LsegPGetDatum, on_pb(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_DATUM, PG_RETURN_POINT_P, PointPGetDatum, statlseg_construct(), Point::x, and Point::y.

Referenced by dist_pb().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
    LSEG        lseg,
                seg;
    Point       point;
    double      dist,
                d;

    if (DatumGetBool(DirectFunctionCall2(on_pb,
                                         PointPGetDatum(pt),
                                         BoxPGetDatum(box))))
        PG_RETURN_POINT_P(pt);

    /* pairwise check lseg distances */
    point.x = box->low.x;
    point.y = box->high.y;
    statlseg_construct(&lseg, &box->low, &point);
    dist = dist_ps_internal(pt, &lseg);

    statlseg_construct(&seg, &box->high, &point);
    if ((d = dist_ps_internal(pt, &seg)) < dist)
    {
        dist = d;
        memcpy(&lseg, &seg, sizeof(lseg));
    }

    point.x = box->high.x;
    point.y = box->low.y;
    statlseg_construct(&seg, &box->low, &point);
    if ((d = dist_ps_internal(pt, &seg)) < dist)
    {
        dist = d;
        memcpy(&lseg, &seg, sizeof(lseg));
    }

    statlseg_construct(&seg, &box->high, &point);
    if ((d = dist_ps_internal(pt, &seg)) < dist)
    {
        dist = d;
        memcpy(&lseg, &seg, sizeof(lseg));
    }

    PG_RETURN_DATUM(DirectFunctionCall2(close_ps,
                                        PointPGetDatum(pt),
                                        LsegPGetDatum(&lseg)));
}

Datum close_pl ( PG_FUNCTION_ARGS   ) 

Definition at line 2762 of file geo_ops.c.

References LINE::A, Assert, LINE::B, LINE::C, FPeq, FPzero, line_construct_pm(), line_interpt_internal(), LINE::m, NULL, palloc(), PG_GETARG_LINE_P, PG_GETARG_POINT_P, PG_RETURN_POINT_P, Point::x, and Point::y.

{
    Point      *pt = PG_GETARG_POINT_P(0);
    LINE       *line = PG_GETARG_LINE_P(1);
    Point      *result;
    LINE       *tmp;
    double      invm;

    result = (Point *) palloc(sizeof(Point));

#ifdef NOT_USED
    if (FPeq(line->A, -1.0) && FPzero(line->B))
    {                           /* vertical */
    }
#endif
    if (FPzero(line->B))        /* vertical? */
    {
        result->x = line->C;
        result->y = pt->y;
        PG_RETURN_POINT_P(result);
    }
    if (FPzero(line->A))        /* horizontal? */
    {
        result->x = pt->x;
        result->y = line->C;
        PG_RETURN_POINT_P(result);
    }
    /* drop a perpendicular and find the intersection point */
#ifdef NOT_USED
    invm = -1.0 / line->m;
#endif
    /* invert and flip the sign on the slope to get a perpendicular */
    invm = line->B / line->A;
    tmp = line_construct_pm(pt, invm);
    result = line_interpt_internal(tmp, line);
    Assert(result != NULL);
    PG_RETURN_POINT_P(result);
}

Datum close_ps ( PG_FUNCTION_ARGS   ) 

Definition at line 2813 of file geo_ops.c.

References LINE::A, Assert, LINE::B, LINE::C, FPeq, interpt_sl(), line_construct_pm(), LINE::m, NULL, LSEG::p, palloc(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, PG_RETURN_POINT_P, point_copy(), point_sl(), Point::x, and Point::y.

Referenced by close_lseg(), close_pb(), and close_sb().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    LSEG       *lseg = PG_GETARG_LSEG_P(1);
    Point      *result = NULL;
    LINE       *tmp;
    double      invm;
    int         xh,
                yh;

#ifdef GEODEBUG
    printf("close_sp:pt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f  lseg(1).x %f lseg(1).y %f\n",
           pt->x, pt->y, lseg->p[0].x, lseg->p[0].y,
           lseg->p[1].x, lseg->p[1].y);
#endif

    /* xh (or yh) is the index of upper x( or y) end point of lseg */
    /* !xh (or !yh) is the index of lower x( or y) end point of lseg */
    xh = lseg->p[0].x < lseg->p[1].x;
    yh = lseg->p[0].y < lseg->p[1].y;

    if (FPeq(lseg->p[0].x, lseg->p[1].x))       /* vertical? */
    {
#ifdef GEODEBUG
        printf("close_ps- segment is vertical\n");
#endif
        /* first check if point is below or above the entire lseg. */
        if (pt->y < lseg->p[!yh].y)
            result = point_copy(&lseg->p[!yh]); /* below the lseg */
        else if (pt->y > lseg->p[yh].y)
            result = point_copy(&lseg->p[yh]);  /* above the lseg */
        if (result != NULL)
            PG_RETURN_POINT_P(result);

        /* point lines along (to left or right) of the vertical lseg. */

        result = (Point *) palloc(sizeof(Point));
        result->x = lseg->p[0].x;
        result->y = pt->y;
        PG_RETURN_POINT_P(result);
    }
    else if (FPeq(lseg->p[0].y, lseg->p[1].y))  /* horizontal? */
    {
#ifdef GEODEBUG
        printf("close_ps- segment is horizontal\n");
#endif
        /* first check if point is left or right of the entire lseg. */
        if (pt->x < lseg->p[!xh].x)
            result = point_copy(&lseg->p[!xh]); /* left of the lseg */
        else if (pt->x > lseg->p[xh].x)
            result = point_copy(&lseg->p[xh]);  /* right of the lseg */
        if (result != NULL)
            PG_RETURN_POINT_P(result);

        /* point lines along (at top or below) the horiz. lseg. */
        result = (Point *) palloc(sizeof(Point));
        result->x = pt->x;
        result->y = lseg->p[0].y;
        PG_RETURN_POINT_P(result);
    }

    /*
     * vert. and horiz. cases are down, now check if the closest point is one
     * of the end points or someplace on the lseg.
     */

    invm = -1.0 / point_sl(&(lseg->p[0]), &(lseg->p[1]));
    tmp = line_construct_pm(&lseg->p[!yh], invm);       /* lower edge of the
                                                         * "band" */
    if (pt->y < (tmp->A * pt->x + tmp->C))
    {                           /* we are below the lower edge */
        result = point_copy(&lseg->p[!yh]);     /* below the lseg, take lower
                                                 * end pt */
#ifdef GEODEBUG
        printf("close_ps below: tmp A %f  B %f   C %f    m %f\n",
               tmp->A, tmp->B, tmp->C, tmp->m);
#endif
        PG_RETURN_POINT_P(result);
    }
    tmp = line_construct_pm(&lseg->p[yh], invm);        /* upper edge of the
                                                         * "band" */
    if (pt->y > (tmp->A * pt->x + tmp->C))
    {                           /* we are below the lower edge */
        result = point_copy(&lseg->p[yh]);      /* above the lseg, take higher
                                                 * end pt */
#ifdef GEODEBUG
        printf("close_ps above: tmp A %f  B %f   C %f    m %f\n",
               tmp->A, tmp->B, tmp->C, tmp->m);
#endif
        PG_RETURN_POINT_P(result);
    }

    /*
     * at this point the "normal" from point will hit lseg. The closet point
     * will be somewhere on the lseg
     */
    tmp = line_construct_pm(pt, invm);
#ifdef GEODEBUG
    printf("close_ps- tmp A %f  B %f   C %f    m %f\n",
           tmp->A, tmp->B, tmp->C, tmp->m);
#endif
    result = interpt_sl(lseg, tmp);
    Assert(result != NULL);
#ifdef GEODEBUG
    printf("close_ps- result.x %f  result.y %f\n", result->x, result->y);
#endif
    PG_RETURN_POINT_P(result);
}

Datum close_sb ( PG_FUNCTION_ARGS   ) 

Definition at line 3089 of file geo_ops.c.

References box_cn(), BoxPGetDatum, close_lseg(), close_ps(), DatumGetBool, DirectFunctionCall2, BOX::high, inter_sb(), BOX::low, lseg_dt(), LsegPGetDatum, PG_GETARG_BOX_P, PG_GETARG_LSEG_P, PG_RETURN_DATUM, PointPGetDatum, statlseg_construct(), Point::x, and Point::y.

Referenced by dist_sb().

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
    Point       point;
    LSEG        bseg,
                seg;
    double      dist,
                d;

    /* segment intersects box? then just return closest point to center */
    if (DatumGetBool(DirectFunctionCall2(inter_sb,
                                         LsegPGetDatum(lseg),
                                         BoxPGetDatum(box))))
    {
        box_cn(&point, box);
        PG_RETURN_DATUM(DirectFunctionCall2(close_ps,
                                            PointPGetDatum(&point),
                                            LsegPGetDatum(lseg)));
    }

    /* pairwise check lseg distances */
    point.x = box->low.x;
    point.y = box->high.y;
    statlseg_construct(&bseg, &box->low, &point);
    dist = lseg_dt(lseg, &bseg);

    statlseg_construct(&seg, &box->high, &point);
    if ((d = lseg_dt(lseg, &seg)) < dist)
    {
        dist = d;
        memcpy(&bseg, &seg, sizeof(bseg));
    }

    point.x = box->high.x;
    point.y = box->low.y;
    statlseg_construct(&seg, &box->low, &point);
    if ((d = lseg_dt(lseg, &seg)) < dist)
    {
        dist = d;
        memcpy(&bseg, &seg, sizeof(bseg));
    }

    statlseg_construct(&seg, &box->high, &point);
    if ((d = lseg_dt(lseg, &seg)) < dist)
    {
        dist = d;
        memcpy(&bseg, &seg, sizeof(bseg));
    }

    /* OK, we now have the closest line segment on the box boundary */
    PG_RETURN_DATUM(DirectFunctionCall2(close_lseg,
                                        LsegPGetDatum(lseg),
                                        LsegPGetDatum(&bseg)));
}

Datum close_sl ( PG_FUNCTION_ARGS   ) 

Definition at line 3037 of file geo_ops.c.

References dist_pl_internal(), interpt_sl(), LSEG::p, PG_GETARG_LINE_P, PG_GETARG_LSEG_P, PG_RETURN_POINT_P, and point_copy().

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    LINE       *line = PG_GETARG_LINE_P(1);
    Point      *result;
    float8      d1,
                d2;

    result = interpt_sl(lseg, line);
    if (result)
        PG_RETURN_POINT_P(result);

    d1 = dist_pl_internal(&lseg->p[0], line);
    d2 = dist_pl_internal(&lseg->p[1], line);
    if (d1 < d2)
        result = point_copy(&lseg->p[0]);
    else
        result = point_copy(&lseg->p[1]);

    PG_RETURN_POINT_P(result);
}

Datum construct_point ( PG_FUNCTION_ARGS   ) 
Datum contjoinsel ( PG_FUNCTION_ARGS   ) 

Definition at line 92 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.001);
}

Datum contsel ( PG_FUNCTION_ARGS   ) 

Definition at line 86 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.001);
}

Datum cr_circle ( PG_FUNCTION_ARGS   ) 

Definition at line 5084 of file geo_ops.c.

References CIRCLE::center, palloc(), PG_GETARG_FLOAT8, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, CIRCLE::radius, Point::x, and Point::y.

{
    Point      *center = PG_GETARG_POINT_P(0);
    float8      radius = PG_GETARG_FLOAT8(1);
    CIRCLE     *result;

    result = (CIRCLE *) palloc(sizeof(CIRCLE));

    result->center.x = center->x;
    result->center.y = center->y;
    result->radius = radius;

    PG_RETURN_CIRCLE_P(result);
}

Datum dist_cpoly ( PG_FUNCTION_ARGS   ) 

Definition at line 2650 of file geo_ops.c.

References CIRCLE::center, dist_ps_internal(), i, POLYGON::npts, LSEG::p, POLYGON::p, PG_GETARG_CIRCLE_P, PG_GETARG_POLYGON_P, PG_RETURN_FLOAT8, point_inside(), CIRCLE::radius, Point::x, and Point::y.

{
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(0);
    POLYGON    *poly = PG_GETARG_POLYGON_P(1);
    float8      result;
    float8      d;
    int         i;
    LSEG        seg;

    if (point_inside(&(circle->center), poly->npts, poly->p) != 0)
    {
#ifdef GEODEBUG
        printf("dist_cpoly- center inside of polygon\n");
#endif
        PG_RETURN_FLOAT8(0.0);
    }

    /* initialize distance with segment between first and last points */
    seg.p[0].x = poly->p[0].x;
    seg.p[0].y = poly->p[0].y;
    seg.p[1].x = poly->p[poly->npts - 1].x;
    seg.p[1].y = poly->p[poly->npts - 1].y;
    result = dist_ps_internal(&circle->center, &seg);
#ifdef GEODEBUG
    printf("dist_cpoly- segment 0/n distance is %f\n", result);
#endif

    /* check distances for other segments */
    for (i = 0; (i < poly->npts - 1); i++)
    {
        seg.p[0].x = poly->p[i].x;
        seg.p[0].y = poly->p[i].y;
        seg.p[1].x = poly->p[i + 1].x;
        seg.p[1].y = poly->p[i + 1].y;
        d = dist_ps_internal(&circle->center, &seg);
#ifdef GEODEBUG
        printf("dist_cpoly- segment %d distance is %f\n", (i + 1), d);
#endif
        if (d < result)
            result = d;
    }

    result -= circle->radius;
    if (result < 0)
        result = 0;

    PG_RETURN_FLOAT8(result);
}

Datum dist_lb ( PG_FUNCTION_ARGS   ) 

Definition at line 2633 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_BOX_P, PG_GETARG_LINE_P, and PG_RETURN_NULL.

{
#ifdef NOT_USED
    LINE       *line = PG_GETARG_LINE_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
#endif

    /* need to think about this one for a while */
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("function \"dist_lb\" not implemented")));

    PG_RETURN_NULL();
}

Datum dist_pb ( PG_FUNCTION_ARGS   ) 
Datum dist_pc ( PG_FUNCTION_ARGS   ) 

Definition at line 5041 of file geo_ops.c.

References CIRCLE::center, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, point_dt(), and CIRCLE::radius.

{
    Point      *point = PG_GETARG_POINT_P(0);
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(1);
    float8      result;

    result = point_dt(point, &circle->center) - circle->radius;
    if (result < 0)
        result = 0;
    PG_RETURN_FLOAT8(result);
}

Datum dist_pl ( PG_FUNCTION_ARGS   ) 
Datum dist_ppath ( PG_FUNCTION_ARGS   ) 

Definition at line 2520 of file geo_ops.c.

References Assert, PATH::closed, dist_ps_internal(), i, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, point_dt(), and statlseg_construct().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    PATH       *path = PG_GETARG_PATH_P(1);
    float8      result = 0.0;   /* keep compiler quiet */
    bool        have_min = false;
    float8      tmp;
    int         i;
    LSEG        lseg;

    switch (path->npts)
    {
        case 0:
            /* no points in path? then result is undefined... */
            PG_RETURN_NULL();
        case 1:
            /* one point in path? then get distance between two points... */
            result = point_dt(pt, &path->p[0]);
            break;
        default:
            /* make sure the path makes sense... */
            Assert(path->npts > 1);

            /*
             * the distance from a point to a path is the smallest distance
             * from the point to any of its constituent segments.
             */
            for (i = 0; i < path->npts; i++)
            {
                int         iprev;

                if (i > 0)
                    iprev = i - 1;
                else
                {
                    if (!path->closed)
                        continue;
                    iprev = path->npts - 1;     /* include the closure segment */
                }

                statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
                tmp = dist_ps_internal(pt, &lseg);
                if (!have_min || tmp < result)
                {
                    result = tmp;
                    have_min = true;
                }
            }
            break;
    }
    PG_RETURN_FLOAT8(result);
}

Datum dist_ps ( PG_FUNCTION_ARGS   ) 
Datum dist_sb ( PG_FUNCTION_ARGS   ) 
Datum dist_sl ( PG_FUNCTION_ARGS   ) 

Definition at line 2591 of file geo_ops.c.

References dist_pl_internal(), has_interpt_sl(), LSEG::p, PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    LINE       *line = PG_GETARG_LINE_P(1);
    float8      result,
                d2;

    if (has_interpt_sl(lseg, line))
        result = 0.0;
    else
    {
        result = dist_pl_internal(&lseg->p[0], line);
        d2 = dist_pl_internal(&lseg->p[1], line);
        /* XXX shouldn't we take the min not max? */
        if (d2 > result)
            result = d2;
    }

    PG_RETURN_FLOAT8(result);
}

Datum gist_box_compress ( PG_FUNCTION_ARGS   ) 

Definition at line 137 of file gistproc.c.

References PG_GETARG_POINTER, and PG_RETURN_POINTER.

Datum gist_box_consistent ( PG_FUNCTION_ARGS   ) 

Definition at line 59 of file gistproc.c.

References DatumGetBoxP, FALSE, gist_box_leaf_consistent(), GIST_LEAF, GISTENTRY::key, NULL, PG_GETARG_BOX_P, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_BOOL, and rtree_internal_consistent().

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    BOX        *query = PG_GETARG_BOX_P(1);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

    /* Oid      subtype = PG_GETARG_OID(3); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);

    /* All cases served by this function are exact */
    *recheck = false;

    if (DatumGetBoxP(entry->key) == NULL || query == NULL)
        PG_RETURN_BOOL(FALSE);

    /*
     * if entry is not leaf, use rtree_internal_consistent, else use
     * gist_box_leaf_consistent
     */
    if (GIST_LEAF(entry))
        PG_RETURN_BOOL(gist_box_leaf_consistent(DatumGetBoxP(entry->key),
                                                query,
                                                strategy));
    else
        PG_RETURN_BOOL(rtree_internal_consistent(DatumGetBoxP(entry->key),
                                                 query,
                                                 strategy));
}

Datum gist_box_decompress ( PG_FUNCTION_ARGS   ) 

Definition at line 149 of file gistproc.c.

References PG_GETARG_POINTER, and PG_RETURN_POINTER.

Datum gist_box_penalty ( PG_FUNCTION_ARGS   ) 

Definition at line 160 of file gistproc.c.

References DatumGetBoxP, GISTENTRY::key, PG_GETARG_POINTER, PG_RETURN_POINTER, rt_box_union(), and size_box().

{
    GISTENTRY  *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
    GISTENTRY  *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
    float      *result = (float *) PG_GETARG_POINTER(2);
    BOX        *origbox = DatumGetBoxP(origentry->key);
    BOX        *newbox = DatumGetBoxP(newentry->key);
    BOX         unionbox;

    rt_box_union(&unionbox, origbox, newbox);
    *result = (float) (size_box(&unionbox) - size_box(origbox));
    PG_RETURN_POINTER(result);
}

Datum gist_box_picksplit ( PG_FUNCTION_ARGS   ) 

Definition at line 489 of file gistproc.c.

References Abs, adjustBox(), Assert, ConsiderSplitContext::boundingBox, box_penalty(), common_entry_cmp(), DatumGetBoxP, CommonEntry::delta, ConsiderSplitContext::dim, ConsiderSplitContext::entriesCount, fallbackSplit(), ConsiderSplitContext::first, FirstOffsetNumber, g_box_consider_split(), BOX::high, i, CommonEntry::index, interval_cmp_lower(), interval_cmp_upper(), GISTENTRY::key, ConsiderSplitContext::leftUpper, LIMIT_RATIO, BOX::low, lower(), SplitInterval::lower, Max, Min, GistEntryVector::n, OffsetNumberNext, palloc(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, PLACE_LEFT, PLACE_RIGHT, PointerGetDatum, qsort, ConsiderSplitContext::rightLower, GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, upper(), SplitInterval::upper, GistEntryVector::vector, Point::x, and Point::y.

{
    GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
    GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
    OffsetNumber i,
                maxoff;
    ConsiderSplitContext context;
    BOX        *box,
               *leftBox,
               *rightBox;
    int         dim,
                commonEntriesCount;
    SplitInterval *intervalsLower,
               *intervalsUpper;
    CommonEntry *commonEntries;
    int         nentries;

    memset(&context, 0, sizeof(ConsiderSplitContext));

    maxoff = entryvec->n - 1;
    nentries = context.entriesCount = maxoff - FirstOffsetNumber + 1;

    /* Allocate arrays for intervals along axes */
    intervalsLower = (SplitInterval *) palloc(nentries * sizeof(SplitInterval));
    intervalsUpper = (SplitInterval *) palloc(nentries * sizeof(SplitInterval));

    /*
     * Calculate the overall minimum bounding box over all the entries.
     */
    for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
    {
        box = DatumGetBoxP(entryvec->vector[i].key);
        if (i == FirstOffsetNumber)
            context.boundingBox = *box;
        else
            adjustBox(&context.boundingBox, box);
    }

    /*
     * Iterate over axes for optimal split searching.
     */
    context.first = true;       /* nothing selected yet */
    for (dim = 0; dim < 2; dim++)
    {
        double      leftUpper,
                    rightLower;
        int         i1,
                    i2;

        /* Project each entry as an interval on the selected axis. */
        for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
        {
            box = DatumGetBoxP(entryvec->vector[i].key);
            if (dim == 0)
            {
                intervalsLower[i - FirstOffsetNumber].lower = box->low.x;
                intervalsLower[i - FirstOffsetNumber].upper = box->high.x;
            }
            else
            {
                intervalsLower[i - FirstOffsetNumber].lower = box->low.y;
                intervalsLower[i - FirstOffsetNumber].upper = box->high.y;
            }
        }

        /*
         * Make two arrays of intervals: one sorted by lower bound and another
         * sorted by upper bound.
         */
        memcpy(intervalsUpper, intervalsLower,
               sizeof(SplitInterval) * nentries);
        qsort(intervalsLower, nentries, sizeof(SplitInterval),
              interval_cmp_lower);
        qsort(intervalsUpper, nentries, sizeof(SplitInterval),
              interval_cmp_upper);

        /*----
         * The goal is to form a left and right interval, so that every entry
         * interval is contained by either left or right interval (or both).
         *
         * For example, with the intervals (0,1), (1,3), (2,3), (2,4):
         *
         * 0 1 2 3 4
         * +-+
         *   +---+
         *     +-+
         *     +---+
         *
         * The left and right intervals are of the form (0,a) and (b,4).
         * We first consider splits where b is the lower bound of an entry.
         * We iterate through all entries, and for each b, calculate the
         * smallest possible a. Then we consider splits where a is the
         * uppper bound of an entry, and for each a, calculate the greatest
         * possible b.
         *
         * In the above example, the first loop would consider splits:
         * b=0: (0,1)-(0,4)
         * b=1: (0,1)-(1,4)
         * b=2: (0,3)-(2,4)
         *
         * And the second loop:
         * a=1: (0,1)-(1,4)
         * a=3: (0,3)-(2,4)
         * a=4: (0,4)-(2,4)
         */

        /*
         * Iterate over lower bound of right group, finding smallest possible
         * upper bound of left group.
         */
        i1 = 0;
        i2 = 0;
        rightLower = intervalsLower[i1].lower;
        leftUpper = intervalsUpper[i2].lower;
        while (true)
        {
            /*
             * Find next lower bound of right group.
             */
            while (i1 < nentries && rightLower == intervalsLower[i1].lower)
            {
                leftUpper = Max(leftUpper, intervalsLower[i1].upper);
                i1++;
            }
            if (i1 >= nentries)
                break;
            rightLower = intervalsLower[i1].lower;

            /*
             * Find count of intervals which anyway should be placed to the
             * left group.
             */
            while (i2 < nentries && intervalsUpper[i2].upper <= leftUpper)
                i2++;

            /*
             * Consider found split.
             */
            g_box_consider_split(&context, dim, rightLower, i1, leftUpper, i2);
        }

        /*
         * Iterate over upper bound of left group finding greates possible
         * lower bound of right group.
         */
        i1 = nentries - 1;
        i2 = nentries - 1;
        rightLower = intervalsLower[i1].upper;
        leftUpper = intervalsUpper[i2].upper;
        while (true)
        {
            /*
             * Find next upper bound of left group.
             */
            while (i2 >= 0 && leftUpper == intervalsUpper[i2].upper)
            {
                rightLower = Min(rightLower, intervalsUpper[i2].lower);
                i2--;
            }
            if (i2 < 0)
                break;
            leftUpper = intervalsUpper[i2].upper;

            /*
             * Find count of intervals which anyway should be placed to the
             * right group.
             */
            while (i1 >= 0 && intervalsLower[i1].lower >= rightLower)
                i1--;

            /*
             * Consider found split.
             */
            g_box_consider_split(&context, dim,
                                 rightLower, i1 + 1, leftUpper, i2 + 1);
        }
    }

    /*
     * If we failed to find any acceptable splits, use trivial split.
     */
    if (context.first)
    {
        fallbackSplit(entryvec, v);
        PG_RETURN_POINTER(v);
    }

    /*
     * Ok, we have now selected the split across one axis.
     *
     * While considering the splits, we already determined that there will be
     * enough entries in both groups to reach the desired ratio, but we did
     * not memorize which entries go to which group. So determine that now.
     */

    /* Allocate vectors for results */
    v->spl_left = (OffsetNumber *) palloc(nentries * sizeof(OffsetNumber));
    v->spl_right = (OffsetNumber *) palloc(nentries * sizeof(OffsetNumber));
    v->spl_nleft = 0;
    v->spl_nright = 0;

    /* Allocate bounding boxes of left and right groups */
    leftBox = palloc0(sizeof(BOX));
    rightBox = palloc0(sizeof(BOX));

    /*
     * Allocate an array for "common entries" - entries which can be placed to
     * either group without affecting overlap along selected axis.
     */
    commonEntriesCount = 0;
    commonEntries = (CommonEntry *) palloc(nentries * sizeof(CommonEntry));

    /* Helper macros to place an entry in the left or right group */
#define PLACE_LEFT(box, off)                    \
    do {                                        \
        if (v->spl_nleft > 0)                   \
            adjustBox(leftBox, box);            \
        else                                    \
            *leftBox = *(box);                  \
        v->spl_left[v->spl_nleft++] = off;      \
    } while(0)

#define PLACE_RIGHT(box, off)                   \
    do {                                        \
        if (v->spl_nright > 0)                  \
            adjustBox(rightBox, box);           \
        else                                    \
            *rightBox = *(box);                 \
        v->spl_right[v->spl_nright++] = off;    \
    } while(0)

    /*
     * Distribute entries which can be distributed unambiguously, and collect
     * common entries.
     */
    for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
    {
        double      lower,
                    upper;

        /*
         * Get upper and lower bounds along selected axis.
         */
        box = DatumGetBoxP(entryvec->vector[i].key);
        if (context.dim == 0)
        {
            lower = box->low.x;
            upper = box->high.x;
        }
        else
        {
            lower = box->low.y;
            upper = box->high.y;
        }

        if (upper <= context.leftUpper)
        {
            /* Fits to the left group */
            if (lower >= context.rightLower)
            {
                /* Fits also to the right group, so "common entry" */
                commonEntries[commonEntriesCount++].index = i;
            }
            else
            {
                /* Doesn't fit to the right group, so join to the left group */
                PLACE_LEFT(box, i);
            }
        }
        else
        {
            /*
             * Each entry should fit on either left or right group. Since this
             * entry didn't fit on the left group, it better fit in the right
             * group.
             */
            Assert(lower >= context.rightLower);

            /* Doesn't fit to the left group, so join to the right group */
            PLACE_RIGHT(box, i);
        }
    }

    /*
     * Distribute "common entries", if any.
     */
    if (commonEntriesCount > 0)
    {
        /*
         * Calculate minimum number of entries that must be placed in both
         * groups, to reach LIMIT_RATIO.
         */
        int         m = ceil(LIMIT_RATIO * (double) nentries);

        /*
         * Calculate delta between penalties of join "common entries" to
         * different groups.
         */
        for (i = 0; i < commonEntriesCount; i++)
        {
            box = DatumGetBoxP(entryvec->vector[commonEntries[i].index].key);
            commonEntries[i].delta = Abs(box_penalty(leftBox, box) -
                                         box_penalty(rightBox, box));
        }

        /*
         * Sort "common entries" by calculated deltas in order to distribute
         * the most ambiguous entries first.
         */
        qsort(commonEntries, commonEntriesCount, sizeof(CommonEntry), common_entry_cmp);

        /*
         * Distribute "common entries" between groups.
         */
        for (i = 0; i < commonEntriesCount; i++)
        {
            box = DatumGetBoxP(entryvec->vector[commonEntries[i].index].key);

            /*
             * Check if we have to place this entry in either group to achieve
             * LIMIT_RATIO.
             */
            if (v->spl_nleft + (commonEntriesCount - i) <= m)
                PLACE_LEFT(box, commonEntries[i].index);
            else if (v->spl_nright + (commonEntriesCount - i) <= m)
                PLACE_RIGHT(box, commonEntries[i].index);
            else
            {
                /* Otherwise select the group by minimal penalty */
                if (box_penalty(leftBox, box) < box_penalty(rightBox, box))
                    PLACE_LEFT(box, commonEntries[i].index);
                else
                    PLACE_RIGHT(box, commonEntries[i].index);
            }
        }
    }

    v->spl_ldatum = PointerGetDatum(leftBox);
    v->spl_rdatum = PointerGetDatum(rightBox);
    PG_RETURN_POINTER(v);
}

Datum gist_box_same ( PG_FUNCTION_ARGS   ) 

Definition at line 842 of file gistproc.c.

References BOX::high, BOX::low, NULL, PG_GETARG_BOX_P, PG_GETARG_POINTER, PG_RETURN_POINTER, Point::x, and Point::y.

{
    BOX        *b1 = PG_GETARG_BOX_P(0);
    BOX        *b2 = PG_GETARG_BOX_P(1);
    bool       *result = (bool *) PG_GETARG_POINTER(2);

    if (b1 && b2)
        *result = (b1->low.x == b2->low.x && b1->low.y == b2->low.y &&
                   b1->high.x == b2->high.x && b1->high.y == b2->high.y);
    else
        *result = (b1 == NULL && b2 == NULL);
    PG_RETURN_POINTER(result);
}

Datum gist_box_union ( PG_FUNCTION_ARGS   ) 

Definition at line 107 of file gistproc.c.

References adjustBox(), cur, DatumGetBoxP, i, GISTENTRY::key, GistEntryVector::n, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, and GistEntryVector::vector.

{
    GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
    int        *sizep = (int *) PG_GETARG_POINTER(1);
    int         numranges,
                i;
    BOX        *cur,
               *pageunion;

    numranges = entryvec->n;
    pageunion = (BOX *) palloc(sizeof(BOX));
    cur = DatumGetBoxP(entryvec->vector[0].key);
    memcpy((void *) pageunion, (void *) cur, sizeof(BOX));

    for (i = 1; i < numranges; i++)
    {
        cur = DatumGetBoxP(entryvec->vector[i].key);
        adjustBox(pageunion, cur);
    }
    *sizep = sizeof(BOX);

    PG_RETURN_POINTER(pageunion);
}

Datum gist_circle_compress ( PG_FUNCTION_ARGS   ) 

Definition at line 1105 of file gistproc.c.

References CIRCLE::center, DatumGetCircleP, FALSE, gistentryinit, BOX::high, GISTENTRY::key, GISTENTRY::leafkey, BOX::low, NULL, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, CIRCLE::radius, GISTENTRY::rel, Point::x, and Point::y.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    GISTENTRY  *retval;

    if (entry->leafkey)
    {
        retval = palloc(sizeof(GISTENTRY));
        if (DatumGetCircleP(entry->key) != NULL)
        {
            CIRCLE     *in = DatumGetCircleP(entry->key);
            BOX        *r;

            r = (BOX *) palloc(sizeof(BOX));
            r->high.x = in->center.x + in->radius;
            r->low.x = in->center.x - in->radius;
            r->high.y = in->center.y + in->radius;
            r->low.y = in->center.y - in->radius;
            gistentryinit(*retval, PointerGetDatum(r),
                          entry->rel, entry->page,
                          entry->offset, FALSE);

        }
        else
        {
            gistentryinit(*retval, (Datum) 0,
                          entry->rel, entry->page,
                          entry->offset, FALSE);
        }
    }
    else
        retval = entry;
    PG_RETURN_POINTER(retval);
}

Datum gist_circle_consistent ( PG_FUNCTION_ARGS   ) 

Definition at line 1144 of file gistproc.c.

References CIRCLE::center, DatumGetBoxP, FALSE, BOX::high, GISTENTRY::key, BOX::low, NULL, PG_GETARG_CIRCLE_P, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_BOOL, CIRCLE::radius, rtree_internal_consistent(), Point::x, and Point::y.

Referenced by gist_point_consistent().

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    CIRCLE     *query = PG_GETARG_CIRCLE_P(1);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

    /* Oid      subtype = PG_GETARG_OID(3); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);
    BOX         bbox;
    bool        result;

    /* All cases served by this function are inexact */
    *recheck = true;

    if (DatumGetBoxP(entry->key) == NULL || query == NULL)
        PG_RETURN_BOOL(FALSE);

    /*
     * Since the operators require recheck anyway, we can just use
     * rtree_internal_consistent even at leaf nodes.  (This works in part
     * because the index entries are bounding boxes not circles.)
     */
    bbox.high.x = query->center.x + query->radius;
    bbox.low.x = query->center.x - query->radius;
    bbox.high.y = query->center.y + query->radius;
    bbox.low.y = query->center.y - query->radius;

    result = rtree_internal_consistent(DatumGetBoxP(entry->key),
                                       &bbox, strategy);

    PG_RETURN_BOOL(result);
}

Datum gist_point_compress ( PG_FUNCTION_ARGS   ) 

Definition at line 1182 of file gistproc.c.

References BoxPGetDatum, DatumGetPointP, FALSE, gistentryinit, BOX::high, GISTENTRY::key, GISTENTRY::leafkey, BOX::low, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, and GISTENTRY::rel.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);

    if (entry->leafkey)         /* Point, actually */
    {
        BOX        *box = palloc(sizeof(BOX));
        Point      *point = DatumGetPointP(entry->key);
        GISTENTRY  *retval = palloc(sizeof(GISTENTRY));

        box->high = box->low = *point;

        gistentryinit(*retval, BoxPGetDatum(box),
                      entry->rel, entry->page, entry->offset, FALSE);

        PG_RETURN_POINTER(retval);
    }

    PG_RETURN_POINTER(entry);
}

Datum gist_point_consistent ( PG_FUNCTION_ARGS   ) 

Definition at line 1322 of file gistproc.c.

References Assert, BoxStrategyNumberGroup, circle_contain_pt(), CirclePGetDatum, CircleStrategyNumberGroup, DatumGetBool, DatumGetBoxP, DirectFunctionCall2, DirectFunctionCall5, elog, ERROR, GeoStrategyNumberOffset, gist_circle_consistent(), GIST_LEAF, gist_point_consistent_internal(), gist_poly_consistent(), BOX::high, Int16GetDatum, GISTENTRY::key, BOX::low, PG_GETARG_BOX_P, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_GETARG_POINTER, PG_GETARG_POLYGON_P, PG_GETARG_UINT16, PG_RETURN_BOOL, PointerGetDatum, PointPGetDatum, PointStrategyNumberGroup, poly_contain_pt(), PolygonPGetDatum, PolygonStrategyNumberGroup, RTOverlapStrategyNumber, Point::x, and Point::y.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);
    bool        result;
    StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;

    switch (strategyGroup)
    {
        case PointStrategyNumberGroup:
            result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset,
                                                    GIST_LEAF(entry),
                                                    DatumGetBoxP(entry->key),
                                                    PG_GETARG_POINT_P(1));
            *recheck = false;
            break;
        case BoxStrategyNumberGroup:
            {
                /*
                 * The only operator in this group is point <@ box (on_pb), so
                 * we needn't examine strategy again.
                 *
                 * For historical reasons, on_pb uses exact rather than fuzzy
                 * comparisons.  We could use box_overlap when at an internal
                 * page, but that would lead to possibly visiting child pages
                 * uselessly, because box_overlap uses fuzzy comparisons.
                 * Instead we write a non-fuzzy overlap test.  The same code
                 * will also serve for leaf-page tests, since leaf keys have
                 * high == low.
                 */
                BOX        *query,
                           *key;

                query = PG_GETARG_BOX_P(1);
                key = DatumGetBoxP(entry->key);

                result = (key->high.x >= query->low.x &&
                          key->low.x <= query->high.x &&
                          key->high.y >= query->low.y &&
                          key->low.y <= query->high.y);
                *recheck = false;
            }
            break;
        case PolygonStrategyNumberGroup:
            {
                POLYGON    *query = PG_GETARG_POLYGON_P(1);

                result = DatumGetBool(DirectFunctionCall5(
                                                        gist_poly_consistent,
                                                      PointerGetDatum(entry),
                                                     PolygonPGetDatum(query),
                                      Int16GetDatum(RTOverlapStrategyNumber),
                                               0, PointerGetDatum(recheck)));

                if (GIST_LEAF(entry) && result)
                {
                    /*
                     * We are on leaf page and quick check shows overlapping
                     * of polygon's bounding box and point
                     */
                    BOX        *box = DatumGetBoxP(entry->key);

                    Assert(box->high.x == box->low.x
                           && box->high.y == box->low.y);
                    result = DatumGetBool(DirectFunctionCall2(
                                                              poly_contain_pt,
                                                     PolygonPGetDatum(query),
                                                PointPGetDatum(&box->high)));
                    *recheck = false;
                }
            }
            break;
        case CircleStrategyNumberGroup:
            {
                CIRCLE     *query = PG_GETARG_CIRCLE_P(1);

                result = DatumGetBool(DirectFunctionCall5(
                                                      gist_circle_consistent,
                                                      PointerGetDatum(entry),
                                                      CirclePGetDatum(query),
                                      Int16GetDatum(RTOverlapStrategyNumber),
                                               0, PointerGetDatum(recheck)));

                if (GIST_LEAF(entry) && result)
                {
                    /*
                     * We are on leaf page and quick check shows overlapping
                     * of polygon's bounding box and point
                     */
                    BOX        *box = DatumGetBoxP(entry->key);

                    Assert(box->high.x == box->low.x
                           && box->high.y == box->low.y);
                    result = DatumGetBool(DirectFunctionCall2(
                                                           circle_contain_pt,
                                                      CirclePGetDatum(query),
                                                PointPGetDatum(&box->high)));
                    *recheck = false;
                }
            }
            break;
        default:
            elog(ERROR, "unknown strategy number: %d", strategy);
            result = false;     /* keep compiler quiet */
    }

    PG_RETURN_BOOL(result);
}

Datum gist_point_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 1433 of file gistproc.c.

References computeDistance(), DatumGetBoxP, elog, ERROR, GIST_LEAF, GISTENTRY::key, PG_GETARG_POINT_P, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_FLOAT8, and PointStrategyNumberGroup.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
    double      distance;
    StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;

    switch (strategyGroup)
    {
        case PointStrategyNumberGroup:
            distance = computeDistance(GIST_LEAF(entry),
                                       DatumGetBoxP(entry->key),
                                       PG_GETARG_POINT_P(1));
            break;
        default:
            elog(ERROR, "unknown strategy number: %d", strategy);
            distance = 0.0;     /* keep compiler quiet */
    }

    PG_RETURN_FLOAT8(distance);
}

Datum gist_poly_compress ( PG_FUNCTION_ARGS   ) 

Definition at line 1031 of file gistproc.c.

References POLYGON::boundbox, DatumGetPointer, DatumGetPolygonP, FALSE, gistentryinit, GISTENTRY::key, GISTENTRY::leafkey, NULL, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, and GISTENTRY::rel.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    GISTENTRY  *retval;

    if (entry->leafkey)
    {
        retval = palloc(sizeof(GISTENTRY));
        if (DatumGetPointer(entry->key) != NULL)
        {
            POLYGON    *in = DatumGetPolygonP(entry->key);
            BOX        *r;

            r = (BOX *) palloc(sizeof(BOX));
            memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));
            gistentryinit(*retval, PointerGetDatum(r),
                          entry->rel, entry->page,
                          entry->offset, FALSE);

        }
        else
        {
            gistentryinit(*retval, (Datum) 0,
                          entry->rel, entry->page,
                          entry->offset, FALSE);
        }
    }
    else
        retval = entry;
    PG_RETURN_POINTER(retval);
}

Datum gist_poly_consistent ( PG_FUNCTION_ARGS   ) 

Definition at line 1067 of file gistproc.c.

References POLYGON::boundbox, DatumGetBoxP, FALSE, GISTENTRY::key, NULL, PG_FREE_IF_COPY, PG_GETARG_POINTER, PG_GETARG_POLYGON_P, PG_GETARG_UINT16, PG_RETURN_BOOL, and rtree_internal_consistent().

Referenced by gist_point_consistent().

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    POLYGON    *query = PG_GETARG_POLYGON_P(1);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

    /* Oid      subtype = PG_GETARG_OID(3); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);
    bool        result;

    /* All cases served by this function are inexact */
    *recheck = true;

    if (DatumGetBoxP(entry->key) == NULL || query == NULL)
        PG_RETURN_BOOL(FALSE);

    /*
     * Since the operators require recheck anyway, we can just use
     * rtree_internal_consistent even at leaf nodes.  (This works in part
     * because the index entries are bounding boxes not polygons.)
     */
    result = rtree_internal_consistent(DatumGetBoxP(entry->key),
                                       &(query->boundbox), strategy);

    /* Avoid memory leak if supplied poly is toasted */
    PG_FREE_IF_COPY(query, 1);

    PG_RETURN_BOOL(result);
}

Datum inter_lb ( PG_FUNCTION_ARGS   ) 

Definition at line 3368 of file geo_ops.c.

References has_interpt_sl(), BOX::high, BOX::low, PG_GETARG_BOX_P, PG_GETARG_LINE_P, PG_RETURN_BOOL, statlseg_construct(), Point::x, and Point::y.

{
    LINE       *line = PG_GETARG_LINE_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
    LSEG        bseg;
    Point       p1,
                p2;

    /* pairwise check lseg intersections */
    p1.x = box->low.x;
    p1.y = box->low.y;
    p2.x = box->low.x;
    p2.y = box->high.y;
    statlseg_construct(&bseg, &p1, &p2);
    if (has_interpt_sl(&bseg, line))
        PG_RETURN_BOOL(true);
    p1.x = box->high.x;
    p1.y = box->high.y;
    statlseg_construct(&bseg, &p1, &p2);
    if (has_interpt_sl(&bseg, line))
        PG_RETURN_BOOL(true);
    p2.x = box->high.x;
    p2.y = box->low.y;
    statlseg_construct(&bseg, &p1, &p2);
    if (has_interpt_sl(&bseg, line))
        PG_RETURN_BOOL(true);
    p1.x = box->low.x;
    p1.y = box->low.y;
    statlseg_construct(&bseg, &p1, &p2);
    if (has_interpt_sl(&bseg, line))
        PG_RETURN_BOOL(true);

    /* if we dropped through, no intersection */
    PG_RETURN_BOOL(false);
}

Datum inter_sb ( PG_FUNCTION_ARGS   ) 

Definition at line 3313 of file geo_ops.c.

References box_ov(), BoxPGetDatum, DatumGetBool, DirectFunctionCall2, BOX::high, BOX::low, lseg_intersect_internal(), Max, Min, on_pb(), LSEG::p, PG_GETARG_BOX_P, PG_GETARG_LSEG_P, PG_RETURN_BOOL, PointPGetDatum, statlseg_construct(), Point::x, and Point::y.

Referenced by close_sb().

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);
    BOX         lbox;
    LSEG        bseg;
    Point       point;

    lbox.low.x = Min(lseg->p[0].x, lseg->p[1].x);
    lbox.low.y = Min(lseg->p[0].y, lseg->p[1].y);
    lbox.high.x = Max(lseg->p[0].x, lseg->p[1].x);
    lbox.high.y = Max(lseg->p[0].y, lseg->p[1].y);

    /* nothing close to overlap? then not going to intersect */
    if (!box_ov(&lbox, box))
        PG_RETURN_BOOL(false);

    /* an endpoint of segment is inside box? then clearly intersects */
    if (DatumGetBool(DirectFunctionCall2(on_pb,
                                         PointPGetDatum(&lseg->p[0]),
                                         BoxPGetDatum(box))) ||
        DatumGetBool(DirectFunctionCall2(on_pb,
                                         PointPGetDatum(&lseg->p[1]),
                                         BoxPGetDatum(box))))
        PG_RETURN_BOOL(true);

    /* pairwise check lseg intersections */
    point.x = box->low.x;
    point.y = box->high.y;
    statlseg_construct(&bseg, &box->low, &point);
    if (lseg_intersect_internal(&bseg, lseg))
        PG_RETURN_BOOL(true);

    statlseg_construct(&bseg, &box->high, &point);
    if (lseg_intersect_internal(&bseg, lseg))
        PG_RETURN_BOOL(true);

    point.x = box->high.x;
    point.y = box->low.y;
    statlseg_construct(&bseg, &box->low, &point);
    if (lseg_intersect_internal(&bseg, lseg))
        PG_RETURN_BOOL(true);

    statlseg_construct(&bseg, &box->high, &point);
    if (lseg_intersect_internal(&bseg, lseg))
        PG_RETURN_BOOL(true);

    /* if we dropped through, no two segs intersected */
    PG_RETURN_BOOL(false);
}

Datum inter_sl ( PG_FUNCTION_ARGS   ) 

Definition at line 3294 of file geo_ops.c.

References has_interpt_sl(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    LINE       *line = PG_GETARG_LINE_P(1);

    PG_RETURN_BOOL(has_interpt_sl(lseg, line));
}

Datum line_construct_pp ( PG_FUNCTION_ARGS   ) 

Definition at line 1144 of file geo_ops.c.

References line_construct_pts(), palloc(), PG_GETARG_POINT_P, and PG_RETURN_LINE_P.

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);
    LINE       *result = (LINE *) palloc(sizeof(LINE));

    line_construct_pts(result, pt1, pt2);
    PG_RETURN_LINE_P(result);
}

Datum line_distance ( PG_FUNCTION_ARGS   ) 
Datum line_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 1222 of file geo_ops.c.

References LINE::A, LINE::B, LINE::C, FPeq, FPzero, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

{
    LINE       *l1 = PG_GETARG_LINE_P(0);
    LINE       *l2 = PG_GETARG_LINE_P(1);
    double      k;

    if (!FPzero(l2->A))
        k = l1->A / l2->A;
    else if (!FPzero(l2->B))
        k = l1->B / l2->B;
    else if (!FPzero(l2->C))
        k = l1->C / l2->C;
    else
        k = 1.0;

    PG_RETURN_BOOL(FPeq(l1->A, k * l2->A) &&
                   FPeq(l1->B, k * l2->B) &&
                   FPeq(l1->C, k * l2->C));
}

Datum line_horizontal ( PG_FUNCTION_ARGS   ) 

Definition at line 1214 of file geo_ops.c.

References LINE::A, FPzero, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

{
    LINE       *line = PG_GETARG_LINE_P(0);

    PG_RETURN_BOOL(FPzero(line->A));
}

Datum line_in ( PG_FUNCTION_ARGS   ) 

Definition at line 934 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, line_construct_pts(), LSEG::p, palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_LINE_P, and TRUE.

{
#ifdef ENABLE_LINE_TYPE
    char       *str = PG_GETARG_CSTRING(0);
#endif
    LINE       *line;

#ifdef ENABLE_LINE_TYPE
    /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */
    LSEG        lseg;
    int         isopen;
    char       *s;

    if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0])))
        || (*s != '\0'))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type line: \"%s\"", str)));

    line = (LINE *) palloc(sizeof(LINE));
    line_construct_pts(line, &lseg.p[0], &lseg.p[1]);
#else
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("type \"line\" not yet implemented")));

    line = NULL;
#endif

    PG_RETURN_LINE_P(line);
}

Datum line_interpt ( PG_FUNCTION_ARGS   ) 

Definition at line 1273 of file geo_ops.c.

References line_interpt_internal(), NULL, PG_GETARG_LINE_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

{
    LINE       *l1 = PG_GETARG_LINE_P(0);
    LINE       *l2 = PG_GETARG_LINE_P(1);
    Point      *result;

    result = line_interpt_internal(l1, l2);

    if (result == NULL)
        PG_RETURN_NULL();
    PG_RETURN_POINT_P(result);
}

Datum line_intersect ( PG_FUNCTION_ARGS   ) 
Datum line_out ( PG_FUNCTION_ARGS   ) 

Definition at line 968 of file geo_ops.c.

References LINE::A, LINE::B, ereport, errcode(), errmsg(), ERROR, FPzero, path_encode(), PG_GETARG_LINE_P, PG_RETURN_CSTRING, and TRUE.

{
#ifdef ENABLE_LINE_TYPE
    LINE       *line = PG_GETARG_LINE_P(0);
#endif
    char       *result;

#ifdef ENABLE_LINE_TYPE
    /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */
    LSEG        lseg;

    if (FPzero(line->B))
    {                           /* vertical */
        /* use "x = C" */
        result->A = -1;
        result->B = 0;
        result->C = pt1->x;
#ifdef GEODEBUG
        printf("line_out- line is vertical\n");
#endif
#ifdef NOT_USED
        result->m = DBL_MAX;
#endif

    }
    else if (FPzero(line->A))
    {                           /* horizontal */
        /* use "x = C" */
        result->A = 0;
        result->B = -1;
        result->C = pt1->y;
#ifdef GEODEBUG
        printf("line_out- line is horizontal\n");
#endif
#ifdef NOT_USED
        result->m = 0.0;
#endif

    }
    else
    {
    }

    if (FPzero(line->A))        /* horizontal? */
    {
    }
    else if (FPzero(line->B))   /* vertical? */
    {
    }
    else
    {
    }

    return path_encode(TRUE, 2, (Point *) &(ls->p[0]));
#else
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("type \"line\" not yet implemented")));
    result = NULL;
#endif

    PG_RETURN_CSTRING(result);
}

Datum line_parallel ( PG_FUNCTION_ARGS   ) 

Definition at line 1171 of file geo_ops.c.

References LINE::A, LINE::B, FPeq, FPzero, LINE::m, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

Referenced by line_distance(), line_interpt_internal(), and line_intersect().

{
    LINE       *l1 = PG_GETARG_LINE_P(0);
    LINE       *l2 = PG_GETARG_LINE_P(1);

#ifdef NOT_USED
    PG_RETURN_BOOL(FPeq(l1->m, l2->m));
#endif
    if (FPzero(l1->B))
        PG_RETURN_BOOL(FPzero(l2->B));

    PG_RETURN_BOOL(FPeq(l2->A, l1->A * (l2->B / l1->B)));
}

Datum line_perp ( PG_FUNCTION_ARGS   ) 

Definition at line 1186 of file geo_ops.c.

References LINE::A, LINE::B, FPeq, FPzero, LINE::m, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

{
    LINE       *l1 = PG_GETARG_LINE_P(0);
    LINE       *l2 = PG_GETARG_LINE_P(1);

#ifdef NOT_USED
    if (l1->m)
        PG_RETURN_BOOL(FPeq(l2->m / l1->m, -1.0));
    else if (l2->m)
        PG_RETURN_BOOL(FPeq(l1->m / l2->m, -1.0));
#endif
    if (FPzero(l1->A))
        PG_RETURN_BOOL(FPzero(l2->B));
    else if (FPzero(l1->B))
        PG_RETURN_BOOL(FPzero(l2->A));

    PG_RETURN_BOOL(FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0));
}

Datum line_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 1036 of file geo_ops.c.

References ereport, errcode(), errmsg(), and ERROR.

{
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("type \"line\" not yet implemented")));
    return 0;
}

Datum line_send ( PG_FUNCTION_ARGS   ) 

Definition at line 1048 of file geo_ops.c.

References ereport, errcode(), errmsg(), and ERROR.

{
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("type \"line\" not yet implemented")));
    return 0;
}

Datum line_vertical ( PG_FUNCTION_ARGS   ) 

Definition at line 1206 of file geo_ops.c.

References LINE::B, FPzero, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

{
    LINE       *line = PG_GETARG_LINE_P(0);

    PG_RETURN_BOOL(FPzero(line->B));
}

Datum lseg_center ( PG_FUNCTION_ARGS   ) 

Definition at line 2348 of file geo_ops.c.

References LSEG::p, palloc(), PG_GETARG_LSEG_P, PG_RETURN_POINT_P, Point::x, and Point::y.

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);
    Point      *result;

    result = (Point *) palloc(sizeof(Point));

    result->x = (lseg->p[0].x + lseg->p[1].x) / 2.0;
    result->y = (lseg->p[0].y + lseg->p[1].y) / 2.0;

    PG_RETURN_POINT_P(result);
}

Datum lseg_construct ( PG_FUNCTION_ARGS   ) 

Definition at line 2102 of file geo_ops.c.

References LSEG::m, LSEG::p, palloc(), PG_GETARG_POINT_P, PG_RETURN_LSEG_P, point_sl(), Point::x, and Point::y.

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);
    LSEG       *result = (LSEG *) palloc(sizeof(LSEG));

    result->p[0].x = pt1->x;
    result->p[0].y = pt1->y;
    result->p[1].x = pt2->x;
    result->p[1].y = pt2->y;

#ifdef NOT_USED
    result->m = point_sl(pt1, pt2);
#endif

    PG_RETURN_LSEG_P(result);
}

Datum lseg_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 2312 of file geo_ops.c.

References lseg_dt(), PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

Referenced by path_distance(), and regress_path_dist().

Datum lseg_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 2238 of file geo_ops.c.

References FPeq, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, Point::x, and Point::y.

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(FPeq(l1->p[0].x, l2->p[0].x) &&
                   FPeq(l1->p[0].y, l2->p[0].y) &&
                   FPeq(l1->p[1].x, l2->p[1].x) &&
                   FPeq(l1->p[1].y, l2->p[1].y));
}

Datum lseg_ge ( PG_FUNCTION_ARGS   ) 

Definition at line 2292 of file geo_ops.c.

References FPge, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_dt().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1]),
                        point_dt(&l2->p[0], &l2->p[1])));
}

Datum lseg_gt ( PG_FUNCTION_ARGS   ) 

Definition at line 2282 of file geo_ops.c.

References FPgt, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_dt().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]),
                        point_dt(&l2->p[0], &l2->p[1])));
}

Datum lseg_horizontal ( PG_FUNCTION_ARGS   ) 

Definition at line 2229 of file geo_ops.c.

References FPeq, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and Point::y.

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);

    PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));
}

Datum lseg_in ( PG_FUNCTION_ARGS   ) 

Definition at line 2026 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, LSEG::m, LSEG::p, palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_LSEG_P, point_sl(), and TRUE.

{
    char       *str = PG_GETARG_CSTRING(0);
    LSEG       *lseg;
    int         isopen;
    char       *s;

    lseg = (LSEG *) palloc(sizeof(LSEG));

    if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))
        || (*s != '\0'))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type lseg: \"%s\"", str)));

#ifdef NOT_USED
    lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);
#endif

    PG_RETURN_LSEG_P(lseg);
}

Datum lseg_interpt ( PG_FUNCTION_ARGS   ) 

Definition at line 2413 of file geo_ops.c.

References lseg_interpt_internal(), PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and PointerIsValid.

Referenced by interpt_pp().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);
    Point      *result;

    result = lseg_interpt_internal(l1, l2);
    if (!PointerIsValid(result))
        PG_RETURN_NULL();

    PG_RETURN_POINT_P(result);
}

Datum lseg_intersect ( PG_FUNCTION_ARGS   ) 

Definition at line 2151 of file geo_ops.c.

References lseg_intersect_internal(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

Referenced by interpt_pp().

Datum lseg_le ( PG_FUNCTION_ARGS   ) 

Definition at line 2272 of file geo_ops.c.

References FPle, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_dt().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1]),
                        point_dt(&l2->p[0], &l2->p[1])));
}

Datum lseg_length ( PG_FUNCTION_ARGS   ) 

Definition at line 2135 of file geo_ops.c.

References LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_FLOAT8, and point_dt().

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);

    PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1]));
}

Datum lseg_lt ( PG_FUNCTION_ARGS   ) 

Definition at line 2262 of file geo_ops.c.

References FPlt, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_dt().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]),
                        point_dt(&l2->p[0], &l2->p[1])));
}

Datum lseg_ne ( PG_FUNCTION_ARGS   ) 

Definition at line 2250 of file geo_ops.c.

References FPeq, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, Point::x, and Point::y.

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

    PG_RETURN_BOOL(!FPeq(l1->p[0].x, l2->p[0].x) ||
                   !FPeq(l1->p[0].y, l2->p[0].y) ||
                   !FPeq(l1->p[1].x, l2->p[1].x) ||
                   !FPeq(l1->p[1].y, l2->p[1].y));
}

Datum lseg_out ( PG_FUNCTION_ARGS   ) 

Definition at line 2050 of file geo_ops.c.

References FALSE, LSEG::p, path_encode(), PG_GETARG_LSEG_P, and PG_RETURN_CSTRING.

{
    LSEG       *ls = PG_GETARG_LSEG_P(0);

    PG_RETURN_CSTRING(path_encode(FALSE, 2, (Point *) &(ls->p[0])));
}

Datum lseg_parallel ( PG_FUNCTION_ARGS   ) 

Definition at line 2177 of file geo_ops.c.

References FPeq, LSEG::m, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_sl().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);

#ifdef NOT_USED
    PG_RETURN_BOOL(FPeq(l1->m, l2->m));
#endif
    PG_RETURN_BOOL(FPeq(point_sl(&l1->p[0], &l1->p[1]),
                        point_sl(&l2->p[0], &l2->p[1])));
}

Datum lseg_perp ( PG_FUNCTION_ARGS   ) 

Definition at line 2199 of file geo_ops.c.

References FPeq, FPzero, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_sl().

{
    LSEG       *l1 = PG_GETARG_LSEG_P(0);
    LSEG       *l2 = PG_GETARG_LSEG_P(1);
    double      m1,
                m2;

    m1 = point_sl(&(l1->p[0]), &(l1->p[1]));
    m2 = point_sl(&(l2->p[0]), &(l2->p[1]));

#ifdef GEODEBUG
    printf("lseg_perp- slopes are %g and %g\n", m1, m2);
#endif
    if (FPzero(m1))
        PG_RETURN_BOOL(FPeq(m2, DBL_MAX));
    else if (FPzero(m2))
        PG_RETURN_BOOL(FPeq(m1, DBL_MAX));

    PG_RETURN_BOOL(FPeq(m1 / m2, -1.0));
}

Datum lseg_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 2061 of file geo_ops.c.

References buf, LSEG::m, LSEG::p, palloc(), PG_GETARG_POINTER, PG_RETURN_LSEG_P, point_sl(), pq_getmsgfloat8(), Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    LSEG       *lseg;

    lseg = (LSEG *) palloc(sizeof(LSEG));

    lseg->p[0].x = pq_getmsgfloat8(buf);
    lseg->p[0].y = pq_getmsgfloat8(buf);
    lseg->p[1].x = pq_getmsgfloat8(buf);
    lseg->p[1].y = pq_getmsgfloat8(buf);

#ifdef NOT_USED
    lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);
#endif

    PG_RETURN_LSEG_P(lseg);
}

Datum lseg_send ( PG_FUNCTION_ARGS   ) 
Datum lseg_vertical ( PG_FUNCTION_ARGS   ) 

Definition at line 2221 of file geo_ops.c.

References FPeq, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and Point::x.

{
    LSEG       *lseg = PG_GETARG_LSEG_P(0);

    PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));
}

Datum on_pb ( PG_FUNCTION_ARGS   ) 

Definition at line 3200 of file geo_ops.c.

References BOX::high, BOX::low, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by close_pb(), inter_sb(), and on_sb().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    BOX        *box = PG_GETARG_BOX_P(1);

    PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x &&
                   pt->y <= box->high.y && pt->y >= box->low.y);
}

Datum on_pl ( PG_FUNCTION_ARGS   ) 

Definition at line 3170 of file geo_ops.c.

References LINE::A, LINE::B, LINE::C, FPzero, PG_GETARG_LINE_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by on_sl().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    LINE       *line = PG_GETARG_LINE_P(1);

    PG_RETURN_BOOL(FPzero(line->A * pt->x + line->B * pt->y + line->C));
}

Datum on_ppath ( PG_FUNCTION_ARGS   ) 

Definition at line 3231 of file geo_ops.c.

References PATH::closed, FPeq, i, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, point_dt(), and point_inside().

{
    Point      *pt = PG_GETARG_POINT_P(0);
    PATH       *path = PG_GETARG_PATH_P(1);
    int         i,
                n;
    double      a,
                b;

    /*-- OPEN --*/
    if (!path->closed)
    {
        n = path->npts - 1;
        a = point_dt(pt, &path->p[0]);
        for (i = 0; i < n; i++)
        {
            b = point_dt(pt, &path->p[i + 1]);
            if (FPeq(a + b,
                     point_dt(&path->p[i], &path->p[i + 1])))
                PG_RETURN_BOOL(true);
            a = b;
        }
        PG_RETURN_BOOL(false);
    }

    /*-- CLOSED --*/
    PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
}

Datum on_ps ( PG_FUNCTION_ARGS   ) 

Definition at line 3184 of file geo_ops.c.

References on_ps_internal(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, and PG_RETURN_BOOL.

Datum on_sb ( PG_FUNCTION_ARGS   ) 
Datum on_sl ( PG_FUNCTION_ARGS   ) 
Datum path_add ( PG_FUNCTION_ARGS   ) 

Definition at line 4226 of file geo_ops.c.

References PATH::closed, PATH::dummy, ereport, errcode(), errmsg(), ERROR, i, PATH::npts, offsetof, PATH::p, palloc(), PG_GETARG_PATH_P, PG_RETURN_NULL, PG_RETURN_PATH_P, SET_VARSIZE, Point::x, and Point::y.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);
    PATH       *result;
    int         size,
                base_size;
    int         i;

    if (p1->closed || p2->closed)
        PG_RETURN_NULL();

    base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
    size = offsetof(PATH, p[0]) +base_size;

    /* Check for integer overflow */
    if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
        size <= base_size)
        ereport(ERROR,
                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                 errmsg("too many points requested")));

    result = (PATH *) palloc(size);

    SET_VARSIZE(result, size);
    result->npts = (p1->npts + p2->npts);
    result->closed = p1->closed;
    /* prevent instability in unused pad bytes */
    result->dummy = 0;

    for (i = 0; i < p1->npts; i++)
    {
        result->p[i].x = p1->p[i].x;
        result->p[i].y = p1->p[i].y;
    }
    for (i = 0; i < p2->npts; i++)
    {
        result->p[i + p1->npts].x = p2->p[i].x;
        result->p[i + p1->npts].y = p2->p[i].y;
    }

    PG_RETURN_PATH_P(result);
}

Datum path_add_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4274 of file geo_ops.c.

References i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);
    Point      *point = PG_GETARG_POINT_P(1);
    int         i;

    for (i = 0; i < path->npts; i++)
    {
        path->p[i].x += point->x;
        path->p[i].y += point->y;
    }

    PG_RETURN_PATH_P(path);
}

Datum path_area ( PG_FUNCTION_ARGS   ) 

Definition at line 1370 of file geo_ops.c.

References PATH::closed, i, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P(0);
    double      area = 0.0;
    int         i,
                j;

    if (!path->closed)
        PG_RETURN_NULL();

    for (i = 0; i < path->npts; i++)
    {
        j = (i + 1) % path->npts;
        area += path->p[i].x * path->p[j].y;
        area -= path->p[i].y * path->p[j].x;
    }

    area *= 0.5;
    PG_RETURN_FLOAT8(area < 0.0 ? -area : area);
}

Datum path_center ( PG_FUNCTION_ARGS   ) 

Definition at line 4350 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_PATH_P, and PG_RETURN_NULL.

{
#ifdef NOT_USED
    PATH       *path = PG_GETARG_PATH_P(0);
#endif

    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("function \"path_center\" not implemented")));

    PG_RETURN_NULL();
}

Datum path_close ( PG_FUNCTION_ARGS   ) 

Definition at line 1593 of file geo_ops.c.

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);

    path->closed = TRUE;

    PG_RETURN_PATH_P(path);
}

Datum path_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 1697 of file geo_ops.c.

References PATH::closed, DatumGetFloat8, DirectFunctionCall2, i, lseg_distance(), LsegPGetDatum, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, and statlseg_construct().

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);
    float8      min = 0.0;      /* initialize to keep compiler quiet */
    bool        have_min = false;
    float8      tmp;
    int         i,
                j;
    LSEG        seg1,
                seg2;

    for (i = 0; i < p1->npts; i++)
    {
        int         iprev;

        if (i > 0)
            iprev = i - 1;
        else
        {
            if (!p1->closed)
                continue;
            iprev = p1->npts - 1;       /* include the closure segment */
        }

        for (j = 0; j < p2->npts; j++)
        {
            int         jprev;

            if (j > 0)
                jprev = j - 1;
            else
            {
                if (!p2->closed)
                    continue;
                jprev = p2->npts - 1;   /* include the closure segment */
            }

            statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
            statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);

            tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance,
                                                     LsegPGetDatum(&seg1),
                                                     LsegPGetDatum(&seg2)));
            if (!have_min || tmp < min)
            {
                min = tmp;
                have_min = true;
            }
        }
    }

    if (!have_min)
        PG_RETURN_NULL();

    PG_RETURN_FLOAT8(min);
}

Datum path_div_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4329 of file geo_ops.c.

References DatumGetPointP, DirectFunctionCall2, i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, point_div(), PointPGetDatum, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);
    Point      *point = PG_GETARG_POINT_P(1);
    Point      *p;
    int         i;

    for (i = 0; i < path->npts; i++)
    {
        p = DatumGetPointP(DirectFunctionCall2(point_div,
                                               PointPGetDatum(&path->p[i]),
                                               PointPGetDatum(point)));
        path->p[i].x = p->x;
        path->p[i].y = p->y;
    }

    PG_RETURN_PATH_P(path);
}

Datum path_in ( PG_FUNCTION_ARGS   ) 

Definition at line 1393 of file geo_ops.c.

References PATH::closed, PATH::dummy, ereport, errcode(), errmsg(), ERROR, LDELIM, PATH::npts, offsetof, PATH::p, pair_count(), palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_PATH_P, RDELIM, SET_VARSIZE, and TRUE.

Referenced by poly2path().

{
    char       *str = PG_GETARG_CSTRING(0);
    PATH       *path;
    int         isopen;
    char       *s;
    int         npts;
    int         size;
    int         depth = 0;

    if ((npts = pair_count(str, ',')) <= 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type path: \"%s\"", str)));

    s = str;
    while (isspace((unsigned char) *s))
        s++;

    /* skip single leading paren */
    if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
    {
        s++;
        depth++;
    }

    size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
    path = (PATH *) palloc(size);

    SET_VARSIZE(path, size);
    path->npts = npts;

    if ((!path_decode(TRUE, npts, s, &isopen, &s, &(path->p[0])))
    && (!((depth == 0) && (*s == '\0'))) && !((depth >= 1) && (*s == RDELIM)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type path: \"%s\"", str)));

    path->closed = (!isopen);
    /* prevent instability in unused pad bytes */
    path->dummy = 0;

    PG_RETURN_PATH_P(path);
}

Datum path_inter ( PG_FUNCTION_ARGS   ) 

Definition at line 1619 of file geo_ops.c.

References box_ov(), PATH::closed, BOX::high, i, BOX::low, lseg_intersect_internal(), Max, Min, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_BOOL, statlseg_construct(), Point::x, and Point::y.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);
    BOX         b1,
                b2;
    int         i,
                j;
    LSEG        seg1,
                seg2;

    if (p1->npts <= 0 || p2->npts <= 0)
        PG_RETURN_BOOL(false);

    b1.high.x = b1.low.x = p1->p[0].x;
    b1.high.y = b1.low.y = p1->p[0].y;
    for (i = 1; i < p1->npts; i++)
    {
        b1.high.x = Max(p1->p[i].x, b1.high.x);
        b1.high.y = Max(p1->p[i].y, b1.high.y);
        b1.low.x = Min(p1->p[i].x, b1.low.x);
        b1.low.y = Min(p1->p[i].y, b1.low.y);
    }
    b2.high.x = b2.low.x = p2->p[0].x;
    b2.high.y = b2.low.y = p2->p[0].y;
    for (i = 1; i < p2->npts; i++)
    {
        b2.high.x = Max(p2->p[i].x, b2.high.x);
        b2.high.y = Max(p2->p[i].y, b2.high.y);
        b2.low.x = Min(p2->p[i].x, b2.low.x);
        b2.low.y = Min(p2->p[i].y, b2.low.y);
    }
    if (!box_ov(&b1, &b2))
        PG_RETURN_BOOL(false);

    /* pairwise check lseg intersections */
    for (i = 0; i < p1->npts; i++)
    {
        int         iprev;

        if (i > 0)
            iprev = i - 1;
        else
        {
            if (!p1->closed)
                continue;
            iprev = p1->npts - 1;       /* include the closure segment */
        }

        for (j = 0; j < p2->npts; j++)
        {
            int         jprev;

            if (j > 0)
                jprev = j - 1;
            else
            {
                if (!p2->closed)
                    continue;
                jprev = p2->npts - 1;   /* include the closure segment */
            }

            statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
            statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
            if (lseg_intersect_internal(&seg1, &seg2))
                PG_RETURN_BOOL(true);
        }
    }

    /* if we dropped through, no two segs intersected */
    PG_RETURN_BOOL(false);
}

Datum path_isclosed ( PG_FUNCTION_ARGS   ) 

Definition at line 1568 of file geo_ops.c.

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *path = PG_GETARG_PATH_P(0);

    PG_RETURN_BOOL(path->closed);
}

Datum path_isopen ( PG_FUNCTION_ARGS   ) 

Definition at line 1576 of file geo_ops.c.

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *path = PG_GETARG_PATH_P(0);

    PG_RETURN_BOOL(!path->closed);
}

Datum path_length ( PG_FUNCTION_ARGS   ) 

Definition at line 1761 of file geo_ops.c.

References PATH::closed, i, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_FLOAT8, and point_dt().

{
    PATH       *path = PG_GETARG_PATH_P(0);
    float8      result = 0.0;
    int         i;

    for (i = 0; i < path->npts; i++)
    {
        int         iprev;

        if (i > 0)
            iprev = i - 1;
        else
        {
            if (!path->closed)
                continue;
            iprev = path->npts - 1;     /* include the closure segment */
        }

        result += point_dt(&path->p[iprev], &path->p[i]);
    }

    PG_RETURN_FLOAT8(result);
}

Datum path_mul_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4309 of file geo_ops.c.

References DatumGetPointP, DirectFunctionCall2, i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, point_mul(), PointPGetDatum, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);
    Point      *point = PG_GETARG_POINT_P(1);
    Point      *p;
    int         i;

    for (i = 0; i < path->npts; i++)
    {
        p = DatumGetPointP(DirectFunctionCall2(point_mul,
                                               PointPGetDatum(&path->p[i]),
                                               PointPGetDatum(point)));
        path->p[i].x = p->x;
        path->p[i].y = p->y;
    }

    PG_RETURN_PATH_P(path);
}

Datum path_n_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 1537 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);

    PG_RETURN_BOOL(p1->npts == p2->npts);
}

Datum path_n_ge ( PG_FUNCTION_ARGS   ) 

Definition at line 1555 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);

    PG_RETURN_BOOL(p1->npts >= p2->npts);
}

Datum path_n_gt ( PG_FUNCTION_ARGS   ) 

Definition at line 1528 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);

    PG_RETURN_BOOL(p1->npts > p2->npts);
}

Datum path_n_le ( PG_FUNCTION_ARGS   ) 

Definition at line 1546 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);

    PG_RETURN_BOOL(p1->npts <= p2->npts);
}

Datum path_n_lt ( PG_FUNCTION_ARGS   ) 

Definition at line 1519 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

{
    PATH       *p1 = PG_GETARG_PATH_P(0);
    PATH       *p2 = PG_GETARG_PATH_P(1);

    PG_RETURN_BOOL(p1->npts < p2->npts);
}

Datum path_npoints ( PG_FUNCTION_ARGS   ) 

Definition at line 1584 of file geo_ops.c.

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_INT32.

{
    PATH       *path = PG_GETARG_PATH_P(0);

    PG_RETURN_INT32(path->npts);
}

Datum path_open ( PG_FUNCTION_ARGS   ) 

Definition at line 1603 of file geo_ops.c.

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);

    path->closed = FALSE;

    PG_RETURN_PATH_P(path);
}

Datum path_out ( PG_FUNCTION_ARGS   ) 

Definition at line 1440 of file geo_ops.c.

References PATH::closed, PATH::npts, PATH::p, path_encode(), PG_GETARG_PATH_P, and PG_RETURN_CSTRING.

{
    PATH       *path = PG_GETARG_PATH_P(0);

    PG_RETURN_CSTRING(path_encode(path->closed, path->npts, path->p));
}

Datum path_poly ( PG_FUNCTION_ARGS   ) 

Definition at line 4364 of file geo_ops.c.

References PATH::closed, ereport, errcode(), errmsg(), ERROR, i, make_bound_box(), POLYGON::npts, PATH::npts, offsetof, PATH::p, POLYGON::p, palloc(), PG_GETARG_PATH_P, PG_RETURN_POLYGON_P, SET_VARSIZE, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P(0);
    POLYGON    *poly;
    int         size;
    int         i;

    /* This is not very consistent --- other similar cases return NULL ... */
    if (!path->closed)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("open path cannot be converted to polygon")));

    size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * path->npts;
    poly = (POLYGON *) palloc(size);

    SET_VARSIZE(poly, size);
    poly->npts = path->npts;

    for (i = 0; i < path->npts; i++)
    {
        poly->p[i].x = path->p[i].x;
        poly->p[i].y = path->p[i].y;
    }

    make_bound_box(poly);

    PG_RETURN_POLYGON_P(poly);
}

Datum path_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 1454 of file geo_ops.c.

References buf, PATH::closed, PATH::dummy, ereport, errcode(), errmsg(), ERROR, i, PATH::npts, offsetof, PATH::p, palloc(), PG_GETARG_POINTER, PG_RETURN_PATH_P, pq_getmsgbyte(), pq_getmsgfloat8(), pq_getmsgint(), SET_VARSIZE, Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    PATH       *path;
    int         closed;
    int32       npts;
    int32       i;
    int         size;

    closed = pq_getmsgbyte(buf);
    npts = pq_getmsgint(buf, sizeof(int32));
    if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p[0])) / sizeof(Point)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
             errmsg("invalid number of points in external \"path\" value")));

    size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
    path = (PATH *) palloc(size);

    SET_VARSIZE(path, size);
    path->npts = npts;
    path->closed = (closed ? 1 : 0);
    /* prevent instability in unused pad bytes */
    path->dummy = 0;

    for (i = 0; i < npts; i++)
    {
        path->p[i].x = pq_getmsgfloat8(buf);
        path->p[i].y = pq_getmsgfloat8(buf);
    }

    PG_RETURN_PATH_P(path);
}

Datum path_send ( PG_FUNCTION_ARGS   ) 

Definition at line 1492 of file geo_ops.c.

References buf, PATH::closed, i, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendfloat8(), pq_sendint(), Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P(0);
    StringInfoData buf;
    int32       i;

    pq_begintypsend(&buf);
    pq_sendbyte(&buf, path->closed ? 1 : 0);
    pq_sendint(&buf, path->npts, sizeof(int32));
    for (i = 0; i < path->npts; i++)
    {
        pq_sendfloat8(&buf, path->p[i].x);
        pq_sendfloat8(&buf, path->p[i].y);
    }
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

Datum path_sub_pt ( PG_FUNCTION_ARGS   ) 

Definition at line 4290 of file geo_ops.c.

References i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, Point::x, and Point::y.

{
    PATH       *path = PG_GETARG_PATH_P_COPY(0);
    Point      *point = PG_GETARG_POINT_P(1);
    int         i;

    for (i = 0; i < path->npts; i++)
    {
        path->p[i].x -= point->x;
        path->p[i].y -= point->y;
    }

    PG_RETURN_PATH_P(path);
}

double pg_hypot ( double  x,
double  y 
)

Definition at line 5445 of file geo_ops.c.

References get_float8_infinity(), get_float8_nan(), and isinf().

{
    double      yx;

    /* Handle INF and NaN properly */
    if (isinf(x) || isinf(y))
        return get_float8_infinity();

    if (isnan(x) || isnan(y))
        return get_float8_nan();

    /* Else, drop any minus signs */
    x = fabs(x);
    y = fabs(y);

    /* Swap x and y if needed to make x the larger one */
    if (x < y)
    {
        double      temp = x;

        x = y;
        y = temp;
    }

    /*
     * If y is zero, the hypotenuse is x.  This test saves a few cycles in
     * such cases, but more importantly it also protects against
     * divide-by-zero errors, since now x >= y.
     */
    if (y == 0.0)
        return x;

    /* Determine the hypotenuse */
    yx = y / x;
    return x * sqrt(1.0 + (yx * yx));
}

Datum point_above ( PG_FUNCTION_ARGS   ) 

Definition at line 1915 of file geo_ops.c.

References FPgt, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::y.

Referenced by getQuadrant(), spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
}

Datum point_add ( PG_FUNCTION_ARGS   ) 

Definition at line 4066 of file geo_ops.c.

References palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, Point::x, and Point::y.

{
    Point      *p1 = PG_GETARG_POINT_P(0);
    Point      *p2 = PG_GETARG_POINT_P(1);
    Point      *result;

    result = (Point *) palloc(sizeof(Point));

    result->x = (p1->x + p2->x);
    result->y = (p1->y + p2->y);

    PG_RETURN_POINT_P(result);
}

Datum point_below ( PG_FUNCTION_ARGS   ) 

Definition at line 1924 of file geo_ops.c.

References FPlt, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::y.

Referenced by getQuadrant(), spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
}

Datum point_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 1973 of file geo_ops.c.

References HYPOT, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, Point::x, and Point::y.

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_FLOAT8(HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));
}

Datum point_div ( PG_FUNCTION_ARGS   ) 

Definition at line 4111 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, Point::x, and Point::y.

Referenced by box_div(), circle_div_pt(), and path_div_pt().

{
    Point      *p1 = PG_GETARG_POINT_P(0);
    Point      *p2 = PG_GETARG_POINT_P(1);
    Point      *result;
    double      div;

    result = (Point *) palloc(sizeof(Point));

    div = (p2->x * p2->x) + (p2->y * p2->y);

    if (div == 0.0)
        ereport(ERROR,
                (errcode(ERRCODE_DIVISION_BY_ZERO),
                 errmsg("division by zero")));

    result->x = ((p1->x * p2->x) + (p1->y * p2->y)) / div;
    result->y = ((p2->x * p1->y) - (p2->y * p1->x)) / div;

    PG_RETURN_POINT_P(result);
}

double point_dt ( Point pt1,
Point pt2 
)

Definition at line 1982 of file geo_ops.c.

References HYPOT, Point::x, and Point::y.

Referenced by box_circle(), circle_contain(), circle_contain_pt(), circle_contained(), circle_distance(), circle_overlap(), dist_pb(), dist_pc(), dist_ppath(), dist_ps_internal(), lseg_ge(), lseg_gt(), lseg_le(), lseg_length(), lseg_lt(), on_ppath(), on_ps_internal(), path_length(), poly_circle(), pt_contained_circle(), pt_in_widget(), and regress_dist_ptpath().

{
#ifdef GEODEBUG
    printf("point_dt- segment (%f,%f),(%f,%f) length is %f\n",
    pt1->x, pt1->y, pt2->x, pt2->y, HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));
#endif
    return HYPOT(pt1->x - pt2->x, pt1->y - pt2->y);
}

Datum point_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 1951 of file geo_ops.c.

References FPeq, PG_GETARG_POINT_P, PG_RETURN_BOOL, Point::x, and Point::y.

Referenced by spg_quad_leaf_consistent().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
}

Datum point_horiz ( PG_FUNCTION_ARGS   ) 

Definition at line 1942 of file geo_ops.c.

References FPeq, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::y.

Referenced by getQuadrant().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));
}

Datum point_in ( PG_FUNCTION_ARGS   ) 

Definition at line 1800 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, pair_decode(), palloc(), PG_GETARG_CSTRING, PG_RETURN_POINT_P, Point::x, and Point::y.

{
    char       *str = PG_GETARG_CSTRING(0);
    Point      *point;
    double      x,
                y;
    char       *s;

    if (!pair_decode(str, &x, &y, &s) || (*s != '\0'))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for type point: \"%s\"", str)));

    point = (Point *) palloc(sizeof(Point));

    point->x = x;
    point->y = y;

    PG_RETURN_POINT_P(point);
}

Datum point_left ( PG_FUNCTION_ARGS   ) 

Definition at line 1897 of file geo_ops.c.

References FPlt, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::x.

Referenced by getQuadrant(), spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));
}

Datum point_mul ( PG_FUNCTION_ARGS   ) 

Definition at line 4096 of file geo_ops.c.

References palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, Point::x, and Point::y.

Referenced by box_mul(), circle_mul_pt(), and path_mul_pt().

{
    Point      *p1 = PG_GETARG_POINT_P(0);
    Point      *p2 = PG_GETARG_POINT_P(1);
    Point      *result;

    result = (Point *) palloc(sizeof(Point));

    result->x = (p1->x * p2->x) - (p1->y * p2->y);
    result->y = (p1->x * p2->y) + (p1->y * p2->x);

    PG_RETURN_POINT_P(result);
}

Datum point_ne ( PG_FUNCTION_ARGS   ) 

Definition at line 1960 of file geo_ops.c.

References FPne, PG_GETARG_POINT_P, PG_RETURN_BOOL, Point::x, and Point::y.

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPne(pt1->x, pt2->x) || FPne(pt1->y, pt2->y));
}

Datum point_out ( PG_FUNCTION_ARGS   ) 

Definition at line 1822 of file geo_ops.c.

References path_encode(), PG_GETARG_POINT_P, and PG_RETURN_CSTRING.

Datum point_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 1833 of file geo_ops.c.

References buf, palloc(), PG_GETARG_POINTER, PG_RETURN_POINT_P, pq_getmsgfloat8(), Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    Point      *point;

    point = (Point *) palloc(sizeof(Point));
    point->x = pq_getmsgfloat8(buf);
    point->y = pq_getmsgfloat8(buf);
    PG_RETURN_POINT_P(point);
}

Datum point_right ( PG_FUNCTION_ARGS   ) 

Definition at line 1906 of file geo_ops.c.

References FPgt, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::x.

Referenced by getQuadrant(), spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));
}

Datum point_send ( PG_FUNCTION_ARGS   ) 
double point_sl ( Point pt1,
Point pt2 
)

Definition at line 2002 of file geo_ops.c.

References FPeq, Point::x, and Point::y.

Referenced by close_ps(), lseg_construct(), lseg_in(), lseg_parallel(), lseg_perp(), lseg_recv(), point_slope(), regress_lseg_construct(), and statlseg_construct().

{
    return (FPeq(pt1->x, pt2->x)
            ? (double) DBL_MAX
            : (pt1->y - pt2->y) / (pt1->x - pt2->x));
}

Datum point_slope ( PG_FUNCTION_ARGS   ) 

Definition at line 1992 of file geo_ops.c.

References PG_GETARG_POINT_P, PG_RETURN_FLOAT8, and point_sl().

Datum point_sub ( PG_FUNCTION_ARGS   ) 

Definition at line 4081 of file geo_ops.c.

References palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, Point::x, and Point::y.

{
    Point      *p1 = PG_GETARG_POINT_P(0);
    Point      *p2 = PG_GETARG_POINT_P(1);
    Point      *result;

    result = (Point *) palloc(sizeof(Point));

    result->x = (p1->x - p2->x);
    result->y = (p1->y - p2->y);

    PG_RETURN_POINT_P(result);
}

Datum point_vert ( PG_FUNCTION_ARGS   ) 

Definition at line 1933 of file geo_ops.c.

References FPeq, PG_GETARG_POINT_P, PG_RETURN_BOOL, and Point::x.

Referenced by getQuadrant().

{
    Point      *pt1 = PG_GETARG_POINT_P(0);
    Point      *pt2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));
}

Datum points_box ( PG_FUNCTION_ARGS   ) 

Definition at line 4141 of file geo_ops.c.

References box_construct(), PG_GETARG_POINT_P, PG_RETURN_BOX_P, Point::x, and Point::y.

{
    Point      *p1 = PG_GETARG_POINT_P(0);
    Point      *p2 = PG_GETARG_POINT_P(1);

    PG_RETURN_BOX_P(box_construct(p1->x, p2->x, p1->y, p2->y));
}

Datum poly_above ( PG_FUNCTION_ARGS   ) 

Definition at line 3705 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::y.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.low.y > polyb->boundbox.high.y;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_below ( PG_FUNCTION_ARGS   ) 

Definition at line 3659 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::y.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.high.y < polyb->boundbox.low.y;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_box ( PG_FUNCTION_ARGS   ) 

Definition at line 4427 of file geo_ops.c.

References POLYGON::boundbox, box_copy(), POLYGON::npts, PG_GETARG_POLYGON_P, PG_RETURN_BOX_P, and PG_RETURN_NULL.

{
    POLYGON    *poly = PG_GETARG_POLYGON_P(0);
    BOX        *box;

    if (poly->npts < 1)
        PG_RETURN_NULL();

    box = box_copy(&poly->boundbox);

    PG_RETURN_BOX_P(box);
}

Datum poly_center ( PG_FUNCTION_ARGS   ) 
Datum poly_circle ( PG_FUNCTION_ARGS   ) 

Definition at line 5193 of file geo_ops.c.

References CIRCLE::center, ereport, errcode(), errmsg(), ERROR, FPzero, i, POLYGON::npts, POLYGON::p, palloc(), PG_GETARG_POLYGON_P, PG_RETURN_CIRCLE_P, point_dt(), CIRCLE::radius, Point::x, and Point::y.

Referenced by poly_center().

{
    POLYGON    *poly = PG_GETARG_POLYGON_P(0);
    CIRCLE     *circle;
    int         i;

    if (poly->npts < 2)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot convert empty polygon to circle")));

    circle = (CIRCLE *) palloc(sizeof(CIRCLE));

    circle->center.x = 0;
    circle->center.y = 0;
    circle->radius = 0;

    for (i = 0; i < poly->npts; i++)
    {
        circle->center.x += poly->p[i].x;
        circle->center.y += poly->p[i].y;
    }
    circle->center.x /= poly->npts;
    circle->center.y /= poly->npts;

    for (i = 0; i < poly->npts; i++)
        circle->radius += point_dt(&poly->p[i], &circle->center);
    circle->radius /= poly->npts;

    if (FPzero(circle->radius))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot convert empty polygon to circle")));

    PG_RETURN_CIRCLE_P(circle);
}

Datum poly_contain ( PG_FUNCTION_ARGS   ) 

Definition at line 3959 of file geo_ops.c.

References POLYGON::boundbox, box_contain(), BoxPGetDatum, DatumGetBool, DirectFunctionCall2, i, lseg_inside_poly(), POLYGON::npts, POLYGON::p, LSEG::p, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, and PG_RETURN_BOOL.

Referenced by poly_contained().

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    /*
     * Quick check to see if bounding box is contained.
     */
    if (polya->npts > 0 && polyb->npts > 0 &&
        DatumGetBool(DirectFunctionCall2(box_contain,
                                         BoxPGetDatum(&polya->boundbox),
                                         BoxPGetDatum(&polyb->boundbox))))
    {
        int         i;
        LSEG        s;

        s.p[0] = polyb->p[polyb->npts - 1];
        result = true;

        for (i = 0; i < polyb->npts && result; i++)
        {
            s.p[1] = polyb->p[i];
            result = lseg_inside_poly(s.p, s.p + 1, polya, 0);
            s.p[0] = s.p[1];
        }
    }
    else
    {
        result = false;
    }

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_contain_pt ( PG_FUNCTION_ARGS   ) 
Datum poly_contained ( PG_FUNCTION_ARGS   ) 

Definition at line 4005 of file geo_ops.c.

References DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_DATUM, and poly_contain().

{
    Datum       polya = PG_GETARG_DATUM(0);
    Datum       polyb = PG_GETARG_DATUM(1);

    /* Just switch the arguments and pass it off to poly_contain */
    PG_RETURN_DATUM(DirectFunctionCall2(poly_contain, polyb, polya));
}

Datum poly_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 4035 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_POLYGON_P, and PG_RETURN_NULL.

{
#ifdef NOT_USED
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
#endif

    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("function \"poly_distance\" not implemented")));

    PG_RETURN_NULL();
}

Datum poly_in ( PG_FUNCTION_ARGS   ) 

Definition at line 3457 of file geo_ops.c.

References ereport, errcode(), errmsg(), ERROR, FALSE, make_bound_box(), POLYGON::npts, offsetof, POLYGON::p, pair_count(), palloc0(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_POLYGON_P, and SET_VARSIZE.

{
    char       *str = PG_GETARG_CSTRING(0);
    POLYGON    *poly;
    int         npts;
    int         size;
    int         isopen;
    char       *s;

    if ((npts = pair_count(str, ',')) <= 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
              errmsg("invalid input syntax for type polygon: \"%s\"", str)));

    size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
    poly = (POLYGON *) palloc0(size);   /* zero any holes */

    SET_VARSIZE(poly, size);
    poly->npts = npts;

    if ((!path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0])))
        || (*s != '\0'))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
              errmsg("invalid input syntax for type polygon: \"%s\"", str)));

    make_bound_box(poly);

    PG_RETURN_POLYGON_P(poly);
}

Datum poly_left ( PG_FUNCTION_ARGS   ) 

Definition at line 3567 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::x.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.high.x < polyb->boundbox.low.x;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_npoints ( PG_FUNCTION_ARGS   ) 

Definition at line 4402 of file geo_ops.c.

References POLYGON::npts, PG_GETARG_POLYGON_P, and PG_RETURN_INT32.

Datum poly_out ( PG_FUNCTION_ARGS   ) 
Datum poly_overabove ( PG_FUNCTION_ARGS   ) 

Definition at line 3728 of file geo_ops.c.

References POLYGON::boundbox, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::y.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.low.y >= polyb->boundbox.low.y;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_overbelow ( PG_FUNCTION_ARGS   ) 

Definition at line 3682 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::y.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.high.y <= polyb->boundbox.high.y;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_overlap ( PG_FUNCTION_ARGS   ) 

Definition at line 3778 of file geo_ops.c.

References POLYGON::boundbox, box_ov(), lseg_intersect_internal(), POLYGON::npts, POLYGON::p, LSEG::p, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and point_inside().

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    /* Quick check by bounding box */
    result = (polya->npts > 0 && polyb->npts > 0 &&
              box_ov(&polya->boundbox, &polyb->boundbox)) ? true : false;

    /*
     * Brute-force algorithm - try to find intersected edges, if so then
     * polygons are overlapped else check is one polygon inside other or not
     * by testing single point of them.
     */
    if (result)
    {
        int         ia,
                    ib;
        LSEG        sa,
                    sb;

        /* Init first of polya's edge with last point */
        sa.p[0] = polya->p[polya->npts - 1];
        result = false;

        for (ia = 0; ia < polya->npts && result == false; ia++)
        {
            /* Second point of polya's edge is a current one */
            sa.p[1] = polya->p[ia];

            /* Init first of polyb's edge with last point */
            sb.p[0] = polyb->p[polyb->npts - 1];

            for (ib = 0; ib < polyb->npts && result == false; ib++)
            {
                sb.p[1] = polyb->p[ib];
                result = lseg_intersect_internal(&sa, &sb);
                sb.p[0] = sb.p[1];
            }

            /*
             * move current endpoint to the first point of next edge
             */
            sa.p[0] = sa.p[1];
        }

        if (result == false)
        {
            result = (point_inside(polya->p, polyb->npts, polyb->p)
                      ||
                      point_inside(polyb->p, polya->npts, polya->p));
        }
    }

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_overleft ( PG_FUNCTION_ARGS   ) 

Definition at line 3590 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::x.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.high.x <= polyb->boundbox.high.x;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_overright ( PG_FUNCTION_ARGS   ) 

Definition at line 3636 of file geo_ops.c.

References POLYGON::boundbox, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::x.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.low.x >= polyb->boundbox.low.x;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_path ( PG_FUNCTION_ARGS   ) 

Definition at line 4475 of file geo_ops.c.

References PATH::closed, PATH::dummy, i, PATH::npts, POLYGON::npts, offsetof, POLYGON::p, PATH::p, palloc(), PG_GETARG_POLYGON_P, PG_RETURN_PATH_P, SET_VARSIZE, Point::x, and Point::y.

{
    POLYGON    *poly = PG_GETARG_POLYGON_P(0);
    PATH       *path;
    int         size;
    int         i;

    size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * poly->npts;
    path = (PATH *) palloc(size);

    SET_VARSIZE(path, size);
    path->npts = poly->npts;
    path->closed = TRUE;
    /* prevent instability in unused pad bytes */
    path->dummy = 0;

    for (i = 0; i < poly->npts; i++)
    {
        path->p[i].x = poly->p[i].x;
        path->p[i].y = poly->p[i].y;
    }

    PG_RETURN_PATH_P(path);
}

Datum poly_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 3509 of file geo_ops.c.

References buf, ereport, errcode(), errmsg(), ERROR, i, make_bound_box(), POLYGON::npts, offsetof, POLYGON::p, palloc0(), PG_GETARG_POINTER, PG_RETURN_POLYGON_P, pq_getmsgfloat8(), pq_getmsgint(), SET_VARSIZE, Point::x, and Point::y.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    POLYGON    *poly;
    int32       npts;
    int32       i;
    int         size;

    npts = pq_getmsgint(buf, sizeof(int32));
    if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p[0])) / sizeof(Point)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
          errmsg("invalid number of points in external \"polygon\" value")));

    size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
    poly = (POLYGON *) palloc0(size);   /* zero any holes */

    SET_VARSIZE(poly, size);
    poly->npts = npts;

    for (i = 0; i < npts; i++)
    {
        poly->p[i].x = pq_getmsgfloat8(buf);
        poly->p[i].y = pq_getmsgfloat8(buf);
    }

    make_bound_box(poly);

    PG_RETURN_POLYGON_P(poly);
}

Datum poly_right ( PG_FUNCTION_ARGS   ) 

Definition at line 3613 of file geo_ops.c.

References POLYGON::boundbox, BOX::high, BOX::low, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and Point::x.

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    result = polya->boundbox.low.x > polyb->boundbox.high.x;

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_same ( PG_FUNCTION_ARGS   ) 

Definition at line 3754 of file geo_ops.c.

References POLYGON::npts, POLYGON::p, PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and plist_same().

{
    POLYGON    *polya = PG_GETARG_POLYGON_P(0);
    POLYGON    *polyb = PG_GETARG_POLYGON_P(1);
    bool        result;

    if (polya->npts != polyb->npts)
        result = false;
    else
        result = plist_same(polya->npts, polya->p, polyb->p);

    /*
     * Avoid leaking memory for toasted inputs ... needed for rtree indexes
     */
    PG_FREE_IF_COPY(polya, 0);
    PG_FREE_IF_COPY(polyb, 1);

    PG_RETURN_BOOL(result);
}

Datum poly_send ( PG_FUNCTION_ARGS   ) 

Definition at line 3544 of file geo_ops.c.

References buf, i, POLYGON::npts, POLYGON::p, PG_GETARG_POLYGON_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), pq_sendint(), Point::x, and Point::y.

{
    POLYGON    *poly = PG_GETARG_POLYGON_P(0);
    StringInfoData buf;
    int32       i;

    pq_begintypsend(&buf);
    pq_sendint(&buf, poly->npts, sizeof(int32));
    for (i = 0; i < poly->npts; i++)
    {
        pq_sendfloat8(&buf, poly->p[i].x);
        pq_sendfloat8(&buf, poly->p[i].y);
    }
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

Datum positionjoinsel ( PG_FUNCTION_ARGS   ) 

Definition at line 73 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.1);
}

Datum positionsel ( PG_FUNCTION_ARGS   ) 

Definition at line 67 of file geo_selfuncs.c.

References PG_RETURN_FLOAT8.

{
    PG_RETURN_FLOAT8(0.1);
}

Datum pt_contained_circle ( PG_FUNCTION_ARGS   ) 

Definition at line 5026 of file geo_ops.c.

References CIRCLE::center, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_dt().

{
    Point      *point = PG_GETARG_POINT_P(0);
    CIRCLE     *circle = PG_GETARG_CIRCLE_P(1);
    double      d;

    d = point_dt(&circle->center, point);
    PG_RETURN_BOOL(d <= circle->radius);
}

Datum pt_contained_poly ( PG_FUNCTION_ARGS   )