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 5555 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 671 of file geo_ops.c.

672{
675
676 PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));
677}
#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 748 of file geo_ops.c.

749{
752
753 PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
754}
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 4324 of file geo_ops.c.

4325{
4326 BOX *box = PG_GETARG_BOX_P(0);
4327 Point *p = PG_GETARG_POINT_P(1);
4328 BOX *result;
4329
4331
4332 point_add_point(&result->high, &box->high, p, NULL);
4333 point_add_point(&result->low, &box->low, p, NULL);
4334
4336}
uint32 result
#define palloc_object(type)
Definition fe_memutils.h:89
#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:4195

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 889 of file geo_ops.c.

890{
891 return float8_mul(box_wd(box), box_ht(box));
892}
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:192
static float8 box_ht(BOX *box)
Definition geo_ops.c:937
static float8 box_wd(BOX *box)
Definition geo_ops.c:926

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 815 of file geo_ops.c.

816{
817 BOX *box = PG_GETARG_BOX_P(0);
818
820}
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
static float8 box_ar(BOX *box)
Definition geo_ops.c:889

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

◆ box_below()

Datum box_below ( PG_FUNCTION_ARGS  )

Definition at line 646 of file geo_ops.c.

647{
650
651 PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));
652}
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 739 of file geo_ops.c.

740{
743
744 PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
745}
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 872 of file geo_ops.c.

873{
874 BOX *box = PG_GETARG_BOX_P(0);
876
877 box_cn(result, box, fcinfo->context);
878 if (SOFT_ERROR_OCCURRED(fcinfo->context))
880
882}
#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:899
#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 5349 of file geo_ops.c.

5350{
5351 BOX *box = PG_GETARG_BOX_P(0);
5352 CIRCLE *circle;
5353 float8 x;
5354 float8 y;
5355
5357
5358 x = float8_pl_safe(box->high.x, box->low.x, fcinfo->context);
5359 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5360 goto fail;
5361
5362 circle->center.x = float8_div_safe(x, 2.0, fcinfo->context);
5363 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5364 goto fail;
5365
5366 y = float8_pl_safe(box->high.y, box->low.y, fcinfo->context);
5367 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5368 goto fail;
5369
5370 circle->center.y = float8_div_safe(y, 2.0, fcinfo->context);
5371 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5372 goto fail;
5373
5374 circle->radius = point_dt(&circle->center, &box->high,
5375 fcinfo->context);
5376
5377 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5378 goto fail;
5379
5381
5382fail:
5384}
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:2053
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 3095 of file geo_ops.c.

3096{
3097 float8 dist,
3098 d;
3099 Point point,
3100 closept;
3101 LSEG bseg;
3102
3104 return 0.0;
3105
3106 /* pairwise check lseg distances */
3107 point.x = box->low.x;
3108 point.y = box->high.y;
3109 statlseg_construct(&bseg, &box->low, &point);
3111
3112 statlseg_construct(&bseg, &box->high, &point);
3114 if (float8_lt(d, dist))
3115 {
3116 dist = d;
3117 if (result != NULL)
3118 *result = closept;
3119 }
3120
3121 point.x = box->high.x;
3122 point.y = box->low.y;
3123 statlseg_construct(&bseg, &box->low, &point);
3125 if (float8_lt(d, dist))
3126 {
3127 dist = d;
3128 if (result != NULL)
3129 *result = closept;
3130 }
3131
3132 statlseg_construct(&bseg, &box->high, &point);
3134 if (float8_lt(d, dist))
3135 {
3136 dist = d;
3137 if (result != NULL)
3138 *result = closept;
3139 }
3140
3141 return dist;
3142}
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:3346
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2)
Definition geo_ops.c:2205
static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
Definition geo_ops.c:2892

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 2960 of file geo_ops.c.

2961{
2962 float8 dist,
2963 d;
2964 Point point,
2965 closept;
2966 LSEG lseg;
2967
2968 if (box_contain_point(box, pt))
2969 {
2970 if (result != NULL)
2971 *result = *pt;
2972
2973 return 0.0;
2974 }
2975
2976 /* pairwise check lseg distances */
2977 point.x = box->low.x;
2978 point.y = box->high.y;
2979 statlseg_construct(&lseg, &box->low, &point);
2981
2982 statlseg_construct(&lseg, &box->high, &point);
2984 if (float8_lt(d, dist))
2985 {
2986 dist = d;
2987 if (result != NULL)
2988 *result = closept;
2989 }
2990
2991 point.x = box->high.x;
2992 point.y = box->low.y;
2993 statlseg_construct(&lseg, &box->low, &point);
2995 if (float8_lt(d, dist))
2996 {
2997 dist = d;
2998 if (result != NULL)
2999 *result = closept;
3000 }
3001
3002 statlseg_construct(&lseg, &box->high, &point);
3004 if (float8_lt(d, dist))
3005 {
3006 dist = d;
3007 if (result != NULL)
3008 *result = closept;
3009 }
3010
3011 return dist;
3012}
static float8 lseg_closept_point(Point *result, LSEG *lseg, Point *pt)
Definition geo_ops.c:2854
static bool box_contain_point(BOX *box, Point *point)
Definition geo_ops.c:3212

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 899 of file geo_ops.c.

900{
901 float8 x;
902 float8 y;
903
904 x = float8_pl_safe(box->high.x, box->low.x, escontext);
905 if (SOFT_ERROR_OCCURRED(escontext))
906 return;
907
908 center->x = float8_div_safe(x, 2.0, escontext);
909 if (SOFT_ERROR_OCCURRED(escontext))
910 return;
911
912 y = float8_pl_safe(box->high.y, box->low.y, escontext);
913 if (SOFT_ERROR_OCCURRED(escontext))
914 return;
915
916 center->y = float8_div_safe(y, 2.0, escontext);
917 if (SOFT_ERROR_OCCURRED(escontext))
918 return;
919}
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 522 of file geo_ops.c.

523{
524 if (float8_gt(pt1->x, pt2->x))
525 {
526 result->high.x = pt1->x;
527 result->low.x = pt2->x;
528 }
529 else
530 {
531 result->high.x = pt2->x;
532 result->low.x = pt1->x;
533 }
534 if (float8_gt(pt1->y, pt2->y))
535 {
536 result->high.y = pt1->y;
537 result->low.y = pt2->y;
538 }
539 else
540 {
541 result->high.y = pt2->y;
542 result->low.y = pt1->y;
543 }
544}
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 708 of file geo_ops.c.

709{
712
714}
static bool box_contain_box(BOX *contains_box, BOX *contained_box)
Definition geo_ops.c:720

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 720 of file geo_ops.c.

721{
722 return FPge(contains_box->high.x, contained_box->high.x) &&
723 FPle(contains_box->low.x, contained_box->low.x) &&
724 FPge(contains_box->high.y, contained_box->high.y) &&
725 FPle(contains_box->low.y, contained_box->low.y);
726}

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 3300 of file geo_ops.c.

3301{
3302 return box_contain_point(box, &lseg->p[0]) &&
3303 box_contain_point(box, &lseg->p[1]);
3304}

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 3212 of file geo_ops.c.

3213{
3214 return box->high.x >= point->x && box->low.x <= point->x &&
3215 box->high.y >= point->y && box->low.y <= point->y;
3216}

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 979 of file geo_ops.c.

980{
981 BOX *box = PG_GETARG_BOX_P(0);
983
984 statlseg_construct(result, &box->high, &box->low);
985
987}
#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 854 of file geo_ops.c.

855{
858 Point a,
859 b;
860
861 box_cn(&a, box1, NULL);
862 box_cn(&b, box2, NULL);
863
865}
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 4373 of file geo_ops.c.

4374{
4375 BOX *box = PG_GETARG_BOX_P(0);
4376 Point *p = PG_GETARG_POINT_P(1);
4377 BOX *result;
4378 Point high,
4379 low;
4380
4382
4383 point_div_point(&high, &box->high, p);
4384 point_div_point(&low, &box->low, p);
4385
4386 box_construct(result, &high, &low);
4387
4389}
static void point_div_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4275
static void box_construct(BOX *result, Point *pt1, Point *pt2)
Definition geo_ops.c:522

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 780 of file geo_ops.c.

781{
784
786}
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 798 of file geo_ops.c.

799{
802
804}

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

◆ box_gt()

Datum box_gt ( PG_FUNCTION_ARGS  )

Definition at line 771 of file geo_ops.c.

772{
775
777}

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

◆ box_height()

Datum box_height ( PG_FUNCTION_ARGS  )

Definition at line 841 of file geo_ops.c.

842{
843 BOX *box = PG_GETARG_BOX_P(0);
844
846}

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

◆ box_ht()

static float8 box_ht ( BOX box)
static

Definition at line 937 of file geo_ops.c.

938{
939 return float8_mi(box->high.y, box->low.y);
940}
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 424 of file geo_ops.c.

425{
426 char *str = PG_GETARG_CSTRING(0);
427 Node *escontext = fcinfo->context;
429 bool isopen;
430 float8 x,
431 y;
432
433 if (!path_decode(str, false, 2, &(box->high), &isopen, NULL, "box", str,
434 escontext))
436
437 /* reorder corners if necessary... */
438 if (float8_lt(box->high.x, box->low.x))
439 {
440 x = box->high.x;
441 box->high.x = box->low.x;
442 box->low.x = x;
443 }
444 if (float8_lt(box->high.y, box->low.y))
445 {
446 y = box->high.y;
447 box->high.y = box->low.y;
448 box->low.y = y;
449 }
450
452}
#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 3346 of file geo_ops.c.

3347{
3348 BOX lbox;
3349 LSEG bseg;
3350 Point point;
3351
3352 lbox.low.x = float8_min(lseg->p[0].x, lseg->p[1].x);
3353 lbox.low.y = float8_min(lseg->p[0].y, lseg->p[1].y);
3354 lbox.high.x = float8_max(lseg->p[0].x, lseg->p[1].x);
3355 lbox.high.y = float8_max(lseg->p[0].y, lseg->p[1].y);
3356
3357 /* nothing close to overlap? then not going to intersect */
3358 if (!box_ov(&lbox, box))
3359 return false;
3360
3361 if (result != NULL)
3362 {
3363 box_cn(&point, box, NULL);
3365 }
3366
3367 /* an endpoint of segment is inside box? then clearly intersects */
3368 if (box_contain_point(box, &lseg->p[0]) ||
3369 box_contain_point(box, &lseg->p[1]))
3370 return true;
3371
3372 /* pairwise check lseg intersections */
3373 point.x = box->low.x;
3374 point.y = box->high.y;
3375 statlseg_construct(&bseg, &box->low, &point);
3377 return true;
3378
3379 statlseg_construct(&bseg, &box->high, &point);
3381 return true;
3382
3383 point.x = box->high.x;
3384 point.y = box->low.y;
3385 statlseg_construct(&bseg, &box->low, &point);
3387 return true;
3388
3389 statlseg_construct(&bseg, &box->high, &point);
3391 return true;
3392
3393 /* if we dropped through, no two segs intersected */
3394 return false;
3395}
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:578
static bool lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2)
Definition geo_ops.c:2420

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 953 of file geo_ops.c.

954{
957 BOX *result;
958
959 if (!box_ov(box1, box2))
961
963
964 result->high.x = float8_min(box1->high.x, box2->high.x);
965 result->low.x = float8_max(box1->low.x, box2->low.x);
966 result->high.y = float8_min(box1->high.y, box2->high.y);
967 result->low.y = float8_max(box1->low.y, box2->low.y);
968
970}

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 789 of file geo_ops.c.

790{
793
795}

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

◆ box_left()

Datum box_left ( PG_FUNCTION_ARGS  )

Definition at line 590 of file geo_ops.c.

591{
594
595 PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x));
596}

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 762 of file geo_ops.c.

763{
766
768}

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

◆ box_mul()

Datum box_mul ( PG_FUNCTION_ARGS  )

Definition at line 4354 of file geo_ops.c.

4355{
4356 BOX *box = PG_GETARG_BOX_P(0);
4357 Point *p = PG_GETARG_POINT_P(1);
4358 BOX *result;
4359 Point high,
4360 low;
4361
4363
4364 point_mul_point(&high, &box->high, p);
4365 point_mul_point(&low, &box->low, p);
4366
4367 box_construct(result, &high, &low);
4368
4370}
static void point_mul_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4250

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 458 of file geo_ops.c.

459{
460 BOX *box = PG_GETARG_BOX_P(0);
461
463}
#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 578 of file geo_ops.c.

579{
580 return (FPle(box1->low.x, box2->high.x) &&
581 FPle(box2->low.x, box1->high.x) &&
582 FPle(box1->low.y, box2->high.y) &&
583 FPle(box2->low.y, box1->high.y));
584}

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 684 of file geo_ops.c.

685{
688
689 PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));
690}

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 659 of file geo_ops.c.

