PostgreSQL Source Code git master
Loading...
Searching...
No Matches
geo_ops.c File Reference
#include "postgres.h"
#include <math.h>
#include <limits.h>
#include <float.h>
#include <ctype.h>
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
#include "utils/fmgrprotos.h"
#include "utils/geo_decls.h"
#include "varatt.h"
Include dependency graph for geo_ops.c:

Go to the source code of this file.

Macros

#define LDELIM   '('
 
#define RDELIM   ')'
 
#define DELIM   ','
 
#define LDELIM_EP   '['
 
#define RDELIM_EP   ']'
 
#define LDELIM_C   '<'
 
#define RDELIM_C   '>'
 
#define LDELIM_L   '{'
 
#define RDELIM_L   '}'
 
#define POINT_ON_POLYGON   INT_MAX
 

Enumerations

enum  path_delim { PATH_NONE , PATH_OPEN , PATH_CLOSED }
 

Functions

static void point_construct (Point *result, float8 x, float8 y)
 
static void point_add_point (Point *result, Point *pt1, Point *pt2, Node *escontext)
 
static void point_sub_point (Point *result, Point *pt1, Point *pt2)
 
static void point_mul_point (Point *result, Point *pt1, Point *pt2)
 
static void point_div_point (Point *result, Point *pt1, Point *pt2)
 
static bool point_eq_point (Point *pt1, Point *pt2)
 
static float8 point_dt (Point *pt1, Point *pt2, Node *escontext)
 
static float8 point_sl (Point *pt1, Point *pt2)
 
static int point_inside (Point *p, int npts, Point *plist)
 
static void line_construct (LINE *result, Point *pt, float8 m)
 
static float8 line_sl (LINE *line)
 
static float8 line_invsl (LINE *line)
 
static bool line_interpt_line (Point *result, LINE *l1, LINE *l2)
 
static bool line_contain_point (LINE *line, Point *point)
 
static float8 line_closept_point (Point *result, LINE *line, Point *point)
 
static void statlseg_construct (LSEG *lseg, Point *pt1, Point *pt2)
 
static float8 lseg_sl (LSEG *lseg)
 
static float8 lseg_invsl (LSEG *lseg)
 
static bool lseg_interpt_line (Point *result, LSEG *lseg, LINE *line)
 
static bool lseg_interpt_lseg (Point *result, LSEG *l1, LSEG *l2)
 
static int lseg_crossing (float8 x, float8 y, float8 prev_x, float8 prev_y)
 
static bool lseg_contain_point (LSEG *lseg, Point *pt)
 
static float8 lseg_closept_point (Point *result, LSEG *lseg, Point *pt)
 
static float8 lseg_closept_line (Point *result, LSEG *lseg, LINE *line)
 
static float8 lseg_closept_lseg (Point *result, LSEG *on_lseg, LSEG *to_lseg)
 
static void box_construct (BOX *result, Point *pt1, Point *pt2)
 
static void box_cn (Point *center, BOX *box, Node *escontext)
 
static bool box_ov (BOX *box1, BOX *box2)
 
static float8 box_ar (BOX *box)
 
static float8 box_ht (BOX *box)
 
static float8 box_wd (BOX *box)
 
static bool box_contain_point (BOX *box, Point *point)
 
static bool box_contain_box (BOX *contains_box, BOX *contained_box)
 
static bool box_contain_lseg (BOX *box, LSEG *lseg)
 
static bool box_interpt_lseg (Point *result, BOX *box, LSEG *lseg)
 
static float8 box_closept_point (Point *result, BOX *box, Point *pt)
 
static float8 box_closept_lseg (Point *result, BOX *box, LSEG *lseg)
 
static float8 circle_ar (CIRCLE *circle)
 
static void make_bound_box (POLYGON *poly)
 
static POLYGONcircle_poly_internal (int32 npts, const CIRCLE *circle, FunctionCallInfo fcinfo)
 
static void poly_to_circle (CIRCLE *result, POLYGON *poly, Node *escontext)
 
static bool lseg_inside_poly (Point *a, Point *b, POLYGON *poly, int start)
 
static bool poly_contain_poly (POLYGON *contains_poly, POLYGON *contained_poly)
 
static bool plist_same (int npts, Point *p1, Point *p2)
 
static float8 dist_ppoly_internal (Point *pt, POLYGON *poly)
 
static bool single_decode (char *num, float8 *x, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
 
static void single_encode (float8 x, StringInfo str)
 
static bool pair_decode (char *str, float8 *x, float8 *y, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
 
static void pair_encode (float8 x, float8 y, StringInfo str)
 
static int pair_count (char *s, char delim)
 
static bool path_decode (char *str, bool opentype, int npts, Point *p, bool *isopen, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
 
static charpath_encode (enum path_delim path_delim, int npts, Point *pt)
 
static charpath_encode (enum path_delim path_delim, int npts, Point *pt)
 
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_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)
 
static bool line_decode (char *s, const char *str, LINE *line, Node *escontext)
 
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_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 line_distance (PG_FUNCTION_ARGS)
 
Datum line_interpt (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_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_inter (PG_FUNCTION_ARGS)
 
Datum path_distance (PG_FUNCTION_ARGS)
 
Datum path_length (PG_FUNCTION_ARGS)
 
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 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)
 
static float8 point_invsl (Point *pt1, Point *pt2)
 
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_construct (PG_FUNCTION_ARGS)
 
Datum lseg_length (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_distance (PG_FUNCTION_ARGS)
 
Datum lseg_center (PG_FUNCTION_ARGS)
 
Datum lseg_interpt (PG_FUNCTION_ARGS)
 
Datum dist_pl (PG_FUNCTION_ARGS)
 
Datum dist_lp (PG_FUNCTION_ARGS)
 
Datum dist_ps (PG_FUNCTION_ARGS)
 
Datum dist_sp (PG_FUNCTION_ARGS)
 
static float8 dist_ppath_internal (Point *pt, PATH *path)
 
Datum dist_ppath (PG_FUNCTION_ARGS)
 
Datum dist_pathp (PG_FUNCTION_ARGS)
 
Datum dist_pb (PG_FUNCTION_ARGS)
 
Datum dist_bp (PG_FUNCTION_ARGS)
 
Datum dist_sl (PG_FUNCTION_ARGS)
 
Datum dist_ls (PG_FUNCTION_ARGS)
 
Datum dist_sb (PG_FUNCTION_ARGS)
 
Datum dist_bs (PG_FUNCTION_ARGS)
 
static float8 dist_cpoly_internal (CIRCLE *circle, POLYGON *poly)
 
Datum dist_cpoly (PG_FUNCTION_ARGS)
 
Datum dist_polyc (PG_FUNCTION_ARGS)
 
Datum dist_ppoly (PG_FUNCTION_ARGS)
 
Datum dist_polyp (PG_FUNCTION_ARGS)
 
Datum close_pl (PG_FUNCTION_ARGS)
 
Datum close_ps (PG_FUNCTION_ARGS)
 
Datum close_lseg (PG_FUNCTION_ARGS)
 
Datum close_pb (PG_FUNCTION_ARGS)
 
Datum close_ls (PG_FUNCTION_ARGS)
 
Datum close_sb (PG_FUNCTION_ARGS)
 
Datum on_pl (PG_FUNCTION_ARGS)
 
Datum on_ps (PG_FUNCTION_ARGS)
 
Datum on_pb (PG_FUNCTION_ARGS)
 
Datum box_contain_pt (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 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)
 
static bool poly_overlap_internal (POLYGON *polya, POLYGON *polyb)
 
Datum poly_overlap (PG_FUNCTION_ARGS)
 
static bool touched_lseg_inside_poly (Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
 
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 construct_point (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)
 
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 point_box (PG_FUNCTION_ARGS)
 
Datum boxes_bound_box (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_poly (PG_FUNCTION_ARGS)
 
Datum poly_npoints (PG_FUNCTION_ARGS)
 
Datum poly_center (PG_FUNCTION_ARGS)
 
Datum poly_box (PG_FUNCTION_ARGS)
 
Datum box_poly (PG_FUNCTION_ARGS)
 
Datum poly_path (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_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_area (PG_FUNCTION_ARGS)
 
Datum circle_diameter (PG_FUNCTION_ARGS)
 
Datum circle_radius (PG_FUNCTION_ARGS)
 
Datum circle_distance (PG_FUNCTION_ARGS)
 
Datum circle_contain_pt (PG_FUNCTION_ARGS)
 
Datum pt_contained_circle (PG_FUNCTION_ARGS)
 
Datum dist_pc (PG_FUNCTION_ARGS)
 
Datum dist_cpoint (PG_FUNCTION_ARGS)
 
Datum circle_center (PG_FUNCTION_ARGS)
 
Datum cr_circle (PG_FUNCTION_ARGS)
 
Datum circle_box (PG_FUNCTION_ARGS)
 
Datum box_circle (PG_FUNCTION_ARGS)
 
Datum circle_poly (PG_FUNCTION_ARGS)
 
Datum circle_to_poly (PG_FUNCTION_ARGS)
 
Datum poly_circle (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ DELIM

#define DELIM   ','

Definition at line 160 of file geo_ops.c.

◆ LDELIM

#define LDELIM   '('

Definition at line 158 of file geo_ops.c.

◆ LDELIM_C

#define LDELIM_C   '<'

Definition at line 163 of file geo_ops.c.

◆ LDELIM_EP

#define LDELIM_EP   '['

Definition at line 161 of file geo_ops.c.

◆ LDELIM_L

#define LDELIM_L   '{'

Definition at line 165 of file geo_ops.c.

◆ POINT_ON_POLYGON

#define POINT_ON_POLYGON   INT_MAX

Definition at line 5489 of file geo_ops.c.

◆ RDELIM

#define RDELIM   ')'

Definition at line 159 of file geo_ops.c.

◆ RDELIM_C

#define RDELIM_C   '>'

Definition at line 164 of file geo_ops.c.

◆ RDELIM_EP

#define RDELIM_EP   ']'

Definition at line 162 of file geo_ops.c.

◆ RDELIM_L

#define RDELIM_L   '}'

Definition at line 166 of file geo_ops.c.

Enumeration Type Documentation

◆ path_delim

Enumerator
PATH_NONE 
PATH_OPEN 
PATH_CLOSED 

Definition at line 73 of file geo_ops.c.

74{
76};
@ PATH_NONE
Definition geo_ops.c:75
@ PATH_CLOSED
Definition geo_ops.c:75
@ PATH_OPEN
Definition geo_ops.c:75

Function Documentation

◆ box_above()

Datum box_above ( PG_FUNCTION_ARGS  )

Definition at line 659 of file geo_ops.c.

660{
663
664 PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));
665}
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_BOX_P(n)
Definition geo_decls.h:242
static bool FPgt(double A, double B)
Definition geo_decls.h:71
static int fb(int x)

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

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

◆ box_above_eq()

Datum box_above_eq ( PG_FUNCTION_ARGS  )

Definition at line 732 of file geo_ops.c.

733{
736
737 PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
738}
static bool FPge(double A, double B)
Definition geo_decls.h:77

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

◆ box_add()

Datum box_add ( PG_FUNCTION_ARGS  )

Definition at line 4287 of file geo_ops.c.

4288{
4289 BOX *box = PG_GETARG_BOX_P(0);
4290 Point *p = PG_GETARG_POINT_P(1);
4291 BOX *result;
4292
4294
4295 point_add_point(&result->high, &box->high, p, NULL);
4296 point_add_point(&result->low, &box->low, p, NULL);
4297
4299}
uint32 result
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_GETARG_POINT_P(n)
Definition geo_decls.h:184
#define PG_RETURN_BOX_P(x)
Definition geo_decls.h:243
static void point_add_point(Point *result, Point *pt1, Point *pt2, Node *escontext)
Definition geo_ops.c:4158

References fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, point_add_point(), and result.

◆ box_ar()

static float8 box_ar ( BOX box)
static

Definition at line 866 of file geo_ops.c.

867{
868 return float8_mul(box_wd(box), box_ht(box));
869}
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:192
static float8 box_ht(BOX *box)
Definition geo_ops.c:911
static float8 box_wd(BOX *box)
Definition geo_ops.c:901

References box_ht(), box_wd(), fb(), and float8_mul().

Referenced by box_area(), box_eq(), box_ge(), box_gt(), box_le(), and box_lt().

◆ box_area()

Datum box_area ( PG_FUNCTION_ARGS  )

Definition at line 797 of file geo_ops.c.

798{
799 BOX *box = PG_GETARG_BOX_P(0);
800
802}
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
static float8 box_ar(BOX *box)
Definition geo_ops.c:866

References box_ar(), fb(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ box_below()

Datum box_below ( PG_FUNCTION_ARGS  )

Definition at line 636 of file geo_ops.c.

637{
640
641 PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));
642}
static bool FPlt(double A, double B)
Definition geo_decls.h:59

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

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

◆ box_below_eq()

Datum box_below_eq ( PG_FUNCTION_ARGS  )

Definition at line 723 of file geo_ops.c.

724{
727
728 PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
729}
static bool FPle(double A, double B)
Definition geo_decls.h:65

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

◆ box_center()

Datum box_center ( PG_FUNCTION_ARGS  )

Definition at line 850 of file geo_ops.c.

851{
852 BOX *box = PG_GETARG_BOX_P(0);
854
855 box_cn(result, box, fcinfo->context);
856 if (SOFT_ERROR_OCCURRED(fcinfo->context))
858
860}
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_POINT_P(x)
Definition geo_decls.h:185
static void box_cn(Point *center, BOX *box, Node *escontext)
Definition geo_ops.c:875
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53

References box_cn(), fb(), palloc_object, PG_GETARG_BOX_P, PG_RETURN_NULL, PG_RETURN_POINT_P, result, and SOFT_ERROR_OCCURRED.

◆ box_circle()

Datum box_circle ( PG_FUNCTION_ARGS  )

Definition at line 5283 of file geo_ops.c.

5284{
5285 BOX *box = PG_GETARG_BOX_P(0);
5286 CIRCLE *circle;
5287 float8 x;
5288 float8 y;
5289
5291
5292 x = float8_pl_safe(box->high.x, box->low.x, fcinfo->context);
5293 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5294 goto fail;
5295
5296 circle->center.x = float8_div_safe(x, 2.0, fcinfo->context);
5297 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5298 goto fail;
5299
5300 y = float8_pl_safe(box->high.y, box->low.y, fcinfo->context);
5301 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5302 goto fail;
5303
5304 circle->center.y = float8_div_safe(y, 2.0, fcinfo->context);
5305 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5306 goto fail;
5307
5308 circle->radius = point_dt(&circle->center, &box->high,
5309 fcinfo->context);
5310
5311 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5312 goto fail;
5313
5315
5316fail:
5318}
double float8
Definition c.h:714
static float8 float8_pl_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:116
static float8 float8_div_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:214
#define PG_RETURN_CIRCLE_P(x)
Definition geo_decls.h:275
static float8 point_dt(Point *pt1, Point *pt2, Node *escontext)
Definition geo_ops.c:2020
int y
Definition isn.c:76
int x
Definition isn.c:75

References fb(), float8_div_safe(), float8_pl_safe(), palloc_object, PG_GETARG_BOX_P, PG_RETURN_CIRCLE_P, PG_RETURN_NULL, point_dt(), SOFT_ERROR_OCCURRED, x, and y.

◆ box_closept_lseg()

static float8 box_closept_lseg ( Point result,
BOX box,
LSEG lseg 
)
static

Definition at line 3060 of file geo_ops.c.

3061{
3062 float8 dist,
3063 d;
3064 Point point,
3065 closept;
3066 LSEG bseg;
3067
3069 return 0.0;
3070
3071 /* pairwise check lseg distances */
3072 point.x = box->low.x;
3073 point.y = box->high.y;
3074 statlseg_construct(&bseg, &box->low, &point);
3076
3077 statlseg_construct(&bseg, &box->high, &point);
3079 if (float8_lt(d, dist))
3080 {
3081 dist = d;
3082 if (result != NULL)
3083 *result = closept;
3084 }
3085
3086 point.x = box->high.x;
3087 point.y = box->low.y;
3088 statlseg_construct(&bseg, &box->low, &point);
3090 if (float8_lt(d, dist))
3091 {
3092 dist = d;
3093 if (result != NULL)
3094 *result = closept;
3095 }
3096
3097 statlseg_construct(&bseg, &box->high, &point);
3099 if (float8_lt(d, dist))
3100 {
3101 dist = d;
3102 if (result != NULL)
3103 *result = closept;
3104 }
3105
3106 return dist;
3107}
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:274
static bool box_interpt_lseg(Point *result, BOX *box, LSEG *lseg)
Definition geo_ops.c:3310
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2)
Definition geo_ops.c:2171
static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
Definition geo_ops.c:2857

References box_interpt_lseg(), fb(), float8_lt(), lseg_closept_lseg(), result, and statlseg_construct().

Referenced by close_sb(), dist_bs(), and dist_sb().

◆ box_closept_point()

static float8 box_closept_point ( Point result,
BOX box,
Point pt 
)
static

Definition at line 2925 of file geo_ops.c.

2926{
2927 float8 dist,
2928 d;
2929 Point point,
2930 closept;
2931 LSEG lseg;
2932
2933 if (box_contain_point(box, pt))
2934 {
2935 if (result != NULL)
2936 *result = *pt;
2937
2938 return 0.0;
2939 }
2940
2941 /* pairwise check lseg distances */
2942 point.x = box->low.x;
2943 point.y = box->high.y;
2944 statlseg_construct(&lseg, &box->low, &point);
2946
2947 statlseg_construct(&lseg, &box->high, &point);
2949 if (float8_lt(d, dist))
2950 {
2951 dist = d;
2952 if (result != NULL)
2953 *result = closept;
2954 }
2955
2956 point.x = box->high.x;
2957 point.y = box->low.y;
2958 statlseg_construct(&lseg, &box->low, &point);
2960 if (float8_lt(d, dist))
2961 {
2962 dist = d;
2963 if (result != NULL)
2964 *result = closept;
2965 }
2966
2967 statlseg_construct(&lseg, &box->high, &point);
2969 if (float8_lt(d, dist))
2970 {
2971 dist = d;
2972 if (result != NULL)
2973 *result = closept;
2974 }
2975
2976 return dist;
2977}
static float8 lseg_closept_point(Point *result, LSEG *lseg, Point *pt)
Definition geo_ops.c:2819
static bool box_contain_point(BOX *box, Point *point)
Definition geo_ops.c:3177

References box_contain_point(), fb(), float8_lt(), lseg_closept_point(), result, and statlseg_construct().

Referenced by close_pb(), dist_bp(), and dist_pb().

◆ box_cn()

static void box_cn ( Point center,
BOX box,
Node escontext 
)
static

Definition at line 875 of file geo_ops.c.

876{
877 float8 x;
878 float8 y;
879
880 x = float8_pl_safe(box->high.x, box->low.x, escontext);
881 if (SOFT_ERROR_OCCURRED(escontext))
882 return;
883
884 center->x = float8_div_safe(x, 2.0, escontext);
885 if (SOFT_ERROR_OCCURRED(escontext))
886 return;
887
888 y = float8_pl_safe(box->high.y, box->low.y, escontext);
889 if (SOFT_ERROR_OCCURRED(escontext))
890 return;
891
892 center->y = float8_div_safe(y, 2.0, escontext);
893 if (SOFT_ERROR_OCCURRED(escontext))
894 return;
895}
float8 y
Definition geo_decls.h:98
float8 x
Definition geo_decls.h:97

References fb(), float8_div_safe(), float8_pl_safe(), SOFT_ERROR_OCCURRED, x, Point::x, y, and Point::y.

Referenced by box_center(), box_distance(), and box_interpt_lseg().

◆ box_construct()

static void box_construct ( BOX result,
Point pt1,
Point pt2 
)
inlinestatic

Definition at line 519 of file geo_ops.c.

520{
521 if (float8_gt(pt1->x, pt2->x))
522 {
523 result->high.x = pt1->x;
524 result->low.x = pt2->x;
525 }
526 else
527 {
528 result->high.x = pt2->x;
529 result->low.x = pt1->x;
530 }
531 if (float8_gt(pt1->y, pt2->y))
532 {
533 result->high.y = pt1->y;
534 result->low.y = pt2->y;
535 }
536 else
537 {
538 result->high.y = pt2->y;
539 result->low.y = pt1->y;
540 }
541}
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:298

References fb(), float8_gt(), and result.

Referenced by box_div(), box_mul(), box_poly(), and points_box().

◆ box_contain()

Datum box_contain ( PG_FUNCTION_ARGS  )

Definition at line 693 of file geo_ops.c.

694{
697
699}
static bool box_contain_box(BOX *contains_box, BOX *contained_box)
Definition geo_ops.c:705

References box_contain_box(), fb(), PG_GETARG_BOX_P, and PG_RETURN_BOOL.

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

◆ box_contain_box()

static bool box_contain_box ( BOX contains_box,
BOX contained_box 
)
static

Definition at line 705 of file geo_ops.c.

706{
707 return FPge(contains_box->high.x, contained_box->high.x) &&
708 FPle(contains_box->low.x, contained_box->low.x) &&
709 FPge(contains_box->high.y, contained_box->high.y) &&
710 FPle(contains_box->low.y, contained_box->low.y);
711}

References fb(), FPge(), and FPle().

Referenced by box_contain(), box_contained(), and poly_contain_poly().

◆ box_contain_lseg()

static bool box_contain_lseg ( BOX box,
LSEG lseg 
)
static

Definition at line 3264 of file geo_ops.c.

3265{
3266 return box_contain_point(box, &lseg->p[0]) &&
3267 box_contain_point(box, &lseg->p[1]);
3268}

References box_contain_point(), and fb().

Referenced by on_sb().

◆ box_contain_point()

static bool box_contain_point ( BOX box,
Point point 
)
static

Definition at line 3177 of file geo_ops.c.

3178{
3179 return box->high.x >= point->x && box->low.x <= point->x &&
3180 box->high.y >= point->y && box->low.y <= point->y;
3181}

References fb().

Referenced by box_closept_point(), box_contain_lseg(), box_contain_pt(), box_interpt_lseg(), and on_pb().

◆ box_contain_pt()

Datum box_contain_pt ( PG_FUNCTION_ARGS  )

◆ box_contained()

Datum box_contained ( PG_FUNCTION_ARGS  )

◆ box_diagonal()

Datum box_diagonal ( PG_FUNCTION_ARGS  )

Definition at line 951 of file geo_ops.c.

952{
953 BOX *box = PG_GETARG_BOX_P(0);
955
956 statlseg_construct(result, &box->high, &box->low);
957
959}
#define PG_RETURN_LSEG_P(x)
Definition geo_decls.h:198

References fb(), palloc_object, PG_GETARG_BOX_P, PG_RETURN_LSEG_P, result, and statlseg_construct().

◆ box_distance()

Datum box_distance ( PG_FUNCTION_ARGS  )

Definition at line 833 of file geo_ops.c.

834{
837 Point a,
838 b;
839
840 box_cn(&a, box1, NULL);
841 box_cn(&b, box2, NULL);
842
844}
int b
Definition isn.c:74
int a
Definition isn.c:73

References a, b, box_cn(), fb(), PG_GETARG_BOX_P, PG_RETURN_FLOAT8, and point_dt().

◆ box_div()

Datum box_div ( PG_FUNCTION_ARGS  )

Definition at line 4336 of file geo_ops.c.

4337{
4338 BOX *box = PG_GETARG_BOX_P(0);
4339 Point *p = PG_GETARG_POINT_P(1);
4340 BOX *result;
4341 Point high,
4342 low;
4343
4345
4346 point_div_point(&high, &box->high, p);
4347 point_div_point(&low, &box->low, p);
4348
4349 box_construct(result, &high, &low);
4350
4352}
static void point_div_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4238
static void box_construct(BOX *result, Point *pt1, Point *pt2)
Definition geo_ops.c:519

References box_construct(), fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, point_div_point(), and result.

◆ box_eq()

Datum box_eq ( PG_FUNCTION_ARGS  )

Definition at line 763 of file geo_ops.c.

764{
767
769}
static bool FPeq(double A, double B)
Definition geo_decls.h:47

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

◆ box_ge()

Datum box_ge ( PG_FUNCTION_ARGS  )

Definition at line 781 of file geo_ops.c.

782{
785
787}

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

◆ box_gt()

Datum box_gt ( PG_FUNCTION_ARGS  )

Definition at line 754 of file geo_ops.c.

755{
758
760}

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

◆ box_height()

Datum box_height ( PG_FUNCTION_ARGS  )

Definition at line 821 of file geo_ops.c.

822{
823 BOX *box = PG_GETARG_BOX_P(0);
824
826}

References box_ht(), fb(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ box_ht()

static float8 box_ht ( BOX box)
static

Definition at line 911 of file geo_ops.c.

912{
913 return float8_mi(box->high.y, box->low.y);
914}
static float8 float8_mi(const float8 val1, const float8 val2)
Definition float.h:158

References fb(), and float8_mi().

Referenced by box_ar(), and box_height().

◆ box_in()

Datum box_in ( PG_FUNCTION_ARGS  )

Definition at line 423 of file geo_ops.c.

424{
425 char *str = PG_GETARG_CSTRING(0);
426 Node *escontext = fcinfo->context;
428 bool isopen;
429 float8 x,
430 y;
431
432 if (!path_decode(str, false, 2, &(box->high), &isopen, NULL, "box", str,
433 escontext))
435
436 /* reorder corners if necessary... */
437 if (float8_lt(box->high.x, box->low.x))
438 {
439 x = box->high.x;
440 box->high.x = box->low.x;
441 box->low.x = x;
442 }
443 if (float8_lt(box->high.y, box->low.y))
444 {
445 y = box->high.y;
446 box->high.y = box->low.y;
447 box->low.y = y;
448 }
449
451}
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
static bool path_decode(char *str, bool opentype, int npts, Point *p, bool *isopen, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Definition geo_ops.c:267
const char * str
Definition nodes.h:135

References fb(), float8_lt(), palloc_object, path_decode(), PG_GETARG_CSTRING, PG_RETURN_BOX_P, PG_RETURN_NULL, str, x, and y.

◆ box_interpt_lseg()

static bool box_interpt_lseg ( Point result,
BOX box,
LSEG lseg 
)
static

Definition at line 3310 of file geo_ops.c.

3311{
3312 BOX lbox;
3313 LSEG bseg;
3314 Point point;
3315
3316 lbox.low.x = float8_min(lseg->p[0].x, lseg->p[1].x);
3317 lbox.low.y = float8_min(lseg->p[0].y, lseg->p[1].y);
3318 lbox.high.x = float8_max(lseg->p[0].x, lseg->p[1].x);
3319 lbox.high.y = float8_max(lseg->p[0].y, lseg->p[1].y);
3320
3321 /* nothing close to overlap? then not going to intersect */
3322 if (!box_ov(&lbox, box))
3323 return false;
3324
3325 if (result != NULL)
3326 {
3327 box_cn(&point, box, NULL);
3329 }
3330
3331 /* an endpoint of segment is inside box? then clearly intersects */
3332 if (box_contain_point(box, &lseg->p[0]) ||
3333 box_contain_point(box, &lseg->p[1]))
3334 return true;
3335
3336 /* pairwise check lseg intersections */
3337 point.x = box->low.x;
3338 point.y = box->high.y;
3339 statlseg_construct(&bseg, &box->low, &point);
3341 return true;
3342
3343 statlseg_construct(&bseg, &box->high, &point);
3345 return true;
3346
3347 point.x = box->high.x;
3348 point.y = box->low.y;
3349 statlseg_construct(&bseg, &box->low, &point);
3351 return true;
3352
3353 statlseg_construct(&bseg, &box->high, &point);
3355 return true;
3356
3357 /* if we dropped through, no two segs intersected */
3358 return false;
3359}
static float8 float8_min(const float8 val1, const float8 val2)
Definition float.h:322
static float8 float8_max(const float8 val1, const float8 val2)
Definition float.h:334
static bool box_ov(BOX *box1, BOX *box2)
Definition geo_ops.c:573
static bool lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2)
Definition geo_ops.c:2385

References box_cn(), box_contain_point(), box_ov(), fb(), float8_max(), float8_min(), lseg_closept_point(), lseg_interpt_lseg(), result, statlseg_construct(), and Point::x.

Referenced by box_closept_lseg(), and inter_sb().

◆ box_intersect()

Datum box_intersect ( PG_FUNCTION_ARGS  )

Definition at line 926 of file geo_ops.c.

927{
930 BOX *result;
931
932 if (!box_ov(box1, box2))
934
936
937 result->high.x = float8_min(box1->high.x, box2->high.x);
938 result->low.x = float8_max(box1->low.x, box2->low.x);
939 result->high.y = float8_min(box1->high.y, box2->high.y);
940 result->low.y = float8_max(box1->low.y, box2->low.y);
941
943}

References box_ov(), fb(), float8_max(), float8_min(), palloc_object, PG_GETARG_BOX_P, PG_RETURN_BOX_P, PG_RETURN_NULL, and result.

◆ box_le()

Datum box_le ( PG_FUNCTION_ARGS  )

Definition at line 772 of file geo_ops.c.

773{
776
778}

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

◆ box_left()

Datum box_left ( PG_FUNCTION_ARGS  )

Definition at line 584 of file geo_ops.c.

585{
588
589 PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x));
590}

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

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

◆ box_lt()

Datum box_lt ( PG_FUNCTION_ARGS  )

Definition at line 745 of file geo_ops.c.

746{
749
751}

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

◆ box_mul()

Datum box_mul ( PG_FUNCTION_ARGS  )

Definition at line 4317 of file geo_ops.c.

4318{
4319 BOX *box = PG_GETARG_BOX_P(0);
4320 Point *p = PG_GETARG_POINT_P(1);
4321 BOX *result;
4322 Point high,
4323 low;
4324
4326
4327 point_mul_point(&high, &box->high, p);
4328 point_mul_point(&low, &box->low, p);
4329
4330 box_construct(result, &high, &low);
4331
4333}
static void point_mul_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4213

References box_construct(), fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, point_mul_point(), and result.

◆ box_out()

Datum box_out ( PG_FUNCTION_ARGS  )

Definition at line 456 of file geo_ops.c.

457{
458 BOX *box = PG_GETARG_BOX_P(0);
459
461}
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
static char * path_encode(enum path_delim path_delim, int npts, Point *pt)

References fb(), path_encode(), PATH_NONE, PG_GETARG_BOX_P, and PG_RETURN_CSTRING.

◆ box_ov()

static bool box_ov ( BOX box1,
BOX box2 
)
static

Definition at line 573 of file geo_ops.c.

574{
575 return (FPle(box1->low.x, box2->high.x) &&
576 FPle(box2->low.x, box1->high.x) &&
577 FPle(box1->low.y, box2->high.y) &&
578 FPle(box2->low.y, box1->high.y));
579}

References fb(), and FPle().

Referenced by box_interpt_lseg(), box_intersect(), box_overlap(), path_inter(), and poly_overlap_internal().

◆ box_overabove()

Datum box_overabove ( PG_FUNCTION_ARGS  )

Definition at line 671 of file geo_ops.c.

672{
675
676 PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));
677}

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

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

◆ box_overbelow()

Datum box_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 648 of file geo_ops.c.

649{
652
653 PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));
654}

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

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

◆ box_overlap()

◆ box_overleft()

Datum box_overleft ( PG_FUNCTION_ARGS  )

Definition at line 599 of file geo_ops.c.

600{
603
604 PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x));
605}

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

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

◆ box_overright()

Datum box_overright ( PG_FUNCTION_ARGS  )

Definition at line 625 of file geo_ops.c.

626{
629
630 PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));
631}

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

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

◆ box_poly()

Datum box_poly ( PG_FUNCTION_ARGS  )

Definition at line 4594 of file geo_ops.c.

4595{
4596 BOX *box = PG_GETARG_BOX_P(0);
4597 POLYGON *poly;
4598 int size;
4599
4600 /* map four corners of the box to a polygon */
4601 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * 4;
4602 poly = (POLYGON *) palloc(size);
4603
4604 SET_VARSIZE(poly, size);
4605 poly->npts = 4;
4606
4607 poly->p[0].x = box->low.x;
4608 poly->p[0].y = box->low.y;
4609 poly->p[1].x = box->low.x;
4610 poly->p[1].y = box->high.y;
4611 poly->p[2].x = box->high.x;
4612 poly->p[2].y = box->high.y;
4613 poly->p[3].x = box->high.x;
4614 poly->p[3].y = box->low.y;
4615
4616 box_construct(&poly->boundbox, &box->high, &box->low);
4617
4619}
#define PG_RETURN_POLYGON_P(x)
Definition geo_decls.h:262
void * palloc(Size size)
Definition mcxt.c:1387
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References box_construct(), fb(), palloc(), PG_GETARG_BOX_P, PG_RETURN_POLYGON_P, and SET_VARSIZE().

◆ box_recv()

Datum box_recv ( PG_FUNCTION_ARGS  )

Definition at line 467 of file geo_ops.c.

468{
470 BOX *box;
471 float8 x,
472 y;
473
475
476 box->high.x = pq_getmsgfloat8(buf);
477 box->high.y = pq_getmsgfloat8(buf);
478 box->low.x = pq_getmsgfloat8(buf);
479 box->low.y = pq_getmsgfloat8(buf);
480
481 /* reorder corners if necessary... */
482 if (float8_lt(box->high.x, box->low.x))
483 {
484 x = box->high.x;
485 box->high.x = box->low.x;
486 box->low.x = x;
487 }
488 if (float8_lt(box->high.y, box->low.y))
489 {
490 y = box->high.y;
491 box->high.y = box->low.y;
492 box->low.y = y;
493 }
494
496}
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
static char buf[DEFAULT_XLOG_SEG_SIZE]
float8 pq_getmsgfloat8(StringInfo msg)
Definition pqformat.c:487
struct StringInfoData * StringInfo
Definition string.h:15

References buf, fb(), float8_lt(), palloc_object, PG_GETARG_POINTER, PG_RETURN_BOX_P, pq_getmsgfloat8(), x, and y.

◆ box_right()

Datum box_right ( PG_FUNCTION_ARGS  )

Definition at line 610 of file geo_ops.c.

611{
614
615 PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));
616}

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

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

◆ box_same()

Datum box_same ( PG_FUNCTION_ARGS  )

Definition at line 552 of file geo_ops.c.

553{
556
557 PG_RETURN_BOOL(point_eq_point(&box1->high, &box2->high) &&
558 point_eq_point(&box1->low, &box2->low));
559}
static bool point_eq_point(Point *pt1, Point *pt2)
Definition geo_ops.c:1995

References fb(), PG_GETARG_BOX_P, PG_RETURN_BOOL, and point_eq_point().

Referenced by gist_box_leaf_consistent(), and spg_box_quad_leaf_consistent().

◆ box_send()

Datum box_send ( PG_FUNCTION_ARGS  )

Definition at line 502 of file geo_ops.c.

503{
504 BOX *box = PG_GETARG_BOX_P(0);
506
508 pq_sendfloat8(&buf, box->high.x);
509 pq_sendfloat8(&buf, box->high.y);
510 pq_sendfloat8(&buf, box->low.x);
511 pq_sendfloat8(&buf, box->low.y);
513}
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
void pq_sendfloat8(StringInfo buf, float8 f)
Definition pqformat.c:276

References buf, fb(), PG_GETARG_BOX_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat8().

◆ box_sub()

Datum box_sub ( PG_FUNCTION_ARGS  )

Definition at line 4302 of file geo_ops.c.

4303{
4304 BOX *box = PG_GETARG_BOX_P(0);
4305 Point *p = PG_GETARG_POINT_P(1);
4306 BOX *result;
4307
4309
4310 point_sub_point(&result->high, &box->high, p);
4311 point_sub_point(&result->low, &box->low, p);
4312
4314}
static void point_sub_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4190

References fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, point_sub_point(), and result.

◆ box_wd()

static float8 box_wd ( BOX box)
static

Definition at line 901 of file geo_ops.c.

902{
903 return float8_mi(box->high.x, box->low.x);
904}

References fb(), and float8_mi().

Referenced by box_ar(), and box_width().

◆ box_width()

Datum box_width ( PG_FUNCTION_ARGS  )

Definition at line 809 of file geo_ops.c.

810{
811 BOX *box = PG_GETARG_BOX_P(0);
812
814}

References box_wd(), fb(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ boxes_bound_box()

Datum boxes_bound_box ( PG_FUNCTION_ARGS  )

Definition at line 4377 of file geo_ops.c.

4378{
4379 BOX *box1 = PG_GETARG_BOX_P(0),
4380 *box2 = PG_GETARG_BOX_P(1),
4381 *container;
4382
4383 container = palloc_object(BOX);
4384
4385 container->high.x = float8_max(box1->high.x, box2->high.x);
4386 container->low.x = float8_min(box1->low.x, box2->low.x);
4387 container->high.y = float8_max(box1->high.y, box2->high.y);
4388 container->low.y = float8_min(box1->low.y, box2->low.y);
4389
4390 PG_RETURN_BOX_P(container);
4391}

References fb(), float8_max(), float8_min(), palloc_object, PG_GETARG_BOX_P, and PG_RETURN_BOX_P.

◆ circle_above()

Datum circle_above ( PG_FUNCTION_ARGS  )

Definition at line 4922 of file geo_ops.c.

4923{
4926
4927 PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.y, circle1->radius),
4928 float8_pl(circle2->center.y, circle2->radius)));
4929}
static float8 float8_pl(const float8 val1, const float8 val2)
Definition float.h:128
#define PG_GETARG_CIRCLE_P(n)
Definition geo_decls.h:274

References fb(), float8_mi(), float8_pl(), FPgt(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_add_pt()

Datum circle_add_pt ( PG_FUNCTION_ARGS  )

Definition at line 5024 of file geo_ops.c.

5025{
5028 CIRCLE *result;
5029
5031
5032 point_add_point(&result->center, &circle->center, point, NULL);
5033 result->radius = circle->radius;
5034
5036}

References fb(), palloc_object, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_add_point(), and result.

◆ circle_ar()

static float8 circle_ar ( CIRCLE circle)
static

Definition at line 5218 of file geo_ops.c.

5219{
5220 return float8_mul(float8_mul(circle->radius, circle->radius), M_PI);
5221}
#define M_PI

References fb(), float8_mul(), and M_PI.

Referenced by circle_area(), circle_eq(), circle_ge(), circle_gt(), circle_le(), circle_lt(), and circle_ne().

◆ circle_area()

Datum circle_area ( PG_FUNCTION_ARGS  )

Definition at line 5091 of file geo_ops.c.

5092{
5094
5096}
static float8 circle_ar(CIRCLE *circle)
Definition geo_ops.c:5218

References circle_ar(), fb(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

◆ circle_below()

Datum circle_below ( PG_FUNCTION_ARGS  )

Definition at line 4910 of file geo_ops.c.

4911{
4914
4915 PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.y, circle1->radius),
4916 float8_mi(circle2->center.y, circle2->radius)));
4917}

References fb(), float8_mi(), float8_pl(), FPlt(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_box()

Datum circle_box ( PG_FUNCTION_ARGS  )

Definition at line 5245 of file geo_ops.c.

5246{
5248 BOX *box;
5249 float8 delta;
5250
5252
5253 delta = float8_div_safe(circle->radius, sqrt(2.0), fcinfo->context);
5254 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5255 goto fail;
5256
5257 box->high.x = float8_pl_safe(circle->center.x, delta, fcinfo->context);
5258 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5259 goto fail;
5260
5261 box->low.x = float8_mi_safe(circle->center.x, delta, fcinfo->context);
5262 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5263 goto fail;
5264
5265 box->high.y = float8_pl_safe(circle->center.y, delta, fcinfo->context);
5266 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5267 goto fail;
5268
5269 box->low.y = float8_mi_safe(circle->center.y, delta, fcinfo->context);
5270 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5271 goto fail;
5272
5274
5275fail:
5277}
static float8 float8_mi_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:146

References fb(), float8_div_safe(), float8_mi_safe(), float8_pl_safe(), palloc_object, PG_GETARG_CIRCLE_P, PG_RETURN_BOX_P, PG_RETURN_NULL, and SOFT_ERROR_OCCURRED.

◆ circle_center()

Datum circle_center ( PG_FUNCTION_ARGS  )

Definition at line 5202 of file geo_ops.c.

5203{
5205 Point *result;
5206
5208 result->x = circle->center.x;
5209 result->y = circle->center.y;
5210
5212}

References fb(), palloc_object, PG_GETARG_CIRCLE_P, PG_RETURN_POINT_P, and result.

◆ circle_contain()

Datum circle_contain ( PG_FUNCTION_ARGS  )

Definition at line 4897 of file geo_ops.c.

4898{
4901
4902 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4903 float8_mi(circle1->radius, circle2->radius)));
4904}

References fb(), float8_mi(), FPle(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, and point_dt().

◆ circle_contain_pt()

Datum circle_contain_pt ( PG_FUNCTION_ARGS  )

Definition at line 5141 of file geo_ops.c.

5142{
5145 float8 d;
5146
5147 d = point_dt(&circle->center, point, NULL);
5149}

References fb(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_dt().

Referenced by gist_point_consistent().

◆ circle_contained()

Datum circle_contained ( PG_FUNCTION_ARGS  )

Definition at line 4885 of file geo_ops.c.

4886{
4889
4890 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4891 float8_mi(circle2->radius, circle1->radius)));
4892}