660{
663
664 PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));
665}

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 606 of file geo_ops.c.

607{
610
611 PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x));
612}

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 634 of file geo_ops.c.

635{
638
639 PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));
640}

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 4635 of file geo_ops.c.

4636{
4637 BOX *box = PG_GETARG_BOX_P(0);
4638 POLYGON *poly;
4639 int size;
4640
4641 /* map four corners of the box to a polygon */
4642 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * 4;
4643 poly = (POLYGON *) palloc(size);
4644
4645 SET_VARSIZE(poly, size);
4646 poly->npts = 4;
4647
4648 poly->p[0].x = box->low.x;
4649 poly->p[0].y = box->low.y;
4650 poly->p[1].x = box->low.x;
4651 poly->p[1].y = box->high.y;
4652 poly->p[2].x = box->high.x;
4653 poly->p[2].y = box->high.y;
4654 poly->p[3].x = box->high.x;
4655 poly->p[3].y = box->low.y;
4656
4657 box_construct(&poly->boundbox, &box->high, &box->low);
4658
4660}
#define PG_RETURN_POLYGON_P(x)
Definition geo_decls.h:262
void * palloc(Size size)
Definition mcxt.c:1390
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 469 of file geo_ops.c.

470{
472 BOX *box;
473 float8 x,
474 y;
475
477
478 box->high.x = pq_getmsgfloat8(buf);
479 box->high.y = pq_getmsgfloat8(buf);
480 box->low.x = pq_getmsgfloat8(buf);
481 box->low.y = pq_getmsgfloat8(buf);
482
483 /* reorder corners if necessary... */
484 if (float8_lt(box->high.x, box->low.x))
485 {
486 x = box->high.x;
487 box->high.x = box->low.x;
488 box->low.x = x;
489 }
490 if (float8_lt(box->high.y, box->low.y))
491 {
492 y = box->high.y;
493 box->high.y = box->low.y;
494 box->low.y = y;
495 }
496
498}
#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 618 of file geo_ops.c.

619{
622
623 PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));
624}

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 556 of file geo_ops.c.

557{
560
561 PG_RETURN_BOOL(point_eq_point(&box1->high, &box2->high) &&
562 point_eq_point(&box1->low, &box2->low));
563}
static bool point_eq_point(Point *pt1, Point *pt2)
Definition geo_ops.c:2028

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 504 of file geo_ops.c.

505{
506 BOX *box = PG_GETARG_BOX_P(0);
508
510 pq_sendfloat8(&buf, box->high.x);
511 pq_sendfloat8(&buf, box->high.y);
512 pq_sendfloat8(&buf, box->low.x);
513 pq_sendfloat8(&buf, box->low.y);
515}
#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 4339 of file geo_ops.c.

4340{
4341 BOX *box = PG_GETARG_BOX_P(0);
4342 Point *p = PG_GETARG_POINT_P(1);
4343 BOX *result;
4344
4346
4347 point_sub_point(&result->high, &box->high, p);
4348 point_sub_point(&result->low, &box->low, p);
4349
4351}
static void point_sub_point(Point *result, Point *pt1, Point *pt2)
Definition geo_ops.c:4227

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 926 of file geo_ops.c.

927{
928 return float8_mi(box->high.x, box->low.x);
929}

References fb(), and float8_mi().

Referenced by box_ar(), and box_width().

◆ box_width()

Datum box_width ( PG_FUNCTION_ARGS  )

Definition at line 828 of file geo_ops.c.

829{
830 BOX *box = PG_GETARG_BOX_P(0);
831
833}

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 4414 of file geo_ops.c.

4415{
4416 BOX *box1 = PG_GETARG_BOX_P(0),
4417 *box2 = PG_GETARG_BOX_P(1),
4418 *container;
4419
4420 container = palloc_object(BOX);
4421
4422 container->high.x = float8_max(box1->high.x, box2->high.x);
4423 container->low.x = float8_min(box1->low.x, box2->low.x);
4424 container->high.y = float8_max(box1->high.y, box2->high.y);
4425 container->low.y = float8_min(box1->low.y, box2->low.y);
4426
4427 PG_RETURN_BOX_P(container);
4428}

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 4975 of file geo_ops.c.

4976{
4979
4980 PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.y, circle1->radius),
4981 float8_pl(circle2->center.y, circle2->radius)));
4982}
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 5081 of file geo_ops.c.

5082{
5085 CIRCLE *result;
5086
5088
5089 point_add_point(&result->center, &circle->center, point, NULL);
5090 result->radius = circle->radius;
5091
5093}

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 5283 of file geo_ops.c.

5284{
5285 return float8_mul(float8_mul(circle->radius, circle->radius), M_PI);
5286}
#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 5150 of file geo_ops.c.

5151{
5153
5155}
static float8 circle_ar(CIRCLE *circle)
Definition geo_ops.c:5283

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

◆ circle_below()

Datum circle_below ( PG_FUNCTION_ARGS  )

Definition at line 4962 of file geo_ops.c.

4963{
4966
4967 PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.y, circle1->radius),
4968 float8_mi(circle2->center.y, circle2->radius)));
4969}

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 5310 of file geo_ops.c.

5311{
5313 BOX *box;
5314 float8 delta;
5315
5317
5318 delta = float8_div_safe(circle->radius, sqrt(2.0), fcinfo->context);
5319 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5320 goto fail;
5321
5322 box->high.x = float8_pl_safe(circle->center.x, delta, fcinfo->context);
5323 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5324 goto fail;
5325
5326 box->low.x = float8_mi_safe(circle->center.x, delta, fcinfo->context);
5327 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5328 goto fail;
5329
5330 box->high.y = float8_pl_safe(circle->center.y, delta, fcinfo->context);
5331 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5332 goto fail;
5333
5334 box->low.y = float8_mi_safe(circle->center.y, delta, fcinfo->context);
5335 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5336 goto fail;
5337
5339
5340fail:
5342}
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 5266 of file geo_ops.c.

5267{
5269 Point *result;
5270
5272 result->x = circle->center.x;
5273 result->y = circle->center.y;
5274
5276}

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 4948 of file geo_ops.c.

4949{
4952
4953 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4954 float8_mi(circle1->radius, circle2->radius)));
4955}

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 5203 of file geo_ops.c.

5204{
5207 float8 d;
5208
5209 d = point_dt(&circle->center, point, NULL);
5211}

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 4935 of file geo_ops.c.

4936{
4939
4940 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4941 float8_mi(circle2->radius, circle1->radius)));
4942}

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 5162 of file geo_ops.c.

5163{
5165
5166 PG_RETURN_FLOAT8(float8_mul(circle->radius, 2.0));
5167}

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

◆ circle_distance()

Datum circle_distance ( PG_FUNCTION_ARGS  )

Definition at line 5187 of file geo_ops.c.

5188{
5191 float8 result;
5192
5193 result = float8_mi(point_dt(&circle1->center, &circle2->center, NULL),
5194 float8_pl(circle1->radius, circle2->radius));
5195 if (result < 0.0)
5196 result = 0.0;
5197
5199}

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 5131 of file geo_ops.c.

5132{
5135 CIRCLE *result;
5136
5138
5139 point_div_point(&result->center, &circle->center, point);
5140 result->radius = float8_div(circle->radius, hypot(point->x, point->y));
5141
5143}
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 5018 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 5063 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 5045 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 4712 of file geo_ops.c.

4713{
4714 char *str = PG_GETARG_CSTRING(0);
4715 Node *escontext = fcinfo->context;
4717 char *s,
4718 *cp;
4719 int depth = 0;
4720
4721 s = str;
4722 while (isspace((unsigned char) *s))
4723 s++;
4724 if (*s == LDELIM_C)
4725 depth++, s++;
4726 else if (*s == LDELIM)
4727 {
4728 /* If there are two left parens, consume the first one */
4729 cp = (s + 1);
4730 while (isspace((unsigned char) *cp))
4731 cp++;
4732 if (*cp == LDELIM)
4733 depth++, s = cp;
4734 }
4735
4736 /* pair_decode will consume parens around the pair, if any */
4737 if (!pair_decode(s, &circle->center.x, &circle->center.y, &s, "circle", str,
4738 escontext))
4740
4741 if (*s == DELIM)
4742 s++;
4743
4744 if (!single_decode(s, &circle->radius, &s, "circle", str, escontext))
4746
4747 /* We have to accept NaN. */
4748 if (circle->radius < 0.0)
4749 ereturn(escontext, (Datum) 0,
4751 errmsg("invalid input syntax for type %s: \"%s\"",
4752 "circle", str)));
4753
4754 while (depth > 0)
4755 {
4756 if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1)))
4757 {
4758 depth--;
4759 s++;
4760 while (isspace((unsigned char) *s))
4761 s++;
4762 }
4763 else
4764 ereturn(escontext, (Datum) 0,
4766 errmsg("invalid input syntax for type %s: \"%s\"",
4767 "circle", str)));
4768 }
4769
4770 if (*s != '\0')
4771 ereturn(escontext, (Datum) 0,
4773 errmsg("invalid input syntax for type %s: \"%s\"",
4774 "circle", str)));
4775
4777}
int errcode(int sqlerrcode)
Definition elog.c:875
#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 5054 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 4895 of file geo_ops.c.

4896{
4899
4900 PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.x, circle1->radius),
4901 float8_mi(circle2->center.x, circle2->radius)));
4902}

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 5036 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 5116 of file geo_ops.c.

5117{
5120 CIRCLE *result;
5121
5123
5124 point_mul_point(&result->center, &circle->center, point);
5125 result->radius = float8_mul(circle->radius, hypot(point->x, point->y));
5126
5128}

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 5027 of file geo_ops.c.

5028{
5031
5033}
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 4783 of file geo_ops.c.

4784{
4787
4789
4792 pair_encode(circle->center.x, circle->center.y, &str);
4795 single_encode(circle->radius, &str);
4797
4798 PG_RETURN_CSTRING(str.data);
4799}
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 5003 of file geo_ops.c.

5004{
5007
5008 PG_RETURN_BOOL(FPge(float8_mi(circle1->center.y, circle1->radius),
5009 float8_mi(circle2->center.y, circle2->radius)));
5010}

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

◆ circle_overbelow()

Datum circle_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 4989 of file geo_ops.c.

4990{
4993
4994 PG_RETURN_BOOL(FPle(float8_pl(circle1->center.y, circle1->radius),
4995 float8_pl(circle2->center.y, circle2->radius)));
4996}

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

◆ circle_overlap()

Datum circle_overlap ( PG_FUNCTION_ARGS  )

Definition at line 4868 of file geo_ops.c.

4869{
4872
4873 PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL),
4874 float8_pl(circle1->radius, circle2->radius)));
4875}

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 4882 of file geo_ops.c.

4883{
4886
4887 PG_RETURN_BOOL(FPle(float8_pl(circle1->center.x, circle1->radius),
4888 float8_pl(circle2->center.x, circle2->radius)));
4889}

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

◆ circle_overright()

Datum circle_overright ( PG_FUNCTION_ARGS  )

Definition at line 4922 of file geo_ops.c.

4923{
4926
4927 PG_RETURN_BOOL(FPge(float8_mi(circle1->center.x, circle1->radius),
4928 float8_mi(circle2->center.x, circle2->radius)));
4929}

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

◆ circle_poly()

Datum circle_poly ( PG_FUNCTION_ARGS  )

Definition at line 5453 of file geo_ops.c.

5454{
5455 int32 npts = PG_GETARG_INT32(0);
5457
5459}
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:5388

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 5388 of file geo_ops.c.

5389{
5390 POLYGON *poly;
5391 int base_size,
5392 size;
5393 int i;
5394 float8 angle;
5396
5397 if (FPzero(circle->radius))
5398 ereturn(fcinfo->context, NULL,
5400 errmsg("cannot convert circle with radius zero to polygon")));
5401
5402 if (npts < 2)
5403 ereturn(fcinfo->context, NULL,
5405 errmsg("must request at least 2 points")));
5406
5407 base_size = sizeof(poly->p[0]) * npts;
5408 size = offsetof(POLYGON, p) + base_size;
5409
5410 /* Check for integer overflow */
5411 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
5412 ereturn(fcinfo->context, NULL,
5414 errmsg("too many points requested")));
5415
5416 poly = (POLYGON *) palloc0(size); /* zero any holes */
5417 SET_VARSIZE(poly, size);
5418 poly->npts = npts;
5419
5420 anglestep = float8_div(2.0 * M_PI, npts);
5421
5422 for (i = 0; i < npts; i++)
5423 {
5424 float8 temp;
5425
5427 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5428 return NULL;
5429
5430 temp = float8_mul_safe(circle->radius, cos(angle), fcinfo->context);
5431 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5432 return NULL;
5433
5434 poly->p[i].x = float8_mi_safe(circle->center.x, temp, fcinfo->context);
5435 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5436 return NULL;
5437
5438 temp = float8_mul_safe(circle->radius, sin(angle), fcinfo->context);
5439 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5440 return NULL;
5441
5442 poly->p[i].y = float8_pl_safe(circle->center.y, temp, fcinfo->context);
5443 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5444 return NULL;
5445 }
5446
5448
5449 return poly;
5450}
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:3460
int i
Definition isn.c:77
void * palloc0(Size size)
Definition mcxt.c:1420

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 5174 of file geo_ops.c.

5175{
5177
5178 PG_RETURN_FLOAT8(circle->radius);
5179}

References fb(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

◆ circle_recv()

Datum circle_recv ( PG_FUNCTION_ARGS  )

Definition at line 4805 of file geo_ops.c.

4806{
4808 CIRCLE *circle;
4809
4811
4812 circle->center.x = pq_getmsgfloat8(buf);
4813 circle->center.y = pq_getmsgfloat8(buf);
4814 circle->radius = pq_getmsgfloat8(buf);
4815
4816 /* We have to accept NaN. */
4817 if (circle->radius < 0.0)
4818 ereport(ERROR,
4820 errmsg("invalid radius in external \"circle\" value")));
4821
4823}
#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 4908 of file geo_ops.c.

4909{
4912
4913 PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.x, circle1->radius),
4914 float8_pl(circle2->center.x, circle2->radius)));
4915}

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 4854 of file geo_ops.c.

4855{
4858
4859 PG_RETURN_BOOL(((isnan(circle1->radius) && isnan(circle2->radius)) ||
4860 FPeq(circle1->radius, circle2->radius)) &&
4861 point_eq_point(&circle1->center, &circle2->center));
4862}

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 4829 of file geo_ops.c.

4830{
4833
4835 pq_sendfloat8(&buf, circle->center.x);
4836 pq_sendfloat8(&buf, circle->center.y);
4837 pq_sendfloat8(&buf, circle->radius);
4839}

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 5096 of file geo_ops.c.

5097{
5100 CIRCLE *result;
5101
5103
5104 point_sub_point(&result->center, &circle->center, point);
5105 result->radius = circle->radius;
5106
5108}

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 5463 of file geo_ops.c.

5464{
5465 int32 npts = 12;
5467
5469}

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 3070 of file geo_ops.c.

3071{
3072 LINE *line = PG_GETARG_LINE_P(0);
3074 Point *result;
3075
3076 if (lseg_sl(lseg) == line_sl(line))
3078
3080
3081 if (isnan(lseg_closept_line(result, lseg, line)))
3083
3085}
#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:3042
static float8 lseg_sl(LSEG *lseg)
Definition geo_ops.c:2218
static float8 line_sl(LINE *line)
Definition geo_ops.c:1280

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 2935 of file geo_ops.c.

2936{
2937 LSEG *l1 = PG_GETARG_LSEG_P(0);
2938 LSEG *l2 = PG_GETARG_LSEG_P(1);
2939 Point *result;
2940
2941 if (lseg_sl(l1) == lseg_sl(l2))
2943
2945
2946 if (isnan(lseg_closept_lseg(result, l2, l1)))
2948
2950}

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 3015 of file geo_ops.c.

3016{
3018 BOX *box = PG_GETARG_BOX_P(1);
3019 Point *result;
3020
3022
3025
3027}
static float8 box_closept_point(Point *result, BOX *box, Point *pt)
Definition geo_ops.c:2960

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 2832 of file geo_ops.c.

2833{
2835 LINE *line = PG_GETARG_LINE_P(1);
2836 Point *result;
2837
2839
2840 if (isnan(line_closept_point(result, line, pt)))
2842
2844}
static float8 line_closept_point(Point *result, LINE *line, Point *point)
Definition geo_ops.c:2806

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 3145 of file geo_ops.c.

3146{
3148 BOX *box = PG_GETARG_BOX_P(1);
3149 Point *result;
3150
3152
3155
3157}
static float8 box_closept_lseg(Point *result, BOX *box, LSEG *lseg)
Definition geo_ops.c:3095

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 4180 of file geo_ops.c.

4181{
4184 Point *result;
4185
4187
4189
4191}
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
static void point_construct(Point *result, float8 x, float8 y)
Definition geo_ops.c:1935

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 5294 of file geo_ops.c.

5295{
5296 Point *center = PG_GETARG_POINT_P(0);
5297 float8 radius = PG_GETARG_FLOAT8(1);
5298 CIRCLE *result;
5299
5301
5302 result->center.x = center->x;
5303 result->center.y = center->y;
5304 result->radius = radius;
5305
5307}

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 2596 of file geo_ops.c.

2597{
2598 BOX *box = PG_GETARG_BOX_P(0);
2600
2602}

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 2644 of file geo_ops.c.

2645{
2646 BOX *box = PG_GETARG_BOX_P(0);
2648
2650}

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 5249 of file geo_ops.c.

5250{
5253 float8 result;
5254
5255 result = float8_mi(point_dt(point, &circle->center, NULL), circle->radius);
5256 if (result < 0.0)
5257 result = 0.0;
5258
5260}

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 2670 of file geo_ops.c.

2671{
2674
2676}
#define PG_GETARG_POLYGON_P(n)
Definition geo_decls.h:260
static float8 dist_cpoly_internal(CIRCLE *circle, POLYGON *poly)
Definition geo_ops.c:2653

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 2653 of file geo_ops.c.

2654{
2655 float8 result;
2656
2657 /* calculate distance to center, and subtract radius */
2659 circle->radius);
2660 if (result < 0.0)
2661 result = 0.0;
2662
2663 return result;
2664}
static float8 dist_ppoly_internal(Point *pt, POLYGON *poly)
Definition geo_ops.c:2712

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 2484 of file geo_ops.c.

2485{
2486 LINE *line = PG_GETARG_LINE_P(0);
2488
2490}

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 2620 of file geo_ops.c.

2621{
2622 LINE *line = PG_GETARG_LINE_P(0);
2624
2626}

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 2572 of file geo_ops.c.

2573{
2574 PATH *path = PG_GETARG_PATH_P(0);
2576
2578}
#define PG_GETARG_PATH_P(n)
Definition geo_decls.h:215
static float8 dist_ppath_internal(Point *pt, PATH *path)
Definition geo_ops.c:2517

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 2584 of file geo_ops.c.

2585{
2587 BOX *box = PG_GETARG_BOX_P(1);
2588
2590}

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 5231 of file geo_ops.c.

5232{
5235 float8 result;
5236
5237 result = float8_mi(point_dt(point, &circle->center, NULL),
5238 circle->radius);
5239 if (result < 0.0)
5240 result = 0.0;
5241
5243}

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 2472 of file geo_ops.c.

2473{
2475 LINE *line = PG_GETARG_LINE_P(1);
2476
2478}

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 2560 of file geo_ops.c.

2561{
2563 PATH *path = PG_GETARG_PATH_P(1);
2564
2566}

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 2517 of file geo_ops.c.

2518{
2519 float8 result = 0.0; /* keep compiler quiet */
2520 bool have_min = false;
2521 float8 tmp;
2522 int i;
2523 LSEG lseg;
2524
2525 Assert(path->npts > 0);
2526
2527 /*
2528 * The distance from a point to a path is the smallest distance from the
2529 * point to any of its constituent segments.
2530 */
2531 for (i = 0; i < path->npts; i++)
2532 {
2533 int iprev;
2534
2535 if (i > 0)
2536 iprev = i - 1;
2537 else
2538 {
2539 if (!path->closed)
2540 continue;
2541 iprev = path->npts - 1; /* Include the closure segment */
2542 }
2543
2544 statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
2545 tmp = lseg_closept_point(NULL, &lseg, pt);
2546 if (!have_min || float8_lt(tmp, result))
2547 {
2548 result = tmp;
2549 have_min = true;
2550 }
2551 }
2552
2553 return result;
2554}
#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 2712 of file geo_ops.c.

2713{
2714 float8 result;
2715 float8 d;
2716 int i;
2717 LSEG seg;
2718
2719 if (point_inside(pt, poly->npts, poly->p) != 0)
2720 return 0.0;
2721
2722 /* initialize distance with segment between first and last points */
2723 seg.p[0].x = poly->p[0].x;
2724 seg.p[0].y = poly->p[0].y;
2725 seg.p[1].x = poly->p[poly->npts - 1].x;
2726 seg.p[1].y = poly->p[poly->npts - 1].y;
2727 result = lseg_closept_point(NULL, &seg, pt);
2728
2729 /* check distances for other segments */
2730 for (i = 0; i < poly->npts - 1; i++)
2731 {
2732 seg.p[0].x = poly->p[i].x;
2733 seg.p[0].y = poly->p[i].y;
2734 seg.p[1].x = poly->p[i + 1].x;
2735 seg.p[1].y = poly->p[i + 1].y;
2736 d = lseg_closept_point(NULL, &seg, pt);
2737 if (float8_lt(d, result))
2738 result = d;
2739 }
2740
2741 return result;
2742}
static int point_inside(Point *p, int npts, Point *plist)
Definition geo_ops.c:5558
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 2632 of file geo_ops.c.

2633{
2635 BOX *box = PG_GETARG_BOX_P(1);
2636
2638}

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 2608 of file geo_ops.c.

2609{
2611 LINE *line = PG_GETARG_LINE_P(1);
2612
2614}

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 3412 of file geo_ops.c.

3413{
3414 LINE *line = PG_GETARG_LINE_P(0);
3415 BOX *box = PG_GETARG_BOX_P(1);
3416 LSEG bseg;
3417 Point p1,
3418 p2;
3419
3420 /* pairwise check lseg intersections */
3421 p1.x = box->low.x;
3422 p1.y = box->low.y;
3423 p2.x = box->low.x;
3424 p2.y = box->high.y;
3426 if (lseg_interpt_line(NULL, &bseg, line))
3427 PG_RETURN_BOOL(true);
3428 p1.x = box->high.x;
3429 p1.y = box->high.y;
3431 if (lseg_interpt_line(NULL, &bseg, line))
3432 PG_RETURN_BOOL(true);
3433 p2.x = box->high.x;
3434 p2.y = box->low.y;
3436 if (lseg_interpt_line(NULL, &bseg, line))
3437 PG_RETURN_BOOL(true);
3438 p1.x = box->low.x;
3439 p1.y = box->low.y;
3441 if (lseg_interpt_line(NULL, &bseg, line))
3442 PG_RETURN_BOOL(true);
3443
3444 /* if we dropped through, no intersection */
3445 PG_RETURN_BOOL(false);
3446}
static bool lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
Definition geo_ops.c:2757

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 3398 of file geo_ops.c.

3399{
3401 BOX *box = PG_GETARG_BOX_P(1);
3402
3404}

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 3321 of file geo_ops.c.

3322{
3324 LINE *line = PG_GETARG_LINE_P(1);
3325
3327}

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 2806 of file geo_ops.c.

2807{
2808 Point closept;
2809 LINE tmp;
2810
2811 /*
2812 * We drop a perpendicular to find the intersection point. Ordinarily we
2813 * should always find it, but that can fail in the presence of NaN
2814 * coordinates, and perhaps even from simple roundoff issues.
2815 */
2816 line_construct(&tmp, point, line_invsl(line));
2817 if (!line_interpt_line(&closept, &tmp, line))
2818 {
2819 if (result != NULL)
2820 *result = *point;
2821
2822 return get_float8_nan();
2823 }
2824
2825 if (result != NULL)
2826 *result = closept;
2827
2828 return point_dt(&closept, point, NULL);
2829}
static float8 get_float8_nan(void)
Definition float.h:87
static void line_construct(LINE *result, Point *pt, float8 m)
Definition geo_ops.c:1129
static bool line_interpt_line(Point *result, LINE *l1, LINE *l2)
Definition geo_ops.c:1363
static float8 line_invsl(LINE *line)
Definition geo_ops.c:1294

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 1129 of file geo_ops.c.

1130{
1131 if (isinf(m))
1132 {
1133 /* vertical - use "x = C" */
1134 result->A = -1.0;
1135 result->B = 0.0;
1136 result->C = pt->x;
1137 }
1138 else if (m == 0)
1139 {
1140 /* horizontal - use "y = C" */
1141 result->A = 0.0;
1142 result->B = -1.0;
1143 result->C = pt->y;
1144 }
1145 else
1146 {
1147 /* use "mx - y + yinter = 0" */
1148 result->A = m;
1149 result->B = -1.0;
1150 result->C = float8_mi(pt->y, float8_mul(m, pt->x));
1151 /* on some platforms, the preceding expression tends to produce -0 */
1152 if (result->C == 0.0)
1153 result->C = 0.0;
1154 }
1155}

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 1162 of file geo_ops.c.