References fb(), float8_mi(), FPle(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, and point_dt().

◆ circle_diameter()

Datum circle_diameter ( PG_FUNCTION_ARGS  )

Definition at line 5102 of file geo_ops.c.

5103{
5105
5106 PG_RETURN_FLOAT8(float8_mul(circle->radius, 2.0));
5107}

References fb(), float8_mul(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

◆ circle_distance()

Datum circle_distance ( PG_FUNCTION_ARGS  )

Definition at line 5125 of file geo_ops.c.

5126{
5129 float8 result;
5130
5131 result = float8_mi(point_dt(&circle1->center, &circle2->center, NULL),
5132 float8_pl(circle1->radius, circle2->radius));
5133 if (result < 0.0)
5134 result = 0.0;
5135
5137}

References fb(), float8_mi(), float8_pl(), PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, point_dt(), and result.

◆ circle_div_pt()

Datum circle_div_pt ( PG_FUNCTION_ARGS  )

Definition at line 5073 of file geo_ops.c.

5074{
5077 CIRCLE *result;
5078
5080
5081 point_div_point(&result->center, &circle->center, point);
5082 result->radius = float8_div(circle->radius, hypot(point->x, point->y));
5083
5085}
static float8 float8_div(const float8 val1, const float8 val2)
Definition float.h:230

References fb(), float8_div(), palloc_object, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_div_point(), and result.

◆ circle_eq()

Datum circle_eq ( PG_FUNCTION_ARGS  )

Definition at line 4962 of file geo_ops.c.

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

◆ circle_ge()

Datum circle_ge ( PG_FUNCTION_ARGS  )

Definition at line 5007 of file geo_ops.c.

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

◆ circle_gt()

Datum circle_gt ( PG_FUNCTION_ARGS  )

Definition at line 4989 of file geo_ops.c.

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

◆ circle_in()

Datum circle_in ( PG_FUNCTION_ARGS  )

Definition at line 4670 of file geo_ops.c.

4671{
4672 char *str = PG_GETARG_CSTRING(0);
4673 Node *escontext = fcinfo->context;
4675 char *s,
4676 *cp;
4677 int depth = 0;
4678
4679 s = str;
4680 while (isspace((unsigned char) *s))
4681 s++;
4682 if (*s == LDELIM_C)
4683 depth++, s++;
4684 else if (*s == LDELIM)
4685 {
4686 /* If there are two left parens, consume the first one */
4687 cp = (s + 1);
4688 while (isspace((unsigned char) *cp))
4689 cp++;
4690 if (*cp == LDELIM)
4691 depth++, s = cp;
4692 }
4693
4694 /* pair_decode will consume parens around the pair, if any */
4695 if (!pair_decode(s, &circle->center.x, &circle->center.y, &s, "circle", str,
4696 escontext))
4698
4699 if (*s == DELIM)
4700 s++;
4701
4702 if (!single_decode(s, &circle->radius, &s, "circle", str, escontext))
4704
4705 /* We have to accept NaN. */
4706 if (circle->radius < 0.0)
4707 ereturn(escontext, (Datum) 0,
4709 errmsg("invalid input syntax for type %s: \"%s\"",
4710 "circle", str)));
4711
4712 while (depth > 0)
4713 {
4714 if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1)))
4715 {
4716 depth--;
4717 s++;
4718 while (isspace((unsigned char) *s))
4719 s++;
4720 }
4721 else
4722 ereturn(escontext, (Datum) 0,
4724 errmsg("invalid input syntax for type %s: \"%s\"",
4725 "circle", str)));
4726 }
4727
4728 if (*s != '\0')
4729 ereturn(escontext, (Datum) 0,
4731 errmsg("invalid input syntax for type %s: \"%s\"",
4732 "circle", str)));
4733
4735}
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereturn(context, dummy_value,...)
Definition elog.h:280
static bool pair_decode(char *str, float8 *x, float8 *y, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Definition geo_ops.c:213
#define DELIM
Definition geo_ops.c:160
static bool single_decode(char *num, float8 *x, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Definition geo_ops.c:195
#define LDELIM_C
Definition geo_ops.c:163
#define RDELIM
Definition geo_ops.c:159
#define RDELIM_C
Definition geo_ops.c:164
#define LDELIM
Definition geo_ops.c:158
static char * errmsg
uint64_t Datum
Definition postgres.h:70

References DELIM, ereturn, errcode(), errmsg, fb(), LDELIM, LDELIM_C, pair_decode(), palloc_object, PG_GETARG_CSTRING, PG_RETURN_CIRCLE_P, PG_RETURN_NULL, RDELIM, RDELIM_C, single_decode(), and str.

◆ circle_le()

Datum circle_le ( PG_FUNCTION_ARGS  )

Definition at line 4998 of file geo_ops.c.

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

◆ circle_left()

Datum circle_left ( PG_FUNCTION_ARGS  )

Definition at line 4848 of file geo_ops.c.

4849{
4852
4853 PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.x, circle1->radius),
4854 float8_mi(circle2->center.x, circle2->radius)));
4855}

References fb(), float8_mi(), float8_pl(), FPlt(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_lt()

Datum circle_lt ( PG_FUNCTION_ARGS  )

Definition at line 4980 of file geo_ops.c.

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

◆ circle_mul_pt()

Datum circle_mul_pt ( PG_FUNCTION_ARGS  )

Definition at line 5058 of file geo_ops.c.

5059{
5062 CIRCLE *result;
5063
5065
5066 point_mul_point(&result->center, &circle->center, point);
5067 result->radius = float8_mul(circle->radius, hypot(point->x, point->y));
5068
5070}

References fb(), float8_mul(), palloc_object, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_mul_point(), and result.

◆ circle_ne()

Datum circle_ne ( PG_FUNCTION_ARGS  )

Definition at line 4971 of file geo_ops.c.

4972{
4975
4977}
static bool FPne(double A, double B)
Definition geo_decls.h:53

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

◆ circle_out()

Datum circle_out ( PG_FUNCTION_ARGS  )

Definition at line 4740 of file geo_ops.c.

4741{
4744
4746
4749 pair_encode(circle->center.x, circle->center.y, &str);
4752 single_encode(circle->radius, &str);
4754
4755 PG_RETURN_CSTRING(str.data);
4756}
static void pair_encode(float8 x, float8 y, StringInfo str)
Definition geo_ops.c:256
static void single_encode(float8 x, StringInfo str)
Definition geo_ops.c:204
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References appendStringInfoChar(), DELIM, fb(), initStringInfo(), LDELIM, LDELIM_C, pair_encode(), PG_GETARG_CIRCLE_P, PG_RETURN_CSTRING, RDELIM, RDELIM_C, single_encode(), and str.

◆ circle_overabove()

Datum circle_overabove ( PG_FUNCTION_ARGS  )

Definition at line 4948 of file geo_ops.c.

4949{
4952
4953 PG_RETURN_BOOL(FPge(float8_mi(circle1->center.y, circle1->radius),
4954 float8_mi(circle2->center.y, circle2->radius)));
4955}

References fb(), float8_mi(), FPge(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_overbelow()

Datum circle_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 4935 of file geo_ops.c.

4936{
4939
4940 PG_RETURN_BOOL(FPle(float8_pl(circle1->center.y, circle1->radius),
4941 float8_pl(circle2->center.y, circle2->radius)));
4942}

References fb(), float8_pl(), FPle(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_overlap()

Datum circle_overlap ( PG_FUNCTION_ARGS  )

Definition at line 4823 of file geo_ops.c.

4824{
4827
4828 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4829 float8_pl(circle1->radius, circle2->radius)));
4830}

References fb(), float8_pl(), FPle(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, and point_dt().

◆ circle_overleft()

Datum circle_overleft ( PG_FUNCTION_ARGS  )

Definition at line 4836 of file geo_ops.c.

4837{
4840
4841 PG_RETURN_BOOL(FPle(float8_pl(circle1->center.x, circle1->radius),
4842 float8_pl(circle2->center.x, circle2->radius)));
4843}

References fb(), float8_pl(), FPle(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_overright()

Datum circle_overright ( PG_FUNCTION_ARGS  )

Definition at line 4873 of file geo_ops.c.

4874{
4877
4878 PG_RETURN_BOOL(FPge(float8_mi(circle1->center.x, circle1->radius),
4879 float8_mi(circle2->center.x, circle2->radius)));
4880}

References fb(), float8_mi(), FPge(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_poly()

Datum circle_poly ( PG_FUNCTION_ARGS  )

Definition at line 5387 of file geo_ops.c.

5388{
5389 int32 npts = PG_GETARG_INT32(0);
5391
5393}
int32_t int32
Definition c.h:620
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
static POLYGON * circle_poly_internal(int32 npts, const CIRCLE *circle, FunctionCallInfo fcinfo)
Definition geo_ops.c:5322

References circle_poly_internal(), fb(), PG_GETARG_CIRCLE_P, PG_GETARG_INT32, and PG_RETURN_POLYGON_P.

◆ circle_poly_internal()

static POLYGON * circle_poly_internal ( int32  npts,
const CIRCLE circle,
FunctionCallInfo  fcinfo 
)
static

Definition at line 5322 of file geo_ops.c.

5323{
5324 POLYGON *poly;
5325 int base_size,
5326 size;
5327 int i;
5328 float8 angle;
5330
5331 if (FPzero(circle->radius))
5332 ereturn(fcinfo->context, NULL,
5334 errmsg("cannot convert circle with radius zero to polygon")));
5335
5336 if (npts < 2)
5337 ereturn(fcinfo->context, NULL,
5339 errmsg("must request at least 2 points")));
5340
5341 base_size = sizeof(poly->p[0]) * npts;
5342 size = offsetof(POLYGON, p) + base_size;
5343
5344 /* Check for integer overflow */
5345 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
5346 ereturn(fcinfo->context, NULL,
5348 errmsg("too many points requested")));
5349
5350 poly = (POLYGON *) palloc0(size); /* zero any holes */
5351 SET_VARSIZE(poly, size);
5352 poly->npts = npts;
5353
5354 anglestep = float8_div(2.0 * M_PI, npts);
5355
5356 for (i = 0; i < npts; i++)
5357 {
5358 float8 temp;
5359
5361 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5362 return NULL;
5363
5364 temp = float8_mul_safe(circle->radius, cos(angle), fcinfo->context);
5365 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5366 return NULL;
5367
5368 poly->p[i].x = float8_mi_safe(circle->center.x, temp, fcinfo->context);
5369 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5370 return NULL;
5371
5372 temp = float8_mul_safe(circle->radius, sin(angle), fcinfo->context);
5373 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5374 return NULL;
5375
5376 poly->p[i].y = float8_pl_safe(circle->center.y, temp, fcinfo->context);
5377 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5378 return NULL;
5379 }
5380
5382
5383 return poly;
5384}
static float8 float8_mul_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:178
#define FPzero(A)
Definition geo_decls.h:44
static void make_bound_box(POLYGON *poly)
Definition geo_ops.c:3423
int i
Definition isn.c:77
void * palloc0(Size size)
Definition mcxt.c:1417

References FunctionCallInfoBaseData::context, ereturn, errcode(), errmsg, fb(), float8_div(), float8_mi_safe(), float8_mul_safe(), float8_pl_safe(), FPzero, i, M_PI, make_bound_box(), palloc0(), SET_VARSIZE(), and SOFT_ERROR_OCCURRED.

Referenced by circle_poly(), and circle_to_poly().

◆ circle_radius()

Datum circle_radius ( PG_FUNCTION_ARGS  )

Definition at line 5113 of file geo_ops.c.

5114{
5116
5117 PG_RETURN_FLOAT8(circle->radius);
5118}

References fb(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

◆ circle_recv()

Datum circle_recv ( PG_FUNCTION_ARGS  )

Definition at line 4762 of file geo_ops.c.

4763{
4765 CIRCLE *circle;
4766
4768
4769 circle->center.x = pq_getmsgfloat8(buf);
4770 circle->center.y = pq_getmsgfloat8(buf);
4771 circle->radius = pq_getmsgfloat8(buf);
4772
4773 /* We have to accept NaN. */
4774 if (circle->radius < 0.0)
4775 ereport(ERROR,
4777 errmsg("invalid radius in external \"circle\" value")));
4778
4780}
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152

References buf, ereport, errcode(), errmsg, ERROR, fb(), palloc_object, PG_GETARG_POINTER, PG_RETURN_CIRCLE_P, and pq_getmsgfloat8().

◆ circle_right()

Datum circle_right ( PG_FUNCTION_ARGS  )

Definition at line 4860 of file geo_ops.c.

4861{
4864
4865 PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.x, circle1->radius),
4866 float8_pl(circle2->center.x, circle2->radius)));
4867}

References fb(), float8_mi(), float8_pl(), FPgt(), PG_GETARG_CIRCLE_P, and PG_RETURN_BOOL.

◆ circle_same()

Datum circle_same ( PG_FUNCTION_ARGS  )

Definition at line 4810 of file geo_ops.c.

4811{
4814
4815 PG_RETURN_BOOL(((isnan(circle1->radius) && isnan(circle2->radius)) ||
4816 FPeq(circle1->radius, circle2->radius)) &&
4817 point_eq_point(&circle1->center, &circle2->center));
4818}