1163{
1167
1168 if (point_eq_point(pt1, pt2))
1169 ereport(ERROR,
1171 errmsg("invalid line specification: must be two distinct points")));
1172
1174
1176}
#define PG_RETURN_LINE_P(x)
Definition geo_decls.h:230
static float8 point_sl(Point *pt1, Point *pt2)
Definition geo_ops.c:2085

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 3169 of file geo_ops.c.

3170{
3171 return FPzero(float8_pl(float8_pl(float8_mul(line->A, point->x),
3172 float8_mul(line->B, point->y)),
3173 line->C));
3174}
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 996 of file geo_ops.c.

997{
998 /* s was already advanced over leading '{' */
999 if (!single_decode(s, &line->A, &s, "line", str, escontext))
1000 return false;
1001 if (*s++ != DELIM)
1002 goto fail;
1003 if (!single_decode(s, &line->B, &s, "line", str, escontext))
1004 return false;
1005 if (*s++ != DELIM)
1006 goto fail;
1007 if (!single_decode(s, &line->C, &s, "line", str, escontext))
1008 return false;
1009 if (*s++ != RDELIM_L)
1010 goto fail;
1011 while (isspace((unsigned char) *s))
1012 s++;
1013 if (*s != '\0')
1014 goto fail;
1015 return true;
1016
1017fail:
1018 ereturn(escontext, false,
1020 errmsg("invalid input syntax for type %s: \"%s\"",
1021 "line", str)));
1022}
#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 1309 of file geo_ops.c.

1310{
1311 LINE *l1 = PG_GETARG_LINE_P(0);
1312 LINE *l2 = PG_GETARG_LINE_P(1);
1313 float8 ratio;
1314
1315 if (line_interpt_line(NULL, l1, l2)) /* intersecting? */
1316 PG_RETURN_FLOAT8(0.0);
1317
1318 if (!FPzero(l1->A) && !isnan(l1->A) && !FPzero(l2->A) && !isnan(l2->A))
1319 ratio = float8_div(l1->A, l2->A);
1320 else if (!FPzero(l1->B) && !isnan(l1->B) && !FPzero(l2->B) && !isnan(l2->B))
1321 ratio = float8_div(l1->B, l2->B);
1322 else
1323 ratio = 1.0;
1324
1326 float8_mul(ratio, l2->C))),
1327 hypot(l1->A, l1->B)));
1328}

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 1241 of file geo_ops.c.

1242{
1243 LINE *l1 = PG_GETARG_LINE_P(0);
1244 LINE *l2 = PG_GETARG_LINE_P(1);
1245 float8 ratio;
1246
1247 /* If any NaNs are involved, insist on exact equality */
1248 if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l1->C) ||
1249 isnan(l2->A) || isnan(l2->B) || isnan(l2->C)))
1250 {
1251 PG_RETURN_BOOL(float8_eq(l1->A, l2->A) &&
1252 float8_eq(l1->B, l2->B) &&
1253 float8_eq(l1->C, l2->C));
1254 }
1255
1256 /* Otherwise, lines whose parameters are proportional are the same */
1257 if (!FPzero(l2->A))
1258 ratio = float8_div(l1->A, l2->A);
1259 else if (!FPzero(l2->B))
1260 ratio = float8_div(l1->B, l2->B);
1261 else if (!FPzero(l2->C))
1262 ratio = float8_div(l1->C, l2->C);
1263 else
1264 ratio = 1.0;
1265
1266 PG_RETURN_BOOL(FPeq(l1->A, float8_mul(ratio, l2->A)) &&
1267 FPeq(l1->B, float8_mul(ratio, l2->B)) &&
1268 FPeq(l1->C, float8_mul(ratio, l2->C)));
1269}
#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 1229 of file geo_ops.c.

1230{
1231 LINE *line = PG_GETARG_LINE_P(0);
1232
1233 PG_RETURN_BOOL(FPzero(line->A));
1234}

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

◆ line_in()

Datum line_in ( PG_FUNCTION_ARGS  )

Definition at line 1025 of file geo_ops.c.

1026{
1027 char *str = PG_GETARG_CSTRING(0);
1028 Node *escontext = fcinfo->context;
1029 LINE *line = palloc_object(LINE);
1030 LSEG lseg;
1031 bool isopen;
1032 char *s;
1033
1034 s = str;
1035 while (isspace((unsigned char) *s))
1036 s++;
1037 if (*s == LDELIM_L)
1038 {
1039 if (!line_decode(s + 1, str, line, escontext))
1041 if (FPzero(line->A) && FPzero(line->B))
1042 ereturn(escontext, (Datum) 0,
1044 errmsg("invalid line specification: A and B cannot both be zero")));
1045 }
1046 else
1047 {
1048 if (!path_decode(s, true, 2, &lseg.p[0], &isopen, NULL, "line", str,
1049 escontext))
1051 if (point_eq_point(&lseg.p[0], &lseg.p[1]))
1052 ereturn(escontext, (Datum) 0,
1054 errmsg("invalid line specification: must be two distinct points")));
1055
1056 /*
1057 * XXX lseg_sl() and line_construct() can throw overflow/underflow
1058 * errors. Eventually we should allow those to be soft, but the
1059 * notational pain seems to outweigh the value for now.
1060 */
1061 line_construct(line, &lseg.p[0], lseg_sl(&lseg));
1062 }
1063
1064 PG_RETURN_LINE_P(line);
1065}
#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:996

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 1335 of file geo_ops.c.

1336{
1337 LINE *l1 = PG_GETARG_LINE_P(0);
1338 LINE *l2 = PG_GETARG_LINE_P(1);
1339 Point *result;
1340
1342
1343 if (!line_interpt_line(result, l1, l2))
1346}

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 1363 of file geo_ops.c.

1364{
1365 float8 x,
1366 y;
1367
1368 if (!FPzero(l1->B))
1369 {
1370 if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B))))
1371 return false;
1372
1373 x = float8_div(float8_mi(float8_mul(l1->B, l2->C),
1374 float8_mul(l2->B, l1->C)),
1375 float8_mi(float8_mul(l1->A, l2->B),
1376 float8_mul(l2->A, l1->B)));
1377 y = float8_div(-float8_pl(float8_mul(l1->A, x), l1->C), l1->B);
1378 }
1379 else if (!FPzero(l2->B))
1380 {
1381 if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B))))
1382 return false;
1383
1384 x = float8_div(float8_mi(float8_mul(l2->B, l1->C),
1385 float8_mul(l1->B, l2->C)),
1386 float8_mi(float8_mul(l2->A, l1->B),
1387 float8_mul(l1->A, l2->B)));
1388 y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B);
1389 }
1390 else
1391 return false;
1392
1393 /* On some platforms, the preceding expressions tend to produce -0. */
1394 if (x == 0.0)
1395 x = 0.0;
1396 if (y == 0.0)
1397 y = 0.0;
1398
1399 if (result != NULL)
1401
1402 return true;
1403}

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 1184 of file geo_ops.c.

1185{
1186 LINE *l1 = PG_GETARG_LINE_P(0);
1187 LINE *l2 = PG_GETARG_LINE_P(1);
1188
1190}

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 1294 of file geo_ops.c.

1295{
1296 if (FPzero(line->A))
1297 return get_float8_infinity();
1298 if (FPzero(line->B))
1299 return 0.0;
1300 return float8_div(line->B, line->A);
1301}
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 1069 of file geo_ops.c.

1070{
1071 LINE *line = PG_GETARG_LINE_P(0);
1072 char *astr = float8out_internal(line->A);
1073 char *bstr = float8out_internal(line->B);
1074 char *cstr = float8out_internal(line->C);
1075
1076 PG_RETURN_CSTRING(psprintf("%c%s%c%s%c%s%c", LDELIM_L, astr, DELIM, bstr,
1077 DELIM, cstr, RDELIM_L));
1078}
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 1193 of file geo_ops.c.

1194{
1195 LINE *l1 = PG_GETARG_LINE_P(0);
1196 LINE *l2 = PG_GETARG_LINE_P(1);
1197
1199}

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

◆ line_perp()

Datum line_perp ( PG_FUNCTION_ARGS  )

Definition at line 1202 of file geo_ops.c.

1203{
1204 LINE *l1 = PG_GETARG_LINE_P(0);
1205 LINE *l2 = PG_GETARG_LINE_P(1);
1206
1207 if (FPzero(l1->A))
1208 PG_RETURN_BOOL(FPzero(l2->B));
1209 if (FPzero(l2->A))
1210 PG_RETURN_BOOL(FPzero(l1->B));
1211 if (FPzero(l1->B))
1212 PG_RETURN_BOOL(FPzero(l2->A));
1213 if (FPzero(l2->B))
1214 PG_RETURN_BOOL(FPzero(l1->A));
1215
1217 float8_mul(l1->B, l2->B)), -1.0));
1218}

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 1084 of file geo_ops.c.

1085{
1087 LINE *line;
1088
1089 line = palloc_object(LINE);
1090
1091 line->A = pq_getmsgfloat8(buf);
1092 line->B = pq_getmsgfloat8(buf);
1093 line->C = pq_getmsgfloat8(buf);
1094
1095 if (FPzero(line->A) && FPzero(line->B))
1096 ereport(ERROR,
1098 errmsg("invalid line specification: A and B cannot both be zero")));
1099
1100 PG_RETURN_LINE_P(line);
1101}

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 1107 of file geo_ops.c.

1108{
1109 LINE *line = PG_GETARG_LINE_P(0);
1111
1113 pq_sendfloat8(&buf, line->A);
1114 pq_sendfloat8(&buf, line->B);
1115 pq_sendfloat8(&buf, line->C);
1117}

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 1280 of file geo_ops.c.

1281{
1282 if (FPzero(line->A))
1283 return 0.0;
1284 if (FPzero(line->B))
1285 return get_float8_infinity();
1286 return float8_div(line->A, -line->B);
1287}

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 1221 of file geo_ops.c.

1222{
1223 LINE *line = PG_GETARG_LINE_P(0);
1224
1225 PG_RETURN_BOOL(FPzero(line->B));
1226}

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

◆ lseg_center()

Datum lseg_center ( PG_FUNCTION_ARGS  )

Definition at line 2380 of file geo_ops.c.

2381{
2383 Point *result;
2384 float8 x;
2385 float8 y;
2386
2388
2389 x = float8_pl_safe(lseg->p[0].x, lseg->p[1].x, fcinfo->context);
2390 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2391 goto fail;
2392
2393 result->x = float8_div_safe(x, 2.0, fcinfo->context);
2394 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2395 goto fail;
2396
2397 y = float8_pl_safe(lseg->p[0].y, lseg->p[1].y, fcinfo->context);
2398 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2399 goto fail;
2400
2401 result->y = float8_div_safe(y, 2.0, fcinfo->context);
2402 if (SOFT_ERROR_OCCURRED(fcinfo->context))
2403 goto fail;
2404
2406
2407fail:
2409}

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 3042 of file geo_ops.c.

3043{
3044 float8 dist1,
3045 dist2;
3046
3047 if (lseg_interpt_line(result, lseg, line))
3048 return 0.0;
3049
3050 dist1 = line_closept_point(NULL, line, &lseg->p[0]);
3051 dist2 = line_closept_point(NULL, line, &lseg->p[1]);
3052
3053 if (dist1 < dist2)
3054 {
3055 if (result != NULL)
3056 *result = lseg->p[0];
3057
3058 return dist1;
3059 }
3060 else
3061 {
3062 if (result != NULL)
3063 *result = lseg->p[1];
3064
3065 return dist2;
3066 }
3067}

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 2892 of file geo_ops.c.

2893{
2894 Point point;
2895 float8 dist,
2896 d;
2897
2898 /* First, we handle the case when the line segments are intersecting. */
2900 return 0.0;
2901
2902 /*
2903 * Then, we find the closest points from the endpoints of the second line
2904 * segment, and keep the closest one.
2905 */
2907 d = lseg_closept_point(&point, on_lseg, &to_lseg->p[1]);
2908 if (float8_lt(d, dist))
2909 {
2910 dist = d;
2911 if (result != NULL)
2912 *result = point;
2913 }
2914
2915 /* The closest point can still be one of the endpoints, so we test them. */
2916 d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[0]);
2917 if (float8_lt(d, dist))
2918 {
2919 dist = d;
2920 if (result != NULL)
2921 *result = on_lseg->p[0];
2922 }
2923 d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[1]);
2924 if (float8_lt(d, dist))
2925 {
2926 dist = d;
2927 if (result != NULL)
2928 *result = on_lseg->p[1];
2929 }
2930
2931 return dist;
2932}

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 2854 of file geo_ops.c.

2855{
2856 Point closept;
2857 LINE tmp;
2858
2859 /*
2860 * To find the closest point, we draw a perpendicular line from the point
2861 * to the line segment.
2862 */
2863 line_construct(&tmp, pt, point_invsl(&lseg->p[0], &lseg->p[1]));
2865
2866 if (result != NULL)
2867 *result = closept;
2868
2869 return point_dt(&closept, pt, NULL);
2870}
static float8 point_invsl(Point *pt1, Point *pt2)
Definition geo_ops.c:2101

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 2192 of file geo_ops.c.

2193{
2197
2199
2201}

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 3191 of file geo_ops.c.

3192{
3193 return FPeq(point_dt(pt, &lseg->p[0], NULL) +
3194 point_dt(pt, &lseg->p[1], NULL),
3195 point_dt(&lseg->p[0], &lseg->p[1], NULL));
3196}

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 5616 of file geo_ops.c.

5617{
5618 float8 z;
5619 int y_sign;
5620
5621 if (FPzero(y))
5622 { /* y == 0, on X axis */
5623 if (FPzero(x)) /* (x,y) is (0,0)? */
5624 return POINT_ON_POLYGON;
5625 else if (FPgt(x, 0))
5626 { /* x > 0 */
5627 if (FPzero(prev_y)) /* y and prev_y are zero */
5628 /* prev_x > 0? */
5629 return FPgt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5630 return FPlt(prev_y, 0.0) ? 1 : -1;
5631 }
5632 else
5633 { /* x < 0, x not on positive X axis */
5634 if (FPzero(prev_y))
5635 /* prev_x < 0? */
5636 return FPlt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5637 return 0;
5638 }
5639 }
5640 else
5641 { /* y != 0 */
5642 /* compute y crossing direction from previous point */
5643 y_sign = FPgt(y, 0.0) ? 1 : -1;
5644
5645 if (FPzero(prev_y))
5646 /* previous point was on X axis, so new point is either off or on */
5647 return FPlt(prev_x, 0.0) ? 0 : y_sign;
5648 else if ((y_sign < 0 && FPlt(prev_y, 0.0)) ||
5649 (y_sign > 0 && FPgt(prev_y, 0.0)))
5650 /* both above or below X axis */
5651 return 0; /* same sign */
5652 else
5653 { /* y and prev_y cross X-axis */
5654 if (FPge(x, 0.0) && FPgt(prev_x, 0.0))
5655 /* both non-negative so cross positive X-axis */
5656 return 2 * y_sign;
5657 if (FPlt(x, 0.0) && FPle(prev_x, 0.0))
5658 /* both non-positive so do not cross positive X-axis */
5659 return 0;
5660
5661 /* x and y cross axes, see URL above point_inside() */
5664 if (FPzero(z))
5665 return POINT_ON_POLYGON;
5666 if ((y_sign < 0 && FPlt(z, 0.0)) ||
5667 (y_sign > 0 && FPgt(z, 0.0)))
5668 return 0;
5669 return 2 * y_sign;
5670 }
5671 }
5672}
#define POINT_ON_POLYGON
Definition geo_ops.c:5555

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 2370 of file geo_ops.c.

2371{
2372 LSEG *l1 = PG_GETARG_LSEG_P(0);
2373 LSEG *l2 = PG_GETARG_LSEG_P(1);
2374
2376}

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

◆ lseg_eq()

Datum lseg_eq ( PG_FUNCTION_ARGS  )

Definition at line 2299 of file geo_ops.c.

2300{
2301 LSEG *l1 = PG_GETARG_LSEG_P(0);
2302 LSEG *l2 = PG_GETARG_LSEG_P(1);
2303
2304 PG_RETURN_BOOL(point_eq_point(&l1->p[0], &l2->p[0]) &&
2305 point_eq_point(&l1->p[1], &l2->p[1]));
2306}

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 2349 of file geo_ops.c.

2350{
2351 LSEG *l1 = PG_GETARG_LSEG_P(0);
2352 LSEG *l2 = PG_GETARG_LSEG_P(1);
2353
2354 PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1], NULL),
2355 point_dt(&l2->p[0], &l2->p[1], NULL)));
2356}

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 2339 of file geo_ops.c.

2340{
2341 LSEG *l1 = PG_GETARG_LSEG_P(0);
2342 LSEG *l2 = PG_GETARG_LSEG_P(1);
2343
2344 PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1], NULL),
2345 point_dt(&l2->p[0], &l2->p[1], NULL)));
2346}

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 2290 of file geo_ops.c.

2291{
2293
2294 PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));
2295}

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

◆ lseg_in()

Datum lseg_in ( PG_FUNCTION_ARGS  )

Definition at line 2127 of file geo_ops.c.

2128{
2129 char *str = PG_GETARG_CSTRING(0);
2130 Node *escontext = fcinfo->context;
2132 bool isopen;
2133
2134 if (!path_decode(str, true, 2, &lseg->p[0], &isopen, NULL, "lseg", str,
2135 escontext))
2137
2139}

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 3950 of file geo_ops.c.

3951{
3952 LSEG s,
3953 t;
3954 int i;
3955 bool res = true,
3956 intersection = false;
3957
3958 /* since this function recurses, it could be driven to stack overflow */
3960
3961 t.p[0] = *a;
3962 t.p[1] = *b;
3963 s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
3964
3965 for (i = start; i < poly->npts && res; i++)
3966 {
3967 Point interpt;
3968
3970
3971 s.p[1] = poly->p[i];
3972
3973 if (lseg_contain_point(&s, t.p))
3974 {
3975 if (lseg_contain_point(&s, t.p + 1))
3976 return true; /* t is contained by s */
3977
3978 /* Y-cross */
3979 res = touched_lseg_inside_poly(t.p, t.p + 1, &s, poly, i + 1);
3980 }
3981 else if (lseg_contain_point(&s, t.p + 1))
3982 {
3983 /* Y-cross */
3984 res = touched_lseg_inside_poly(t.p + 1, t.p, &s, poly, i + 1);
3985 }
3986 else if (lseg_interpt_lseg(&interpt, &t, &s))
3987 {
3988 /*
3989 * segments are X-crossing, go to check each subsegment
3990 */
3991
3992 intersection = true;
3993 res = lseg_inside_poly(t.p, &interpt, poly, i + 1);
3994 if (res)
3995 res = lseg_inside_poly(t.p + 1, &interpt, poly, i + 1);
3996 }
3997
3998 s.p[0] = s.p[1];
3999 }
4000
4001 if (res && !intersection)
4002 {
4003 Point p;
4004
4005 /*
4006 * if X-intersection wasn't found, then check central point of tested
4007 * segment. In opposite case we already check all subsegments
4008 */
4009 p.x = float8_div(float8_pl(t.p[0].x, t.p[1].x), 2.0);
4010 p.y = float8_div(float8_pl(t.p[0].y, t.p[1].y), 2.0);
4011
4012 res = point_inside(&p, poly->npts, poly->p);
4013 }
4014
4015 return res;
4016}
static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
Definition geo_ops.c:3950
static bool lseg_contain_point(LSEG *lseg, Point *pt)
Definition geo_ops.c:3191
static bool touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
Definition geo_ops.c:3914
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 2443 of file geo_ops.c.

2444{
2445 LSEG *l1 = PG_GETARG_LSEG_P(0);
2446 LSEG *l2 = PG_GETARG_LSEG_P(1);
2447 Point *result;
2448
2450
2451 if (!lseg_interpt_lseg(result, l1, l2))
2454}

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 2757 of file geo_ops.c.

2758{
2759 Point interpt;
2760 LINE tmp;
2761
2762 /*
2763 * First, we promote the line segment to a line, because we know how to
2764 * find the intersection point of two lines. If they don't have an
2765 * intersection point, we are done.
2766 */
2767 line_construct(&tmp, &lseg->p[0], lseg_sl(lseg));
2768 if (!line_interpt_line(&interpt, &tmp, line))
2769 return false;
2770
2771 /*
2772 * Then, we check whether the intersection point is actually on the line
2773 * segment.
2774 */
2776 return false;
2777 if (result != NULL)
2778 {
2779 /*
2780 * If there is an intersection, then check explicitly for matching
2781 * endpoints since there may be rounding effects with annoying LSB
2782 * residue.
2783 */
2784 if (point_eq_point(&lseg->p[0], &interpt))
2785 *result = lseg->p[0];
2786 else if (point_eq_point(&lseg->p[1], &interpt))
2787 *result = lseg->p[1];
2788 else
2789 *result = interpt;
2790 }
2791
2792 return true;
2793}

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 2420 of file geo_ops.c.

2421{
2422 Point interpt;
2423 LINE tmp;
2424
2425 line_construct(&tmp, &l2->p[0], lseg_sl(l2));
2426 if (!lseg_interpt_line(&interpt, l1, &tmp))
2427 return false;
2428
2429 /*
2430 * If the line intersection point isn't within l2, there is no valid
2431 * segment intersection point at all.
2432 */
2433 if (!lseg_contain_point(l2, &interpt))
2434 return false;
2435
2436 if (result != NULL)
2437 *result = interpt;
2438
2439 return true;
2440}

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 2251 of file geo_ops.c.

2252{
2253 LSEG *l1 = PG_GETARG_LSEG_P(0);
2254 LSEG *l2 = PG_GETARG_LSEG_P(1);
2255
2257}

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 2228 of file geo_ops.c.

2229{
2230 return point_invsl(&lseg->p[0], &lseg->p[1]);
2231}

References fb(), and point_invsl().

Referenced by lseg_perp().

◆ lseg_le()

Datum lseg_le ( PG_FUNCTION_ARGS  )

Definition at line 2329 of file geo_ops.c.

2330{
2331 LSEG *l1 = PG_GETARG_LSEG_P(0);
2332 LSEG *l2 = PG_GETARG_LSEG_P(1);
2333
2334 PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1], NULL),
2335 point_dt(&l2->p[0], &l2->p[1], NULL)));
2336}

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 2235 of file geo_ops.c.

2236{
2238
2239 PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1], NULL));
2240}

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

◆ lseg_lt()

Datum lseg_lt ( PG_FUNCTION_ARGS  )

Definition at line 2319 of file geo_ops.c.

2320{
2321 LSEG *l1 = PG_GETARG_LSEG_P(0);
2322 LSEG *l2 = PG_GETARG_LSEG_P(1);
2323
2324 PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1], NULL),
2325 point_dt(&l2->p[0], &l2->p[1], NULL)));
2326}

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 2309 of file geo_ops.c.

2310{
2311 LSEG *l1 = PG_GETARG_LSEG_P(0);
2312 LSEG *l2 = PG_GETARG_LSEG_P(1);
2313
2314 PG_RETURN_BOOL(!point_eq_point(&l1->p[0], &l2->p[0]) ||
2315 !point_eq_point(&l1->p[1], &l2->p[1]));
2316}

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 2143 of file geo_ops.c.

2144{
2145 LSEG *ls = PG_GETARG_LSEG_P(0);
2146
2148}

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 2261 of file geo_ops.c.

2262{
2263 LSEG *l1 = PG_GETARG_LSEG_P(0);
2264 LSEG *l2 = PG_GETARG_LSEG_P(1);
2265
2267}

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

◆ lseg_perp()

Datum lseg_perp ( PG_FUNCTION_ARGS  )

Definition at line 2273 of file geo_ops.c.

2274{
2275 LSEG *l1 = PG_GETARG_LSEG_P(0);
2276 LSEG *l2 = PG_GETARG_LSEG_P(1);
2277
2279}
static float8 lseg_invsl(LSEG *lseg)
Definition geo_ops.c:2228

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 2154 of file geo_ops.c.

2155{
2157 LSEG *lseg;
2158
2160
2161 lseg->p[0].x = pq_getmsgfloat8(buf);
2162 lseg->p[0].y = pq_getmsgfloat8(buf);
2163 lseg->p[1].x = pq_getmsgfloat8(buf);
2164 lseg->p[1].y = pq_getmsgfloat8(buf);
2165
2167}

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 2173 of file geo_ops.c.

2174{
2175 LSEG *ls = PG_GETARG_LSEG_P(0);
2177
2179 pq_sendfloat8(&buf, ls->p[0].x);
2180 pq_sendfloat8(&buf, ls->p[0].y);
2181 pq_sendfloat8(&buf, ls->p[1].x);
2182 pq_sendfloat8(&buf, ls->p[1].y);
2184}

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 2218 of file geo_ops.c.

2219{
2220 return point_sl(&lseg->p[0], &lseg->p[1]);
2221}

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 2282 of file geo_ops.c.

2283{
2285
2286 PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));
2287}

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 3460 of file geo_ops.c.