References fb(), FPeq(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, and point_eq_point().

◆ circle_send()

Datum circle_send ( PG_FUNCTION_ARGS  )

Definition at line 4786 of file geo_ops.c.

4787{
4790
4792 pq_sendfloat8(&buf, circle->center.x);
4793 pq_sendfloat8(&buf, circle->center.y);
4794 pq_sendfloat8(&buf, circle->radius);
4796}

References buf, fb(), PG_GETARG_CIRCLE_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat8().

◆ circle_sub_pt()

Datum circle_sub_pt ( PG_FUNCTION_ARGS  )

Definition at line 5039 of file geo_ops.c.

5040{
5043 CIRCLE *result;
5044
5046
5047 point_sub_point(&result->center, &circle->center, point);
5048 result->radius = circle->radius;
5049
5051}

References fb(), palloc_object, PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_sub_point(), and result.

◆ circle_to_poly()

Datum circle_to_poly ( PG_FUNCTION_ARGS  )

Definition at line 5397 of file geo_ops.c.

5398{
5399 int32 npts = 12;
5401
5403}

References circle_poly_internal(), fb(), PG_GETARG_CIRCLE_P, and PG_RETURN_POLYGON_P.

◆ close_ls()

Datum close_ls ( PG_FUNCTION_ARGS  )

Definition at line 3035 of file geo_ops.c.

3036{
3037 LINE *line = PG_GETARG_LINE_P(0);
3039 Point *result;
3040
3041 if (lseg_sl(lseg) == line_sl(line))
3043
3045
3046 if (isnan(lseg_closept_line(result, lseg, line)))
3048
3050}
#define PG_GETARG_LINE_P(n)
Definition geo_decls.h:229
#define PG_GETARG_LSEG_P(n)
Definition geo_decls.h:197
static float8 lseg_closept_line(Point *result, LSEG *lseg, LINE *line)
Definition geo_ops.c:3007
static float8 lseg_sl(LSEG *lseg)
Definition geo_ops.c:2184
static float8 line_sl(LINE *line)
Definition geo_ops.c:1251

References fb(), line_sl(), lseg_closept_line(), lseg_sl(), palloc_object, PG_GETARG_LINE_P, PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ close_lseg()

Datum close_lseg ( PG_FUNCTION_ARGS  )

Definition at line 2900 of file geo_ops.c.

2901{
2902 LSEG *l1 = PG_GETARG_LSEG_P(0);
2903 LSEG *l2 = PG_GETARG_LSEG_P(1);
2904 Point *result;
2905
2906 if (lseg_sl(l1) == lseg_sl(l2))
2908
2910
2911 if (isnan(lseg_closept_lseg(result, l2, l1)))
2913
2915}

References fb(), lseg_closept_lseg(), lseg_sl(), palloc_object, PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ close_pb()

Datum close_pb ( PG_FUNCTION_ARGS  )

Definition at line 2980 of file geo_ops.c.

2981{
2983 BOX *box = PG_GETARG_BOX_P(1);
2984 Point *result;
2985
2987
2990
2992}
static float8 box_closept_point(Point *result, BOX *box, Point *pt)
Definition geo_ops.c:2925

References box_closept_point(), fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ close_pl()

Datum close_pl ( PG_FUNCTION_ARGS  )

Definition at line 2797 of file geo_ops.c.

2798{
2800 LINE *line = PG_GETARG_LINE_P(1);
2801 Point *result;
2802
2804
2805 if (isnan(line_closept_point(result, line, pt)))
2807
2809}
static float8 line_closept_point(Point *result, LINE *line, Point *point)
Definition geo_ops.c:2771

References fb(), line_closept_point(), palloc_object, PG_GETARG_LINE_P, PG_GETARG_POINT_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ close_ps()

◆ close_sb()

Datum close_sb ( PG_FUNCTION_ARGS  )

Definition at line 3110 of file geo_ops.c.

3111{
3113 BOX *box = PG_GETARG_BOX_P(1);
3114 Point *result;
3115
3117
3120
3122}
static float8 box_closept_lseg(Point *result, BOX *box, LSEG *lseg)
Definition geo_ops.c:3060

References box_closept_lseg(), fb(), palloc_object, PG_GETARG_BOX_P, PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ construct_point()

Datum construct_point ( PG_FUNCTION_ARGS  )

Definition at line 4143 of file geo_ops.c.

4144{
4147 Point *result;
4148
4150
4152
4154}
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
static void point_construct(Point *result, float8 x, float8 y)
Definition geo_ops.c:1902

References palloc_object, PG_GETARG_FLOAT8, PG_RETURN_POINT_P, point_construct(), result, x, and y.

◆ cr_circle()

Datum cr_circle ( PG_FUNCTION_ARGS  )

Definition at line 5229 of file geo_ops.c.

5230{
5231 Point *center = PG_GETARG_POINT_P(0);
5232 float8 radius = PG_GETARG_FLOAT8(1);
5233 CIRCLE *result;
5234
5236
5237 result->center.x = center->x;
5238 result->center.y = center->y;
5239 result->radius = radius;
5240
5242}

References palloc_object, PG_GETARG_FLOAT8, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, result, Point::x, and Point::y.

◆ dist_bp()

Datum dist_bp ( PG_FUNCTION_ARGS  )

Definition at line 2561 of file geo_ops.c.

2562{
2563 BOX *box = PG_GETARG_BOX_P(0);
2565
2567}

References box_closept_point(), fb(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_bs()

Datum dist_bs ( PG_FUNCTION_ARGS  )

Definition at line 2609 of file geo_ops.c.

2610{
2611 BOX *box = PG_GETARG_BOX_P(0);
2613
2615}

References box_closept_lseg(), fb(), PG_GETARG_BOX_P, PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ dist_cpoint()

Datum dist_cpoint ( PG_FUNCTION_ARGS  )

Definition at line 5186 of file geo_ops.c.

5187{
5190 float8 result;
5191
5192 result = float8_mi(point_dt(point, &circle->center, NULL), circle->radius);
5193 if (result < 0.0)
5194 result = 0.0;
5195
5197}

References fb(), float8_mi(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, point_dt(), and result.

◆ dist_cpoly()

Datum dist_cpoly ( PG_FUNCTION_ARGS  )

Definition at line 2635 of file geo_ops.c.

2636{
2639
2641}
#define PG_GETARG_POLYGON_P(n)
Definition geo_decls.h:260
static float8 dist_cpoly_internal(CIRCLE *circle, POLYGON *poly)
Definition geo_ops.c:2618

References dist_cpoly_internal(), fb(), PG_GETARG_CIRCLE_P, PG_GETARG_POLYGON_P, and PG_RETURN_FLOAT8.

◆ dist_cpoly_internal()

static float8 dist_cpoly_internal ( CIRCLE circle,
POLYGON poly 
)
static

Definition at line 2618 of file geo_ops.c.

2619{
2620 float8 result;
2621
2622 /* calculate distance to center, and subtract radius */
2624 circle->radius);
2625 if (result < 0.0)
2626 result = 0.0;
2627
2628 return result;
2629}
static float8 dist_ppoly_internal(Point *pt, POLYGON *poly)
Definition geo_ops.c:2677

References dist_ppoly_internal(), fb(), float8_mi(), and result.

Referenced by dist_cpoly(), and dist_polyc().

◆ dist_lp()

Datum dist_lp ( PG_FUNCTION_ARGS  )

Definition at line 2449 of file geo_ops.c.

2450{
2451 LINE *line = PG_GETARG_LINE_P(0);
2453
2455}

References fb(), line_closept_point(), PG_GETARG_LINE_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_ls()

Datum dist_ls ( PG_FUNCTION_ARGS  )

Definition at line 2585 of file geo_ops.c.

2586{
2587 LINE *line = PG_GETARG_LINE_P(0);
2589
2591}

References fb(), lseg_closept_line(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ dist_pathp()

Datum dist_pathp ( PG_FUNCTION_ARGS  )

Definition at line 2537 of file geo_ops.c.

2538{
2539 PATH *path = PG_GETARG_PATH_P(0);
2541
2543}
#define PG_GETARG_PATH_P(n)
Definition geo_decls.h:215
static float8 dist_ppath_internal(Point *pt, PATH *path)
Definition geo_ops.c:2482

References dist_ppath_internal(), fb(), PG_GETARG_PATH_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_pb()

Datum dist_pb ( PG_FUNCTION_ARGS  )

Definition at line 2549 of file geo_ops.c.

2550{
2552 BOX *box = PG_GETARG_BOX_P(1);
2553
2555}

References box_closept_point(), fb(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_pc()

Datum dist_pc ( PG_FUNCTION_ARGS  )

Definition at line 5168 of file geo_ops.c.

5169{
5172 float8 result;
5173
5174 result = float8_mi(point_dt(point, &circle->center, NULL),
5175 circle->radius);
5176 if (result < 0.0)
5177 result = 0.0;
5178
5180}

References fb(), float8_mi(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, point_dt(), and result.

◆ dist_pl()

Datum dist_pl ( PG_FUNCTION_ARGS  )

Definition at line 2437 of file geo_ops.c.

2438{
2440 LINE *line = PG_GETARG_LINE_P(1);
2441
2443}

References fb(), line_closept_point(), PG_GETARG_LINE_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_polyc()

◆ dist_polyp()

◆ dist_ppath()

Datum dist_ppath ( PG_FUNCTION_ARGS  )

Definition at line 2525 of file geo_ops.c.

2526{
2528 PATH *path = PG_GETARG_PATH_P(1);
2529
2531}

References dist_ppath_internal(), fb(), PG_GETARG_PATH_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_ppath_internal()

static float8 dist_ppath_internal ( Point pt,
PATH path 
)
static

Definition at line 2482 of file geo_ops.c.

2483{
2484 float8 result = 0.0; /* keep compiler quiet */
2485 bool have_min = false;
2486 float8 tmp;
2487 int i;
2488 LSEG lseg;
2489
2490 Assert(path->npts > 0);
2491
2492 /*
2493 * The distance from a point to a path is the smallest distance from the
2494 * point to any of its constituent segments.
2495 */
2496 for (i = 0; i < path->npts; i++)
2497 {
2498 int iprev;
2499
2500 if (i > 0)
2501 iprev = i - 1;
2502 else
2503 {
2504 if (!path->closed)
2505 continue;
2506 iprev = path->npts - 1; /* Include the closure segment */
2507 }
2508
2509 statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
2510 tmp = lseg_closept_point(NULL, &lseg, pt);
2511 if (!have_min || float8_lt(tmp, result))
2512 {
2513 result = tmp;
2514 have_min = true;
2515 }
2516 }
2517
2518 return result;
2519}
#define Assert(condition)
Definition c.h:943
Point p[FLEXIBLE_ARRAY_MEMBER]
Definition geo_decls.h:120
int32 npts
Definition geo_decls.h:117
int32 closed
Definition geo_decls.h:118

References Assert, PATH::closed, fb(), float8_lt(), i, lseg_closept_point(), PATH::npts, PATH::p, result, and statlseg_construct().

Referenced by dist_pathp(), and dist_ppath().

◆ dist_ppoly()

◆ dist_ppoly_internal()

static float8 dist_ppoly_internal ( Point pt,
POLYGON poly 
)
static

Definition at line 2677 of file geo_ops.c.

2678{
2679 float8 result;
2680 float8 d;
2681 int i;
2682 LSEG seg;
2683
2684 if (point_inside(pt, poly->npts, poly->p) != 0)
2685 return 0.0;
2686
2687 /* initialize distance with segment between first and last points */
2688 seg.p[0].x = poly->p[0].x;
2689 seg.p[0].y = poly->p[0].y;
2690 seg.p[1].x = poly->p[poly->npts - 1].x;
2691 seg.p[1].y = poly->p[poly->npts - 1].y;
2692 result = lseg_closept_point(NULL, &seg, pt);
2693
2694 /* check distances for other segments */
2695 for (i = 0; i < poly->npts - 1; i++)
2696 {
2697 seg.p[0].x = poly->p[i].x;
2698 seg.p[0].y = poly->p[i].y;
2699 seg.p[1].x = poly->p[i + 1].x;
2700 seg.p[1].y = poly->p[i + 1].y;
2701 d = lseg_closept_point(NULL, &seg, pt);
2702 if (float8_lt(d, result))
2703 result = d;
2704 }
2705
2706 return result;
2707}
static int point_inside(Point *p, int npts, Point *plist)
Definition geo_ops.c:5492
Point p[2]
Definition geo_decls.h:107

References fb(), float8_lt(), i, lseg_closept_point(), LSEG::p, point_inside(), result, Point::x, and Point::y.

Referenced by dist_cpoly_internal(), dist_polyp(), and dist_ppoly().

◆ dist_ps()

Datum dist_ps ( PG_FUNCTION_ARGS  )

◆ dist_sb()

Datum dist_sb ( PG_FUNCTION_ARGS  )

Definition at line 2597 of file geo_ops.c.

2598{
2600 BOX *box = PG_GETARG_BOX_P(1);
2601
2603}

References box_closept_lseg(), fb(), PG_GETARG_BOX_P, PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ dist_sl()

Datum dist_sl ( PG_FUNCTION_ARGS  )

Definition at line 2573 of file geo_ops.c.

2574{
2576 LINE *line = PG_GETARG_LINE_P(1);
2577
2579}

References fb(), lseg_closept_line(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ dist_sp()

Datum dist_sp ( PG_FUNCTION_ARGS  )

◆ inter_lb()

Datum inter_lb ( PG_FUNCTION_ARGS  )

Definition at line 3375 of file geo_ops.c.

3376{
3377 LINE *line = PG_GETARG_LINE_P(0);
3378 BOX *box = PG_GETARG_BOX_P(1);
3379 LSEG bseg;
3380 Point p1,
3381 p2;
3382
3383 /* pairwise check lseg intersections */
3384 p1.x = box->low.x;
3385 p1.y = box->low.y;
3386 p2.x = box->low.x;
3387 p2.y = box->high.y;
3389 if (lseg_interpt_line(NULL, &bseg, line))
3390 PG_RETURN_BOOL(true);
3391 p1.x = box->high.x;
3392 p1.y = box->high.y;
3394 if (lseg_interpt_line(NULL, &bseg, line))
3395 PG_RETURN_BOOL(true);
3396 p2.x = box->high.x;
3397 p2.y = box->low.y;
3399 if (lseg_interpt_line(NULL, &bseg, line))
3400 PG_RETURN_BOOL(true);
3401 p1.x = box->low.x;
3402 p1.y = box->low.y;
3404 if (lseg_interpt_line(NULL, &bseg, line))
3405 PG_RETURN_BOOL(true);
3406
3407 /* if we dropped through, no intersection */
3408 PG_RETURN_BOOL(false);
3409}
static bool lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
Definition geo_ops.c:2722

References fb(), lseg_interpt_line(), PG_GETARG_BOX_P, PG_GETARG_LINE_P, PG_RETURN_BOOL, statlseg_construct(), and Point::x.

◆ inter_sb()

Datum inter_sb ( PG_FUNCTION_ARGS  )

Definition at line 3362 of file geo_ops.c.

3363{
3365 BOX *box = PG_GETARG_BOX_P(1);
3366
3368}

References box_interpt_lseg(), fb(), PG_GETARG_BOX_P, PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ inter_sl()

Datum inter_sl ( PG_FUNCTION_ARGS  )

Definition at line 3285 of file geo_ops.c.

3286{
3288 LINE *line = PG_GETARG_LINE_P(1);
3289
3291}

References fb(), lseg_interpt_line(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ line_closept_point()

static float8 line_closept_point ( Point result,
LINE line,
Point point 
)
static

Definition at line 2771 of file geo_ops.c.

2772{
2773 Point closept;
2774 LINE tmp;
2775
2776 /*
2777 * We drop a perpendicular to find the intersection point. Ordinarily we
2778 * should always find it, but that can fail in the presence of NaN
2779 * coordinates, and perhaps even from simple roundoff issues.
2780 */
2781 line_construct(&tmp, point, line_invsl(line));
2782 if (!line_interpt_line(&closept, &tmp, line))
2783 {
2784 if (result != NULL)
2785 *result = *point;
2786
2787 return get_float8_nan();
2788 }
2789
2790 if (result != NULL)
2791 *result = closept;
2792
2793 return point_dt(&closept, point, NULL);
2794}
static float8 get_float8_nan(void)
Definition float.h:87
static void line_construct(LINE *result, Point *pt, float8 m)
Definition geo_ops.c:1101
static bool line_interpt_line(Point *result, LINE *l1, LINE *l2)
Definition geo_ops.c:1332
static float8 line_invsl(LINE *line)
Definition geo_ops.c:1265

References fb(), get_float8_nan(), line_construct(), line_interpt_line(), line_invsl(), point_dt(), and result.

Referenced by close_pl(), dist_lp(), dist_pl(), and lseg_closept_line().

◆ line_construct()

static void line_construct ( LINE result,
Point pt,
float8  m 
)
inlinestatic

Definition at line 1101 of file geo_ops.c.

1102{
1103 if (isinf(m))
1104 {
1105 /* vertical - use "x = C" */
1106 result->A = -1.0;
1107 result->B = 0.0;
1108 result->C = pt->x;
1109 }
1110 else if (m == 0)
1111 {
1112 /* horizontal - use "y = C" */
1113 result->A = 0.0;
1114 result->B = -1.0;
1115 result->C = pt->y;
1116 }
1117 else
1118 {
1119 /* use "mx - y + yinter = 0" */
1120 result->A = m;
1121 result->B = -1.0;
1122 result->C = float8_mi(pt->y, float8_mul(m, pt->x));
1123 /* on some platforms, the preceding expression tends to produce -0 */
1124 if (result->C == 0.0)
1125 result->C = 0.0;
1126 }
1127}

References fb(), float8_mi(), float8_mul(), and result.

Referenced by line_closept_point(), line_construct_pp(), line_in(), lseg_closept_point(), lseg_interpt_line(), and lseg_interpt_lseg().

◆ line_construct_pp()

Datum line_construct_pp ( PG_FUNCTION_ARGS  )

Definition at line 1133 of file geo_ops.c.

1134{
1138
1139 if (point_eq_point(pt1, pt2))
1140 ereport(ERROR,
1142 errmsg("invalid line specification: must be two distinct points")));
1143
1145
1147}
#define PG_RETURN_LINE_P(x)
Definition geo_decls.h:230
static float8 point_sl(Point *pt1, Point *pt2)
Definition geo_ops.c:2052

References ereport, errcode(), errmsg, ERROR, fb(), line_construct(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_LINE_P, point_eq_point(), point_sl(), and result.

◆ line_contain_point()

static bool line_contain_point ( LINE line,
Point point 
)
static

Definition at line 3134 of file geo_ops.c.

3135{
3136 return FPzero(float8_pl(float8_pl(float8_mul(line->A, point->x),
3137 float8_mul(line->B, point->y)),
3138 line->C));
3139}
float8 A
Definition geo_decls.h:129
float8 B
Definition geo_decls.h:130
float8 C
Definition geo_decls.h:131

References LINE::A, LINE::B, LINE::C, fb(), float8_mul(), float8_pl(), and FPzero.

Referenced by on_pl(), and on_sl().

◆ line_decode()

static bool line_decode ( char s,
const char str,
LINE line,
Node escontext 
)
static

Definition at line 968 of file geo_ops.c.

969{
970 /* s was already advanced over leading '{' */
971 if (!single_decode(s, &line->A, &s, "line", str, escontext))
972 return false;
973 if (*s++ != DELIM)
974 goto fail;
975 if (!single_decode(s, &line->B, &s, "line", str, escontext))
976 return false;
977 if (*s++ != DELIM)
978 goto fail;
979 if (!single_decode(s, &line->C, &s, "line", str, escontext))
980 return false;
981 if (*s++ != RDELIM_L)
982 goto fail;
983 while (isspace((unsigned char) *s))
984 s++;
985 if (*s != '\0')
986 goto fail;
987 return true;
988
989fail:
990 ereturn(escontext, false,
992 errmsg("invalid input syntax for type %s: \"%s\"",
993 "line", str)));
994}
#define RDELIM_L
Definition geo_ops.c:166

References LINE::A, LINE::B, LINE::C, DELIM, ereturn, errcode(), errmsg, fb(), RDELIM_L, single_decode(), and str.

Referenced by line_in().

◆ line_distance()

Datum line_distance ( PG_FUNCTION_ARGS  )

Definition at line 1279 of file geo_ops.c.

1280{
1281 LINE *l1 = PG_GETARG_LINE_P(0);
1282 LINE *l2 = PG_GETARG_LINE_P(1);
1283 float8 ratio;
1284
1285 if (line_interpt_line(NULL, l1, l2)) /* intersecting? */
1286 PG_RETURN_FLOAT8(0.0);
1287
1288 if (!FPzero(l1->A) && !isnan(l1->A) && !FPzero(l2->A) && !isnan(l2->A))
1289 ratio = float8_div(l1->A, l2->A);
1290 else if (!FPzero(l1->B) && !isnan(l1->B) && !FPzero(l2->B) && !isnan(l2->B))
1291 ratio = float8_div(l1->B, l2->B);
1292 else
1293 ratio = 1.0;
1294
1296 float8_mul(ratio, l2->C))),
1297 hypot(l1->A, l1->B)));
1298}

References LINE::A, LINE::B, LINE::C, fb(), float8_div(), float8_mi(), float8_mul(), FPzero, line_interpt_line(), PG_GETARG_LINE_P, and PG_RETURN_FLOAT8.

◆ line_eq()

Datum line_eq ( PG_FUNCTION_ARGS  )

Definition at line 1212 of file geo_ops.c.

1213{
1214 LINE *l1 = PG_GETARG_LINE_P(0);
1215 LINE *l2 = PG_GETARG_LINE_P(1);
1216 float8 ratio;
1217
1218 /* If any NaNs are involved, insist on exact equality */
1219 if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l1->C) ||
1220 isnan(l2->A) || isnan(l2->B) || isnan(l2->C)))
1221 {
1222 PG_RETURN_BOOL(float8_eq(l1->A, l2->A) &&
1223 float8_eq(l1->B, l2->B) &&
1224 float8_eq(l1->C, l2->C));
1225 }
1226
1227 /* Otherwise, lines whose parameters are proportional are the same */
1228 if (!FPzero(l2->A))
1229 ratio = float8_div(l1->A, l2->A);
1230 else if (!FPzero(l2->B))
1231 ratio = float8_div(l1->B, l2->B);
1232 else if (!FPzero(l2->C))
1233 ratio = float8_div(l1->C, l2->C);
1234 else
1235 ratio = 1.0;
1236
1237 PG_RETURN_BOOL(FPeq(l1->A, float8_mul(ratio, l2->A)) &&
1238 FPeq(l1->B, float8_mul(ratio, l2->B)) &&
1239 FPeq(l1->C, float8_mul(ratio, l2->C)));
1240}
#define unlikely(x)
Definition c.h:438
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:250

References LINE::A, LINE::B, LINE::C, fb(), float8_div(), float8_eq(), float8_mul(), FPeq(), FPzero, PG_GETARG_LINE_P, PG_RETURN_BOOL, and unlikely.

◆ line_horizontal()

Datum line_horizontal ( PG_FUNCTION_ARGS  )

Definition at line 1200 of file geo_ops.c.

1201{
1202 LINE *line = PG_GETARG_LINE_P(0);
1203
1204 PG_RETURN_BOOL(FPzero(line->A));
1205}

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

◆ line_in()

Datum line_in ( PG_FUNCTION_ARGS  )

Definition at line 997 of file geo_ops.c.

998{
999 char *str = PG_GETARG_CSTRING(0);
1000 Node *escontext = fcinfo->context;
1001 LINE *line = palloc_object(LINE);
1002 LSEG lseg;
1003 bool isopen;
1004 char *s;
1005
1006 s = str;
1007 while (isspace((unsigned char) *s))
1008 s++;
1009 if (*s == LDELIM_L)
1010 {
1011 if (!line_decode(s + 1, str, line, escontext))
1013 if (FPzero(line->A) && FPzero(line->B))
1014 ereturn(escontext, (Datum) 0,
1016 errmsg("invalid line specification: A and B cannot both be zero")));
1017 }
1018 else
1019 {
1020 if (!path_decode(s, true, 2, &lseg.p[0], &isopen, NULL, "line", str,
1021 escontext))
1023 if (point_eq_point(&lseg.p[0], &lseg.p[1]))
1024 ereturn(escontext, (Datum) 0,
1026 errmsg("invalid line specification: must be two distinct points")));
1027
1028 /*
1029 * XXX lseg_sl() and line_construct() can throw overflow/underflow
1030 * errors. Eventually we should allow those to be soft, but the
1031 * notational pain seems to outweigh the value for now.
1032 */
1033 line_construct(line, &lseg.p[0], lseg_sl(&lseg));
1034 }
1035
1036 PG_RETURN_LINE_P(line);
1037}
#define LDELIM_L
Definition geo_ops.c:165
static bool line_decode(char *s, const char *str, LINE *line, Node *escontext)
Definition geo_ops.c:968

References LINE::A, LINE::B, ereturn, errcode(), errmsg, fb(), FPzero, LDELIM_L, line_construct(), line_decode(), lseg_sl(), palloc_object, path_decode(), PG_GETARG_CSTRING, PG_RETURN_LINE_P, PG_RETURN_NULL, point_eq_point(), and str.

◆ line_interpt()

Datum line_interpt ( PG_FUNCTION_ARGS  )

Definition at line 1304 of file geo_ops.c.

1305{
1306 LINE *l1 = PG_GETARG_LINE_P(0);
1307 LINE *l2 = PG_GETARG_LINE_P(1);
1308 Point *result;
1309
1311
1312 if (!line_interpt_line(result, l1, l2))
1315}

References line_interpt_line(), palloc_object, PG_GETARG_LINE_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

◆ line_interpt_line()

static bool line_interpt_line ( Point result,
LINE l1,
LINE l2 
)
static

Definition at line 1332 of file geo_ops.c.

1333{
1334 float8 x,
1335 y;
1336
1337 if (!FPzero(l1->B))
1338 {
1339 if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B))))
1340 return false;
1341
1342 x = float8_div(float8_mi(float8_mul(l1->B, l2->C),
1343 float8_mul(l2->B, l1->C)),
1344 float8_mi(float8_mul(l1->A, l2->B),
1345 float8_mul(l2->A, l1->B)));
1346 y = float8_div(-float8_pl(float8_mul(l1->A, x), l1->C), l1->B);
1347 }
1348 else if (!FPzero(l2->B))
1349 {
1350 if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B))))
1351 return false;
1352
1353 x = float8_div(float8_mi(float8_mul(l2->B, l1->C),
1354 float8_mul(l1->B, l2->C)),
1355 float8_mi(float8_mul(l2->A, l1->B),
1356 float8_mul(l1->A, l2->B)));
1357 y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B);
1358 }
1359 else
1360 return false;
1361
1362 /* On some platforms, the preceding expressions tend to produce -0. */
1363 if (x == 0.0)
1364 x = 0.0;
1365 if (y == 0.0)
1366 y = 0.0;
1367
1368 if (result != NULL)
1370
1371 return true;
1372}

References LINE::A, LINE::B, LINE::C, fb(), float8_div(), float8_mi(), float8_mul(), float8_pl(), FPeq(), FPzero, point_construct(), result, x, and y.

Referenced by line_closept_point(), line_distance(), line_interpt(), line_intersect(), line_parallel(), and lseg_interpt_line().

◆ line_intersect()

Datum line_intersect ( PG_FUNCTION_ARGS  )

Definition at line 1155 of file geo_ops.c.

1156{
1157 LINE *l1 = PG_GETARG_LINE_P(0);
1158 LINE *l2 = PG_GETARG_LINE_P(1);
1159
1161}

References fb(), line_interpt_line(), PG_GETARG_LINE_P, and PG_RETURN_BOOL.

◆ line_invsl()

static float8 line_invsl ( LINE line)
inlinestatic

Definition at line 1265 of file geo_ops.c.

1266{
1267 if (FPzero(line->A))
1268 return get_float8_infinity();
1269 if (FPzero(line->B))
1270 return 0.0;
1271 return float8_div(line->B, line->A);
1272}
static float8 get_float8_infinity(void)
Definition float.h:68

References LINE::A, LINE::B, float8_div(), FPzero, and get_float8_infinity().

Referenced by line_closept_point().

◆ line_out()

Datum line_out ( PG_FUNCTION_ARGS  )

Definition at line 1041 of file geo_ops.c.

1042{
1043 LINE *line = PG_GETARG_LINE_P(0);
1044 char *astr = float8out_internal(line->A);
1045 char *bstr = float8out_internal(line->B);
1046 char *cstr = float8out_internal(line->C);
1047
1048 PG_RETURN_CSTRING(psprintf("%c%s%c%s%c%s%c", LDELIM_L, astr, DELIM, bstr,
1049 DELIM, cstr, RDELIM_L));
1050}
char * float8out_internal(double num)
Definition float.c:578
char * psprintf(const char *fmt,...)
Definition psprintf.c:43

References LINE::A, LINE::B, LINE::C, DELIM, fb(), float8out_internal(), LDELIM_L, PG_GETARG_LINE_P, PG_RETURN_CSTRING, psprintf(), and RDELIM_L.

◆ line_parallel()

Datum line_parallel ( PG_FUNCTION_ARGS  )

Definition at line 1164 of file geo_ops.c.

1165{
1166 LINE *l1 = PG_GETARG_LINE_P(0);
1167 LINE *l2 = PG_GETARG_LINE_P(1);
1168
1170}

References fb(), line_interpt_line(), PG_GETARG_LINE_P, and PG_RETURN_BOOL.

◆ line_perp()

Datum line_perp ( PG_FUNCTION_ARGS  )

Definition at line 1173 of file geo_ops.c.

1174{
1175 LINE *l1 = PG_GETARG_LINE_P(0);
1176 LINE *l2 = PG_GETARG_LINE_P(1);
1177
1178 if (FPzero(l1->A))
1179 PG_RETURN_BOOL(FPzero(l2->B));
1180 if (FPzero(l2->A))
1181 PG_RETURN_BOOL(FPzero(l1->B));
1182 if (FPzero(l1->B))
1183 PG_RETURN_BOOL(FPzero(l2->A));
1184 if (FPzero(l2->B))
1185 PG_RETURN_BOOL(FPzero(l1->A));
1186
1188 float8_mul(l1->B, l2->B)), -1.0));
1189}