3461{
3462 int i;
3463 float8 x1,
3464 y1,
3465 x2,
3466 y2;
3467
3468 Assert(poly->npts > 0);
3469
3470 x1 = x2 = poly->p[0].x;
3471 y2 = y1 = poly->p[0].y;
3472 for (i = 1; i < poly->npts; i++)
3473 {
3474 if (float8_lt(poly->p[i].x, x1))
3475 x1 = poly->p[i].x;
3476 if (float8_gt(poly->p[i].x, x2))
3477 x2 = poly->p[i].x;
3478 if (float8_lt(poly->p[i].y, y1))
3479 y1 = poly->p[i].y;
3480 if (float8_gt(poly->p[i].y, y2))
3481 y2 = poly->p[i].y;
3482 }
3483
3484 poly->boundbox.low.x = x1;
3485 poly->boundbox.high.x = x2;
3486 poly->boundbox.low.y = y1;
3487 poly->boundbox.high.y = y2;
3488}

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 3219 of file geo_ops.c.

3220{
3222 BOX *box = PG_GETARG_BOX_P(1);
3223
3225}

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 3177 of file geo_ops.c.

3178{
3180 LINE *line = PG_GETARG_LINE_P(1);
3181
3183}
static bool line_contain_point(LINE *line, Point *point)
Definition geo_ops.c:3169

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 3249 of file geo_ops.c.

3250{
3252 PATH *path = PG_GETARG_PATH_P(1);
3253 int i,
3254 n;
3255 float8 a,
3256 b;
3257
3258 /*-- OPEN --*/
3259 if (!path->closed)
3260 {
3261 n = path->npts - 1;
3262 a = point_dt(pt, &path->p[0], NULL);
3263 for (i = 0; i < n; i++)
3264 {
3265 b = point_dt(pt, &path->p[i + 1], NULL);
3266 if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1], NULL)))
3267 PG_RETURN_BOOL(true);
3268 a = b;
3269 }
3270 PG_RETURN_BOOL(false);
3271 }
3272
3273 /*-- CLOSED --*/
3274 PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
3275}

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 3199 of file geo_ops.c.

3200{
3203
3205}

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 3307 of file geo_ops.c.

3308{
3310 BOX *box = PG_GETARG_BOX_P(1);
3311
3313}
static bool box_contain_lseg(BOX *box, LSEG *lseg)
Definition geo_ops.c:3300

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 3284 of file geo_ops.c.

3285{
3287 LINE *line = PG_GETARG_LINE_P(1);
3288
3289 PG_RETURN_BOOL(line_contain_point(line, &lseg->p[0]) &&
3290 line_contain_point(line, &lseg->p[1]));
3291}

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:1619
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 4442 of file geo_ops.c.

4443{
4444 PATH *p1 = PG_GETARG_PATH_P(0);
4445 PATH *p2 = PG_GETARG_PATH_P(1);
4446 PATH *result;
4447 int size,
4448 base_size;
4449 int i;
4450
4451 if (p1->closed || p2->closed)
4453
4454 base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
4455 size = offsetof(PATH, p) + base_size;
4456
4457 /* Check for integer overflow */
4458 if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
4459 size <= base_size)
4460 ereport(ERROR,
4462 errmsg("too many points requested")));
4463
4464 result = (PATH *) palloc(size);
4465
4466 SET_VARSIZE(result, size);
4467 result->npts = (p1->npts + p2->npts);
4468 result->closed = p1->closed;
4469 /* prevent instability in unused pad bytes */
4470 result->dummy = 0;
4471
4472 for (i = 0; i < p1->npts; i++)
4473 {
4474 result->p[i].x = p1->p[i].x;
4475 result->p[i].y = p1->p[i].y;
4476 }
4477 for (i = 0; i < p2->npts; i++)
4478 {
4479 result->p[i + p1->npts].x = p2->p[i].x;
4480 result->p[i + p1->npts].y = p2->p[i].y;
4481 }
4482
4484}
#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 4491 of file geo_ops.c.

4492{
4493 PATH *path = PG_GETARG_PATH_P_COPY(0);
4495 int i;
4496
4497 for (i = 0; i < path->npts; i++)
4498 point_add_point(&path->p[i], &path->p[i], point, NULL);
4499
4500 PG_RETURN_PATH_P(path);
4501}
#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 1429 of file geo_ops.c.

1430{
1431 PATH *path = PG_GETARG_PATH_P(0);
1432 float8 area = 0.0;
1433 int i,
1434 j;
1435
1436 if (!path->closed)
1438
1439 for (i = 0; i < path->npts; i++)
1440 {
1441 j = (i + 1) % path->npts;
1442 area = float8_pl(area, float8_mul(path->p[i].x, path->p[j].y));
1443 area = float8_mi(area, float8_mul(path->p[i].y, path->p[j].x));
1444 }
1445
1446 PG_RETURN_FLOAT8(float8_div(fabs(area), 2.0));
1447}
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 1676 of file geo_ops.c.

1677{
1678 PATH *path = PG_GETARG_PATH_P_COPY(0);
1679
1680 path->closed = true;
1681
1682 PG_RETURN_PATH_P(path);
1683}

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 1781 of file geo_ops.c.

1782{
1783 PATH *p1 = PG_GETARG_PATH_P(0);
1784 PATH *p2 = PG_GETARG_PATH_P(1);
1785 float8 min = 0.0; /* initialize to keep compiler quiet */
1786 bool have_min = false;
1787 float8 tmp;
1788 int i,
1789 j;
1790 LSEG seg1,
1791 seg2;
1792
1793 for (i = 0; i < p1->npts; i++)
1794 {
1795 int iprev;
1796
1797 if (i > 0)
1798 iprev = i - 1;
1799 else
1800 {
1801 if (!p1->closed)
1802 continue;
1803 iprev = p1->npts - 1; /* include the closure segment */
1804 }
1805
1806 for (j = 0; j < p2->npts; j++)
1807 {
1808 int jprev;
1809
1810 if (j > 0)
1811 jprev = j - 1;
1812 else
1813 {
1814 if (!p2->closed)
1815 continue;
1816 jprev = p2->npts - 1; /* include the closure segment */
1817 }
1818
1819 statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1820 statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1821
1822 tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
1823 if (!have_min || float8_lt(tmp, min))
1824 {
1825 min = tmp;
1826 have_min = true;
1827 }
1828 }
1829 }
1830
1831 if (!have_min)
1833
1834 PG_RETURN_FLOAT8(min);
1835}

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 4534 of file geo_ops.c.

4535{
4536 PATH *path = PG_GETARG_PATH_P_COPY(0);
4538 int i;
4539
4540 for (i = 0; i < path->npts; i++)
4541 point_div_point(&path->p[i], &path->p[i], point);
4542
4543 PG_RETURN_PATH_P(path);
4544}

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 1451 of file geo_ops.c.

1452{
1453 char *str = PG_GETARG_CSTRING(0);
1454 Node *escontext = fcinfo->context;
1455 PATH *path;
1456 bool isopen;
1457 char *s;
1458 int npts;
1459 int size;
1460 int base_size;
1461 int depth = 0;
1462
1463 if ((npts = pair_count(str, ',')) <= 0)
1464 ereturn(escontext, (Datum) 0,
1466 errmsg("invalid input syntax for type %s: \"%s\"",
1467 "path", str)));
1468
1469 s = str;
1470 while (isspace((unsigned char) *s))
1471 s++;
1472
1473 /* skip single leading paren */
1474 if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
1475 {
1476 s++;
1477 depth++;
1478 }
1479
1480 base_size = sizeof(path->p[0]) * npts;
1481 size = offsetof(PATH, p) + base_size;
1482
1483 /* Check for integer overflow */
1484 if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
1485 ereturn(escontext, (Datum) 0,
1487 errmsg("too many points requested")));
1488
1489 path = (PATH *) palloc(size);
1490
1491 SET_VARSIZE(path, size);
1492 path->npts = npts;
1493
1494 if (!path_decode(s, true, npts, &(path->p[0]), &isopen, &s, "path", str,
1495 escontext))
1497
1498 if (depth >= 1)
1499 {
1500 if (*s++ != RDELIM)
1501 ereturn(escontext, (Datum) 0,
1503 errmsg("invalid input syntax for type %s: \"%s\"",
1504 "path", str)));
1505 while (isspace((unsigned char) *s))
1506 s++;
1507 }
1508 if (*s != '\0')
1509 ereturn(escontext, (Datum) 0,
1511 errmsg("invalid input syntax for type %s: \"%s\"",
1512 "path", str)));
1513
1514 path->closed = (!isopen);
1515 /* prevent instability in unused pad bytes */
1516 path->dummy = 0;
1517
1518 PG_RETURN_PATH_P(path);
1519}
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 1703 of file geo_ops.c.

1704{
1705 PATH *p1 = PG_GETARG_PATH_P(0);
1706 PATH *p2 = PG_GETARG_PATH_P(1);
1707 BOX b1,
1708 b2;
1709 int i,
1710 j;
1711 LSEG seg1,
1712 seg2;
1713
1714 Assert(p1->npts > 0 && p2->npts > 0);
1715
1716 b1.high.x = b1.low.x = p1->p[0].x;
1717 b1.high.y = b1.low.y = p1->p[0].y;
1718 for (i = 1; i < p1->npts; i++)
1719 {
1720 b1.high.x = float8_max(p1->p[i].x, b1.high.x);
1721 b1.high.y = float8_max(p1->p[i].y, b1.high.y);
1722 b1.low.x = float8_min(p1->p[i].x, b1.low.x);
1723 b1.low.y = float8_min(p1->p[i].y, b1.low.y);
1724 }
1725 b2.high.x = b2.low.x = p2->p[0].x;
1726 b2.high.y = b2.low.y = p2->p[0].y;
1727 for (i = 1; i < p2->npts; i++)
1728 {
1729 b2.high.x = float8_max(p2->p[i].x, b2.high.x);
1730 b2.high.y = float8_max(p2->p[i].y, b2.high.y);
1731 b2.low.x = float8_min(p2->p[i].x, b2.low.x);
1732 b2.low.y = float8_min(p2->p[i].y, b2.low.y);
1733 }
1734 if (!box_ov(&b1, &b2))
1735 PG_RETURN_BOOL(false);
1736
1737 /* pairwise check lseg intersections */
1738 for (i = 0; i < p1->npts; i++)
1739 {
1740 int iprev;
1741
1742 if (i > 0)
1743 iprev = i - 1;
1744 else
1745 {
1746 if (!p1->closed)
1747 continue;
1748 iprev = p1->npts - 1; /* include the closure segment */
1749 }
1750
1751 for (j = 0; j < p2->npts; j++)
1752 {
1753 int jprev;
1754
1755 if (j > 0)
1756 jprev = j - 1;
1757 else
1758 {
1759 if (!p2->closed)
1760 continue;
1761 jprev = p2->npts - 1; /* include the closure segment */
1762 }
1763
1764 statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1765 statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1767 PG_RETURN_BOOL(true);
1768 }
1769 }
1770
1771 /* if we dropped through, no two segs intersected */
1772 PG_RETURN_BOOL(false);
1773}

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 1651 of file geo_ops.c.

1652{
1653 PATH *path = PG_GETARG_PATH_P(0);
1654
1655 PG_RETURN_BOOL(path->closed);
1656}

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_isopen()

Datum path_isopen ( PG_FUNCTION_ARGS  )

Definition at line 1659 of file geo_ops.c.

1660{
1661 PATH *path = PG_GETARG_PATH_P(0);
1662
1663 PG_RETURN_BOOL(!path->closed);
1664}

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_length()

Datum path_length ( PG_FUNCTION_ARGS  )

Definition at line 1843 of file geo_ops.c.

1844{
1845 PATH *path = PG_GETARG_PATH_P(0);
1846 float8 result = 0.0;
1847 int i;
1848
1849 for (i = 0; i < path->npts; i++)
1850 {
1851 int iprev;
1852
1853 if (i > 0)
1854 iprev = i - 1;
1855 else
1856 {
1857 if (!path->closed)
1858 continue;
1859 iprev = path->npts - 1; /* include the closure segment */
1860 }
1861
1862 result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i], NULL));
1863 }
1864
1866}

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 4521 of file geo_ops.c.

4522{
4523 PATH *path = PG_GETARG_PATH_P_COPY(0);
4525 int i;
4526
4527 for (i = 0; i < path->npts; i++)
4528 point_mul_point(&path->p[i], &path->p[i], point);
4529
4530 PG_RETURN_PATH_P(path);
4531}

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 1620 of file geo_ops.c.

1621{
1622 PATH *p1 = PG_GETARG_PATH_P(0);
1623 PATH *p2 = PG_GETARG_PATH_P(1);
1624
1625 PG_RETURN_BOOL(p1->npts == p2->npts);
1626}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_ge()

Datum path_n_ge ( PG_FUNCTION_ARGS  )

Definition at line 1638 of file geo_ops.c.

1639{
1640 PATH *p1 = PG_GETARG_PATH_P(0);
1641 PATH *p2 = PG_GETARG_PATH_P(1);
1642
1643 PG_RETURN_BOOL(p1->npts >= p2->npts);
1644}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_gt()

Datum path_n_gt ( PG_FUNCTION_ARGS  )

Definition at line 1611 of file geo_ops.c.