References LINE::A, LINE::B, float8_div(), float8_mul(), FPeq(), FPzero, PG_GETARG_LINE_P, and PG_RETURN_BOOL.

◆ line_recv()

Datum line_recv ( PG_FUNCTION_ARGS  )

Definition at line 1056 of file geo_ops.c.

1057{
1059 LINE *line;
1060
1061 line = palloc_object(LINE);
1062
1063 line->A = pq_getmsgfloat8(buf);
1064 line->B = pq_getmsgfloat8(buf);
1065 line->C = pq_getmsgfloat8(buf);
1066
1067 if (FPzero(line->A) && FPzero(line->B))
1068 ereport(ERROR,
1070 errmsg("invalid line specification: A and B cannot both be zero")));
1071
1072 PG_RETURN_LINE_P(line);
1073}

References LINE::A, LINE::B, buf, LINE::C, ereport, errcode(), errmsg, ERROR, fb(), FPzero, palloc_object, PG_GETARG_POINTER, PG_RETURN_LINE_P, and pq_getmsgfloat8().

◆ line_send()

Datum line_send ( PG_FUNCTION_ARGS  )

Definition at line 1079 of file geo_ops.c.

1080{
1081 LINE *line = PG_GETARG_LINE_P(0);
1083
1085 pq_sendfloat8(&buf, line->A);
1086 pq_sendfloat8(&buf, line->B);
1087 pq_sendfloat8(&buf, line->C);
1089}

References LINE::A, LINE::B, buf, LINE::C, PG_GETARG_LINE_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat8().

◆ line_sl()

static float8 line_sl ( LINE line)
inlinestatic

Definition at line 1251 of file geo_ops.c.

1252{
1253 if (FPzero(line->A))
1254 return 0.0;
1255 if (FPzero(line->B))
1256 return get_float8_infinity();
1257 return float8_div(line->A, -line->B);
1258}

References LINE::A, LINE::B, float8_div(), FPzero, and get_float8_infinity().

Referenced by close_ls().

◆ line_vertical()

Datum line_vertical ( PG_FUNCTION_ARGS  )

Definition at line 1192 of file geo_ops.c.

1193{
1194 LINE *line = PG_GETARG_LINE_P(0);
1195
1196 PG_RETURN_BOOL(FPzero(line->B));
1197}

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

◆ lseg_center()

Datum lseg_center ( PG_FUNCTION_ARGS  )

Definition at line 2345 of file geo_ops.c.

2346{
2348 Point *result;
2349 float8 x;
2350 float8 y;
2351
2353
2354 x = float8_pl_safe(lseg->p[0].x, lseg->p[1].x, fcinfo->context);
2355 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2356 goto fail;
2357
2358 result->x = float8_div_safe(x, 2.0, fcinfo->context);
2359 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2360 goto fail;
2361
2362 y = float8_pl_safe(lseg->p[0].y, lseg->p[1].y, fcinfo->context);
2363 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2364 goto fail;
2365
2366 result->y = float8_div_safe(y, 2.0, fcinfo->context);
2367 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2368 goto fail;
2369
2371
2372fail:
2374}

References fb(), float8_div_safe(), float8_pl_safe(), palloc_object, PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, result, SOFT_ERROR_OCCURRED, x, and y.

◆ lseg_closept_line()

static float8 lseg_closept_line ( Point result,
LSEG lseg,
LINE line 
)
static

Definition at line 3007 of file geo_ops.c.

3008{
3009 float8 dist1,
3010 dist2;
3011
3012 if (lseg_interpt_line(result, lseg, line))
3013 return 0.0;
3014
3015 dist1 = line_closept_point(NULL, line, &lseg->p[0]);
3016 dist2 = line_closept_point(NULL, line, &lseg->p[1]);
3017
3018 if (dist1 < dist2)
3019 {
3020 if (result != NULL)
3021 *result = lseg->p[0];
3022
3023 return dist1;
3024 }
3025 else
3026 {
3027 if (result != NULL)
3028 *result = lseg->p[1];
3029
3030 return dist2;
3031 }
3032}

References fb(), line_closept_point(), lseg_interpt_line(), and result.

Referenced by close_ls(), dist_ls(), dist_sl(), and lseg_closept_point().

◆ lseg_closept_lseg()

static float8 lseg_closept_lseg ( Point result,
LSEG on_lseg,
LSEG to_lseg 
)
static

Definition at line 2857 of file geo_ops.c.

2858{
2859 Point point;
2860 float8 dist,
2861 d;
2862
2863 /* First, we handle the case when the line segments are intersecting. */
2865 return 0.0;
2866
2867 /*
2868 * Then, we find the closest points from the endpoints of the second line
2869 * segment, and keep the closest one.
2870 */
2872 d = lseg_closept_point(&point, on_lseg, &to_lseg->p[1]);
2873 if (float8_lt(d, dist))
2874 {
2875 dist = d;
2876 if (result != NULL)
2877 *result = point;
2878 }
2879
2880 /* The closest point can still be one of the endpoints, so we test them. */
2881 d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[0]);
2882 if (float8_lt(d, dist))
2883 {
2884 dist = d;
2885 if (result != NULL)
2886 *result = on_lseg->p[0];
2887 }
2888 d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[1]);
2889 if (float8_lt(d, dist))
2890 {
2891 dist = d;
2892 if (result != NULL)
2893 *result = on_lseg->p[1];
2894 }
2895
2896 return dist;
2897}

References fb(), float8_lt(), lseg_closept_point(), lseg_interpt_lseg(), and result.

Referenced by box_closept_lseg(), close_lseg(), lseg_distance(), path_distance(), and poly_distance().

◆ lseg_closept_point()

static float8 lseg_closept_point ( Point result,
LSEG lseg,
Point pt 
)
static

Definition at line 2819 of file geo_ops.c.

2820{
2821 Point closept;
2822 LINE tmp;
2823
2824 /*
2825 * To find the closest point, we draw a perpendicular line from the point
2826 * to the line segment.
2827 */
2828 line_construct(&tmp, pt, point_invsl(&lseg->p[0], &lseg->p[1]));
2830
2831 if (result != NULL)
2832 *result = closept;
2833
2834 return point_dt(&closept, pt, NULL);
2835}
static float8 point_invsl(Point *pt1, Point *pt2)
Definition geo_ops.c:2068

References fb(), line_construct(), lseg_closept_line(), point_dt(), point_invsl(), and result.

Referenced by box_closept_point(), box_interpt_lseg(), close_ps(), dist_ppath_internal(), dist_ppoly_internal(), dist_ps(), dist_sp(), and lseg_closept_lseg().

◆ lseg_construct()

Datum lseg_construct ( PG_FUNCTION_ARGS  )

Definition at line 2158 of file geo_ops.c.

2159{
2163
2165
2167}

References fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_LSEG_P, result, and statlseg_construct().

◆ lseg_contain_point()

static bool lseg_contain_point ( LSEG lseg,
Point pt 
)
static

Definition at line 3156 of file geo_ops.c.

3157{
3158 return FPeq(point_dt(pt, &lseg->p[0], NULL) +
3159 point_dt(pt, &lseg->p[1], NULL),
3160 point_dt(&lseg->p[0], &lseg->p[1], NULL));
3161}

References fb(), FPeq(), and point_dt().

Referenced by lseg_inside_poly(), lseg_interpt_line(), lseg_interpt_lseg(), on_ps(), and touched_lseg_inside_poly().

◆ lseg_crossing()

static int lseg_crossing ( float8  x,
float8  y,
float8  prev_x,
float8  prev_y 
)
static

Definition at line 5549 of file geo_ops.c.

5550{
5551 float8 z;
5552 int y_sign;
5553
5554 if (FPzero(y))
5555 { /* y == 0, on X axis */
5556 if (FPzero(x)) /* (x,y) is (0,0)? */
5557 return POINT_ON_POLYGON;
5558 else if (FPgt(x, 0))
5559 { /* x > 0 */
5560 if (FPzero(prev_y)) /* y and prev_y are zero */
5561 /* prev_x > 0? */
5562 return FPgt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5563 return FPlt(prev_y, 0.0) ? 1 : -1;
5564 }
5565 else
5566 { /* x < 0, x not on positive X axis */
5567 if (FPzero(prev_y))
5568 /* prev_x < 0? */
5569 return FPlt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5570 return 0;
5571 }
5572 }
5573 else
5574 { /* y != 0 */
5575 /* compute y crossing direction from previous point */
5576 y_sign = FPgt(y, 0.0) ? 1 : -1;
5577
5578 if (FPzero(prev_y))
5579 /* previous point was on X axis, so new point is either off or on */
5580 return FPlt(prev_x, 0.0) ? 0 : y_sign;
5581 else if ((y_sign < 0 && FPlt(prev_y, 0.0)) ||
5582 (y_sign > 0 && FPgt(prev_y, 0.0)))
5583 /* both above or below X axis */
5584 return 0; /* same sign */
5585 else
5586 { /* y and prev_y cross X-axis */
5587 if (FPge(x, 0.0) && FPgt(prev_x, 0.0))
5588 /* both non-negative so cross positive X-axis */
5589 return 2 * y_sign;
5590 if (FPlt(x, 0.0) && FPle(prev_x, 0.0))
5591 /* both non-positive so do not cross positive X-axis */
5592 return 0;
5593
5594 /* x and y cross axes, see URL above point_inside() */
5597 if (FPzero(z))
5598 return POINT_ON_POLYGON;
5599 if ((y_sign < 0 && FPlt(z, 0.0)) ||
5600 (y_sign > 0 && FPgt(z, 0.0)))
5601 return 0;
5602 return 2 * y_sign;
5603 }
5604 }
5605}
#define POINT_ON_POLYGON
Definition geo_ops.c:5489

References fb(), float8_mi(), float8_mul(), FPge(), FPgt(), FPle(), FPlt(), FPzero, POINT_ON_POLYGON, x, and y.

Referenced by point_inside().

◆ lseg_distance()

Datum lseg_distance ( PG_FUNCTION_ARGS  )

Definition at line 2335 of file geo_ops.c.

2336{
2337 LSEG *l1 = PG_GETARG_LSEG_P(0);
2338 LSEG *l2 = PG_GETARG_LSEG_P(1);
2339
2341}

References fb(), lseg_closept_lseg(), PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ lseg_eq()

Datum lseg_eq ( PG_FUNCTION_ARGS  )

Definition at line 2265 of file geo_ops.c.

2266{
2267 LSEG *l1 = PG_GETARG_LSEG_P(0);
2268 LSEG *l2 = PG_GETARG_LSEG_P(1);
2269
2270 PG_RETURN_BOOL(point_eq_point(&l1->p[0], &l2->p[0]) &&
2271 point_eq_point(&l1->p[1], &l2->p[1]));
2272}

References LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_eq_point().

◆ lseg_ge()

Datum lseg_ge ( PG_FUNCTION_ARGS  )

Definition at line 2315 of file geo_ops.c.

2316{
2317 LSEG *l1 = PG_GETARG_LSEG_P(0);
2318 LSEG *l2 = PG_GETARG_LSEG_P(1);
2319
2320 PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1], NULL),
2321 point_dt(&l2->p[0], &l2->p[1], NULL)));
2322}

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

◆ lseg_gt()

Datum lseg_gt ( PG_FUNCTION_ARGS  )

Definition at line 2305 of file geo_ops.c.

2306{
2307 LSEG *l1 = PG_GETARG_LSEG_P(0);
2308 LSEG *l2 = PG_GETARG_LSEG_P(1);
2309
2310 PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1], NULL),
2311 point_dt(&l2->p[0], &l2->p[1], NULL)));
2312}

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

◆ lseg_horizontal()

Datum lseg_horizontal ( PG_FUNCTION_ARGS  )

Definition at line 2256 of file geo_ops.c.

2257{
2259
2260 PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));
2261}

References fb(), FPeq(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ lseg_in()

Datum lseg_in ( PG_FUNCTION_ARGS  )

Definition at line 2094 of file geo_ops.c.

2095{
2096 char *str = PG_GETARG_CSTRING(0);
2097 Node *escontext = fcinfo->context;
2099 bool isopen;
2100
2101 if (!path_decode(str, true, 2, &lseg->p[0], &isopen, NULL, "lseg", str,
2102 escontext))
2104
2106}

References fb(), palloc_object, path_decode(), PG_GETARG_CSTRING, PG_RETURN_LSEG_P, PG_RETURN_NULL, and str.

◆ lseg_inside_poly()

static bool lseg_inside_poly ( Point a,
Point b,
POLYGON poly,
int  start 
)
static

Definition at line 3913 of file geo_ops.c.

3914{
3915 LSEG s,
3916 t;
3917 int i;
3918 bool res = true,
3919 intersection = false;
3920
3921 /* since this function recurses, it could be driven to stack overflow */
3923
3924 t.p[0] = *a;
3925 t.p[1] = *b;
3926 s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
3927
3928 for (i = start; i < poly->npts && res; i++)
3929 {
3930 Point interpt;
3931
3933
3934 s.p[1] = poly->p[i];
3935
3936 if (lseg_contain_point(&s, t.p))
3937 {
3938 if (lseg_contain_point(&s, t.p + 1))
3939 return true; /* t is contained by s */
3940
3941 /* Y-cross */
3942 res = touched_lseg_inside_poly(t.p, t.p + 1, &s, poly, i + 1);
3943 }
3944 else if (lseg_contain_point(&s, t.p + 1))
3945 {
3946 /* Y-cross */
3947 res = touched_lseg_inside_poly(t.p + 1, t.p, &s, poly, i + 1);
3948 }
3949 else if (lseg_interpt_lseg(&interpt, &t, &s))
3950 {
3951 /*
3952 * segments are X-crossing, go to check each subsegment
3953 */
3954
3955 intersection = true;
3956 res = lseg_inside_poly(t.p, &interpt, poly, i + 1);
3957 if (res)
3958 res = lseg_inside_poly(t.p + 1, &interpt, poly, i + 1);
3959 }
3960
3961 s.p[0] = s.p[1];
3962 }
3963
3964 if (res && !intersection)
3965 {
3966 Point p;
3967
3968 /*
3969 * if X-intersection wasn't found, then check central point of tested
3970 * segment. In opposite case we already check all subsegments
3971 */
3972 p.x = float8_div(float8_pl(t.p[0].x, t.p[1].x), 2.0);
3973 p.y = float8_div(float8_pl(t.p[0].y, t.p[1].y), 2.0);
3974
3975 res = point_inside(&p, poly->npts, poly->p);
3976 }
3977
3978 return res;
3979}
static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
Definition geo_ops.c:3913
static bool lseg_contain_point(LSEG *lseg, Point *pt)
Definition geo_ops.c:3156
static bool touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
Definition geo_ops.c:3877
return str start
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
void check_stack_depth(void)
Definition stack_depth.c:95

References a, b, CHECK_FOR_INTERRUPTS, check_stack_depth(), fb(), float8_div(), float8_pl(), i, lseg_contain_point(), lseg_inside_poly(), lseg_interpt_lseg(), LSEG::p, point_inside(), start, touched_lseg_inside_poly(), Point::x, and Point::y.

Referenced by lseg_inside_poly(), poly_contain_poly(), and touched_lseg_inside_poly().

◆ lseg_interpt()

Datum lseg_interpt ( PG_FUNCTION_ARGS  )

Definition at line 2408 of file geo_ops.c.

2409{
2410 LSEG *l1 = PG_GETARG_LSEG_P(0);
2411 LSEG *l2 = PG_GETARG_LSEG_P(1);
2412 Point *result;
2413
2415
2416 if (!lseg_interpt_lseg(result, l1, l2))
2419}

References lseg_interpt_lseg(), palloc_object, PG_GETARG_LSEG_P, PG_RETURN_NULL, PG_RETURN_POINT_P, and result.

Referenced by interpt_pp().

◆ lseg_interpt_line()

static bool lseg_interpt_line ( Point result,
LSEG lseg,
LINE line 
)
static

Definition at line 2722 of file geo_ops.c.

2723{
2724 Point interpt;
2725 LINE tmp;
2726
2727 /*
2728 * First, we promote the line segment to a line, because we know how to
2729 * find the intersection point of two lines. If they don't have an
2730 * intersection point, we are done.
2731 */
2732 line_construct(&tmp, &lseg->p[0], lseg_sl(lseg));
2733 if (!line_interpt_line(&interpt, &tmp, line))
2734 return false;
2735
2736 /*
2737 * Then, we check whether the intersection point is actually on the line
2738 * segment.
2739 */
2741 return false;
2742 if (result != NULL)
2743 {
2744 /*
2745 * If there is an intersection, then check explicitly for matching
2746 * endpoints since there may be rounding effects with annoying LSB
2747 * residue.
2748 */
2749 if (point_eq_point(&lseg->p[0], &interpt))
2750 *result = lseg->p[0];
2751 else if (point_eq_point(&lseg->p[1], &interpt))
2752 *result = lseg->p[1];
2753 else
2754 *result = interpt;
2755 }
2756
2757 return true;
2758}

References fb(), line_construct(), line_interpt_line(), lseg_contain_point(), lseg_sl(), point_eq_point(), and result.

Referenced by inter_lb(), inter_sl(), lseg_closept_line(), and lseg_interpt_lseg().

◆ lseg_interpt_lseg()

static bool lseg_interpt_lseg ( Point result,
LSEG l1,
LSEG l2 
)
static

Definition at line 2385 of file geo_ops.c.

2386{
2387 Point interpt;
2388 LINE tmp;
2389
2390 line_construct(&tmp, &l2->p[0], lseg_sl(l2));
2391 if (!lseg_interpt_line(&interpt, l1, &tmp))
2392 return false;
2393
2394 /*
2395 * If the line intersection point isn't within l2, there is no valid
2396 * segment intersection point at all.
2397 */
2398 if (!lseg_contain_point(l2, &interpt))
2399 return false;
2400
2401 if (result != NULL)
2402 *result = interpt;
2403
2404 return true;
2405}

References fb(), line_construct(), lseg_contain_point(), lseg_interpt_line(), lseg_sl(), LSEG::p, and result.

Referenced by box_interpt_lseg(), lseg_closept_lseg(), lseg_inside_poly(), lseg_interpt(), lseg_intersect(), path_inter(), and poly_overlap_internal().

◆ lseg_intersect()

Datum lseg_intersect ( PG_FUNCTION_ARGS  )

Definition at line 2217 of file geo_ops.c.

2218{
2219 LSEG *l1 = PG_GETARG_LSEG_P(0);
2220 LSEG *l2 = PG_GETARG_LSEG_P(1);
2221
2223}

References fb(), lseg_interpt_lseg(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

Referenced by interpt_pp().

◆ lseg_invsl()

static float8 lseg_invsl ( LSEG lseg)
inlinestatic

Definition at line 2194 of file geo_ops.c.

2195{
2196 return point_invsl(&lseg->p[0], &lseg->p[1]);
2197}

References fb(), and point_invsl().

Referenced by lseg_perp().

◆ lseg_le()

Datum lseg_le ( PG_FUNCTION_ARGS  )

Definition at line 2295 of file geo_ops.c.

2296{
2297 LSEG *l1 = PG_GETARG_LSEG_P(0);
2298 LSEG *l2 = PG_GETARG_LSEG_P(1);
2299
2300 PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1], NULL),
2301 point_dt(&l2->p[0], &l2->p[1], NULL)));
2302}

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

◆ lseg_length()

Datum lseg_length ( PG_FUNCTION_ARGS  )

Definition at line 2201 of file geo_ops.c.

2202{
2204
2205 PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1], NULL));
2206}

References fb(), PG_GETARG_LSEG_P, PG_RETURN_FLOAT8, and point_dt().

◆ lseg_lt()

Datum lseg_lt ( PG_FUNCTION_ARGS  )

Definition at line 2285 of file geo_ops.c.

2286{
2287 LSEG *l1 = PG_GETARG_LSEG_P(0);
2288 LSEG *l2 = PG_GETARG_LSEG_P(1);
2289
2290 PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1], NULL),
2291 point_dt(&l2->p[0], &l2->p[1], NULL)));
2292}

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

◆ lseg_ne()

Datum lseg_ne ( PG_FUNCTION_ARGS  )

Definition at line 2275 of file geo_ops.c.

2276{
2277 LSEG *l1 = PG_GETARG_LSEG_P(0);
2278 LSEG *l2 = PG_GETARG_LSEG_P(1);
2279
2280 PG_RETURN_BOOL(!point_eq_point(&l1->p[0], &l2->p[0]) ||
2281 !point_eq_point(&l1->p[1], &l2->p[1]));
2282}

References LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BOOL, and point_eq_point().

◆ lseg_out()

Datum lseg_out ( PG_FUNCTION_ARGS  )

Definition at line 2110 of file geo_ops.c.

2111{
2112 LSEG *ls = PG_GETARG_LSEG_P(0);
2113
2115}

References fb(), path_encode(), PATH_OPEN, PG_GETARG_LSEG_P, and PG_RETURN_CSTRING.

◆ lseg_parallel()

Datum lseg_parallel ( PG_FUNCTION_ARGS  )

Definition at line 2227 of file geo_ops.c.

2228{
2229 LSEG *l1 = PG_GETARG_LSEG_P(0);
2230 LSEG *l2 = PG_GETARG_LSEG_P(1);
2231
2233}

References FPeq(), lseg_sl(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ lseg_perp()

Datum lseg_perp ( PG_FUNCTION_ARGS  )

Definition at line 2239 of file geo_ops.c.

2240{
2241 LSEG *l1 = PG_GETARG_LSEG_P(0);
2242 LSEG *l2 = PG_GETARG_LSEG_P(1);
2243
2245}
static float8 lseg_invsl(LSEG *lseg)
Definition geo_ops.c:2194

References FPeq(), lseg_invsl(), lseg_sl(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ lseg_recv()

Datum lseg_recv ( PG_FUNCTION_ARGS  )

Definition at line 2121 of file geo_ops.c.

2122{
2124 LSEG *lseg;
2125
2127
2128 lseg->p[0].x = pq_getmsgfloat8(buf);
2129 lseg->p[0].y = pq_getmsgfloat8(buf);
2130 lseg->p[1].x = pq_getmsgfloat8(buf);
2131 lseg->p[1].y = pq_getmsgfloat8(buf);
2132
2134}

References buf, fb(), palloc_object, PG_GETARG_POINTER, PG_RETURN_LSEG_P, and pq_getmsgfloat8().

◆ lseg_send()

Datum lseg_send ( PG_FUNCTION_ARGS  )

Definition at line 2140 of file geo_ops.c.

2141{
2142 LSEG *ls = PG_GETARG_LSEG_P(0);
2144
2146 pq_sendfloat8(&buf, ls->p[0].x);
2147 pq_sendfloat8(&buf, ls->p[0].y);
2148 pq_sendfloat8(&buf, ls->p[1].x);
2149 pq_sendfloat8(&buf, ls->p[1].y);
2151}

References buf, fb(), PG_GETARG_LSEG_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat8().

◆ lseg_sl()

static float8 lseg_sl ( LSEG lseg)
inlinestatic

Definition at line 2184 of file geo_ops.c.

2185{
2186 return point_sl(&lseg->p[0], &lseg->p[1]);
2187}

References fb(), and point_sl().

Referenced by close_ls(), close_lseg(), line_in(), lseg_interpt_line(), lseg_interpt_lseg(), lseg_parallel(), and lseg_perp().

◆ lseg_vertical()

Datum lseg_vertical ( PG_FUNCTION_ARGS  )

Definition at line 2248 of file geo_ops.c.

2249{
2251
2252 PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));
2253}

References fb(), FPeq(), PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ make_bound_box()

static void make_bound_box ( POLYGON poly)
static

Definition at line 3423 of file geo_ops.c.

3424{
3425 int i;
3426 float8 x1,
3427 y1,
3428 x2,
3429 y2;
3430
3431 Assert(poly->npts > 0);
3432
3433 x1 = x2 = poly->p[0].x;
3434 y2 = y1 = poly->p[0].y;
3435 for (i = 1; i < poly->npts; i++)
3436 {
3437 if (float8_lt(poly->p[i].x, x1))
3438 x1 = poly->p[i].x;
3439 if (float8_gt(poly->p[i].x, x2))
3440 x2 = poly->p[i].x;
3441 if (float8_lt(poly->p[i].y, y1))
3442 y1 = poly->p[i].y;
3443 if (float8_gt(poly->p[i].y, y2))
3444 y2 = poly->p[i].y;
3445 }
3446
3447 poly->boundbox.low.x = x1;
3448 poly->boundbox.high.x = x2;
3449 poly->boundbox.low.y = y1;
3450 poly->boundbox.high.y = y2;
3451}

References Assert, fb(), float8_gt(), float8_lt(), and i.

Referenced by circle_poly_internal(), path_poly(), poly_in(), and poly_recv().

◆ on_pb()

Datum on_pb ( PG_FUNCTION_ARGS  )

Definition at line 3184 of file geo_ops.c.

3185{
3187 BOX *box = PG_GETARG_BOX_P(1);
3188
3190}

References box_contain_point(), fb(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, and PG_RETURN_BOOL.

◆ on_pl()

Datum on_pl ( PG_FUNCTION_ARGS  )

Definition at line 3142 of file geo_ops.c.

3143{
3145 LINE *line = PG_GETARG_LINE_P(1);
3146
3148}
static bool line_contain_point(LINE *line, Point *point)
Definition geo_ops.c:3134

References fb(), line_contain_point(), PG_GETARG_LINE_P, PG_GETARG_POINT_P, and PG_RETURN_BOOL.

◆ on_ppath()

Datum on_ppath ( PG_FUNCTION_ARGS  )

Definition at line 3213 of file geo_ops.c.

3214{
3216 PATH *path = PG_GETARG_PATH_P(1);
3217 int i,
3218 n;
3219 float8 a,
3220 b;
3221
3222 /*-- OPEN --*/
3223 if (!path->closed)
3224 {
3225 n = path->npts - 1;
3226 a = point_dt(pt, &path->p[0], NULL);
3227 for (i = 0; i < n; i++)
3228 {
3229 b = point_dt(pt, &path->p[i + 1], NULL);
3230 if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1], NULL)))
3231 PG_RETURN_BOOL(true);
3232 a = b;
3233 }
3234 PG_RETURN_BOOL(false);
3235 }
3236
3237 /*-- CLOSED --*/
3238 PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
3239}

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

◆ on_ps()

Datum on_ps ( PG_FUNCTION_ARGS  )

Definition at line 3164 of file geo_ops.c.

3165{
3168
3170}

References fb(), lseg_contain_point(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, and PG_RETURN_BOOL.

◆ on_sb()

Datum on_sb ( PG_FUNCTION_ARGS  )

Definition at line 3271 of file geo_ops.c.

3272{
3274 BOX *box = PG_GETARG_BOX_P(1);
3275
3277}
static bool box_contain_lseg(BOX *box, LSEG *lseg)
Definition geo_ops.c:3264

References box_contain_lseg(), fb(), PG_GETARG_BOX_P, PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ on_sl()

Datum on_sl ( PG_FUNCTION_ARGS  )

Definition at line 3248 of file geo_ops.c.

3249{
3251 LINE *line = PG_GETARG_LINE_P(1);
3252
3253 PG_RETURN_BOOL(line_contain_point(line, &lseg->p[0]) &&
3254 line_contain_point(line, &lseg->p[1]));
3255}

References fb(), line_contain_point(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, and PG_RETURN_BOOL.

◆ pair_count()

static int pair_count ( char s,
char  delim 
)
static

Definition at line 393 of file geo_ops.c.

394{
395 int ndelim = 0;
396
397 while ((s = strchr(s, delim)) != NULL)
398 {
399 ndelim++;
400 s++;
401 }
402 return (ndelim % 2) ? ((ndelim + 1) / 2) : -1;
403}

References fb().

Referenced by path_in(), and poly_in().

◆ pair_decode()

static bool pair_decode ( char str,
float8 x,
float8 y,
char **  endptr_p,
const char type_name,
const char orig_string,
Node escontext 
)
static

Definition at line 213 of file geo_ops.c.

216{
217 bool has_delim;
218
219 while (isspace((unsigned char) *str))
220 str++;
221 if ((has_delim = (*str == LDELIM)))
222 str++;
223
224 if (!single_decode(str, x, &str, type_name, orig_string, escontext))
225 return false;
226
227 if (*str++ != DELIM)
228 goto fail;
229
230 if (!single_decode(str, y, &str, type_name, orig_string, escontext))
231 return false;
232
233 if (has_delim)
234 {
235 if (*str++ != RDELIM)
236 goto fail;
237 while (isspace((unsigned char) *str))
238 str++;
239 }
240
241 /* report stopping point if wanted, else complain if not end of string */
242 if (endptr_p)
243 *endptr_p = str;
244 else if (*str != '\0')
245 goto fail;
246 return true;
247
248fail:
249 ereturn(escontext, false,
251 errmsg("invalid input syntax for type %s: \"%s\"",
252 type_name, orig_string)));
253}

References DELIM, ereturn, errcode(), errmsg, fb(), LDELIM, RDELIM, single_decode(), str, x, and y.

Referenced by circle_in(), path_decode(), and point_in().

◆ pair_encode()

static void pair_encode ( float8  x,
float8  y,
StringInfo  str 
)
static

Definition at line 256 of file geo_ops.c.

257{
258 char *xstr = float8out_internal(x);
259 char *ystr = float8out_internal(y);
260
261 appendStringInfo(str, "%s,%s", xstr, ystr);
262 pfree(xstr);
263 pfree(ystr);
264}
void pfree(void *pointer)
Definition mcxt.c:1616
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145

References appendStringInfo(), fb(), float8out_internal(), pfree(), str, x, and y.

Referenced by circle_out(), and path_encode().

◆ path_add()

Datum path_add ( PG_FUNCTION_ARGS  )

Definition at line 4404 of file geo_ops.c.

4405{
4406 PATH *p1 = PG_GETARG_PATH_P(0);
4407 PATH *p2 = PG_GETARG_PATH_P(1);
4408 PATH *result;
4409 int size,
4410 base_size;
4411 int i;
4412
4413 if (p1->closed || p2->closed)
4415
4416 base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
4417 size = offsetof(PATH, p) + base_size;
4418
4419 /* Check for integer overflow */
4420 if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
4421 size <= base_size)
4422 ereport(ERROR,
4424 errmsg("too many points requested")));
4425
4426 result = (PATH *) palloc(size);
4427
4428 SET_VARSIZE(result, size);
4429 result->npts = (p1->npts + p2->npts);
4430 result->closed = p1->closed;
4431 /* prevent instability in unused pad bytes */
4432 result->dummy = 0;
4433
4434 for (i = 0; i < p1->npts; i++)
4435 {
4436 result->p[i].x = p1->p[i].x;
4437 result->p[i].y = p1->p[i].y;
4438 }
4439 for (i = 0; i < p2->npts; i++)
4440 {
4441 result->p[i + p1->npts].x = p2->p[i].x;
4442 result->p[i + p1->npts].y = p2->p[i].y;
4443 }
4444
4446}
#define PG_RETURN_PATH_P(x)
Definition geo_decls.h:217

References ereport, errcode(), errmsg, ERROR, fb(), i, palloc(), PG_GETARG_PATH_P, PG_RETURN_NULL, PG_RETURN_PATH_P, result, and SET_VARSIZE().

◆ path_add_pt()

Datum path_add_pt ( PG_FUNCTION_ARGS  )

Definition at line 4452 of file geo_ops.c.

4453{
4454 PATH *path = PG_GETARG_PATH_P_COPY(0);
4456 int i;
4457
4458 for (i = 0; i < path->npts; i++)
4459 point_add_point(&path->p[i], &path->p[i], point, NULL);
4460
4461 PG_RETURN_PATH_P(path);
4462}
#define PG_GETARG_PATH_P_COPY(n)
Definition geo_decls.h:216

References fb(), i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, and point_add_point().

◆ path_area()

Datum path_area ( PG_FUNCTION_ARGS  )

Definition at line 1398 of file geo_ops.c.

1399{
1400 PATH *path = PG_GETARG_PATH_P(0);
1401 float8 area = 0.0;
1402 int i,
1403 j;
1404
1405 if (!path->closed)
1407
1408 for (i = 0; i < path->npts; i++)
1409 {
1410 j = (i + 1) % path->npts;
1411 area = float8_pl(area, float8_mul(path->p[i].x, path->p[j].y));
1412 area = float8_mi(area, float8_mul(path->p[i].y, path->p[j].x));
1413 }
1414
1415 PG_RETURN_FLOAT8(float8_div(fabs(area), 2.0));
1416}
int j
Definition isn.c:78

References PATH::closed, fb(), float8_div(), float8_mi(), float8_mul(), float8_pl(), i, j, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, Point::x, and Point::y.

◆ path_close()

Datum path_close ( PG_FUNCTION_ARGS  )

Definition at line 1645 of file geo_ops.c.

1646{
1647 PATH *path = PG_GETARG_PATH_P_COPY(0);
1648
1649 path->closed = true;
1650
1651 PG_RETURN_PATH_P(path);
1652}

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

◆ path_decode()

static bool path_decode ( char str,
bool  opentype,
int  npts,
Point p,
bool isopen,
char **  endptr_p,
const char type_name,
const char orig_string,
Node escontext 
)
static

Definition at line 267 of file geo_ops.c.

271{
272 int depth = 0;
273 char *cp;
274 int i;
275
276 while (isspace((unsigned char) *str))
277 str++;
278 if ((*isopen = (*str == LDELIM_EP)))
279 {
280 /* no open delimiter allowed? */
281 if (!opentype)
282 goto fail;
283 depth++;
284 str++;
285 }
286 else if (*str == LDELIM)
287 {
288 cp = (str + 1);
289 while (isspace((unsigned char) *cp))
290 cp++;
291 if (*cp == LDELIM)
292 {
293 depth++;
294 str = cp;
295 }
296 else if (strrchr(str, LDELIM) == str)
297 {
298 depth++;
299 str = cp;
300 }
301 }
302
303 for (i = 0; i < npts; i++)
304 {
305 if (!pair_decode(str, &(p->x), &(p->y), &str, type_name, orig_string,
306 escontext))
307 return false;
308 if (*str == DELIM)
309 str++;
310 p++;
311 }
312
313 while (depth > 0)
314 {
315 if (*str == RDELIM || (*str == RDELIM_EP && *isopen && depth == 1))
316 {
317 depth--;
318 str++;
319 while (isspace((unsigned char) *str))
320 str++;
321 }
322 else
323 goto fail;
324 }
325
326 /* report stopping point if wanted, else complain if not end of string */
327 if (endptr_p)
328 *endptr_p = str;
329 else if (*str != '\0')
330 goto fail;
331 return true;
332
333fail:
334 ereturn(escontext, false,
336 errmsg("invalid input syntax for type %s: \"%s\"",
337 type_name, orig_string)));
338} /* path_decode() */
#define LDELIM_EP
Definition geo_ops.c:161
#define RDELIM_EP
Definition geo_ops.c:162

References DELIM, ereturn, errcode(), errmsg, fb(), i, LDELIM, LDELIM_EP, pair_decode(), RDELIM, RDELIM_EP, str, Point::x, and Point::y.

Referenced by box_in(), line_in(), lseg_in(), path_in(), and poly_in().

◆ path_distance()

Datum path_distance ( PG_FUNCTION_ARGS  )

Definition at line 1748 of file geo_ops.c.

1749{
1750 PATH *p1 = PG_GETARG_PATH_P(0);
1751 PATH *p2 = PG_GETARG_PATH_P(1);
1752 float8 min = 0.0; /* initialize to keep compiler quiet */
1753 bool have_min = false;
1754 float8 tmp;
1755 int i,
1756 j;
1757 LSEG seg1,
1758 seg2;
1759
1760 for (i = 0; i < p1->npts; i++)
1761 {
1762 int iprev;
1763
1764 if (i > 0)
1765 iprev = i - 1;
1766 else
1767 {
1768 if (!p1->closed)
1769 continue;
1770 iprev = p1->npts - 1; /* include the closure segment */
1771 }
1772
1773 for (j = 0; j < p2->npts; j++)
1774 {
1775 int jprev;
1776
1777 if (j > 0)
1778 jprev = j - 1;
1779 else
1780 {
1781 if (!p2->closed)
1782 continue;
1783 jprev = p2->npts - 1; /* include the closure segment */
1784 }
1785
1786 statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1787 statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1788
1789 tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
1790 if (!have_min || float8_lt(tmp, min))
1791 {
1792 min = tmp;
1793 have_min = true;
1794 }
1795 }
1796 }
1797
1798 if (!have_min)
1800
1801 PG_RETURN_FLOAT8(min);
1802}

References fb(), float8_lt(), i, j, lseg_closept_lseg(), PG_GETARG_PATH_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, and statlseg_construct().

◆ path_div_pt()

Datum path_div_pt ( PG_FUNCTION_ARGS  )

Definition at line 4494 of file geo_ops.c.

4495{
4496 PATH *path = PG_GETARG_PATH_P_COPY(0);
4498 int i;
4499
4500 for (i = 0; i < path->npts; i++)
4501 point_div_point(&path->p[i], &path->p[i], point);
4502
4503 PG_RETURN_PATH_P(path);
4504}

References fb(), i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, and point_div_point().

◆ path_encode() [1/2]

static char * path_encode ( enum path_delim  path_delim,
int  npts,
Point pt 
)
static

◆ path_encode() [2/2]

static char * path_encode ( enum path_delim  path_delim,
int  npts,
Point pt 
)
static

Definition at line 341 of file geo_ops.c.

342{
344 int i;
345
347
348 switch (path_delim)
349 {
350 case PATH_CLOSED:
352 break;
353 case PATH_OPEN:
355 break;
356 case PATH_NONE:
357 break;
358 }
359
360 for (i = 0; i < npts; i++)
361 {
362 if (i > 0)
365 pair_encode(pt->x, pt->y, &str);
367 pt++;
368 }
369
370 switch (path_delim)
371 {
372 case PATH_CLOSED:
374 break;
375 case PATH_OPEN:
377 break;
378 case PATH_NONE:
379 break;
380 }
381
382 return str.data;
383} /* path_encode() */
path_delim
Definition geo_ops.c:74

References appendStringInfoChar(), DELIM, fb(), i, initStringInfo(), LDELIM, LDELIM_EP, pair_encode(), PATH_CLOSED, PATH_NONE, PATH_OPEN, RDELIM, RDELIM_EP, and str.

◆ path_in()

Datum path_in ( PG_FUNCTION_ARGS  )

Definition at line 1420 of file geo_ops.c.

1421{
1422 char *str = PG_GETARG_CSTRING(0);
1423 Node *escontext = fcinfo->context;
1424 PATH *path;
1425 bool isopen;
1426 char *s;
1427 int npts;
1428 int size;
1429 int base_size;
1430 int depth = 0;
1431
1432 if ((npts = pair_count(str, ',')) <= 0)
1433 ereturn(escontext, (Datum) 0,
1435 errmsg("invalid input syntax for type %s: \"%s\"",
1436 "path", str)));
1437
1438 s = str;
1439 while (isspace((unsigned char) *s))
1440 s++;
1441
1442 /* skip single leading paren */
1443 if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
1444 {
1445 s++;
1446 depth++;
1447 }
1448
1449 base_size = sizeof(path->p[0]) * npts;
1450 size = offsetof(PATH, p) + base_size;
1451
1452 /* Check for integer overflow */
1453 if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
1454 ereturn(escontext, (Datum) 0,
1456 errmsg("too many points requested")));
1457
1458 path = (PATH *) palloc(size);
1459
1460 SET_VARSIZE(path, size);
1461 path->npts = npts;
1462
1463 if (!path_decode(s, true, npts, &(path->p[0]), &isopen, &s, "path", str,
1464 escontext))
1466
1467 if (depth >= 1)
1468 {
1469 if (*s++ != RDELIM)
1470 ereturn(escontext, (Datum) 0,
1472 errmsg("invalid input syntax for type %s: \"%s\"",
1473 "path", str)));
1474 while (isspace((unsigned char) *s))
1475 s++;
1476 }
1477 if (*s != '\0')
1478 ereturn(escontext, (Datum) 0,
1480 errmsg("invalid input syntax for type %s: \"%s\"",
1481 "path", str)));
1482
1483 path->closed = (!isopen);
1484 /* prevent instability in unused pad bytes */
1485 path->dummy = 0;
1486
1487 PG_RETURN_PATH_P(path);
1488}
static int pair_count(char *s, char delim)
Definition geo_ops.c:393
int32 dummy
Definition geo_decls.h:119

References PATH::closed, PATH::dummy, ereturn, errcode(), errmsg, fb(), LDELIM, PATH::npts, PATH::p, pair_count(), palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_PATH_P, RDELIM, SET_VARSIZE(), and str.

◆ path_inter()

Datum path_inter ( PG_FUNCTION_ARGS  )

Definition at line 1671 of file geo_ops.c.

1672{
1673 PATH *p1 = PG_GETARG_PATH_P(0);
1674 PATH *p2 = PG_GETARG_PATH_P(1);
1675 BOX b1,
1676 b2;
1677 int i,
1678 j;
1679 LSEG seg1,
1680 seg2;
1681
1682 Assert(p1->npts > 0 && p2->npts > 0);
1683
1684 b1.high.x = b1.low.x = p1->p[0].x;
1685 b1.high.y = b1.low.y = p1->p[0].y;
1686 for (i = 1; i < p1->npts; i++)
1687 {
1688 b1.high.x = float8_max(p1->p[i].x, b1.high.x);
1689 b1.high.y = float8_max(p1->p[i].y, b1.high.y);
1690 b1.low.x = float8_min(p1->p[i].x, b1.low.x);
1691 b1.low.y = float8_min(p1->p[i].y, b1.low.y);
1692 }
1693 b2.high.x = b2.low.x = p2->p[0].x;
1694 b2.high.y = b2.low.y = p2->p[0].y;
1695 for (i = 1; i < p2->npts; i++)
1696 {
1697 b2.high.x = float8_max(p2->p[i].x, b2.high.x);
1698 b2.high.y = float8_max(p2->p[i].y, b2.high.y);
1699 b2.low.x = float8_min(p2->p[i].x, b2.low.x);
1700 b2.low.y = float8_min(p2->p[i].y, b2.low.y);
1701 }
1702 if (!box_ov(&b1, &b2))
1703 PG_RETURN_BOOL(false);
1704
1705 /* pairwise check lseg intersections */
1706 for (i = 0; i < p1->npts; i++)
1707 {
1708 int iprev;
1709
1710 if (i > 0)
1711 iprev = i - 1;
1712 else
1713 {
1714 if (!p1->closed)
1715 continue;
1716 iprev = p1->npts - 1; /* include the closure segment */
1717 }
1718
1719 for (j = 0; j < p2->npts; j++)
1720 {
1721 int jprev;
1722
1723 if (j > 0)
1724 jprev = j - 1;
1725 else
1726 {
1727 if (!p2->closed)
1728 continue;
1729 jprev = p2->npts - 1; /* include the closure segment */
1730 }
1731
1732 statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1733 statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1735 PG_RETURN_BOOL(true);
1736 }
1737 }
1738
1739 /* if we dropped through, no two segs intersected */
1740 PG_RETURN_BOOL(false);
1741}