1612{
1613 PATH *p1 = PG_GETARG_PATH_P(0);
1614 PATH *p2 = PG_GETARG_PATH_P(1);
1615
1616 PG_RETURN_BOOL(p1->npts > p2->npts);
1617}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_le()

Datum path_n_le ( PG_FUNCTION_ARGS  )

Definition at line 1629 of file geo_ops.c.

1630{
1631 PATH *p1 = PG_GETARG_PATH_P(0);
1632 PATH *p2 = PG_GETARG_PATH_P(1);
1633
1634 PG_RETURN_BOOL(p1->npts <= p2->npts);
1635}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_lt()

Datum path_n_lt ( PG_FUNCTION_ARGS  )

Definition at line 1602 of file geo_ops.c.

1603{
1604 PATH *p1 = PG_GETARG_PATH_P(0);
1605 PATH *p2 = PG_GETARG_PATH_P(1);
1606
1607 PG_RETURN_BOOL(p1->npts < p2->npts);
1608}

References fb(), PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_npoints()

Datum path_npoints ( PG_FUNCTION_ARGS  )

Definition at line 1667 of file geo_ops.c.

1668{
1669 PATH *path = PG_GETARG_PATH_P(0);
1670
1671 PG_RETURN_INT32(path->npts);
1672}
#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 1686 of file geo_ops.c.

1687{
1688 PATH *path = PG_GETARG_PATH_P_COPY(0);
1689
1690 path->closed = false;
1691
1692 PG_RETURN_PATH_P(path);
1693}

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

◆ path_out()

Datum path_out ( PG_FUNCTION_ARGS  )

Definition at line 1523 of file geo_ops.c.

1524{
1525 PATH *path = PG_GETARG_PATH_P(0);
1526
1527 PG_RETURN_CSTRING(path_encode(path->closed ? PATH_CLOSED : PATH_OPEN, path->npts, path->p));
1528}

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 4548 of file geo_ops.c.

4549{
4550 PATH *path = PG_GETARG_PATH_P(0);
4551 POLYGON *poly;
4552 int size;
4553 int i;
4554
4555 /* This is not very consistent --- other similar cases return NULL ... */
4556 if (!path->closed)
4557 ereturn(fcinfo->context, (Datum) 0,
4559 errmsg("open path cannot be converted to polygon")));
4560
4561 /*
4562 * Never overflows: the old size fit in MaxAllocSize, and the new size is
4563 * just a small constant larger.
4564 */
4565 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * path->npts;
4566 poly = (POLYGON *) palloc(size);
4567
4568 SET_VARSIZE(poly, size);
4569 poly->npts = path->npts;
4570
4571 for (i = 0; i < path->npts; i++)
4572 {
4573 poly->p[i].x = path->p[i].x;
4574 poly->p[i].y = path->p[i].y;
4575 }
4576
4578
4580}

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 1537 of file geo_ops.c.

1538{
1540 PATH *path;
1541 int closed;
1542 int32 npts;
1543 int32 i;
1544 int size;
1545
1546 closed = pq_getmsgbyte(buf);
1547 npts = pq_getmsgint(buf, sizeof(int32));
1548 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p)) / sizeof(Point)))
1549 ereport(ERROR,
1551 errmsg("invalid number of points in external \"path\" value")));
1552
1553 size = offsetof(PATH, p) + sizeof(path->p[0]) * npts;
1554 path = (PATH *) palloc(size);
1555
1556 SET_VARSIZE(path, size);
1557 path->npts = npts;
1558 path->closed = (closed ? 1 : 0);
1559 /* prevent instability in unused pad bytes */
1560 path->dummy = 0;
1561
1562 for (i = 0; i < npts; i++)
1563 {
1564 path->p[i].x = pq_getmsgfloat8(buf);
1565 path->p[i].y = pq_getmsgfloat8(buf);
1566 }
1567
1568 PG_RETURN_PATH_P(path);
1569}
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 1575 of file geo_ops.c.

1576{
1577 PATH *path = PG_GETARG_PATH_P(0);
1579 int32 i;
1580
1582 pq_sendbyte(&buf, path->closed ? 1 : 0);
1583 pq_sendint32(&buf, path->npts);
1584 for (i = 0; i < path->npts; i++)
1585 {
1586 pq_sendfloat8(&buf, path->p[i].x);
1587 pq_sendfloat8(&buf, path->p[i].y);
1588 }
1590}
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 4504 of file geo_ops.c.

4505{
4506 PATH *path = PG_GETARG_PATH_P_COPY(0);
4508 int i;
4509
4510 for (i = 0; i < path->npts; i++)
4511 point_sub_point(&path->p[i], &path->p[i], point);
4512
4513 PG_RETURN_PATH_P(path);
4514}

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 5676 of file geo_ops.c.

5677{
5678 int i,
5679 ii,
5680 j;
5681
5682 /* find match for first point */
5683 for (i = 0; i < npts; i++)
5684 {
5685 if (point_eq_point(&p2[i], &p1[0]))
5686 {
5687
5688 /* match found? then look forward through remaining points */
5689 for (ii = 1, j = i + 1; ii < npts; ii++, j++)
5690 {
5691 if (j >= npts)
5692 j = 0;
5693 if (!point_eq_point(&p2[j], &p1[ii]))
5694 break;
5695 }
5696 if (ii == npts)
5697 return true;
5698
5699 /* match not found forwards? then look backwards */
5700 for (ii = 1, j = i - 1; ii < npts; ii++, j--)
5701 {
5702 if (j < 0)
5703 j = (npts - 1);
5704 if (!point_eq_point(&p2[j], &p1[ii]))
5705 break;
5706 }
5707 if (ii == npts)
5708 return true;
5709 }
5710 }
5711
5712 return false;
5713}

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

Referenced by poly_same().

◆ point_above()

Datum point_above ( PG_FUNCTION_ARGS  )

Definition at line 1970 of file geo_ops.c.

1971{
1974
1975 PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
1976}

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 4212 of file geo_ops.c.

4213{
4216 Point *result;
4217
4219
4221
4223}

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 4195 of file geo_ops.c.

4196{
4197 float8 x;
4198 float8 y;
4199
4200 x = float8_pl_safe(pt1->x, pt2->x, escontext);
4201 if (SOFT_ERROR_OCCURRED(escontext))
4202 return;
4203
4204 y = float8_pl_safe(pt1->y, pt2->y, escontext);
4205 if (SOFT_ERROR_OCCURRED(escontext))
4206 return;
4207
4209}

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 1979 of file geo_ops.c.

1980{
1983
1984 PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
1985}

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 4395 of file geo_ops.c.

4396{
4398 BOX *box;
4399
4401
4402 box->high.x = pt->x;
4403 box->low.x = pt->x;
4404 box->high.y = pt->y;
4405 box->low.y = pt->y;
4406
4408}

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 1935 of file geo_ops.c.

1936{
1937 result->x = x;
1938 result->y = y;
1939}

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 2044 of file geo_ops.c.

2045{
2048
2050}

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 4289 of file geo_ops.c.

4290{
4293 Point *result;
4294
4296
4298
4300}

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 4275 of file geo_ops.c.

4276{
4277 float8 div;
4278
4279 div = float8_pl(float8_mul(pt2->x, pt2->x), float8_mul(pt2->y, pt2->y));
4280
4283 float8_mul(pt1->y, pt2->y)), div),
4285 float8_mul(pt1->x, pt2->y)), div));
4286}

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 2006 of file geo_ops.c.

2007{
2010
2012}

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 2028 of file geo_ops.c.

2029{
2030 /* If any NaNs are involved, insist on exact equality */
2031 if (unlikely(isnan(pt1->x) || isnan(pt1->y) ||
2032 isnan(pt2->x) || isnan(pt2->y)))
2033 return (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y));
2034
2035 return (FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
2036}

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 1997 of file geo_ops.c.

1998{
2001
2002 PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));
2003}

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 1882 of file geo_ops.c.

1883{
1884 char *str = PG_GETARG_CSTRING(0);
1886
1887 /* Ignore failure from pair_decode, since our return value won't matter */
1888 pair_decode(str, &point->x, &point->y, NULL, "point", str, fcinfo->context);
1890}

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 5558 of file geo_ops.c.

5559{
5560 float8 x0,
5561 y0;
5562 float8 prev_x,
5563 prev_y;
5564 int i = 0;
5565 float8 x,
5566 y;
5567 int cross,
5568 total_cross = 0;
5569
5570 Assert(npts > 0);
5571
5572 /* compute first polygon point relative to single point */
5573 x0 = float8_mi(plist[0].x, p->x);
5574 y0 = float8_mi(plist[0].y, p->y);
5575
5576 prev_x = x0;
5577 prev_y = y0;
5578 /* loop over polygon points and aggregate total_cross */
5579 for (i = 1; i < npts; i++)
5580 {
5581 /* compute next polygon point relative to single point */
5582 x = float8_mi(plist[i].x, p->x);
5583 y = float8_mi(plist[i].y, p->y);
5584
5585 /* compute previous to current point crossing */
5587 return 2;
5588 total_cross += cross;
5589
5590 prev_x = x;
5591 prev_y = y;
5592 }
5593
5594 /* now do the first point */
5596 return 2;
5597 total_cross += cross;
5598
5599 if (total_cross != 0)
5600 return 1;
5601 return 0;
5602}
static int lseg_crossing(float8 x, float8 y, float8 prev_x, float8 prev_y)
Definition geo_ops.c:5616

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 2101 of file geo_ops.c.

2102{
2103 if (FPeq(pt1->x, pt2->x))
2104 return 0.0;
2105 if (FPeq(pt1->y, pt2->y))
2106 return get_float8_infinity();
2107 return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y));
2108}

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 1952 of file geo_ops.c.

1953{
1956
1957 PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));
1958}

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 4260 of file geo_ops.c.

4261{
4264 Point *result;
4265
4267
4269
4271}

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 4250 of file geo_ops.c.

4251{
4253 float8_mi(float8_mul(pt1->x, pt2->x),
4254 float8_mul(pt1->y, pt2->y)),
4255 float8_pl(float8_mul(pt1->x, pt2->y),
4256 float8_mul(pt1->y, pt2->x)));
4257}

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 2015 of file geo_ops.c.

2016{
2019
2021}

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

◆ point_out()

Datum point_out ( PG_FUNCTION_ARGS  )

Definition at line 1893 of file geo_ops.c.

1894{
1896
1898}

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 1904 of file geo_ops.c.

1905{
1907 Point *point;
1908
1913}

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 1961 of file geo_ops.c.

1962{
1965
1966 PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));
1967}

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 2085 of file geo_ops.c.

2086{
2087 if (FPeq(pt1->x, pt2->x))
2088 return get_float8_infinity();
2089 if (FPeq(pt1->y, pt2->y))
2090 return 0.0;
2091 return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x));
2092}

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 2070 of file geo_ops.c.

2071{
2074
2076}

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

◆ point_sub()

Datum point_sub ( PG_FUNCTION_ARGS  )

Definition at line 4235 of file geo_ops.c.

4236{
4239 Point *result;
4240
4242
4244
4246}

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 4227 of file geo_ops.c.

4228{
4230 float8_mi(pt1->x, pt2->x),
4231 float8_mi(pt1->y, pt2->y));
4232}

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 1988 of file geo_ops.c.

1989{
1992
1993 PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));
1994}

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 4310 of file geo_ops.c.

4311{
4314 BOX *result;
4315
4317
4319
4321}

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 3755 of file geo_ops.c.

3756{
3759 bool result;
3760
3761 result = polya->boundbox.low.y > polyb->boundbox.high.y;
3762
3763 /*
3764 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3765 */
3768
3770}
#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 3709 of file geo_ops.c.

3710{
3713 bool result;
3714
3715 result = polya->boundbox.high.y < polyb->boundbox.low.y;
3716
3717 /*
3718 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3719 */
3722
3724}

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 4618 of file geo_ops.c.

4619{
4621 BOX *box;
4622
4624 *box = poly->boundbox;
4625
4627}

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

◆ poly_center()

Datum poly_center ( PG_FUNCTION_ARGS  )

Definition at line 4599 of file geo_ops.c.

4600{
4602 Point *result;
4603 CIRCLE circle;
4604
4606
4607 poly_to_circle(&circle, poly, fcinfo->context);
4608 if (SOFT_ERROR_OCCURRED(fcinfo->context))
4610
4611 *result = circle.center;
4612
4614}
static void poly_to_circle(CIRCLE *result, POLYGON *poly, Node *escontext)
Definition geo_ops.c:5480

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 5523 of file geo_ops.c.

5524{
5526 CIRCLE *result;
5527
5529
5530 poly_to_circle(result, poly, fcinfo->context);
5531 if (SOFT_ERROR_OCCURRED(fcinfo->context))
5533
5535}

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 4050 of file geo_ops.c.