References Assert, box_ov(), fb(), float8_max(), float8_min(), i, j, lseg_interpt_lseg(), PG_GETARG_PATH_P, PG_RETURN_BOOL, and statlseg_construct().

◆ path_isclosed()

Datum path_isclosed ( PG_FUNCTION_ARGS  )

Definition at line 1620 of file geo_ops.c.

1621{
1622 PATH *path = PG_GETARG_PATH_P(0);
1623
1624 PG_RETURN_BOOL(path->closed);
1625}

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_isopen()

Datum path_isopen ( PG_FUNCTION_ARGS  )

Definition at line 1628 of file geo_ops.c.

1629{
1630 PATH *path = PG_GETARG_PATH_P(0);
1631
1632 PG_RETURN_BOOL(!path->closed);
1633}

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_length()

Datum path_length ( PG_FUNCTION_ARGS  )

Definition at line 1810 of file geo_ops.c.

1811{
1812 PATH *path = PG_GETARG_PATH_P(0);
1813 float8 result = 0.0;
1814 int i;
1815
1816 for (i = 0; i < path->npts; i++)
1817 {
1818 int iprev;
1819
1820 if (i > 0)
1821 iprev = i - 1;
1822 else
1823 {
1824 if (!path->closed)
1825 continue;
1826 iprev = path->npts - 1; /* include the closure segment */
1827 }
1828
1829 result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i], NULL));
1830 }
1831
1833}

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

◆ path_mul_pt()

Datum path_mul_pt ( PG_FUNCTION_ARGS  )

Definition at line 4481 of file geo_ops.c.

4482{
4483 PATH *path = PG_GETARG_PATH_P_COPY(0);
4485 int i;
4486
4487 for (i = 0; i < path->npts; i++)
4488 point_mul_point(&path->p[i], &path->p[i], point);
4489
4490 PG_RETURN_PATH_P(path);
4491}

References fb(), i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, and point_mul_point().

◆ path_n_eq()

Datum path_n_eq ( PG_FUNCTION_ARGS  )

Definition at line 1589 of file geo_ops.c.

1590{
1591 PATH *p1 = PG_GETARG_PATH_P(0);
1592 PATH *p2 = PG_GETARG_PATH_P(1);
1593
1594 PG_RETURN_BOOL(p1->npts == p2->npts);
1595}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_ge()

Datum path_n_ge ( PG_FUNCTION_ARGS  )

Definition at line 1607 of file geo_ops.c.

1608{
1609 PATH *p1 = PG_GETARG_PATH_P(0);
1610 PATH *p2 = PG_GETARG_PATH_P(1);
1611
1612 PG_RETURN_BOOL(p1->npts >= p2->npts);
1613}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_gt()

Datum path_n_gt ( PG_FUNCTION_ARGS  )

Definition at line 1580 of file geo_ops.c.

1581{
1582 PATH *p1 = PG_GETARG_PATH_P(0);
1583 PATH *p2 = PG_GETARG_PATH_P(1);
1584
1585 PG_RETURN_BOOL(p1->npts > p2->npts);
1586}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_le()

Datum path_n_le ( PG_FUNCTION_ARGS  )

Definition at line 1598 of file geo_ops.c.

1599{
1600 PATH *p1 = PG_GETARG_PATH_P(0);
1601 PATH *p2 = PG_GETARG_PATH_P(1);
1602
1603 PG_RETURN_BOOL(p1->npts <= p2->npts);
1604}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_lt()

Datum path_n_lt ( PG_FUNCTION_ARGS  )

Definition at line 1571 of file geo_ops.c.

1572{
1573 PATH *p1 = PG_GETARG_PATH_P(0);
1574 PATH *p2 = PG_GETARG_PATH_P(1);
1575
1576 PG_RETURN_BOOL(p1->npts < p2->npts);
1577}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_npoints()

Datum path_npoints ( PG_FUNCTION_ARGS  )

Definition at line 1636 of file geo_ops.c.

1637{
1638 PATH *path = PG_GETARG_PATH_P(0);
1639
1640 PG_RETURN_INT32(path->npts);
1641}
#define PG_RETURN_INT32(x)
Definition fmgr.h:355

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_INT32.

◆ path_open()

Datum path_open ( PG_FUNCTION_ARGS  )

Definition at line 1655 of file geo_ops.c.

1656{
1657 PATH *path = PG_GETARG_PATH_P_COPY(0);
1658
1659 path->closed = false;
1660
1661 PG_RETURN_PATH_P(path);
1662}

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

◆ path_out()

Datum path_out ( PG_FUNCTION_ARGS  )

Definition at line 1492 of file geo_ops.c.

1493{
1494 PATH *path = PG_GETARG_PATH_P(0);
1495
1496 PG_RETURN_CSTRING(path_encode(path->closed ? PATH_CLOSED : PATH_OPEN, path->npts, path->p));
1497}

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

◆ path_poly()

Datum path_poly ( PG_FUNCTION_ARGS  )

Definition at line 4508 of file geo_ops.c.

4509{
4510 PATH *path = PG_GETARG_PATH_P(0);
4511 POLYGON *poly;
4512 int size;
4513 int i;
4514
4515 /* This is not very consistent --- other similar cases return NULL ... */
4516 if (!path->closed)
4517 ereturn(fcinfo->context, (Datum) 0,
4519 errmsg("open path cannot be converted to polygon")));
4520
4521 /*
4522 * Never overflows: the old size fit in MaxAllocSize, and the new size is
4523 * just a small constant larger.
4524 */
4525 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * path->npts;
4526 poly = (POLYGON *) palloc(size);
4527
4528 SET_VARSIZE(poly, size);
4529 poly->npts = path->npts;
4530
4531 for (i = 0; i < path->npts; i++)
4532 {
4533 poly->p[i].x = path->p[i].x;
4534 poly->p[i].y = path->p[i].y;
4535 }
4536
4538
4540}

References PATH::closed, ereturn, errcode(), errmsg, fb(), i, make_bound_box(), PATH::npts, PATH::p, palloc(), PG_GETARG_PATH_P, PG_RETURN_POLYGON_P, SET_VARSIZE(), Point::x, and Point::y.

◆ path_recv()

Datum path_recv ( PG_FUNCTION_ARGS  )

Definition at line 1506 of file geo_ops.c.

1507{
1509 PATH *path;
1510 int closed;
1511 int32 npts;
1512 int32 i;
1513 int size;
1514
1515 closed = pq_getmsgbyte(buf);
1516 npts = pq_getmsgint(buf, sizeof(int32));
1517 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p)) / sizeof(Point)))
1518 ereport(ERROR,
1520 errmsg("invalid number of points in external \"path\" value")));
1521
1522 size = offsetof(PATH, p) + sizeof(path->p[0]) * npts;
1523 path = (PATH *) palloc(size);
1524
1525 SET_VARSIZE(path, size);
1526 path->npts = npts;
1527 path->closed = (closed ? 1 : 0);
1528 /* prevent instability in unused pad bytes */
1529 path->dummy = 0;
1530
1531 for (i = 0; i < npts; i++)
1532 {
1533 path->p[i].x = pq_getmsgfloat8(buf);
1534 path->p[i].y = pq_getmsgfloat8(buf);
1535 }
1536
1537 PG_RETURN_PATH_P(path);
1538}
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
int pq_getmsgbyte(StringInfo msg)
Definition pqformat.c:398

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

◆ path_send()

Datum path_send ( PG_FUNCTION_ARGS  )

Definition at line 1544 of file geo_ops.c.

1545{
1546 PATH *path = PG_GETARG_PATH_P(0);
1548 int32 i;
1549
1551 pq_sendbyte(&buf, path->closed ? 1 : 0);
1552 pq_sendint32(&buf, path->npts);
1553 for (i = 0; i < path->npts; i++)
1554 {
1555 pq_sendfloat8(&buf, path->p[i].x);
1556 pq_sendfloat8(&buf, path->p[i].y);
1557 }
1559}
static void pq_sendint32(StringInfo buf, uint32 i)
Definition pqformat.h:144
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition pqformat.h:160

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_sendint32(), Point::x, and Point::y.

◆ path_sub_pt()

Datum path_sub_pt ( PG_FUNCTION_ARGS  )

Definition at line 4465 of file geo_ops.c.

4466{
4467 PATH *path = PG_GETARG_PATH_P_COPY(0);
4469 int i;
4470
4471 for (i = 0; i < path->npts; i++)
4472 point_sub_point(&path->p[i], &path->p[i], point);
4473
4474 PG_RETURN_PATH_P(path);
4475}

References fb(), i, PATH::npts, PATH::p, PG_GETARG_PATH_P_COPY, PG_GETARG_POINT_P, PG_RETURN_PATH_P, and point_sub_point().

◆ plist_same()

static bool plist_same ( int  npts,
Point p1,
Point p2 
)
static

Definition at line 5609 of file geo_ops.c.

5610{
5611 int i,
5612 ii,
5613 j;
5614
5615 /* find match for first point */
5616 for (i = 0; i < npts; i++)
5617 {
5618 if (point_eq_point(&p2[i], &p1[0]))
5619 {
5620
5621 /* match found? then look forward through remaining points */
5622 for (ii = 1, j = i + 1; ii < npts; ii++, j++)
5623 {
5624 if (j >= npts)
5625 j = 0;
5626 if (!point_eq_point(&p2[j], &p1[ii]))
5627 break;
5628 }
5629 if (ii == npts)
5630 return true;
5631
5632 /* match not found forwards? then look backwards */
5633 for (ii = 1, j = i - 1; ii < npts; ii++, j--)
5634 {
5635 if (j < 0)
5636 j = (npts - 1);
5637 if (!point_eq_point(&p2[j], &p1[ii]))
5638 break;
5639 }
5640 if (ii == npts)
5641 return true;
5642 }
5643 }
5644
5645 return false;
5646}

References fb(), i, j, and point_eq_point().

Referenced by poly_same().

◆ point_above()

Datum point_above ( PG_FUNCTION_ARGS  )

Definition at line 1937 of file geo_ops.c.

1938{
1941
1942 PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
1943}

References fb(), FPgt(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

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

◆ point_add()

Datum point_add ( PG_FUNCTION_ARGS  )

Definition at line 4175 of file geo_ops.c.

4176{
4179 Point *result;
4180
4182
4184
4186}

References fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_POINT_P, point_add_point(), and result.

◆ point_add_point()

static void point_add_point ( Point result,
Point pt1,
Point pt2,
Node escontext 
)
inlinestatic

Definition at line 4158 of file geo_ops.c.

4159{
4160 float8 x;
4161 float8 y;
4162
4163 x = float8_pl_safe(pt1->x, pt2->x, escontext);
4164 if (SOFT_ERROR_OCCURRED(escontext))
4165 return;
4166
4167 y = float8_pl_safe(pt1->y, pt2->y, escontext);
4168 if (SOFT_ERROR_OCCURRED(escontext))
4169 return;
4170
4172}

References fb(), float8_pl_safe(), point_construct(), result, SOFT_ERROR_OCCURRED, x, and y.

Referenced by box_add(), circle_add_pt(), path_add_pt(), point_add(), and poly_to_circle().

◆ point_below()

Datum point_below ( PG_FUNCTION_ARGS  )

Definition at line 1946 of file geo_ops.c.

1947{
1950
1951 PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
1952}

References fb(), FPlt(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

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

◆ point_box()

Datum point_box ( PG_FUNCTION_ARGS  )

Definition at line 4358 of file geo_ops.c.

4359{
4361 BOX *box;
4362
4364
4365 box->high.x = pt->x;
4366 box->low.x = pt->x;
4367 box->high.y = pt->y;
4368 box->low.y = pt->y;
4369
4371}

References fb(), palloc_object, PG_GETARG_POINT_P, and PG_RETURN_BOX_P.

◆ point_construct()

static void point_construct ( Point result,
float8  x,
float8  y 
)
inlinestatic

Definition at line 1902 of file geo_ops.c.

1903{
1904 result->x = x;
1905 result->y = y;
1906}

References result, x, and y.

Referenced by construct_point(), line_interpt_line(), point_add_point(), point_div_point(), point_mul_point(), and point_sub_point().

◆ point_distance()

Datum point_distance ( PG_FUNCTION_ARGS  )

Definition at line 2011 of file geo_ops.c.

2012{
2015
2017}

References fb(), PG_GETARG_POINT_P, PG_RETURN_FLOAT8, and point_dt().

Referenced by pt_in_widget().

◆ point_div()

Datum point_div ( PG_FUNCTION_ARGS  )

Definition at line 4252 of file geo_ops.c.

4253{
4256 Point *result;
4257
4259
4261
4263}

References fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_POINT_P, point_div_point(), and result.

◆ point_div_point()

static void point_div_point ( Point result,
Point pt1,
Point pt2 
)
inlinestatic

Definition at line 4238 of file geo_ops.c.

4239{
4240 float8 div;
4241
4242 div = float8_pl(float8_mul(pt2->x, pt2->x), float8_mul(pt2->y, pt2->y));
4243
4246 float8_mul(pt1->y, pt2->y)), div),
4248 float8_mul(pt1->x, pt2->y)), div));
4249}

References fb(), float8_div(), float8_mi(), float8_mul(), float8_pl(), point_construct(), and result.

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

◆ point_dt()

static float8 point_dt ( Point pt1,
Point pt2,
Node escontext 
)
inlinestatic

◆ point_eq()

Datum point_eq ( PG_FUNCTION_ARGS  )

Definition at line 1973 of file geo_ops.c.

1974{
1977
1979}

References fb(), PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_eq_point().

Referenced by spg_quad_leaf_consistent().

◆ point_eq_point()

static bool point_eq_point ( Point pt1,
Point pt2 
)
inlinestatic

Definition at line 1995 of file geo_ops.c.

1996{
1997 /* If any NaNs are involved, insist on exact equality */
1998 if (unlikely(isnan(pt1->x) || isnan(pt1->y) ||
1999 isnan(pt2->x) || isnan(pt2->y)))
2000 return (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y));
2001
2002 return (FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
2003}

References fb(), float8_eq(), FPeq(), and unlikely.

Referenced by box_same(), circle_same(), line_construct_pp(), line_in(), lseg_eq(), lseg_interpt_line(), lseg_ne(), plist_same(), point_eq(), point_ne(), and touched_lseg_inside_poly().

◆ point_horiz()

Datum point_horiz ( PG_FUNCTION_ARGS  )

Definition at line 1964 of file geo_ops.c.

1965{
1968
1969 PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));
1970}

References fb(), FPeq(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

Referenced by getQuadrant().

◆ point_in()

Datum point_in ( PG_FUNCTION_ARGS  )

Definition at line 1849 of file geo_ops.c.

1850{
1851 char *str = PG_GETARG_CSTRING(0);
1853
1854 /* Ignore failure from pair_decode, since our return value won't matter */
1855 pair_decode(str, &point->x, &point->y, NULL, "point", str, fcinfo->context);
1857}

References fb(), pair_decode(), palloc_object, PG_GETARG_CSTRING, PG_RETURN_POINT_P, and str.

◆ point_inside()

static int point_inside ( Point p,
int  npts,
Point plist 
)
static

Definition at line 5492 of file geo_ops.c.

5493{
5494 float8 x0,
5495 y0;
5496 float8 prev_x,
5497 prev_y;
5498 int i = 0;
5499 float8 x,
5500 y;
5501 int cross,
5502 total_cross = 0;
5503
5504 Assert(npts > 0);
5505
5506 /* compute first polygon point relative to single point */
5507 x0 = float8_mi(plist[0].x, p->x);
5508 y0 = float8_mi(plist[0].y, p->y);
5509
5510 prev_x = x0;
5511 prev_y = y0;
5512 /* loop over polygon points and aggregate total_cross */
5513 for (i = 1; i < npts; i++)
5514 {
5515 /* compute next polygon point relative to single point */
5516 x = float8_mi(plist[i].x, p->x);
5517 y = float8_mi(plist[i].y, p->y);
5518
5519 /* compute previous to current point crossing */
5521 return 2;
5522 total_cross += cross;
5523
5524 prev_x = x;
5525 prev_y = y;
5526 }
5527
5528 /* now do the first point */
5530 return 2;
5531 total_cross += cross;
5532
5533 if (total_cross != 0)
5534 return 1;
5535 return 0;
5536}
static int lseg_crossing(float8 x, float8 y, float8 prev_x, float8 prev_y)
Definition geo_ops.c:5549

References Assert, fb(), float8_mi(), i, lseg_crossing(), POINT_ON_POLYGON, x, Point::x, y, and Point::y.

Referenced by dist_ppoly_internal(), lseg_inside_poly(), on_ppath(), poly_contain_pt(), poly_overlap_internal(), and pt_contained_poly().

◆ point_invsl()

static float8 point_invsl ( Point pt1,
Point pt2 
)
inlinestatic

Definition at line 2068 of file geo_ops.c.

2069{
2070 if (FPeq(pt1->x, pt2->x))
2071 return 0.0;
2072 if (FPeq(pt1->y, pt2->y))
2073 return get_float8_infinity();
2074 return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y));
2075}

References fb(), float8_div(), float8_mi(), FPeq(), and get_float8_infinity().

Referenced by lseg_closept_point(), and lseg_invsl().

◆ point_left()

Datum point_left ( PG_FUNCTION_ARGS  )

Definition at line 1919 of file geo_ops.c.

1920{
1923
1924 PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));
1925}

References fb(), FPlt(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

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

◆ point_mul()

Datum point_mul ( PG_FUNCTION_ARGS  )

Definition at line 4223 of file geo_ops.c.

4224{
4227 Point *result;
4228
4230
4232
4234}

References fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_POINT_P, point_mul_point(), and result.

◆ point_mul_point()

static void point_mul_point ( Point result,
Point pt1,
Point pt2 
)
inlinestatic

Definition at line 4213 of file geo_ops.c.

4214{
4216 float8_mi(float8_mul(pt1->x, pt2->x),
4217 float8_mul(pt1->y, pt2->y)),
4218 float8_pl(float8_mul(pt1->x, pt2->y),
4219 float8_mul(pt1->y, pt2->x)));
4220}

References fb(), float8_mi(), float8_mul(), float8_pl(), point_construct(), and result.

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

◆ point_ne()

Datum point_ne ( PG_FUNCTION_ARGS  )

Definition at line 1982 of file geo_ops.c.

1983{
1986
1988}

References fb(), PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_eq_point().

◆ point_out()

Datum point_out ( PG_FUNCTION_ARGS  )

Definition at line 1860 of file geo_ops.c.

1861{
1863
1865}

References fb(), path_encode(), PATH_NONE, PG_GETARG_POINT_P, and PG_RETURN_CSTRING.

◆ point_recv()

Datum point_recv ( PG_FUNCTION_ARGS  )

Definition at line 1871 of file geo_ops.c.

1872{
1874 Point *point;
1875
1880}

References buf, fb(), palloc_object, PG_GETARG_POINTER, PG_RETURN_POINT_P, and pq_getmsgfloat8().

◆ point_right()

Datum point_right ( PG_FUNCTION_ARGS  )

Definition at line 1928 of file geo_ops.c.

1929{
1932
1933 PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));
1934}

References fb(), FPgt(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

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

◆ point_send()

Datum point_send ( PG_FUNCTION_ARGS  )

◆ point_sl()

static float8 point_sl ( Point pt1,
Point pt2 
)
inlinestatic

Definition at line 2052 of file geo_ops.c.

2053{
2054 if (FPeq(pt1->x, pt2->x))
2055 return get_float8_infinity();
2056 if (FPeq(pt1->y, pt2->y))
2057 return 0.0;
2058 return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x));
2059}

References fb(), float8_div(), float8_mi(), FPeq(), and get_float8_infinity().

Referenced by line_construct_pp(), lseg_sl(), and point_slope().

◆ point_slope()

Datum point_slope ( PG_FUNCTION_ARGS  )

Definition at line 2037 of file geo_ops.c.

2038{
2041
2043}

References fb(), PG_GETARG_POINT_P, PG_RETURN_FLOAT8, and point_sl().

◆ point_sub()

Datum point_sub ( PG_FUNCTION_ARGS  )

Definition at line 4198 of file geo_ops.c.

4199{
4202 Point *result;
4203
4205
4207
4209}

References fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_POINT_P, point_sub_point(), and result.

◆ point_sub_point()

static void point_sub_point ( Point result,
Point pt1,
Point pt2 
)
inlinestatic

Definition at line 4190 of file geo_ops.c.

4191{
4193 float8_mi(pt1->x, pt2->x),
4194 float8_mi(pt1->y, pt2->y));
4195}

References fb(), float8_mi(), point_construct(), and result.

Referenced by box_sub(), circle_sub_pt(), path_sub_pt(), and point_sub().

◆ point_vert()

Datum point_vert ( PG_FUNCTION_ARGS  )

Definition at line 1955 of file geo_ops.c.

1956{
1959
1960 PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));
1961}

References fb(), FPeq(), PG_GETARG_POINT_P, and PG_RETURN_BOOL.

Referenced by getQuadrant().

◆ points_box()

Datum points_box ( PG_FUNCTION_ARGS  )

Definition at line 4273 of file geo_ops.c.

4274{
4277 BOX *result;
4278
4280
4282
4284}

References box_construct(), fb(), palloc_object, PG_GETARG_POINT_P, PG_RETURN_BOX_P, and result.

◆ poly_above()

Datum poly_above ( PG_FUNCTION_ARGS  )

Definition at line 3718 of file geo_ops.c.

3719{
3722 bool result;
3723
3724 result = polya->boundbox.low.y > polyb->boundbox.high.y;
3725
3726 /*
3727 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3728 */
3731
3733}
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_below()

Datum poly_below ( PG_FUNCTION_ARGS  )

Definition at line 3672 of file geo_ops.c.

3673{
3676 bool result;
3677
3678 result = polya->boundbox.high.y < polyb->boundbox.low.y;
3679
3680 /*
3681 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3682 */
3685
3687}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_box()

Datum poly_box ( PG_FUNCTION_ARGS  )

Definition at line 4578 of file geo_ops.c.

4579{
4581 BOX *box;
4582
4584 *box = poly->boundbox;
4585
4587}

References fb(), palloc_object, PG_GETARG_POLYGON_P, and PG_RETURN_BOX_P.

◆ poly_center()

Datum poly_center ( PG_FUNCTION_ARGS  )

Definition at line 4559 of file geo_ops.c.

4560{
4562 Point *result;
4563 CIRCLE circle;
4564
4566
4567 poly_to_circle(&circle, poly, fcinfo->context);
4568 if (SOFT_ERROR_OCCURRED(fcinfo->context))
4570
4571 *result = circle.center;
4572
4574}
static void poly_to_circle(CIRCLE *result, POLYGON *poly, Node *escontext)
Definition geo_ops.c:5414

References fb(), palloc_object, PG_GETARG_POLYGON_P, PG_RETURN_NULL, PG_RETURN_POINT_P, poly_to_circle(), result, and SOFT_ERROR_OCCURRED.

◆ poly_circle()

Datum poly_circle ( PG_FUNCTION_ARGS  )

Definition at line 5457 of file geo_ops.c.

5458{
5460 CIRCLE *result;
5461
5463
5464 poly_to_circle(result, poly, fcinfo->context);
5465 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5467
5469}

References fb(), palloc_object, PG_GETARG_POLYGON_P, PG_RETURN_CIRCLE_P, PG_RETURN_NULL, poly_to_circle(), result, and SOFT_ERROR_OCCURRED.

◆ poly_contain()

Datum poly_contain ( PG_FUNCTION_ARGS  )

Definition at line 4013 of file geo_ops.c.

4014{
4017 bool result;
4018
4020
4021 /*
4022 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
4023 */
4026
4028}
static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly)
Definition geo_ops.c:3985

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, poly_contain_poly(), and result.

◆ poly_contain_poly()

static bool poly_contain_poly ( POLYGON contains_poly,
POLYGON contained_poly 
)
static

Definition at line 3985 of file geo_ops.c.

3986{
3987 int i;
3988 LSEG s;
3989
3990 Assert(contains_poly->npts > 0 && contained_poly->npts > 0);
3991
3992 /*
3993 * Quick check to see if contained's bounding box is contained in
3994 * contains' bb.
3995 */
3996 if (!box_contain_box(&contains_poly->boundbox, &contained_poly->boundbox))
3997 return false;
3998
3999 s.p[0] = contained_poly->p[contained_poly->npts - 1];
4000
4001 for (i = 0; i < contained_poly->npts; i++)
4002 {
4003 s.p[1] = contained_poly->p[i];
4004 if (!lseg_inside_poly(s.p, s.p + 1, contains_poly, 0))
4005 return false;
4006 s.p[0] = s.p[1];
4007 }
4008
4009 return true;
4010}

References Assert, box_contain_box(), fb(), i, lseg_inside_poly(), and LSEG::p.

Referenced by poly_contain(), and poly_contained().

◆ poly_contain_pt()

Datum poly_contain_pt ( PG_FUNCTION_ARGS  )

Definition at line 4055 of file geo_ops.c.

4056{
4058 Point *p = PG_GETARG_POINT_P(1);
4059
4060 PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4061}

References fb(), PG_GETARG_POINT_P, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and point_inside().

Referenced by gist_point_consistent().

◆ poly_contained()

Datum poly_contained ( PG_FUNCTION_ARGS  )

Definition at line 4035 of file geo_ops.c.

4036{
4039 bool result;
4040
4041 /* Just switch the arguments and pass it off to poly_contain */
4043
4044 /*
4045 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
4046 */
4049
4051}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, poly_contain_poly(), and result.

◆ poly_distance()

Datum poly_distance ( PG_FUNCTION_ARGS  )

Definition at line 4074 of file geo_ops.c.

4075{
4078 float8 min = 0.0; /* initialize to keep compiler quiet */
4079 bool have_min = false;
4080 float8 tmp;
4081 int i,
4082 j;
4083 LSEG seg1,
4084 seg2;
4085
4086 /*
4087 * Distance is zero if polygons overlap. We must check this because the
4088 * path distance will not give the right answer if one poly is entirely
4089 * within the other.
4090 */
4092 PG_RETURN_FLOAT8(0.0);
4093
4094 /*
4095 * When they don't overlap, the distance calculation is identical to that
4096 * for closed paths (i.e., we needn't care about the fact that polygons
4097 * include their contained areas). See path_distance().
4098 */
4099 for (i = 0; i < polya->npts; i++)
4100 {
4101 int iprev;
4102
4103 if (i > 0)
4104 iprev = i - 1;
4105 else
4106 iprev = polya->npts - 1;
4107
4108 for (j = 0; j < polyb->npts; j++)
4109 {
4110 int jprev;
4111
4112 if (j > 0)
4113 jprev = j - 1;
4114 else
4115 jprev = polyb->npts - 1;
4116
4117 statlseg_construct(&seg1, &polya->p[iprev], &polya->p[i]);
4118 statlseg_construct(&seg2, &polyb->p[jprev], &polyb->p[j]);
4119
4120 tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
4121 if (!have_min || float8_lt(tmp, min))
4122 {
4123 min = tmp;
4124 have_min = true;
4125 }
4126 }
4127 }
4128
4129 if (!have_min)
4131
4132 PG_RETURN_FLOAT8(min);
4133}
static bool poly_overlap_internal(POLYGON *polya, POLYGON *polyb)
Definition geo_ops.c:3791

References fb(), float8_lt(), i, j, lseg_closept_lseg(), PG_GETARG_POLYGON_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, poly_overlap_internal(), and statlseg_construct().

◆ poly_in()

Datum poly_in ( PG_FUNCTION_ARGS  )

Definition at line 3462 of file geo_ops.c.

3463{
3464 char *str = PG_GETARG_CSTRING(0);
3465 Node *escontext = fcinfo->context;
3466 POLYGON *poly;
3467 int npts;
3468 int size;
3469 int base_size;
3470 bool isopen;
3471
3472 if ((npts = pair_count(str, ',')) <= 0)
3473 ereturn(escontext, (Datum) 0,
3475 errmsg("invalid input syntax for type %s: \"%s\"",
3476 "polygon", str)));
3477
3478 base_size = sizeof(poly->p[0]) * npts;
3479 size = offsetof(POLYGON, p) + base_size;
3480
3481 /* Check for integer overflow */
3482 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
3483 ereturn(escontext, (Datum) 0,
3485 errmsg("too many points requested")));
3486
3487 poly = (POLYGON *) palloc0(size); /* zero any holes */
3488
3489 SET_VARSIZE(poly, size);
3490 poly->npts = npts;
3491
3492 if (!path_decode(str, false, npts, &(poly->p[0]), &isopen, NULL, "polygon",
3493 str, escontext))
3495
3497
3499}

References ereturn, errcode(), errmsg, fb(), make_bound_box(), pair_count(), palloc0(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_POLYGON_P, SET_VARSIZE(), and str.

◆ poly_left()

Datum poly_left ( PG_FUNCTION_ARGS  )

Definition at line 3580 of file geo_ops.c.

3581{
3584 bool result;
3585
3586 result = polya->boundbox.high.x < polyb->boundbox.low.x;
3587
3588 /*
3589 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3590 */
3593
3595}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_npoints()

Datum poly_npoints ( PG_FUNCTION_ARGS  )

Definition at line 4550 of file geo_ops.c.

4551{
4553
4554 PG_RETURN_INT32(poly->npts);
4555}

References fb(), PG_GETARG_POLYGON_P, and PG_RETURN_INT32.

◆ poly_out()

Datum poly_out ( PG_FUNCTION_ARGS  )

Definition at line 3506 of file geo_ops.c.

3507{
3509
3511}

References fb(), PATH_CLOSED, path_encode(), PG_GETARG_POLYGON_P, and PG_RETURN_CSTRING.

◆ poly_overabove()

Datum poly_overabove ( PG_FUNCTION_ARGS  )

Definition at line 3741 of file geo_ops.c.

3742{
3745 bool result;
3746
3747 result = polya->boundbox.low.y >= polyb->boundbox.low.y;
3748
3749 /*
3750 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3751 */
3754
3756}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_overbelow()

Datum poly_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 3695 of file geo_ops.c.

3696{
3699 bool result;
3700
3701 result = polya->boundbox.high.y <= polyb->boundbox.high.y;
3702
3703 /*
3704 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3705 */
3708
3710}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_overlap()

Datum poly_overlap ( PG_FUNCTION_ARGS  )

Definition at line 3848 of file geo_ops.c.

3849{
3852 bool result;
3853
3855
3856 /*
3857 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3858 */
3861
3863}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, poly_overlap_internal(), and result.

◆ poly_overlap_internal()

static bool poly_overlap_internal ( POLYGON polya,
POLYGON polyb 
)
static

Definition at line 3791 of file geo_ops.c.

3792{
3793 bool result;
3794
3795 Assert(polya->npts > 0 && polyb->npts > 0);
3796
3797 /* Quick check by bounding box */
3798 result = box_ov(&polya->boundbox, &polyb->boundbox);
3799
3800 /*
3801 * Brute-force algorithm - try to find intersected edges, if so then
3802 * polygons are overlapped else check is one polygon inside other or not
3803 * by testing single point of them.
3804 */
3805 if (result)
3806 {
3807 int ia,
3808 ib;
3809 LSEG sa,
3810 sb;
3811
3812 /* Init first of polya's edge with last point */
3813 sa.p[0] = polya->p[polya->npts - 1];
3814 result = false;
3815
3816 for (ia = 0; ia < polya->npts && !result; ia++)
3817 {
3818 /* Second point of polya's edge is a current one */
3819 sa.p[1] = polya->p[ia];
3820
3821 /* Init first of polyb's edge with last point */
3822 sb.p[0] = polyb->p[polyb->npts - 1];
3823
3824 for (ib = 0; ib < polyb->npts && !result; ib++)
3825 {
3826 sb.p[1] = polyb->p[ib];
3828 sb.p[0] = sb.p[1];
3829 }
3830
3831 /*
3832 * move current endpoint to the first point of next edge
3833 */
3834 sa.p[0] = sa.p[1];
3835 }
3836
3837 if (!result)
3838 {
3839 result = (point_inside(polya->p, polyb->npts, polyb->p) ||
3840 point_inside(polyb->p, polya->npts, polya->p));
3841 }
3842 }
3843
3844 return result;
3845}

References Assert, box_ov(), fb(), lseg_interpt_lseg(), point_inside(), and result.

Referenced by poly_distance(), and poly_overlap().

◆ poly_overleft()

Datum poly_overleft ( PG_FUNCTION_ARGS  )

Definition at line 3603 of file geo_ops.c.

3604{
3607 bool result;
3608
3609 result = polya->boundbox.high.x <= polyb->boundbox.high.x;
3610
3611 /*
3612 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3613 */
3616
3618}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_overright()

Datum poly_overright ( PG_FUNCTION_ARGS  )

Definition at line 3649 of file geo_ops.c.

3650{
3653 bool result;
3654
3655 result = polya->boundbox.low.x >= polyb->boundbox.low.x;
3656
3657 /*
3658 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3659 */
3662
3664}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_path()

Datum poly_path ( PG_FUNCTION_ARGS  )

Definition at line 4623 of file geo_ops.c.

4624{
4626 PATH *path;
4627 int size;
4628 int i;
4629
4630 /*
4631 * Never overflows: the old size fit in MaxAllocSize, and the new size is
4632 * smaller by a small constant.
4633 */
4634 size = offsetof(PATH, p) + sizeof(path->p[0]) * poly->npts;
4635 path = (PATH *) palloc(size);
4636
4637 SET_VARSIZE(path, size);
4638 path->npts = poly->npts;
4639 path->closed = true;
4640 /* prevent instability in unused pad bytes */
4641 path->dummy = 0;
4642
4643 for (i = 0; i < poly->npts; i++)
4644 {
4645 path->p[i].x = poly->p[i].x;
4646 path->p[i].y = poly->p[i].y;
4647 }
4648
4649 PG_RETURN_PATH_P(path);
4650}

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

◆ poly_recv()

Datum poly_recv ( PG_FUNCTION_ARGS  )

Definition at line 3522 of file geo_ops.c.

3523{
3525 POLYGON *poly;
3526 int32 npts;
3527 int32 i;
3528 int size;
3529
3530 npts = pq_getmsgint(buf, sizeof(int32));
3531 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p)) / sizeof(Point)))
3532 ereport(ERROR,
3534 errmsg("invalid number of points in external \"polygon\" value")));
3535
3536 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * npts;
3537 poly = (POLYGON *) palloc0(size); /* zero any holes */
3538
3539 SET_VARSIZE(poly, size);
3540 poly->npts = npts;
3541
3542 for (i = 0; i < npts; i++)
3543 {
3544 poly->p[i].x = pq_getmsgfloat8(buf);
3545 poly->p[i].y = pq_getmsgfloat8(buf);
3546 }
3547
3549
3551}

References buf, ereport, errcode(), errmsg, ERROR, fb(), i, make_bound_box(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POLYGON_P, pq_getmsgfloat8(), pq_getmsgint(), and SET_VARSIZE().

◆ poly_right()

Datum poly_right ( PG_FUNCTION_ARGS  )

Definition at line 3626 of file geo_ops.c.

3627{
3630 bool result;
3631
3632 result = polya->boundbox.low.x > polyb->boundbox.high.x;
3633
3634 /*
3635 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3636 */
3639
3641}

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and result.

◆ poly_same()

Datum poly_same ( PG_FUNCTION_ARGS  )

Definition at line 3767 of file geo_ops.c.

3768{
3771 bool result;
3772
3773 if (polya->npts != polyb->npts)
3774 result = false;
3775 else
3776 result = plist_same(polya->npts, polya->p, polyb->p);
3777
3778 /*
3779 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3780 */
3783
3785}
static bool plist_same(int npts, Point *p1, Point *p2)
Definition geo_ops.c:5609

References fb(), PG_FREE_IF_COPY, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, plist_same(), and result.

◆ poly_send()

Datum poly_send ( PG_FUNCTION_ARGS  )

Definition at line 3557 of file geo_ops.c.

3558{
3561 int32 i;
3562
3564 pq_sendint32(&buf, poly->npts);
3565 for (i = 0; i < poly->npts; i++)
3566 {
3567 pq_sendfloat8(&buf, poly->p[i].x);
3568 pq_sendfloat8(&buf, poly->p[i].y);
3569 }
3571}

References buf, fb(), i, PG_GETARG_POLYGON_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), and pq_sendint32().

◆ poly_to_circle()

static void poly_to_circle ( CIRCLE result,
POLYGON poly,
Node escontext 
)
static

Definition at line 5414 of file geo_ops.c.

5415{
5416 int i;
5417 float8 x;
5418
5419 Assert(poly->npts > 0);
5420
5421 result->center.x = 0;
5422 result->center.y = 0;
5423 result->radius = 0;
5424
5425 for (i = 0; i < poly->npts; i++)
5426 {
5427 point_add_point(&result->center, &result->center, &poly->p[i], escontext);
5428 if (SOFT_ERROR_OCCURRED(escontext))
5429 return;
5430 }
5431
5432 result->center.x = float8_div_safe(result->center.x, poly->npts, escontext);
5433 if (SOFT_ERROR_OCCURRED(escontext))
5434 return;
5435
5436 result->center.y = float8_div_safe(result->center.y, poly->npts, escontext);
5437 if (SOFT_ERROR_OCCURRED(escontext))
5438 return;
5439
5440 for (i = 0; i < poly->npts; i++)
5441 {
5442 x = point_dt(&poly->p[i], &result->center, escontext);
5443 if (SOFT_ERROR_OCCURRED(escontext))
5444 return;
5445
5446 result->radius = float8_pl_safe(result->radius, x, escontext);
5447 if (SOFT_ERROR_OCCURRED(escontext))
5448 return;
5449 }
5450
5451 result->radius = float8_div_safe(result->radius, poly->npts, escontext);
5452 if (SOFT_ERROR_OCCURRED(escontext))
5453 return;
5454}

References Assert, fb(), float8_div_safe(), float8_pl_safe(), i, point_add_point(), point_dt(), result, SOFT_ERROR_OCCURRED, and x.

Referenced by poly_center(), and poly_circle().

◆ pt_contained_circle()

Datum pt_contained_circle ( PG_FUNCTION_ARGS  )

Definition at line 5153 of file geo_ops.c.

5154{
5157 float8 d;
5158
5159 d = point_dt(&circle->center, point, NULL);
5161}

References fb(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_dt().

◆ pt_contained_poly()

Datum pt_contained_poly ( PG_FUNCTION_ARGS  )

Definition at line 4064 of file geo_ops.c.

4065{
4066 Point *p = PG_GETARG_POINT_P(0);
4068
4069 PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4070}

References fb(), PG_GETARG_POINT_P, PG_GETARG_POLYGON_P, PG_RETURN_BOOL, and point_inside().

◆ single_decode()

static bool single_decode ( char num,
float8 x,
char **  endptr_p,
const char type_name,
const char orig_string,
Node escontext 
)
static

Definition at line 195 of file geo_ops.c.

198{
199 *x = float8in_internal(num, endptr_p, type_name, orig_string, escontext);
200 return (!SOFT_ERROR_OCCURRED(escontext));
201} /* single_decode() */
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:436

References fb(), float8in_internal(), SOFT_ERROR_OCCURRED, and x.

Referenced by circle_in(), line_decode(), and pair_decode().

◆ single_encode()

static void single_encode ( float8  x,
StringInfo  str 
)
static

Definition at line 204 of file geo_ops.c.

205{
206 char *xstr = float8out_internal(x);
207
209 pfree(xstr);
210} /* single_encode() */
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230

References appendStringInfoString(), fb(), float8out_internal(), pfree(), str, and x.

Referenced by circle_out().

◆ statlseg_construct()

static void statlseg_construct ( LSEG lseg,
Point pt1,
Point pt2 
)
inlinestatic

Definition at line 2171 of file geo_ops.c.

2172{
2173 lseg->p[0].x = pt1->x;
2174 lseg->p[0].y = pt1->y;
2175 lseg->p[1].x = pt2->x;
2176 lseg->p[1].y = pt2->y;
2177}

References fb().

Referenced by box_closept_lseg(), box_closept_point(), box_diagonal(), box_interpt_lseg(), dist_ppath_internal(), inter_lb(), lseg_construct(), path_distance(), path_inter(), and poly_distance().

◆ touched_lseg_inside_poly()

static bool touched_lseg_inside_poly ( Point a,
Point b,
LSEG s,
POLYGON poly,
int  start 
)
static

Definition at line 3877 of file geo_ops.c.

3878{
3879 /* point a is on s, b is not */
3880 LSEG t;
3881
3882 t.p[0] = *a;
3883 t.p[1] = *b;
3884
3885 if (point_eq_point(a, s->p))
3886 {
3887 if (lseg_contain_point(&t, s->p + 1))
3888 return lseg_inside_poly(b, s->p + 1, poly, start);
3889 }
3890 else if (point_eq_point(a, s->p + 1))
3891 {
3892 if (lseg_contain_point(&t, s->p))
3893 return lseg_inside_poly(b, s->p, poly, start);
3894 }
3895 else if (lseg_contain_point(&t, s->p))
3896 {
3897 return lseg_inside_poly(b, s->p, poly, start);
3898 }
3899 else if (lseg_contain_point(&t, s->p + 1))
3900 {
3901 return lseg_inside_poly(b, s->p + 1, poly, start);
3902 }
3903
3904 return true; /* may be not true, but that will check later */
3905}

References a, b, fb(), lseg_contain_point(), lseg_inside_poly(), LSEG::p, point_eq_point(), and start.

Referenced by lseg_inside_poly().