4051{
4054 bool result;
4055
4057
4058 /*
4059 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
4060 */
4063
4065}
static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly)
Definition geo_ops.c:4022

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 4022 of file geo_ops.c.

4023{
4024 int i;
4025 LSEG s;
4026
4027 Assert(contains_poly->npts > 0 && contained_poly->npts > 0);
4028
4029 /*
4030 * Quick check to see if contained's bounding box is contained in
4031 * contains' bb.
4032 */
4033 if (!box_contain_box(&contains_poly->boundbox, &contained_poly->boundbox))
4034 return false;
4035
4036 s.p[0] = contained_poly->p[contained_poly->npts - 1];
4037
4038 for (i = 0; i < contained_poly->npts; i++)
4039 {
4040 s.p[1] = contained_poly->p[i];
4041 if (!lseg_inside_poly(s.p, s.p + 1, contains_poly, 0))
4042 return false;
4043 s.p[0] = s.p[1];
4044 }
4045
4046 return true;
4047}

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 4092 of file geo_ops.c.

4093{
4095 Point *p = PG_GETARG_POINT_P(1);
4096
4097 PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4098}

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 4072 of file geo_ops.c.

4073{
4076 bool result;
4077
4078 /* Just switch the arguments and pass it off to poly_contain */
4080
4081 /*
4082 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
4083 */
4086
4088}

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 4111 of file geo_ops.c.

4112{
4115 float8 min = 0.0; /* initialize to keep compiler quiet */
4116 bool have_min = false;
4117 float8 tmp;
4118 int i,
4119 j;
4120 LSEG seg1,
4121 seg2;
4122
4123 /*
4124 * Distance is zero if polygons overlap. We must check this because the
4125 * path distance will not give the right answer if one poly is entirely
4126 * within the other.
4127 */
4129 PG_RETURN_FLOAT8(0.0);
4130
4131 /*
4132 * When they don't overlap, the distance calculation is identical to that
4133 * for closed paths (i.e., we needn't care about the fact that polygons
4134 * include their contained areas). See path_distance().
4135 */
4136 for (i = 0; i < polya->npts; i++)
4137 {
4138 int iprev;
4139
4140 if (i > 0)
4141 iprev = i - 1;
4142 else
4143 iprev = polya->npts - 1;
4144
4145 for (j = 0; j < polyb->npts; j++)
4146 {
4147 int jprev;
4148
4149 if (j > 0)
4150 jprev = j - 1;
4151 else
4152 jprev = polyb->npts - 1;
4153
4154 statlseg_construct(&seg1, &polya->p[iprev], &polya->p[i]);
4155 statlseg_construct(&seg2, &polyb->p[jprev], &polyb->p[j]);
4156
4157 tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
4158 if (!have_min || float8_lt(tmp, min))
4159 {
4160 min = tmp;
4161 have_min = true;
4162 }
4163 }
4164 }
4165
4166 if (!have_min)
4168
4169 PG_RETURN_FLOAT8(min);
4170}
static bool poly_overlap_internal(POLYGON *polya, POLYGON *polyb)
Definition geo_ops.c:3828

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 3499 of file geo_ops.c.

3500{
3501 char *str = PG_GETARG_CSTRING(0);
3502 Node *escontext = fcinfo->context;
3503 POLYGON *poly;
3504 int npts;
3505 int size;
3506 int base_size;
3507 bool isopen;
3508
3509 if ((npts = pair_count(str, ',')) <= 0)
3510 ereturn(escontext, (Datum) 0,
3512 errmsg("invalid input syntax for type %s: \"%s\"",
3513 "polygon", str)));
3514
3515 base_size = sizeof(poly->p[0]) * npts;
3516 size = offsetof(POLYGON, p) + base_size;
3517
3518 /* Check for integer overflow */
3519 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
3520 ereturn(escontext, (Datum) 0,
3522 errmsg("too many points requested")));
3523
3524 poly = (POLYGON *) palloc0(size); /* zero any holes */
3525
3526 SET_VARSIZE(poly, size);
3527 poly->npts = npts;
3528
3529 if (!path_decode(str, false, npts, &(poly->p[0]), &isopen, NULL, "polygon",
3530 str, escontext))
3532
3534
3536}

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 3617 of file geo_ops.c.

3618{
3621 bool result;
3622
3623 result = polya->boundbox.high.x < polyb->boundbox.low.x;
3624
3625 /*
3626 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3627 */
3630
3632}

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 4590 of file geo_ops.c.

4591{
4593
4594 PG_RETURN_INT32(poly->npts);
4595}

References fb(), PG_GETARG_POLYGON_P, and PG_RETURN_INT32.

◆ poly_out()

Datum poly_out ( PG_FUNCTION_ARGS  )

Definition at line 3543 of file geo_ops.c.

3544{
3546
3548}

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 3778 of file geo_ops.c.

3779{
3782 bool result;
3783
3784 result = polya->boundbox.low.y >= polyb->boundbox.low.y;
3785
3786 /*
3787 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3788 */
3791
3793}

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 3732 of file geo_ops.c.

3733{
3736 bool result;
3737
3738 result = polya->boundbox.high.y <= polyb->boundbox.high.y;
3739
3740 /*
3741 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3742 */
3745
3747}

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 3885 of file geo_ops.c.

3886{
3889 bool result;
3890
3892
3893 /*
3894 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3895 */
3898
3900}

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 3828 of file geo_ops.c.

3829{
3830 bool result;
3831
3832 Assert(polya->npts > 0 && polyb->npts > 0);
3833
3834 /* Quick check by bounding box */
3835 result = box_ov(&polya->boundbox, &polyb->boundbox);
3836
3837 /*
3838 * Brute-force algorithm - try to find intersected edges, if so then
3839 * polygons are overlapped else check is one polygon inside other or not
3840 * by testing single point of them.
3841 */
3842 if (result)
3843 {
3844 int ia,
3845 ib;
3846 LSEG sa,
3847 sb;
3848
3849 /* Init first of polya's edge with last point */
3850 sa.p[0] = polya->p[polya->npts - 1];
3851 result = false;
3852
3853 for (ia = 0; ia < polya->npts && !result; ia++)
3854 {
3855 /* Second point of polya's edge is a current one */
3856 sa.p[1] = polya->p[ia];
3857
3858 /* Init first of polyb's edge with last point */
3859 sb.p[0] = polyb->p[polyb->npts - 1];
3860
3861 for (ib = 0; ib < polyb->npts && !result; ib++)
3862 {
3863 sb.p[1] = polyb->p[ib];
3865 sb.p[0] = sb.p[1];
3866 }
3867
3868 /*
3869 * move current endpoint to the first point of next edge
3870 */
3871 sa.p[0] = sa.p[1];
3872 }
3873
3874 if (!result)
3875 {
3876 result = (point_inside(polya->p, polyb->npts, polyb->p) ||
3877 point_inside(polyb->p, polya->npts, polya->p));
3878 }
3879 }
3880
3881 return result;
3882}

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 3640 of file geo_ops.c.

3641{
3644 bool result;
3645
3646 result = polya->boundbox.high.x <= polyb->boundbox.high.x;
3647
3648 /*
3649 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3650 */
3653
3655}

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 3686 of file geo_ops.c.

3687{
3690 bool result;
3691
3692 result = polya->boundbox.low.x >= polyb->boundbox.low.x;
3693
3694 /*
3695 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3696 */
3699
3701}

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 4664 of file geo_ops.c.

4665{
4667 PATH *path;
4668 int size;
4669 int i;
4670
4671 /*
4672 * Never overflows: the old size fit in MaxAllocSize, and the new size is
4673 * smaller by a small constant.
4674 */
4675 size = offsetof(PATH, p) + sizeof(path->p[0]) * poly->npts;
4676 path = (PATH *) palloc(size);
4677
4678 SET_VARSIZE(path, size);
4679 path->npts = poly->npts;
4680 path->closed = true;
4681 /* prevent instability in unused pad bytes */
4682 path->dummy = 0;
4683
4684 for (i = 0; i < poly->npts; i++)
4685 {
4686 path->p[i].x = poly->p[i].x;
4687 path->p[i].y = poly->p[i].y;
4688 }
4689
4690 PG_RETURN_PATH_P(path);
4691}

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 3559 of file geo_ops.c.

3560{
3562 POLYGON *poly;
3563 int32 npts;
3564 int32 i;
3565 int size;
3566
3567 npts = pq_getmsgint(buf, sizeof(int32));
3568 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p)) / sizeof(Point)))
3569 ereport(ERROR,
3571 errmsg("invalid number of points in external \"polygon\" value")));
3572
3573 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * npts;
3574 poly = (POLYGON *) palloc0(size); /* zero any holes */
3575
3576 SET_VARSIZE(poly, size);
3577 poly->npts = npts;
3578
3579 for (i = 0; i < npts; i++)
3580 {
3581 poly->p[i].x = pq_getmsgfloat8(buf);
3582 poly->p[i].y = pq_getmsgfloat8(buf);
3583 }
3584
3586
3588}

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 3663 of file geo_ops.c.

3664{
3667 bool result;
3668
3669 result = polya->boundbox.low.x > polyb->boundbox.high.x;
3670
3671 /*
3672 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3673 */
3676
3678}

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 3804 of file geo_ops.c.

3805{
3808 bool result;
3809
3810 if (polya->npts != polyb->npts)
3811 result = false;
3812 else
3813 result = plist_same(polya->npts, polya->p, polyb->p);
3814
3815 /*
3816 * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3817 */
3820
3822}
static bool plist_same(int npts, Point *p1, Point *p2)
Definition geo_ops.c:5676

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 3594 of file geo_ops.c.

3595{
3598 int32 i;
3599
3601 pq_sendint32(&buf, poly->npts);
3602 for (i = 0; i < poly->npts; i++)
3603 {
3604 pq_sendfloat8(&buf, poly->p[i].x);
3605 pq_sendfloat8(&buf, poly->p[i].y);
3606 }
3608}

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 5480 of file geo_ops.c.

5481{
5482 int i;
5483 float8 x;
5484
5485 Assert(poly->npts > 0);
5486
5487 result->center.x = 0;
5488 result->center.y = 0;
5489 result->radius = 0;
5490
5491 for (i = 0; i < poly->npts; i++)
5492 {
5493 point_add_point(&result->center, &result->center, &poly->p[i], escontext);
5494 if (SOFT_ERROR_OCCURRED(escontext))
5495 return;
5496 }
5497
5498 result->center.x = float8_div_safe(result->center.x, poly->npts, escontext);
5499 if (SOFT_ERROR_OCCURRED(escontext))
5500 return;
5501
5502 result->center.y = float8_div_safe(result->center.y, poly->npts, escontext);
5503 if (SOFT_ERROR_OCCURRED(escontext))
5504 return;
5505
5506 for (i = 0; i < poly->npts; i++)
5507 {
5508 x = point_dt(&poly->p[i], &result->center, escontext);
5509 if (SOFT_ERROR_OCCURRED(escontext))
5510 return;
5511
5512 result->radius = float8_pl_safe(result->radius, x, escontext);
5513 if (SOFT_ERROR_OCCURRED(escontext))
5514 return;
5515 }
5516
5517 result->radius = float8_div_safe(result->radius, poly->npts, escontext);
5518 if (SOFT_ERROR_OCCURRED(escontext))
5519 return;
5520}

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 5215 of file geo_ops.c.

5216{
5219 float8 d;
5220
5221 d = point_dt(&circle->center, point, NULL);
5223}

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 4101 of file geo_ops.c.

4102{
4103 Point *p = PG_GETARG_POINT_P(0);
4105
4106 PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4107}

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 2205 of file geo_ops.c.

2206{
2207 lseg->p[0].x = pt1->x;
2208 lseg->p[0].y = pt1->y;
2209 lseg->p[1].x = pt2->x;
2210 lseg->p[1].y = pt2->y;
2211}

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 3914 of file geo_ops.c.

3915{
3916 /* point a is on s, b is not */
3917 LSEG t;
3918
3919 t.p[0] = *a;
3920 t.p[1] = *b;
3921
3922 if (point_eq_point(a, s->p))
3923 {
3924 if (lseg_contain_point(&t, s->p + 1))
3925 return lseg_inside_poly(b, s->p + 1, poly, start);
3926 }
3927 else if (point_eq_point(a, s->p + 1))
3928 {
3929 if (lseg_contain_point(&t, s->p))
3930 return lseg_inside_poly(b, s->p, poly, start);
3931 }
3932 else if (lseg_contain_point(&t, s->p))
3933 {
3934 return lseg_inside_poly(b, s->p, poly, start);
3935 }
3936 else if (lseg_contain_point(&t, s->p + 1))
3937 {
3938 return lseg_inside_poly(b, s->p + 1, poly, start);
3939 }
3940
3941 return true; /* may be not true, but that will check later */
3942}

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

Referenced by lseg_inside_poly().