PostgreSQL Source Code  git master
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)
 
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)
 
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)
 
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 void poly_to_circle (CIRCLE *result, POLYGON *poly)
 
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 char * path_encode (enum path_delim path_delim, int npts, Point *pt)
 
static char * path_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 poly_circle (PG_FUNCTION_ARGS)
 
float8 pg_hypot (float8 x, float8 y)
 

Macro Definition Documentation

◆ DELIM

#define DELIM   ','

Definition at line 159 of file geo_ops.c.

◆ LDELIM

#define LDELIM   '('

Definition at line 157 of file geo_ops.c.

◆ LDELIM_C

#define LDELIM_C   '<'

Definition at line 162 of file geo_ops.c.

◆ LDELIM_EP

#define LDELIM_EP   '['

Definition at line 160 of file geo_ops.c.

◆ LDELIM_L

#define LDELIM_L   '{'

Definition at line 164 of file geo_ops.c.

◆ POINT_ON_POLYGON

#define POINT_ON_POLYGON   INT_MAX

Definition at line 5337 of file geo_ops.c.

◆ RDELIM

#define RDELIM   ')'

Definition at line 158 of file geo_ops.c.

◆ RDELIM_C

#define RDELIM_C   '>'

Definition at line 163 of file geo_ops.c.

◆ RDELIM_EP

#define RDELIM_EP   ']'

Definition at line 161 of file geo_ops.c.

◆ RDELIM_L

#define RDELIM_L   '}'

Definition at line 165 of file geo_ops.c.

Enumeration Type Documentation

◆ path_delim

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

659 {
660  BOX *box1 = PG_GETARG_BOX_P(0);
661  BOX *box2 = PG_GETARG_BOX_P(1);
662 
663  PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));
664 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_BOX_P(n)
Definition: geo_decls.h:243
static bool FPgt(double A, double B)
Definition: geo_decls.h:71
Definition: geo_decls.h:141
Point low
Definition: geo_decls.h:143
Point high
Definition: geo_decls.h:142
float8 y
Definition: geo_decls.h:99

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

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

732 {
733  BOX *box1 = PG_GETARG_BOX_P(0);
734  BOX *box2 = PG_GETARG_BOX_P(1);
735 
736  PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
737 }
static bool FPge(double A, double B)
Definition: geo_decls.h:77

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

◆ box_add()

Datum box_add ( PG_FUNCTION_ARGS  )

Definition at line 4231 of file geo_ops.c.

4232 {
4233  BOX *box = PG_GETARG_BOX_P(0);
4234  Point *p = PG_GETARG_POINT_P(1);
4235  BOX *result;
4236 
4237  result = (BOX *) palloc(sizeof(BOX));
4238 
4239  point_add_point(&result->high, &box->high, p);
4240  point_add_point(&result->low, &box->low, p);
4241 
4242  PG_RETURN_BOX_P(result);
4243 }
#define PG_GETARG_POINT_P(n)
Definition: geo_decls.h:185
#define PG_RETURN_BOX_P(x)
Definition: geo_decls.h:244
static void point_add_point(Point *result, Point *pt1, Point *pt2)
Definition: geo_ops.c:4111
void * palloc(Size size)
Definition: mcxt.c:1304

References BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, and point_add_point().

◆ box_ar()

static float8 box_ar ( BOX box)
static

Definition at line 863 of file geo_ops.c.

864 {
865  return float8_mul(box_wd(box), box_ht(box));
866 }
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:208
static float8 box_ht(BOX *box)
Definition: geo_ops.c:893
static float8 box_wd(BOX *box)
Definition: geo_ops.c:883

References box_ht(), box_wd(), 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 796 of file geo_ops.c.

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

References box_ar(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ box_below()

Datum box_below ( PG_FUNCTION_ARGS  )

Definition at line 635 of file geo_ops.c.

636 {
637  BOX *box1 = PG_GETARG_BOX_P(0);
638  BOX *box2 = PG_GETARG_BOX_P(1);
639 
640  PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));
641 }
static bool FPlt(double A, double B)
Definition: geo_decls.h:59

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

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

723 {
724  BOX *box1 = PG_GETARG_BOX_P(0);
725  BOX *box2 = PG_GETARG_BOX_P(1);
726 
727  PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
728 }
static bool FPle(double A, double B)
Definition: geo_decls.h:65

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

◆ box_center()

Datum box_center ( PG_FUNCTION_ARGS  )

Definition at line 849 of file geo_ops.c.

850 {
851  BOX *box = PG_GETARG_BOX_P(0);
852  Point *result = (Point *) palloc(sizeof(Point));
853 
854  box_cn(result, box);
855 
856  PG_RETURN_POINT_P(result);
857 }
#define PG_RETURN_POINT_P(x)
Definition: geo_decls.h:186
static void box_cn(Point *center, BOX *box)
Definition: geo_ops.c:872

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

◆ box_circle()

Datum box_circle ( PG_FUNCTION_ARGS  )

Definition at line 5208 of file geo_ops.c.

5209 {
5210  BOX *box = PG_GETARG_BOX_P(0);
5211  CIRCLE *circle;
5212 
5213  circle = (CIRCLE *) palloc(sizeof(CIRCLE));
5214 
5215  circle->center.x = float8_div(float8_pl(box->high.x, box->low.x), 2.0);
5216  circle->center.y = float8_div(float8_pl(box->high.y, box->low.y), 2.0);
5217 
5218  circle->radius = point_dt(&circle->center, &box->high);
5219 
5220  PG_RETURN_CIRCLE_P(circle);
5221 }
static float8 float8_pl(const float8 val1, const float8 val2)
Definition: float.h:158
static float8 float8_div(const float8 val1, const float8 val2)
Definition: float.h:238
#define PG_RETURN_CIRCLE_P(x)
Definition: geo_decls.h:276
static float8 point_dt(Point *pt1, Point *pt2)
Definition: geo_ops.c:2002
float8 radius
Definition: geo_decls.h:165
Point center
Definition: geo_decls.h:164
float8 x
Definition: geo_decls.h:98

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

◆ box_closept_lseg()

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

Definition at line 3013 of file geo_ops.c.

3014 {
3015  float8 dist,
3016  d;
3017  Point point,
3018  closept;
3019  LSEG bseg;
3020 
3021  if (box_interpt_lseg(result, box, lseg))
3022  return 0.0;
3023 
3024  /* pairwise check lseg distances */
3025  point.x = box->low.x;
3026  point.y = box->high.y;
3027  statlseg_construct(&bseg, &box->low, &point);
3028  dist = lseg_closept_lseg(result, &bseg, lseg);
3029 
3030  statlseg_construct(&bseg, &box->high, &point);
3031  d = lseg_closept_lseg(&closept, &bseg, lseg);
3032  if (float8_lt(d, dist))
3033  {
3034  dist = d;
3035  if (result != NULL)
3036  *result = closept;
3037  }
3038 
3039  point.x = box->high.x;
3040  point.y = box->low.y;
3041  statlseg_construct(&bseg, &box->low, &point);
3042  d = lseg_closept_lseg(&closept, &bseg, lseg);
3043  if (float8_lt(d, dist))
3044  {
3045  dist = d;
3046  if (result != NULL)
3047  *result = closept;
3048  }
3049 
3050  statlseg_construct(&bseg, &box->high, &point);
3051  d = lseg_closept_lseg(&closept, &bseg, lseg);
3052  if (float8_lt(d, dist))
3053  {
3054  dist = d;
3055  if (result != NULL)
3056  *result = closept;
3057  }
3058 
3059  return dist;
3060 }
double float8
Definition: c.h:617
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:292
static bool box_interpt_lseg(Point *result, BOX *box, LSEG *lseg)
Definition: geo_ops.c:3263
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2)
Definition: geo_ops.c:2142
static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
Definition: geo_ops.c:2810

References box_interpt_lseg(), float8_lt(), BOX::high, BOX::low, lseg_closept_lseg(), statlseg_construct(), Point::x, and Point::y.

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

2879 {
2880  float8 dist,
2881  d;
2882  Point point,
2883  closept;
2884  LSEG lseg;
2885 
2886  if (box_contain_point(box, pt))
2887  {
2888  if (result != NULL)
2889  *result = *pt;
2890 
2891  return 0.0;
2892  }
2893 
2894  /* pairwise check lseg distances */
2895  point.x = box->low.x;
2896  point.y = box->high.y;
2897  statlseg_construct(&lseg, &box->low, &point);
2898  dist = lseg_closept_point(result, &lseg, pt);
2899 
2900  statlseg_construct(&lseg, &box->high, &point);
2901  d = lseg_closept_point(&closept, &lseg, pt);
2902  if (float8_lt(d, dist))
2903  {
2904  dist = d;
2905  if (result != NULL)
2906  *result = closept;
2907  }
2908 
2909  point.x = box->high.x;
2910  point.y = box->low.y;
2911  statlseg_construct(&lseg, &box->low, &point);
2912  d = lseg_closept_point(&closept, &lseg, pt);
2913  if (float8_lt(d, dist))
2914  {
2915  dist = d;
2916  if (result != NULL)
2917  *result = closept;
2918  }
2919 
2920  statlseg_construct(&lseg, &box->high, &point);
2921  d = lseg_closept_point(&closept, &lseg, pt);
2922  if (float8_lt(d, dist))
2923  {
2924  dist = d;
2925  if (result != NULL)
2926  *result = closept;
2927  }
2928 
2929  return dist;
2930 }
static float8 lseg_closept_point(Point *result, LSEG *lseg, Point *pt)
Definition: geo_ops.c:2772
static bool box_contain_point(BOX *box, Point *point)
Definition: geo_ops.c:3130

References box_contain_point(), float8_lt(), BOX::high, BOX::low, lseg_closept_point(), statlseg_construct(), Point::x, and Point::y.

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

◆ box_cn()

static void box_cn ( Point center,
BOX box 
)
static

Definition at line 872 of file geo_ops.c.

873 {
874  center->x = float8_div(float8_pl(box->high.x, box->low.x), 2.0);
875  center->y = float8_div(float8_pl(box->high.y, box->low.y), 2.0);
876 }

References float8_div(), float8_pl(), BOX::high, BOX::low, Point::x, 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 518 of file geo_ops.c.

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

References float8_gt(), BOX::high, BOX::low, Point::x, and Point::y.

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

◆ box_contain()

Datum box_contain ( PG_FUNCTION_ARGS  )

Definition at line 692 of file geo_ops.c.

693 {
694  BOX *box1 = PG_GETARG_BOX_P(0);
695  BOX *box2 = PG_GETARG_BOX_P(1);
696 
697  PG_RETURN_BOOL(box_contain_box(box1, box2));
698 }
static bool box_contain_box(BOX *contains_box, BOX *contained_box)
Definition: geo_ops.c:704

References box_contain_box(), 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 704 of file geo_ops.c.

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

References FPge(), FPle(), BOX::high, BOX::low, Point::x, and Point::y.

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

3218 {
3219  return box_contain_point(box, &lseg->p[0]) &&
3220  box_contain_point(box, &lseg->p[1]);
3221 }
Point p[2]
Definition: geo_decls.h:108

References box_contain_point(), and LSEG::p.

Referenced by on_sb().

◆ box_contain_point()

static bool box_contain_point ( BOX box,
Point point 
)
static

Definition at line 3130 of file geo_ops.c.

3131 {
3132  return box->high.x >= point->x && box->low.x <= point->x &&
3133  box->high.y >= point->y && box->low.y <= point->y;
3134 }

References BOX::high, BOX::low, Point::x, and Point::y.

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  )

Definition at line 3146 of file geo_ops.c.

3147 {
3148  BOX *box = PG_GETARG_BOX_P(0);
3149  Point *pt = PG_GETARG_POINT_P(1);
3150 
3152 }

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

Referenced by spg_quad_inner_consistent(), and spg_quad_leaf_consistent().

◆ box_contained()

Datum box_contained ( PG_FUNCTION_ARGS  )

Definition at line 681 of file geo_ops.c.

682 {
683  BOX *box1 = PG_GETARG_BOX_P(0);
684  BOX *box2 = PG_GETARG_BOX_P(1);
685 
686  PG_RETURN_BOOL(box_contain_box(box2, box1));
687 }

References box_contain_box(), PG_GETARG_BOX_P, and PG_RETURN_BOOL.

Referenced by gist_box_leaf_consistent(), and spg_box_quad_leaf_consistent().

◆ box_diagonal()

Datum box_diagonal ( PG_FUNCTION_ARGS  )

Definition at line 933 of file geo_ops.c.

934 {
935  BOX *box = PG_GETARG_BOX_P(0);
936  LSEG *result = (LSEG *) palloc(sizeof(LSEG));
937 
938  statlseg_construct(result, &box->high, &box->low);
939 
940  PG_RETURN_LSEG_P(result);
941 }
#define PG_RETURN_LSEG_P(x)
Definition: geo_decls.h:199

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

◆ box_distance()

Datum box_distance ( PG_FUNCTION_ARGS  )

Definition at line 832 of file geo_ops.c.

833 {
834  BOX *box1 = PG_GETARG_BOX_P(0);
835  BOX *box2 = PG_GETARG_BOX_P(1);
836  Point a,
837  b;
838 
839  box_cn(&a, box1);
840  box_cn(&b, box2);
841 
843 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69

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

◆ box_div()

Datum box_div ( PG_FUNCTION_ARGS  )

Definition at line 4280 of file geo_ops.c.

4281 {
4282  BOX *box = PG_GETARG_BOX_P(0);
4283  Point *p = PG_GETARG_POINT_P(1);
4284  BOX *result;
4285  Point high,
4286  low;
4287 
4288  result = (BOX *) palloc(sizeof(BOX));
4289 
4290  point_div_point(&high, &box->high, p);
4291  point_div_point(&low, &box->low, p);
4292 
4293  box_construct(result, &high, &low);
4294 
4295  PG_RETURN_BOX_P(result);
4296 }
static void point_div_point(Point *result, Point *pt1, Point *pt2)
Definition: geo_ops.c:4182
static void box_construct(BOX *result, Point *pt1, Point *pt2)
Definition: geo_ops.c:518

References box_construct(), BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, and point_div_point().

◆ box_eq()

Datum box_eq ( PG_FUNCTION_ARGS  )

Definition at line 762 of file geo_ops.c.

763 {
764  BOX *box1 = PG_GETARG_BOX_P(0);
765  BOX *box2 = PG_GETARG_BOX_P(1);
766 
767  PG_RETURN_BOOL(FPeq(box_ar(box1), box_ar(box2)));
768 }
static bool FPeq(double A, double B)
Definition: geo_decls.h:47

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

◆ box_ge()

Datum box_ge ( PG_FUNCTION_ARGS  )

Definition at line 780 of file geo_ops.c.

781 {
782  BOX *box1 = PG_GETARG_BOX_P(0);
783  BOX *box2 = PG_GETARG_BOX_P(1);
784 
785  PG_RETURN_BOOL(FPge(box_ar(box1), box_ar(box2)));
786 }

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

◆ box_gt()

Datum box_gt ( PG_FUNCTION_ARGS  )

Definition at line 753 of file geo_ops.c.

754 {
755  BOX *box1 = PG_GETARG_BOX_P(0);
756  BOX *box2 = PG_GETARG_BOX_P(1);
757 
758  PG_RETURN_BOOL(FPgt(box_ar(box1), box_ar(box2)));
759 }

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

◆ box_height()

Datum box_height ( PG_FUNCTION_ARGS  )

Definition at line 820 of file geo_ops.c.

821 {
822  BOX *box = PG_GETARG_BOX_P(0);
823 
824  PG_RETURN_FLOAT8(box_ht(box));
825 }

References box_ht(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ box_ht()

static float8 box_ht ( BOX box)
static

Definition at line 893 of file geo_ops.c.

894 {
895  return float8_mi(box->high.y, box->low.y);
896 }
static float8 float8_mi(const float8 val1, const float8 val2)
Definition: float.h:182

References float8_mi(), BOX::high, BOX::low, and Point::y.

Referenced by box_ar(), and box_height().

◆ box_in()

Datum box_in ( PG_FUNCTION_ARGS  )

Definition at line 422 of file geo_ops.c.

423 {
424  char *str = PG_GETARG_CSTRING(0);
425  Node *escontext = fcinfo->context;
426  BOX *box = (BOX *) palloc(sizeof(BOX));
427  bool isopen;
428  float8 x,
429  y;
430 
431  if (!path_decode(str, false, 2, &(box->high), &isopen, NULL, "box", str,
432  escontext))
433  PG_RETURN_NULL();
434 
435  /* reorder corners if necessary... */
436  if (float8_lt(box->high.x, box->low.x))
437  {
438  x = box->high.x;
439  box->high.x = box->low.x;
440  box->low.x = x;
441  }
442  if (float8_lt(box->high.y, box->low.y))
443  {
444  y = box->high.y;
445  box->high.y = box->low.y;
446  box->low.y = y;
447  }
448 
449  PG_RETURN_BOX_P(box);
450 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
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:266
int y
Definition: isn.c:72
int x
Definition: isn.c:71
Definition: nodes.h:129

References float8_lt(), BOX::high, BOX::low, palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_BOX_P, PG_RETURN_NULL, generate_unaccent_rules::str, x, Point::x, y, and Point::y.

◆ box_interpt_lseg()

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

Definition at line 3263 of file geo_ops.c.

3264 {
3265  BOX lbox;
3266  LSEG bseg;
3267  Point point;
3268 
3269  lbox.low.x = float8_min(lseg->p[0].x, lseg->p[1].x);
3270  lbox.low.y = float8_min(lseg->p[0].y, lseg->p[1].y);
3271  lbox.high.x = float8_max(lseg->p[0].x, lseg->p[1].x);
3272  lbox.high.y = float8_max(lseg->p[0].y, lseg->p[1].y);
3273 
3274  /* nothing close to overlap? then not going to intersect */
3275  if (!box_ov(&lbox, box))
3276  return false;
3277 
3278  if (result != NULL)
3279  {
3280  box_cn(&point, box);
3281  lseg_closept_point(result, lseg, &point);
3282  }
3283 
3284  /* an endpoint of segment is inside box? then clearly intersects */
3285  if (box_contain_point(box, &lseg->p[0]) ||
3286  box_contain_point(box, &lseg->p[1]))
3287  return true;
3288 
3289  /* pairwise check lseg intersections */
3290  point.x = box->low.x;
3291  point.y = box->high.y;
3292  statlseg_construct(&bseg, &box->low, &point);
3293  if (lseg_interpt_lseg(NULL, &bseg, lseg))
3294  return true;
3295 
3296  statlseg_construct(&bseg, &box->high, &point);
3297  if (lseg_interpt_lseg(NULL, &bseg, lseg))
3298  return true;
3299 
3300  point.x = box->high.x;
3301  point.y = box->low.y;
3302  statlseg_construct(&bseg, &box->low, &point);
3303  if (lseg_interpt_lseg(NULL, &bseg, lseg))
3304  return true;
3305 
3306  statlseg_construct(&bseg, &box->high, &point);
3307  if (lseg_interpt_lseg(NULL, &bseg, lseg))
3308  return true;
3309 
3310  /* if we dropped through, no two segs intersected */
3311  return false;
3312 }
static float8 float8_min(const float8 val1, const float8 val2)
Definition: float.h:340
static float8 float8_max(const float8 val1, const float8 val2)
Definition: float.h:352
static bool box_ov(BOX *box1, BOX *box2)
Definition: geo_ops.c:572
static bool lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2)
Definition: geo_ops.c:2338

References box_cn(), box_contain_point(), box_ov(), float8_max(), float8_min(), BOX::high, BOX::low, lseg_closept_point(), lseg_interpt_lseg(), LSEG::p, statlseg_construct(), Point::x, and Point::y.

Referenced by box_closept_lseg(), and inter_sb().

◆ box_intersect()

Datum box_intersect ( PG_FUNCTION_ARGS  )

Definition at line 908 of file geo_ops.c.

909 {
910  BOX *box1 = PG_GETARG_BOX_P(0);
911  BOX *box2 = PG_GETARG_BOX_P(1);
912  BOX *result;
913 
914  if (!box_ov(box1, box2))
915  PG_RETURN_NULL();
916 
917  result = (BOX *) palloc(sizeof(BOX));
918 
919  result->high.x = float8_min(box1->high.x, box2->high.x);
920  result->low.x = float8_max(box1->low.x, box2->low.x);
921  result->high.y = float8_min(box1->high.y, box2->high.y);
922  result->low.y = float8_max(box1->low.y, box2->low.y);
923 
924  PG_RETURN_BOX_P(result);
925 }

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

◆ box_le()

Datum box_le ( PG_FUNCTION_ARGS  )

Definition at line 771 of file geo_ops.c.

772 {
773  BOX *box1 = PG_GETARG_BOX_P(0);
774  BOX *box2 = PG_GETARG_BOX_P(1);
775 
776  PG_RETURN_BOOL(FPle(box_ar(box1), box_ar(box2)));
777 }

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

◆ box_left()

Datum box_left ( PG_FUNCTION_ARGS  )

Definition at line 583 of file geo_ops.c.

584 {
585  BOX *box1 = PG_GETARG_BOX_P(0);
586  BOX *box2 = PG_GETARG_BOX_P(1);
587 
588  PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x));
589 }

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

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

745 {
746  BOX *box1 = PG_GETARG_BOX_P(0);
747  BOX *box2 = PG_GETARG_BOX_P(1);
748 
749  PG_RETURN_BOOL(FPlt(box_ar(box1), box_ar(box2)));
750 }

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

◆ box_mul()

Datum box_mul ( PG_FUNCTION_ARGS  )

Definition at line 4261 of file geo_ops.c.

4262 {
4263  BOX *box = PG_GETARG_BOX_P(0);
4264  Point *p = PG_GETARG_POINT_P(1);
4265  BOX *result;
4266  Point high,
4267  low;
4268 
4269  result = (BOX *) palloc(sizeof(BOX));
4270 
4271  point_mul_point(&high, &box->high, p);
4272  point_mul_point(&low, &box->low, p);
4273 
4274  box_construct(result, &high, &low);
4275 
4276  PG_RETURN_BOX_P(result);
4277 }
static void point_mul_point(Point *result, Point *pt1, Point *pt2)
Definition: geo_ops.c:4157

References box_construct(), BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, and point_mul_point().

◆ box_out()

Datum box_out ( PG_FUNCTION_ARGS  )

Definition at line 455 of file geo_ops.c.

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

References BOX::high, 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 572 of file geo_ops.c.

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

References FPle(), BOX::high, BOX::low, Point::x, and Point::y.

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

671 {
672  BOX *box1 = PG_GETARG_BOX_P(0);
673  BOX *box2 = PG_GETARG_BOX_P(1);
674 
675  PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));
676 }

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

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

648 {
649  BOX *box1 = PG_GETARG_BOX_P(0);
650  BOX *box2 = PG_GETARG_BOX_P(1);
651 
652  PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));
653 }

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

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

◆ box_overlap()

Datum box_overlap ( PG_FUNCTION_ARGS  )

Definition at line 563 of file geo_ops.c.

564 {
565  BOX *box1 = PG_GETARG_BOX_P(0);
566  BOX *box2 = PG_GETARG_BOX_P(1);
567 
568  PG_RETURN_BOOL(box_ov(box1, box2));
569 }

References box_ov(), PG_GETARG_BOX_P, and PG_RETURN_BOOL.

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

◆ box_overleft()

Datum box_overleft ( PG_FUNCTION_ARGS  )

Definition at line 598 of file geo_ops.c.

599 {
600  BOX *box1 = PG_GETARG_BOX_P(0);
601  BOX *box2 = PG_GETARG_BOX_P(1);
602 
603  PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x));
604 }

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

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

625 {
626  BOX *box1 = PG_GETARG_BOX_P(0);
627  BOX *box2 = PG_GETARG_BOX_P(1);
628 
629  PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));
630 }

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

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

4536 {
4537  BOX *box = PG_GETARG_BOX_P(0);
4538  POLYGON *poly;
4539  int size;
4540 
4541  /* map four corners of the box to a polygon */
4542  size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * 4;
4543  poly = (POLYGON *) palloc(size);
4544 
4545  SET_VARSIZE(poly, size);
4546  poly->npts = 4;
4547 
4548  poly->p[0].x = box->low.x;
4549  poly->p[0].y = box->low.y;
4550  poly->p[1].x = box->low.x;
4551  poly->p[1].y = box->high.y;
4552  poly->p[2].x = box->high.x;
4553  poly->p[2].y = box->high.y;
4554  poly->p[3].x = box->high.x;
4555  poly->p[3].y = box->low.y;
4556 
4557  box_construct(&poly->boundbox, &box->high, &box->low);
4558 
4559  PG_RETURN_POLYGON_P(poly);
4560 }
#define PG_RETURN_POLYGON_P(x)
Definition: geo_decls.h:263
static pg_noinline void Size size
Definition: slab.c:607
Point p[FLEXIBLE_ARRAY_MEMBER]
Definition: geo_decls.h:156
int32 npts
Definition: geo_decls.h:154
BOX boundbox
Definition: geo_decls.h:155
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

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

◆ box_recv()

Datum box_recv ( PG_FUNCTION_ARGS  )

Definition at line 466 of file geo_ops.c.

467 {
469  BOX *box;
470  float8 x,
471  y;
472 
473  box = (BOX *) palloc(sizeof(BOX));
474 
475  box->high.x = pq_getmsgfloat8(buf);
476  box->high.y = pq_getmsgfloat8(buf);
477  box->low.x = pq_getmsgfloat8(buf);
478  box->low.y = pq_getmsgfloat8(buf);
479 
480  /* reorder corners if necessary... */
481  if (float8_lt(box->high.x, box->low.x))
482  {
483  x = box->high.x;
484  box->high.x = box->low.x;
485  box->low.x = x;
486  }
487  if (float8_lt(box->high.y, box->low.y))
488  {
489  y = box->high.y;
490  box->high.y = box->low.y;
491  box->low.y = y;
492  }
493 
494  PG_RETURN_BOX_P(box);
495 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
static char * buf
Definition: pg_test_fsync.c:73
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:488
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

◆ box_right()

Datum box_right ( PG_FUNCTION_ARGS  )

Definition at line 609 of file geo_ops.c.

610 {
611  BOX *box1 = PG_GETARG_BOX_P(0);
612  BOX *box2 = PG_GETARG_BOX_P(1);
613 
614  PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));
615 }

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

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

552 {
553  BOX *box1 = PG_GETARG_BOX_P(0);
554  BOX *box2 = PG_GETARG_BOX_P(1);
555 
556  PG_RETURN_BOOL(point_eq_point(&box1->high, &box2->high) &&
557  point_eq_point(&box1->low, &box2->low));
558 }
static bool point_eq_point(Point *pt1, Point *pt2)
Definition: geo_ops.c:1977

References BOX::high, BOX::low, 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 501 of file geo_ops.c.

502 {
503  BOX *box = PG_GETARG_BOX_P(0);
505 
507  pq_sendfloat8(&buf, box->high.x);
508  pq_sendfloat8(&buf, box->high.y);
509  pq_sendfloat8(&buf, box->low.x);
510  pq_sendfloat8(&buf, box->low.y);
512 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:276

References buf, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), Point::x, and Point::y.

◆ box_sub()

Datum box_sub ( PG_FUNCTION_ARGS  )

Definition at line 4246 of file geo_ops.c.

4247 {
4248  BOX *box = PG_GETARG_BOX_P(0);
4249  Point *p = PG_GETARG_POINT_P(1);
4250  BOX *result;
4251 
4252  result = (BOX *) palloc(sizeof(BOX));
4253 
4254  point_sub_point(&result->high, &box->high, p);
4255  point_sub_point(&result->low, &box->low, p);
4256 
4257  PG_RETURN_BOX_P(result);
4258 }
static void point_sub_point(Point *result, Point *pt1, Point *pt2)
Definition: geo_ops.c:4134

References BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_BOX_P, and point_sub_point().

◆ box_wd()

static float8 box_wd ( BOX box)
static

Definition at line 883 of file geo_ops.c.

884 {
885  return float8_mi(box->high.x, box->low.x);
886 }

References float8_mi(), BOX::high, BOX::low, and Point::x.

Referenced by box_ar(), and box_width().

◆ box_width()

Datum box_width ( PG_FUNCTION_ARGS  )

Definition at line 808 of file geo_ops.c.

809 {
810  BOX *box = PG_GETARG_BOX_P(0);
811 
812  PG_RETURN_FLOAT8(box_wd(box));
813 }

References box_wd(), PG_GETARG_BOX_P, and PG_RETURN_FLOAT8.

◆ boxes_bound_box()

Datum boxes_bound_box ( PG_FUNCTION_ARGS  )

Definition at line 4321 of file geo_ops.c.

4322 {
4323  BOX *box1 = PG_GETARG_BOX_P(0),
4324  *box2 = PG_GETARG_BOX_P(1),
4325  *container;
4326 
4327  container = (BOX *) palloc(sizeof(BOX));
4328 
4329  container->high.x = float8_max(box1->high.x, box2->high.x);
4330  container->low.x = float8_min(box1->low.x, box2->low.x);
4331  container->high.y = float8_max(box1->high.y, box2->high.y);
4332  container->low.y = float8_min(box1->low.y, box2->low.y);
4333 
4334  PG_RETURN_BOX_P(container);
4335 }

References float8_max(), float8_min(), BOX::high, BOX::low, palloc(), PG_GETARG_BOX_P, PG_RETURN_BOX_P, Point::x, and Point::y.

◆ circle_above()

Datum circle_above ( PG_FUNCTION_ARGS  )

Definition at line 4863 of file geo_ops.c.

4864 {
4865  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4866  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4867 
4868  PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.y, circle1->radius),
4869  float8_pl(circle2->center.y, circle2->radius)));
4870 }
#define PG_GETARG_CIRCLE_P(n)
Definition: geo_decls.h:275

References CIRCLE::center, float8_mi(), float8_pl(), FPgt(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

◆ circle_add_pt()

Datum circle_add_pt ( PG_FUNCTION_ARGS  )

Definition at line 4965 of file geo_ops.c.

4966 {
4967  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
4968  Point *point = PG_GETARG_POINT_P(1);
4969  CIRCLE *result;
4970 
4971  result = (CIRCLE *) palloc(sizeof(CIRCLE));
4972 
4973  point_add_point(&result->center, &circle->center, point);
4974  result->radius = circle->radius;
4975 
4976  PG_RETURN_CIRCLE_P(result);
4977 }

References CIRCLE::center, palloc(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_add_point(), and CIRCLE::radius.

◆ circle_ar()

static float8 circle_ar ( CIRCLE circle)
static

Definition at line 5159 of file geo_ops.c.

5160 {
5161  return float8_mul(float8_mul(circle->radius, circle->radius), M_PI);
5162 }
#define M_PI
Definition: earthdistance.c:11

References float8_mul(), M_PI, and CIRCLE::radius.

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

5033 {
5034  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5035 
5036  PG_RETURN_FLOAT8(circle_ar(circle));
5037 }
static float8 circle_ar(CIRCLE *circle)
Definition: geo_ops.c:5159

References circle_ar(), PG_GETARG_CIRCLE_P, and PG_RETURN_FLOAT8.

◆ circle_below()

Datum circle_below ( PG_FUNCTION_ARGS  )

Definition at line 4851 of file geo_ops.c.

4852 {
4853  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4854  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4855 
4856  PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.y, circle1->radius),
4857  float8_mi(circle2->center.y, circle2->radius)));
4858 }

References CIRCLE::center, float8_mi(), float8_pl(), FPlt(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::y.

◆ circle_box()

Datum circle_box ( PG_FUNCTION_ARGS  )

Definition at line 5186 of file geo_ops.c.

5187 {
5188  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5189  BOX *box;
5190  float8 delta;
5191 
5192  box = (BOX *) palloc(sizeof(BOX));
5193 
5194  delta = float8_div(circle->radius, sqrt(2.0));
5195 
5196  box->high.x = float8_pl(circle->center.x, delta);
5197  box->low.x = float8_mi(circle->center.x, delta);
5198  box->high.y = float8_pl(circle->center.y, delta);
5199  box->low.y = float8_mi(circle->center.y, delta);
5200 
5201  PG_RETURN_BOX_P(box);
5202 }

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

◆ circle_center()

Datum circle_center ( PG_FUNCTION_ARGS  )

Definition at line 5143 of file geo_ops.c.

5144 {
5145  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5146  Point *result;
5147 
5148  result = (Point *) palloc(sizeof(Point));
5149  result->x = circle->center.x;
5150  result->y = circle->center.y;
5151 
5152  PG_RETURN_POINT_P(result);
5153 }

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

◆ circle_contain()

Datum circle_contain ( PG_FUNCTION_ARGS  )

Definition at line 4838 of file geo_ops.c.

4839 {
4840  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4841  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4842 
4843  PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center),
4844  float8_mi(circle1->radius, circle2->radius)));
4845 }

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

◆ circle_contain_pt()

Datum circle_contain_pt ( PG_FUNCTION_ARGS  )

Definition at line 5082 of file geo_ops.c.

5083 {
5084  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5085  Point *point = PG_GETARG_POINT_P(1);
5086  float8 d;
5087 
5088  d = point_dt(&circle->center, point);
5089  PG_RETURN_BOOL(d <= circle->radius);
5090 }

References CIRCLE::center, 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 4826 of file geo_ops.c.

4827 {
4828  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4829  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4830 
4831  PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center),
4832  float8_mi(circle2->radius, circle1->radius)));
4833 }

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

◆ circle_diameter()

Datum circle_diameter ( PG_FUNCTION_ARGS  )

Definition at line 5043 of file geo_ops.c.

5044 {
5045  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5046 
5047  PG_RETURN_FLOAT8(float8_mul(circle->radius, 2.0));
5048 }

References float8_mul(), PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, and CIRCLE::radius.

◆ circle_distance()

Datum circle_distance ( PG_FUNCTION_ARGS  )

Definition at line 5066 of file geo_ops.c.

5067 {
5068  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
5069  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
5070  float8 result;
5071 
5072  result = float8_mi(point_dt(&circle1->center, &circle2->center),
5073  float8_pl(circle1->radius, circle2->radius));
5074  if (result < 0.0)
5075  result = 0.0;
5076 
5077  PG_RETURN_FLOAT8(result);
5078 }

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

◆ circle_div_pt()

Datum circle_div_pt ( PG_FUNCTION_ARGS  )

Definition at line 5014 of file geo_ops.c.

5015 {
5016  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5017  Point *point = PG_GETARG_POINT_P(1);
5018  CIRCLE *result;
5019 
5020  result = (CIRCLE *) palloc(sizeof(CIRCLE));
5021 
5022  point_div_point(&result->center, &circle->center, point);
5023  result->radius = float8_div(circle->radius, HYPOT(point->x, point->y));
5024 
5025  PG_RETURN_CIRCLE_P(result);
5026 }
#define HYPOT(A, B)
Definition: geo_decls.h:91

References CIRCLE::center, float8_div(), HYPOT, palloc(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_div_point(), CIRCLE::radius, Point::x, and Point::y.

◆ circle_eq()

Datum circle_eq ( PG_FUNCTION_ARGS  )

Definition at line 4903 of file geo_ops.c.

4904 {
4905  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4906  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4907 
4908  PG_RETURN_BOOL(FPeq(circle_ar(circle1), circle_ar(circle2)));
4909 }

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

◆ circle_ge()

Datum circle_ge ( PG_FUNCTION_ARGS  )

Definition at line 4948 of file geo_ops.c.

4949 {
4950  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4951  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4952 
4953  PG_RETURN_BOOL(FPge(circle_ar(circle1), circle_ar(circle2)));
4954 }

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

◆ circle_gt()

Datum circle_gt ( PG_FUNCTION_ARGS  )

Definition at line 4930 of file geo_ops.c.

4931 {
4932  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4933  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4934 
4935  PG_RETURN_BOOL(FPgt(circle_ar(circle1), circle_ar(circle2)));
4936 }

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

◆ circle_in()

Datum circle_in ( PG_FUNCTION_ARGS  )

Definition at line 4611 of file geo_ops.c.

4612 {
4613  char *str = PG_GETARG_CSTRING(0);
4614  Node *escontext = fcinfo->context;
4615  CIRCLE *circle = (CIRCLE *) palloc(sizeof(CIRCLE));
4616  char *s,
4617  *cp;
4618  int depth = 0;
4619 
4620  s = str;
4621  while (isspace((unsigned char) *s))
4622  s++;
4623  if (*s == LDELIM_C)
4624  depth++, s++;
4625  else if (*s == LDELIM)
4626  {
4627  /* If there are two left parens, consume the first one */
4628  cp = (s + 1);
4629  while (isspace((unsigned char) *cp))
4630  cp++;
4631  if (*cp == LDELIM)
4632  depth++, s = cp;
4633  }
4634 
4635  /* pair_decode will consume parens around the pair, if any */
4636  if (!pair_decode(s, &circle->center.x, &circle->center.y, &s, "circle", str,
4637  escontext))
4638  PG_RETURN_NULL();
4639 
4640  if (*s == DELIM)
4641  s++;
4642 
4643  if (!single_decode(s, &circle->radius, &s, "circle", str, escontext))
4644  PG_RETURN_NULL();
4645 
4646  /* We have to accept NaN. */
4647  if (circle->radius < 0.0)
4648  ereturn(escontext, (Datum) 0,
4649  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4650  errmsg("invalid input syntax for type %s: \"%s\"",
4651  "circle", str)));
4652 
4653  while (depth > 0)
4654  {
4655  if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1)))
4656  {
4657  depth--;
4658  s++;
4659  while (isspace((unsigned char) *s))
4660  s++;
4661  }
4662  else
4663  ereturn(escontext, (Datum) 0,
4664  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4665  errmsg("invalid input syntax for type %s: \"%s\"",
4666  "circle", str)));
4667  }
4668 
4669  if (*s != '\0')
4670  ereturn(escontext, (Datum) 0,
4671  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4672  errmsg("invalid input syntax for type %s: \"%s\"",
4673  "circle", str)));
4674 
4675  PG_RETURN_CIRCLE_P(circle);
4676 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
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:212
#define DELIM
Definition: geo_ops.c:159
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:194
#define LDELIM_C
Definition: geo_ops.c:162
#define RDELIM
Definition: geo_ops.c:158
#define RDELIM_C
Definition: geo_ops.c:163
#define LDELIM
Definition: geo_ops.c:157
uintptr_t Datum
Definition: postgres.h:64

References CIRCLE::center, DELIM, ereturn, errcode(), errmsg(), LDELIM, LDELIM_C, pair_decode(), palloc(), PG_GETARG_CSTRING, PG_RETURN_CIRCLE_P, PG_RETURN_NULL, CIRCLE::radius, RDELIM, RDELIM_C, single_decode(), generate_unaccent_rules::str, Point::x, and Point::y.

◆ circle_le()

Datum circle_le ( PG_FUNCTION_ARGS  )

Definition at line 4939 of file geo_ops.c.

4940 {
4941  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4942  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4943 
4944  PG_RETURN_BOOL(FPle(circle_ar(circle1), circle_ar(circle2)));
4945 }

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

◆ circle_left()

Datum circle_left ( PG_FUNCTION_ARGS  )

Definition at line 4789 of file geo_ops.c.

4790 {
4791  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4792  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4793 
4794  PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.x, circle1->radius),
4795  float8_mi(circle2->center.x, circle2->radius)));
4796 }

References CIRCLE::center, float8_mi(), float8_pl(), FPlt(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

◆ circle_lt()

Datum circle_lt ( PG_FUNCTION_ARGS  )

Definition at line 4921 of file geo_ops.c.

4922 {
4923  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4924  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4925 
4926  PG_RETURN_BOOL(FPlt(circle_ar(circle1), circle_ar(circle2)));
4927 }

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

◆ circle_mul_pt()

Datum circle_mul_pt ( PG_FUNCTION_ARGS  )

Definition at line 4999 of file geo_ops.c.

5000 {
5001  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5002  Point *point = PG_GETARG_POINT_P(1);
5003  CIRCLE *result;
5004 
5005  result = (CIRCLE *) palloc(sizeof(CIRCLE));
5006 
5007  point_mul_point(&result->center, &circle->center, point);
5008  result->radius = float8_mul(circle->radius, HYPOT(point->x, point->y));
5009 
5010  PG_RETURN_CIRCLE_P(result);
5011 }

References CIRCLE::center, float8_mul(), HYPOT, palloc(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_mul_point(), CIRCLE::radius, Point::x, and Point::y.

◆ circle_ne()

Datum circle_ne ( PG_FUNCTION_ARGS  )

Definition at line 4912 of file geo_ops.c.

4913 {
4914  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4915  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4916 
4917  PG_RETURN_BOOL(FPne(circle_ar(circle1), circle_ar(circle2)));
4918 }
static bool FPne(double A, double B)
Definition: geo_decls.h:53

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

◆ circle_out()

Datum circle_out ( PG_FUNCTION_ARGS  )

Definition at line 4681 of file geo_ops.c.

4682 {
4683  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
4685 
4686  initStringInfo(&str);
4687 
4690  pair_encode(circle->center.x, circle->center.y, &str);
4693  single_encode(circle->radius, &str);
4695 
4696  PG_RETURN_CSTRING(str.data);
4697 }
static void pair_encode(float8 x, float8 y, StringInfo str)
Definition: geo_ops.c:255
static void single_encode(float8 x, StringInfo str)
Definition: geo_ops.c:203
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

References appendStringInfoChar(), CIRCLE::center, DELIM, initStringInfo(), LDELIM, LDELIM_C, pair_encode(), PG_GETARG_CIRCLE_P, PG_RETURN_CSTRING, CIRCLE::radius, RDELIM, RDELIM_C, single_encode(), generate_unaccent_rules::str, Point::x, and Point::y.

◆ circle_overabove()

Datum circle_overabove ( PG_FUNCTION_ARGS  )

Definition at line 4889 of file geo_ops.c.

4890 {
4891  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4892  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4893 
4894  PG_RETURN_BOOL(FPge(float8_mi(circle1->center.y, circle1->radius),
4895  float8_mi(circle2->center.y, circle2->radius)));
4896 }

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

◆ circle_overbelow()

Datum circle_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 4876 of file geo_ops.c.

4877 {
4878  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4879  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4880 
4881  PG_RETURN_BOOL(FPle(float8_pl(circle1->center.y, circle1->radius),
4882  float8_pl(circle2->center.y, circle2->radius)));
4883 }

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

◆ circle_overlap()

Datum circle_overlap ( PG_FUNCTION_ARGS  )

Definition at line 4764 of file geo_ops.c.

4765 {
4766  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4767  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4768 
4769  PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center),
4770  float8_pl(circle1->radius, circle2->radius)));
4771 }

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

◆ circle_overleft()

Datum circle_overleft ( PG_FUNCTION_ARGS  )

Definition at line 4777 of file geo_ops.c.

4778 {
4779  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4780  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4781 
4782  PG_RETURN_BOOL(FPle(float8_pl(circle1->center.x, circle1->radius),
4783  float8_pl(circle2->center.x, circle2->radius)));
4784 }

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

◆ circle_overright()

Datum circle_overright ( PG_FUNCTION_ARGS  )

Definition at line 4814 of file geo_ops.c.

4815 {
4816  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4817  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4818 
4819  PG_RETURN_BOOL(FPge(float8_mi(circle1->center.x, circle1->radius),
4820  float8_mi(circle2->center.x, circle2->radius)));
4821 }

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

◆ circle_poly()

Datum circle_poly ( PG_FUNCTION_ARGS  )

Definition at line 5225 of file geo_ops.c.

5226 {
5227  int32 npts = PG_GETARG_INT32(0);
5228  CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
5229  POLYGON *poly;
5230  int base_size,
5231  size;
5232  int i;
5233  float8 angle;
5234  float8 anglestep;
5235 
5236  if (FPzero(circle->radius))
5237  ereport(ERROR,
5238  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5239  errmsg("cannot convert circle with radius zero to polygon")));
5240 
5241  if (npts < 2)
5242  ereport(ERROR,
5243  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5244  errmsg("must request at least 2 points")));
5245 
5246  base_size = sizeof(poly->p[0]) * npts;
5247  size = offsetof(POLYGON, p) + base_size;
5248 
5249  /* Check for integer overflow */
5250  if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
5251  ereport(ERROR,
5252  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5253  errmsg("too many points requested")));
5254 
5255  poly = (POLYGON *) palloc0(size); /* zero any holes */
5256  SET_VARSIZE(poly, size);
5257  poly->npts = npts;
5258 
5259  anglestep = float8_div(2.0 * M_PI, npts);
5260 
5261  for (i = 0; i < npts; i++)
5262  {
5263  angle = float8_mul(anglestep, i);
5264 
5265  poly->p[i].x = float8_mi(circle->center.x,
5266  float8_mul(circle->radius, cos(angle)));
5267  poly->p[i].y = float8_pl(circle->center.y,
5268  float8_mul(circle->radius, sin(angle)));
5269  }
5270 
5271  make_bound_box(poly);
5272 
5273  PG_RETURN_POLYGON_P(poly);
5274 }
signed int int32
Definition: c.h:481
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define FPzero(A)
Definition: geo_decls.h:44
static void make_bound_box(POLYGON *poly)
Definition: geo_ops.c:3376
int i
Definition: isn.c:73
void * palloc0(Size size)
Definition: mcxt.c:1334

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

◆ circle_radius()

Datum circle_radius ( PG_FUNCTION_ARGS  )

Definition at line 5054 of file geo_ops.c.

5055 {
5056  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5057 
5058  PG_RETURN_FLOAT8(circle->radius);
5059 }

References PG_GETARG_CIRCLE_P, PG_RETURN_FLOAT8, and CIRCLE::radius.

◆ circle_recv()

Datum circle_recv ( PG_FUNCTION_ARGS  )

Definition at line 4703 of file geo_ops.c.

4704 {
4706  CIRCLE *circle;
4707 
4708  circle = (CIRCLE *) palloc(sizeof(CIRCLE));
4709 
4710  circle->center.x = pq_getmsgfloat8(buf);
4711  circle->center.y = pq_getmsgfloat8(buf);
4712  circle->radius = pq_getmsgfloat8(buf);
4713 
4714  /* We have to accept NaN. */
4715  if (circle->radius < 0.0)
4716  ereport(ERROR,
4717  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
4718  errmsg("invalid radius in external \"circle\" value")));
4719 
4720  PG_RETURN_CIRCLE_P(circle);
4721 }

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

◆ circle_right()

Datum circle_right ( PG_FUNCTION_ARGS  )

Definition at line 4801 of file geo_ops.c.

4802 {
4803  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4804  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4805 
4806  PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.x, circle1->radius),
4807  float8_pl(circle2->center.x, circle2->radius)));
4808 }

References CIRCLE::center, float8_mi(), float8_pl(), FPgt(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, CIRCLE::radius, and Point::x.

◆ circle_same()

Datum circle_same ( PG_FUNCTION_ARGS  )

Definition at line 4751 of file geo_ops.c.

4752 {
4753  CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0);
4754  CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1);
4755 
4756  PG_RETURN_BOOL(((isnan(circle1->radius) && isnan(circle2->radius)) ||
4757  FPeq(circle1->radius, circle2->radius)) &&
4758  point_eq_point(&circle1->center, &circle2->center));
4759 }

References CIRCLE::center, FPeq(), PG_GETARG_CIRCLE_P, PG_RETURN_BOOL, point_eq_point(), and CIRCLE::radius.

◆ circle_send()

Datum circle_send ( PG_FUNCTION_ARGS  )

Definition at line 4727 of file geo_ops.c.

4728 {
4729  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
4731 
4732  pq_begintypsend(&buf);
4733  pq_sendfloat8(&buf, circle->center.x);
4734  pq_sendfloat8(&buf, circle->center.y);
4735  pq_sendfloat8(&buf, circle->radius);
4737 }

References buf, CIRCLE::center, PG_GETARG_CIRCLE_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), CIRCLE::radius, Point::x, and Point::y.

◆ circle_sub_pt()

Datum circle_sub_pt ( PG_FUNCTION_ARGS  )

Definition at line 4980 of file geo_ops.c.

4981 {
4982  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
4983  Point *point = PG_GETARG_POINT_P(1);
4984  CIRCLE *result;
4985 
4986  result = (CIRCLE *) palloc(sizeof(CIRCLE));
4987 
4988  point_sub_point(&result->center, &circle->center, point);
4989  result->radius = circle->radius;
4990 
4991  PG_RETURN_CIRCLE_P(result);
4992 }

References CIRCLE::center, palloc(), PG_GETARG_CIRCLE_P, PG_GETARG_POINT_P, PG_RETURN_CIRCLE_P, point_sub_point(), and CIRCLE::radius.

◆ close_ls()

Datum close_ls ( PG_FUNCTION_ARGS  )

Definition at line 2988 of file geo_ops.c.

2989 {
2990  LINE *line = PG_GETARG_LINE_P(0);
2991  LSEG *lseg = PG_GETARG_LSEG_P(1);
2992  Point *result;
2993 
2994  if (lseg_sl(lseg) == line_sl(line))
2995  PG_RETURN_NULL();
2996 
2997  result = (Point *) palloc(sizeof(Point));
2998 
2999  if (isnan(lseg_closept_line(result, lseg, line)))
3000  PG_RETURN_NULL();
3001 
3002  PG_RETURN_POINT_P(result);
3003 }
#define PG_GETARG_LINE_P(n)
Definition: geo_decls.h:230
#define PG_GETARG_LSEG_P(n)
Definition: geo_decls.h:198
static float8 lseg_closept_line(Point *result, LSEG *lseg, LINE *line)
Definition: geo_ops.c:2960
static float8 lseg_sl(LSEG *lseg)
Definition: geo_ops.c:2155
static float8 line_sl(LINE *line)
Definition: geo_ops.c:1233

References line_sl(), lseg_closept_line(), lseg_sl(), palloc(), PG_GETARG_LINE_P, PG_GETARG_LSEG_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ close_lseg()

Datum close_lseg ( PG_FUNCTION_ARGS  )

Definition at line 2853 of file geo_ops.c.

2854 {
2855  LSEG *l1 = PG_GETARG_LSEG_P(0);
2856  LSEG *l2 = PG_GETARG_LSEG_P(1);
2857  Point *result;
2858 
2859  if (lseg_sl(l1) == lseg_sl(l2))
2860  PG_RETURN_NULL();
2861 
2862  result = (Point *) palloc(sizeof(Point));
2863 
2864  if (isnan(lseg_closept_lseg(result, l2, l1)))
2865  PG_RETURN_NULL();
2866 
2867  PG_RETURN_POINT_P(result);
2868 }

References lseg_closept_lseg(), lseg_sl(), palloc(), PG_GETARG_LSEG_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ close_pb()

Datum close_pb ( PG_FUNCTION_ARGS  )

Definition at line 2933 of file geo_ops.c.

2934 {
2935  Point *pt = PG_GETARG_POINT_P(0);
2936  BOX *box = PG_GETARG_BOX_P(1);
2937  Point *result;
2938 
2939  result = (Point *) palloc(sizeof(Point));
2940 
2941  if (isnan(box_closept_point(result, box, pt)))
2942  PG_RETURN_NULL();
2943 
2944  PG_RETURN_POINT_P(result);
2945 }
static float8 box_closept_point(Point *result, BOX *box, Point *pt)
Definition: geo_ops.c:2878

References box_closept_point(), palloc(), PG_GETARG_BOX_P, PG_GETARG_POINT_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ close_pl()

Datum close_pl ( PG_FUNCTION_ARGS  )

Definition at line 2750 of file geo_ops.c.

2751 {
2752  Point *pt = PG_GETARG_POINT_P(0);
2753  LINE *line = PG_GETARG_LINE_P(1);
2754  Point *result;
2755 
2756  result = (Point *) palloc(sizeof(Point));
2757 
2758  if (isnan(line_closept_point(result, line, pt)))
2759  PG_RETURN_NULL();
2760 
2761  PG_RETURN_POINT_P(result);
2762 }
static float8 line_closept_point(Point *result, LINE *line, Point *point)
Definition: geo_ops.c:2724

References line_closept_point(), palloc(), PG_GETARG_LINE_P, PG_GETARG_POINT_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ close_ps()

Datum close_ps ( PG_FUNCTION_ARGS  )

Definition at line 2791 of file geo_ops.c.

2792 {
2793  Point *pt = PG_GETARG_POINT_P(0);
2794  LSEG *lseg = PG_GETARG_LSEG_P(1);
2795  Point *result;
2796 
2797  result = (Point *) palloc(sizeof(Point));
2798 
2799  if (isnan(lseg_closept_point(result, lseg, pt)))
2800  PG_RETURN_NULL();
2801 
2802  PG_RETURN_POINT_P(result);
2803 }

References lseg_closept_point(), palloc(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ close_sb()

Datum close_sb ( PG_FUNCTION_ARGS  )

Definition at line 3063 of file geo_ops.c.

3064 {
3065  LSEG *lseg = PG_GETARG_LSEG_P(0);
3066  BOX *box = PG_GETARG_BOX_P(1);
3067  Point *result;
3068 
3069  result = (Point *) palloc(sizeof(Point));
3070 
3071  if (isnan(box_closept_lseg(result, box, lseg)))
3072  PG_RETURN_NULL();
3073 
3074  PG_RETURN_POINT_P(result);
3075 }
static float8 box_closept_lseg(Point *result, BOX *box, LSEG *lseg)
Definition: geo_ops.c:3013

References box_closept_lseg(), palloc(), PG_GETARG_BOX_P, PG_GETARG_LSEG_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ construct_point()

Datum construct_point ( PG_FUNCTION_ARGS  )

Definition at line 4096 of file geo_ops.c.

4097 {
4098  float8 x = PG_GETARG_FLOAT8(0);
4099  float8 y = PG_GETARG_FLOAT8(1);
4100  Point *result;
4101 
4102  result = (Point *) palloc(sizeof(Point));
4103 
4104  point_construct(result, x, y);
4105 
4106  PG_RETURN_POINT_P(result);
4107 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
static void point_construct(Point *result, float8 x, float8 y)
Definition: geo_ops.c:1884

References palloc(), PG_GETARG_FLOAT8, PG_RETURN_POINT_P, point_construct(), x, and y.

◆ cr_circle()

Datum cr_circle ( PG_FUNCTION_ARGS  )

Definition at line 5170 of file geo_ops.c.

5171 {
5172  Point *center = PG_GETARG_POINT_P(0);
5173  float8 radius = PG_GETARG_FLOAT8(1);
5174  CIRCLE *result;
5175 
5176  result = (CIRCLE *) palloc(sizeof(CIRCLE));
5177 
5178  result->center.x = center->x;
5179  result->center.y = center->y;
5180  result->radius = radius;
5181 
5182  PG_RETURN_CIRCLE_P(result);
5183 }

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

◆ dist_bp()

Datum dist_bp ( PG_FUNCTION_ARGS  )

Definition at line 2514 of file geo_ops.c.

2515 {
2516  BOX *box = PG_GETARG_BOX_P(0);
2517  Point *pt = PG_GETARG_POINT_P(1);
2518 
2519  PG_RETURN_FLOAT8(box_closept_point(NULL, box, pt));
2520 }

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

◆ dist_bs()

Datum dist_bs ( PG_FUNCTION_ARGS  )

Definition at line 2562 of file geo_ops.c.

2563 {
2564  BOX *box = PG_GETARG_BOX_P(0);
2565  LSEG *lseg = PG_GETARG_LSEG_P(1);
2566 
2567  PG_RETURN_FLOAT8(box_closept_lseg(NULL, box, lseg));
2568 }

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

◆ dist_cpoint()

Datum dist_cpoint ( PG_FUNCTION_ARGS  )

Definition at line 5127 of file geo_ops.c.

5128 {
5129  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
5130  Point *point = PG_GETARG_POINT_P(1);
5131  float8 result;
5132 
5133  result = float8_mi(point_dt(point, &circle->center), circle->radius);
5134  if (result < 0.0)
5135  result = 0.0;
5136 
5137  PG_RETURN_FLOAT8(result);
5138 }

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

◆ dist_cpoly()

Datum dist_cpoly ( PG_FUNCTION_ARGS  )

Definition at line 2588 of file geo_ops.c.

2589 {
2590  CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
2591  POLYGON *poly = PG_GETARG_POLYGON_P(1);
2592 
2593  PG_RETURN_FLOAT8(dist_cpoly_internal(circle, poly));
2594 }
#define PG_GETARG_POLYGON_P(n)
Definition: geo_decls.h:261
static float8 dist_cpoly_internal(CIRCLE *circle, POLYGON *poly)
Definition: geo_ops.c:2571

References dist_cpoly_internal(), 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 2571 of file geo_ops.c.

2572 {
2573  float8 result;
2574 
2575  /* calculate distance to center, and subtract radius */
2576  result = float8_mi(dist_ppoly_internal(&circle->center, poly),
2577  circle->radius);
2578  if (result < 0.0)
2579  result = 0.0;
2580 
2581  return result;
2582 }
static float8 dist_ppoly_internal(Point *pt, POLYGON *poly)
Definition: geo_ops.c:2630

References CIRCLE::center, dist_ppoly_internal(), float8_mi(), and CIRCLE::radius.

Referenced by dist_cpoly(), and dist_polyc().

◆ dist_lp()

Datum dist_lp ( PG_FUNCTION_ARGS  )

Definition at line 2402 of file geo_ops.c.

2403 {
2404  LINE *line = PG_GETARG_LINE_P(0);
2405  Point *pt = PG_GETARG_POINT_P(1);
2406 
2407  PG_RETURN_FLOAT8(line_closept_point(NULL, line, pt));
2408 }

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

2539 {
2540  LINE *line = PG_GETARG_LINE_P(0);
2541  LSEG *lseg = PG_GETARG_LSEG_P(1);
2542 
2543  PG_RETURN_FLOAT8(lseg_closept_line(NULL, lseg, line));
2544 }

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

2491 {
2492  PATH *path = PG_GETARG_PATH_P(0);
2493  Point *pt = PG_GETARG_POINT_P(1);
2494 
2496 }
#define PG_GETARG_PATH_P(n)
Definition: geo_decls.h:216
static float8 dist_ppath_internal(Point *pt, PATH *path)
Definition: geo_ops.c:2435

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

◆ dist_pb()

Datum dist_pb ( PG_FUNCTION_ARGS  )

Definition at line 2502 of file geo_ops.c.

2503 {
2504  Point *pt = PG_GETARG_POINT_P(0);
2505  BOX *box = PG_GETARG_BOX_P(1);
2506 
2507  PG_RETURN_FLOAT8(box_closept_point(NULL, box, pt));
2508 }

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

◆ dist_pc()

Datum dist_pc ( PG_FUNCTION_ARGS  )

Definition at line 5109 of file geo_ops.c.

5110 {
5111  Point *point = PG_GETARG_POINT_P(0);
5112  CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
5113  float8 result;
5114 
5115  result = float8_mi(point_dt(point, &circle->center),
5116  circle->radius);
5117  if (result < 0.0)
5118  result = 0.0;
5119 
5120  PG_RETURN_FLOAT8(result);
5121 }

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

◆ dist_pl()

Datum dist_pl ( PG_FUNCTION_ARGS  )

Definition at line 2390 of file geo_ops.c.

2391 {
2392  Point *pt = PG_GETARG_POINT_P(0);
2393  LINE *line = PG_GETARG_LINE_P(1);
2394 
2395  PG_RETURN_FLOAT8(line_closept_point(NULL, line, pt));
2396 }

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

◆ dist_polyc()

Datum dist_polyc ( PG_FUNCTION_ARGS  )

Definition at line 2600 of file geo_ops.c.

2601 {
2602  POLYGON *poly = PG_GETARG_POLYGON_P(0);
2603  CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
2604 
2605  PG_RETURN_FLOAT8(dist_cpoly_internal(circle, poly));
2606 }

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

◆ dist_polyp()

Datum dist_polyp ( PG_FUNCTION_ARGS  )

Definition at line 2621 of file geo_ops.c.

2622 {
2623  POLYGON *poly = PG_GETARG_POLYGON_P(0);
2624  Point *point = PG_GETARG_POINT_P(1);
2625 
2626  PG_RETURN_FLOAT8(dist_ppoly_internal(point, poly));
2627 }

References dist_ppoly_internal(), PG_GETARG_POINT_P, PG_GETARG_POLYGON_P, and PG_RETURN_FLOAT8.

◆ dist_ppath()

Datum dist_ppath ( PG_FUNCTION_ARGS  )

Definition at line 2478 of file geo_ops.c.

2479 {
2480  Point *pt = PG_GETARG_POINT_P(0);
2481  PATH *path = PG_GETARG_PATH_P(1);
2482 
2484 }

References dist_ppath_internal(), 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 2435 of file geo_ops.c.

2436 {
2437  float8 result = 0.0; /* keep compiler quiet */
2438  bool have_min = false;
2439  float8 tmp;
2440  int i;
2441  LSEG lseg;
2442 
2443  Assert(path->npts > 0);
2444 
2445  /*
2446  * The distance from a point to a path is the smallest distance from the
2447  * point to any of its constituent segments.
2448  */
2449  for (i = 0; i < path->npts; i++)
2450  {
2451  int iprev;
2452 
2453  if (i > 0)
2454  iprev = i - 1;
2455  else
2456  {
2457  if (!path->closed)
2458  continue;
2459  iprev = path->npts - 1; /* Include the closure segment */
2460  }
2461 
2462  statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
2463  tmp = lseg_closept_point(NULL, &lseg, pt);
2464  if (!have_min || float8_lt(tmp, result))
2465  {
2466  result = tmp;
2467  have_min = true;
2468  }
2469  }
2470 
2471  return result;
2472 }
Assert(fmt[strlen(fmt) - 1] !='\n')
Point p[FLEXIBLE_ARRAY_MEMBER]
Definition: geo_decls.h:121
int32 npts
Definition: geo_decls.h:118
int32 closed
Definition: geo_decls.h:119

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

Referenced by dist_pathp(), and dist_ppath().

◆ dist_ppoly()

Datum dist_ppoly ( PG_FUNCTION_ARGS  )

Definition at line 2612 of file geo_ops.c.

2613 {
2614  Point *point = PG_GETARG_POINT_P(0);
2615  POLYGON *poly = PG_GETARG_POLYGON_P(1);
2616 
2617  PG_RETURN_FLOAT8(dist_ppoly_internal(point, poly));
2618 }

References dist_ppoly_internal(), PG_GETARG_POINT_P, PG_GETARG_POLYGON_P, and PG_RETURN_FLOAT8.

◆ dist_ppoly_internal()

static float8 dist_ppoly_internal ( Point pt,
POLYGON poly 
)
static

Definition at line 2630 of file geo_ops.c.

2631 {
2632  float8 result;
2633  float8 d;
2634  int i;
2635  LSEG seg;
2636 
2637  if (point_inside(pt, poly->npts, poly->p) != 0)
2638  return 0.0;
2639 
2640  /* initialize distance with segment between first and last points */
2641  seg.p[0].x = poly->p[0].x;
2642  seg.p[0].y = poly->p[0].y;
2643  seg.p[1].x = poly->p[poly->npts - 1].x;
2644  seg.p[1].y = poly->p[poly->npts - 1].y;
2645  result = lseg_closept_point(NULL, &seg, pt);
2646 
2647  /* check distances for other segments */
2648  for (i = 0; i < poly->npts - 1; i++)
2649  {
2650  seg.p[0].x = poly->p[i].x;
2651  seg.p[0].y = poly->p[i].y;
2652  seg.p[1].x = poly->p[i + 1].x;
2653  seg.p[1].y = poly->p[i + 1].y;
2654  d = lseg_closept_point(NULL, &seg, pt);
2655  if (float8_lt(d, result))
2656  result = d;
2657  }
2658 
2659  return result;
2660 }
static int point_inside(Point *p, int npts, Point *plist)
Definition: geo_ops.c:5340

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

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

◆ dist_ps()

Datum dist_ps ( PG_FUNCTION_ARGS  )

Definition at line 2414 of file geo_ops.c.

2415 {
2416  Point *pt = PG_GETARG_POINT_P(0);
2417  LSEG *lseg = PG_GETARG_LSEG_P(1);
2418 
2419  PG_RETURN_FLOAT8(lseg_closept_point(NULL, lseg, pt));
2420 }

References lseg_closept_point(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ dist_sb()

Datum dist_sb ( PG_FUNCTION_ARGS  )

Definition at line 2550 of file geo_ops.c.

2551 {
2552  LSEG *lseg = PG_GETARG_LSEG_P(0);
2553  BOX *box = PG_GETARG_BOX_P(1);
2554 
2555  PG_RETURN_FLOAT8(box_closept_lseg(NULL, box, lseg));
2556 }

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

◆ dist_sl()

Datum dist_sl ( PG_FUNCTION_ARGS  )

Definition at line 2526 of file geo_ops.c.

2527 {
2528  LSEG *lseg = PG_GETARG_LSEG_P(0);
2529  LINE *line = PG_GETARG_LINE_P(1);
2530 
2531  PG_RETURN_FLOAT8(lseg_closept_line(NULL, lseg, line));
2532 }

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

◆ dist_sp()

Datum dist_sp ( PG_FUNCTION_ARGS  )

Definition at line 2426 of file geo_ops.c.

2427 {
2428  LSEG *lseg = PG_GETARG_LSEG_P(0);
2429  Point *pt = PG_GETARG_POINT_P(1);
2430 
2431  PG_RETURN_FLOAT8(lseg_closept_point(NULL, lseg, pt));
2432 }

References lseg_closept_point(), PG_GETARG_LSEG_P, PG_GETARG_POINT_P, and PG_RETURN_FLOAT8.

◆ inter_lb()

Datum inter_lb ( PG_FUNCTION_ARGS  )

Definition at line 3328 of file geo_ops.c.

3329 {
3330  LINE *line = PG_GETARG_LINE_P(0);
3331  BOX *box = PG_GETARG_BOX_P(1);
3332  LSEG bseg;
3333  Point p1,
3334  p2;
3335 
3336  /* pairwise check lseg intersections */
3337  p1.x = box->low.x;
3338  p1.y = box->low.y;
3339  p2.x = box->low.x;
3340  p2.y = box->high.y;
3341  statlseg_construct(&bseg, &p1, &p2);
3342  if (lseg_interpt_line(NULL, &bseg, line))
3343  PG_RETURN_BOOL(true);
3344  p1.x = box->high.x;
3345  p1.y = box->high.y;
3346  statlseg_construct(&bseg, &p1, &p2);
3347  if (lseg_interpt_line(NULL, &bseg, line))
3348  PG_RETURN_BOOL(true);
3349  p2.x = box->high.x;
3350  p2.y = box->low.y;
3351  statlseg_construct(&bseg, &p1, &p2);
3352  if (lseg_interpt_line(NULL, &bseg, line))
3353  PG_RETURN_BOOL(true);
3354  p1.x = box->low.x;
3355  p1.y = box->low.y;
3356  statlseg_construct(&bseg, &p1, &p2);
3357  if (lseg_interpt_line(NULL, &bseg, line))
3358  PG_RETURN_BOOL(true);
3359 
3360  /* if we dropped through, no intersection */
3361  PG_RETURN_BOOL(false);
3362 }
static bool lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
Definition: geo_ops.c:2675

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

◆ inter_sb()

Datum inter_sb ( PG_FUNCTION_ARGS  )

Definition at line 3315 of file geo_ops.c.

3316 {
3317  LSEG *lseg = PG_GETARG_LSEG_P(0);
3318  BOX *box = PG_GETARG_BOX_P(1);
3319 
3320  PG_RETURN_BOOL(box_interpt_lseg(NULL, box, lseg));
3321 }

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

◆ inter_sl()

Datum inter_sl ( PG_FUNCTION_ARGS  )

Definition at line 3238 of file geo_ops.c.

3239 {
3240  LSEG *lseg = PG_GETARG_LSEG_P(0);
3241  LINE *line = PG_GETARG_LINE_P(1);
3242 
3243  PG_RETURN_BOOL(lseg_interpt_line(NULL, lseg, line));
3244 }

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

2725 {
2726  Point closept;
2727  LINE tmp;
2728 
2729  /*
2730  * We drop a perpendicular to find the intersection point. Ordinarily we
2731  * should always find it, but that can fail in the presence of NaN
2732  * coordinates, and perhaps even from simple roundoff issues.
2733  */
2734  line_construct(&tmp, point, line_invsl(line));
2735  if (!line_interpt_line(&closept, &tmp, line))
2736  {
2737  if (result != NULL)
2738  *result = *point;
2739 
2740  return get_float8_nan();
2741  }
2742 
2743  if (result != NULL)
2744  *result = closept;
2745 
2746  return point_dt(&closept, point);
2747 }
static float8 get_float8_nan(void)
Definition: float.h:123
static void line_construct(LINE *result, Point *pt, float8 m)
Definition: geo_ops.c:1083
static bool line_interpt_line(Point *result, LINE *l1, LINE *l2)
Definition: geo_ops.c:1314
static float8 line_invsl(LINE *line)
Definition: geo_ops.c:1247

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

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

1084 {
1085  if (isinf(m))
1086  {
1087  /* vertical - use "x = C" */
1088  result->A = -1.0;
1089  result->B = 0.0;
1090  result->C = pt->x;
1091  }
1092  else if (m == 0)
1093  {
1094  /* horizontal - use "y = C" */
1095  result->A = 0.0;
1096  result->B = -1.0;
1097  result->C = pt->y;
1098  }
1099  else
1100  {
1101  /* use "mx - y + yinter = 0" */
1102  result->A = m;
1103  result->B = -1.0;
1104  result->C = float8_mi(pt->y, float8_mul(m, pt->x));
1105  /* on some platforms, the preceding expression tends to produce -0 */
1106  if (result->C == 0.0)
1107  result->C = 0.0;
1108  }
1109 }
float8 A
Definition: geo_decls.h:130
float8 B
Definition: geo_decls.h:131
float8 C
Definition: geo_decls.h:132

References LINE::A, LINE::B, LINE::C, float8_mi(), float8_mul(), Point::x, and Point::y.

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

1116 {
1117  Point *pt1 = PG_GETARG_POINT_P(0);
1118  Point *pt2 = PG_GETARG_POINT_P(1);
1119  LINE *result = (LINE *) palloc(sizeof(LINE));
1120 
1121  if (point_eq_point(pt1, pt2))
1122  ereport(ERROR,
1123  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1124  errmsg("invalid line specification: must be two distinct points")));
1125 
1126  line_construct(result, pt1, point_sl(pt1, pt2));
1127 
1128  PG_RETURN_LINE_P(result);
1129 }
#define PG_RETURN_LINE_P(x)
Definition: geo_decls.h:231
static float8 point_sl(Point *pt1, Point *pt2)
Definition: geo_ops.c:2023

References ereport, errcode(), errmsg(), ERROR, line_construct(), palloc(), PG_GETARG_POINT_P, PG_RETURN_LINE_P, point_eq_point(), and point_sl().

◆ line_contain_point()

static bool line_contain_point ( LINE line,
Point point 
)
static

Definition at line 3087 of file geo_ops.c.

3088 {
3089  return FPzero(float8_pl(float8_pl(float8_mul(line->A, point->x),
3090  float8_mul(line->B, point->y)),
3091  line->C));
3092 }

References LINE::A, LINE::B, LINE::C, float8_mul(), float8_pl(), FPzero, Point::x, and Point::y.

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

951 {
952  /* s was already advanced over leading '{' */
953  if (!single_decode(s, &line->A, &s, "line", str, escontext))
954  return false;
955  if (*s++ != DELIM)
956  goto fail;
957  if (!single_decode(s, &line->B, &s, "line", str, escontext))
958  return false;
959  if (*s++ != DELIM)
960  goto fail;
961  if (!single_decode(s, &line->C, &s, "line", str, escontext))
962  return false;
963  if (*s++ != RDELIM_L)
964  goto fail;
965  while (isspace((unsigned char) *s))
966  s++;
967  if (*s != '\0')
968  goto fail;
969  return true;
970 
971 fail:
972  ereturn(escontext, false,
973  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
974  errmsg("invalid input syntax for type %s: \"%s\"",
975  "line", str)));
976 }
#define RDELIM_L
Definition: geo_ops.c:165

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

Referenced by line_in().

◆ line_distance()

Datum line_distance ( PG_FUNCTION_ARGS  )

Definition at line 1261 of file geo_ops.c.

1262 {
1263  LINE *l1 = PG_GETARG_LINE_P(0);
1264  LINE *l2 = PG_GETARG_LINE_P(1);
1265  float8 ratio;
1266 
1267  if (line_interpt_line(NULL, l1, l2)) /* intersecting? */
1268  PG_RETURN_FLOAT8(0.0);
1269 
1270  if (!FPzero(l1->A) && !isnan(l1->A) && !FPzero(l2->A) && !isnan(l2->A))
1271  ratio = float8_div(l1->A, l2->A);
1272  else if (!FPzero(l1->B) && !isnan(l1->B) && !FPzero(l2->B) && !isnan(l2->B))
1273  ratio = float8_div(l1->B, l2->B);
1274  else
1275  ratio = 1.0;
1276 
1278  float8_mul(ratio, l2->C))),
1279  HYPOT(l1->A, l1->B)));
1280 }

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

◆ line_eq()

Datum line_eq ( PG_FUNCTION_ARGS  )

Definition at line 1194 of file geo_ops.c.

1195 {
1196  LINE *l1 = PG_GETARG_LINE_P(0);
1197  LINE *l2 = PG_GETARG_LINE_P(1);
1198  float8 ratio;
1199 
1200  /* If any NaNs are involved, insist on exact equality */
1201  if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l1->C) ||
1202  isnan(l2->A) || isnan(l2->B) || isnan(l2->C)))
1203  {
1204  PG_RETURN_BOOL(float8_eq(l1->A, l2->A) &&
1205  float8_eq(l1->B, l2->B) &&
1206  float8_eq(l1->C, l2->C));
1207  }
1208 
1209  /* Otherwise, lines whose parameters are proportional are the same */
1210  if (!FPzero(l2->A))
1211  ratio = float8_div(l1->A, l2->A);
1212  else if (!FPzero(l2->B))
1213  ratio = float8_div(l1->B, l2->B);
1214  else if (!FPzero(l2->C))
1215  ratio = float8_div(l1->C, l2->C);
1216  else
1217  ratio = 1.0;
1218 
1219  PG_RETURN_BOOL(FPeq(l1->A, float8_mul(ratio, l2->A)) &&
1220  FPeq(l1->B, float8_mul(ratio, l2->B)) &&
1221  FPeq(l1->C, float8_mul(ratio, l2->C)));
1222 }
#define unlikely(x)
Definition: c.h:298
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:268

References LINE::A, LINE::B, LINE::C, 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 1182 of file geo_ops.c.

1183 {
1184  LINE *line = PG_GETARG_LINE_P(0);
1185 
1186  PG_RETURN_BOOL(FPzero(line->A));
1187 }

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

◆ line_in()

Datum line_in ( PG_FUNCTION_ARGS  )

Definition at line 979 of file geo_ops.c.

980 {
981  char *str = PG_GETARG_CSTRING(0);
982  Node *escontext = fcinfo->context;
983  LINE *line = (LINE *) palloc(sizeof(LINE));
984  LSEG lseg;
985  bool isopen;
986  char *s;
987 
988  s = str;
989  while (isspace((unsigned char) *s))
990  s++;
991  if (*s == LDELIM_L)
992  {
993  if (!line_decode(s + 1, str, line, escontext))
994  PG_RETURN_NULL();
995  if (FPzero(line->A) && FPzero(line->B))
996  ereturn(escontext, (Datum) 0,
997  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
998  errmsg("invalid line specification: A and B cannot both be zero")));
999  }
1000  else
1001  {
1002  if (!path_decode(s, true, 2, &lseg.p[0], &isopen, NULL, "line", str,
1003  escontext))
1004  PG_RETURN_NULL();
1005  if (point_eq_point(&lseg.p[0], &lseg.p[1]))
1006  ereturn(escontext, (Datum) 0,
1007  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1008  errmsg("invalid line specification: must be two distinct points")));
1009 
1010  /*
1011  * XXX lseg_sl() and line_construct() can throw overflow/underflow
1012  * errors. Eventually we should allow those to be soft, but the
1013  * notational pain seems to outweigh the value for now.
1014  */
1015  line_construct(line, &lseg.p[0], lseg_sl(&lseg));
1016  }
1017 
1018  PG_RETURN_LINE_P(line);
1019 }
#define LDELIM_L
Definition: geo_ops.c:164
static bool line_decode(char *s, const char *str, LINE *line, Node *escontext)
Definition: geo_ops.c:950

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

◆ line_interpt()

Datum line_interpt ( PG_FUNCTION_ARGS  )

Definition at line 1286 of file geo_ops.c.

1287 {
1288  LINE *l1 = PG_GETARG_LINE_P(0);
1289  LINE *l2 = PG_GETARG_LINE_P(1);
1290  Point *result;
1291 
1292  result = (Point *) palloc(sizeof(Point));
1293 
1294  if (!line_interpt_line(result, l1, l2))
1295  PG_RETURN_NULL();
1296  PG_RETURN_POINT_P(result);
1297 }

References line_interpt_line(), palloc(), PG_GETARG_LINE_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

◆ line_interpt_line()

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

Definition at line 1314 of file geo_ops.c.

1315 {
1316  float8 x,
1317  y;
1318 
1319  if (!FPzero(l1->B))
1320  {
1321  if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B))))
1322  return false;
1323 
1324  x = float8_div(float8_mi(float8_mul(l1->B, l2->C),
1325  float8_mul(l2->B, l1->C)),
1326  float8_mi(float8_mul(l1->A, l2->B),
1327  float8_mul(l2->A, l1->B)));
1328  y = float8_div(-float8_pl(float8_mul(l1->A, x), l1->C), l1->B);
1329  }
1330  else if (!FPzero(l2->B))
1331  {
1332  if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B))))
1333  return false;
1334 
1335  x = float8_div(float8_mi(float8_mul(l2->B, l1->C),
1336  float8_mul(l1->B, l2->C)),
1337  float8_mi(float8_mul(l2->A, l1->B),
1338  float8_mul(l1->A, l2->B)));
1339  y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B);
1340  }
1341  else
1342  return false;
1343 
1344  /* On some platforms, the preceding expressions tend to produce -0. */
1345  if (x == 0.0)
1346  x = 0.0;
1347  if (y == 0.0)
1348  y = 0.0;
1349 
1350  if (result != NULL)
1351  point_construct(result, x, y);
1352 
1353  return true;
1354 }

References LINE::A, LINE::B, LINE::C, float8_div(), float8_mi(), float8_mul(), float8_pl(), FPeq(), FPzero, point_construct(), 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 1137 of file geo_ops.c.

1138 {
1139  LINE *l1 = PG_GETARG_LINE_P(0);
1140  LINE *l2 = PG_GETARG_LINE_P(1);
1141 
1142  PG_RETURN_BOOL(line_interpt_line(NULL, l1, l2));
1143 }

References line_interpt_line(), PG_GETARG_LINE_P, and PG_RETURN_BOOL.

◆ line_invsl()

static float8 line_invsl ( LINE line)
inlinestatic

Definition at line 1247 of file geo_ops.c.

1248 {
1249  if (FPzero(line->A))
1250  return get_float8_infinity();
1251  if (FPzero(line->B))
1252  return 0.0;
1253  return float8_div(line->B, line->A);
1254 }
static float8 get_float8_infinity(void)
Definition: float.h:94

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

1024 {
1025  LINE *line = PG_GETARG_LINE_P(0);
1026  char *astr = float8out_internal(line->A);
1027  char *bstr = float8out_internal(line->B);
1028  char *cstr = float8out_internal(line->C);
1029 
1030  PG_RETURN_CSTRING(psprintf("%c%s%c%s%c%s%c", LDELIM_L, astr, DELIM, bstr,
1031  DELIM, cstr, RDELIM_L));
1032 }
char * float8out_internal(double num)
Definition: float.c:536
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References LINE::A, LINE::B, LINE::C, DELIM, 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 1146 of file geo_ops.c.

1147 {
1148  LINE *l1 = PG_GETARG_LINE_P(0);
1149  LINE *l2 = PG_GETARG_LINE_P(1);
1150 
1151  PG_RETURN_BOOL(!line_interpt_line(NULL, l1, l2));
1152 }

References line_interpt_line(), PG_GETARG_LINE_P, and PG_RETURN_BOOL.

◆ line_perp()

Datum line_perp ( PG_FUNCTION_ARGS  )

Definition at line 1155 of file geo_ops.c.

1156 {
1157  LINE *l1 = PG_GETARG_LINE_P(0);
1158  LINE *l2 = PG_GETARG_LINE_P(1);
1159 
1160  if (FPzero(l1->A))
1161  PG_RETURN_BOOL(FPzero(l2->B));
1162  if (FPzero(l2->A))
1163  PG_RETURN_BOOL(FPzero(l1->B));
1164  if (FPzero(l1->B))
1165  PG_RETURN_BOOL(FPzero(l2->A));
1166  if (FPzero(l2->B))
1167  PG_RETURN_BOOL(FPzero(l1->A));
1168 
1170  float8_mul(l1->B, l2->B)), -1.0));
1171 }

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

1039 {
1041  LINE *line;
1042 
1043  line = (LINE *) palloc(sizeof(LINE));
1044 
1045  line->A = pq_getmsgfloat8(buf);
1046  line->B = pq_getmsgfloat8(buf);
1047  line->C = pq_getmsgfloat8(buf);
1048 
1049  if (FPzero(line->A) && FPzero(line->B))
1050  ereport(ERROR,
1051  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1052  errmsg("invalid line specification: A and B cannot both be zero")));
1053 
1054  PG_RETURN_LINE_P(line);
1055 }

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

◆ line_send()

Datum line_send ( PG_FUNCTION_ARGS  )

Definition at line 1061 of file geo_ops.c.

1062 {
1063  LINE *line = PG_GETARG_LINE_P(0);
1065 
1066  pq_begintypsend(&buf);
1067  pq_sendfloat8(&buf, line->A);
1068  pq_sendfloat8(&buf, line->B);
1069  pq_sendfloat8(&buf, line->C);
1071 }

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

1234 {
1235  if (FPzero(line->A))
1236  return 0.0;
1237  if (FPzero(line->B))
1238  return get_float8_infinity();
1239  return float8_div(line->A, -line->B);
1240 }

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

1175 {
1176  LINE *line = PG_GETARG_LINE_P(0);
1177 
1178  PG_RETURN_BOOL(FPzero(line->B));
1179 }

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

◆ lseg_center()

Datum lseg_center ( PG_FUNCTION_ARGS  )

Definition at line 2316 of file geo_ops.c.

2317 {
2318  LSEG *lseg = PG_GETARG_LSEG_P(0);
2319  Point *result;
2320 
2321  result = (Point *) palloc(sizeof(Point));
2322 
2323  result->x = float8_div(float8_pl(lseg->p[0].x, lseg->p[1].x), 2.0);
2324  result->y = float8_div(float8_pl(lseg->p[0].y, lseg->p[1].y), 2.0);
2325 
2326  PG_RETURN_POINT_P(result);
2327 }

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

◆ lseg_closept_line()

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

Definition at line 2960 of file geo_ops.c.

2961 {
2962  float8 dist1,
2963  dist2;
2964 
2965  if (lseg_interpt_line(result, lseg, line))
2966  return 0.0;
2967 
2968  dist1 = line_closept_point(NULL, line, &lseg->p[0]);
2969  dist2 = line_closept_point(NULL, line, &lseg->p[1]);
2970 
2971  if (dist1 < dist2)
2972  {
2973  if (result != NULL)
2974  *result = lseg->p[0];
2975 
2976  return dist1;
2977  }
2978  else
2979  {
2980  if (result != NULL)
2981  *result = lseg->p[1];
2982 
2983  return dist2;
2984  }
2985 }

References line_closept_point(), lseg_interpt_line(), and LSEG::p.

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

2811 {
2812  Point point;
2813  float8 dist,
2814  d;
2815 
2816  /* First, we handle the case when the line segments are intersecting. */
2817  if (lseg_interpt_lseg(result, on_lseg, to_lseg))
2818  return 0.0;
2819 
2820  /*
2821  * Then, we find the closest points from the endpoints of the second line
2822  * segment, and keep the closest one.
2823  */
2824  dist = lseg_closept_point(result, on_lseg, &to_lseg->p[0]);
2825  d = lseg_closept_point(&point, on_lseg, &to_lseg->p[1]);
2826  if (float8_lt(d, dist))
2827  {
2828  dist = d;
2829  if (result != NULL)
2830  *result = point;
2831  }
2832 
2833  /* The closest point can still be one of the endpoints, so we test them. */
2834  d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[0]);
2835  if (float8_lt(d, dist))
2836  {
2837  dist = d;
2838  if (result != NULL)
2839  *result = on_lseg->p[0];
2840  }
2841  d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[1]);
2842  if (float8_lt(d, dist))
2843  {
2844  dist = d;
2845  if (result != NULL)
2846  *result = on_lseg->p[1];
2847  }
2848 
2849  return dist;
2850 }

References float8_lt(), lseg_closept_point(), lseg_interpt_lseg(), and LSEG::p.

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

2773 {
2774  Point closept;
2775  LINE tmp;
2776 
2777  /*
2778  * To find the closest point, we draw a perpendicular line from the point
2779  * to the line segment.
2780  */
2781  line_construct(&tmp, pt, point_invsl(&lseg->p[0], &lseg->p[1]));
2782  lseg_closept_line(&closept, lseg, &tmp);
2783 
2784  if (result != NULL)
2785  *result = closept;
2786 
2787  return point_dt(&closept, pt);
2788 }
static float8 point_invsl(Point *pt1, Point *pt2)
Definition: geo_ops.c:2039

References line_construct(), lseg_closept_line(), LSEG::p, point_dt(), and point_invsl().

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

2130 {
2131  Point *pt1 = PG_GETARG_POINT_P(0);
2132  Point *pt2 = PG_GETARG_POINT_P(1);
2133  LSEG *result = (LSEG *) palloc(sizeof(LSEG));
2134 
2135  statlseg_construct(result, pt1, pt2);
2136 
2137  PG_RETURN_LSEG_P(result);
2138 }

References palloc(), PG_GETARG_POINT_P, PG_RETURN_LSEG_P, and statlseg_construct().

◆ lseg_contain_point()

static bool lseg_contain_point ( LSEG lseg,
Point pt 
)
static

Definition at line 3109 of file geo_ops.c.

3110 {
3111  return FPeq(point_dt(pt, &lseg->p[0]) +
3112  point_dt(pt, &lseg->p[1]),
3113  point_dt(&lseg->p[0], &lseg->p[1]));
3114 }

References FPeq(), LSEG::p, 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 5397 of file geo_ops.c.

5398 {
5399  float8 z;
5400  int y_sign;
5401 
5402  if (FPzero(y))
5403  { /* y == 0, on X axis */
5404  if (FPzero(x)) /* (x,y) is (0,0)? */
5405  return POINT_ON_POLYGON;
5406  else if (FPgt(x, 0))
5407  { /* x > 0 */
5408  if (FPzero(prev_y)) /* y and prev_y are zero */
5409  /* prev_x > 0? */
5410  return FPgt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5411  return FPlt(prev_y, 0.0) ? 1 : -1;
5412  }
5413  else
5414  { /* x < 0, x not on positive X axis */
5415  if (FPzero(prev_y))
5416  /* prev_x < 0? */
5417  return FPlt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON;
5418  return 0;
5419  }
5420  }
5421  else
5422  { /* y != 0 */
5423  /* compute y crossing direction from previous point */
5424  y_sign = FPgt(y, 0.0) ? 1 : -1;
5425 
5426  if (FPzero(prev_y))
5427  /* previous point was on X axis, so new point is either off or on */
5428  return FPlt(prev_x, 0.0) ? 0 : y_sign;
5429  else if ((y_sign < 0 && FPlt(prev_y, 0.0)) ||
5430  (y_sign > 0 && FPgt(prev_y, 0.0)))
5431  /* both above or below X axis */
5432  return 0; /* same sign */
5433  else
5434  { /* y and prev_y cross X-axis */
5435  if (FPge(x, 0.0) && FPgt(prev_x, 0.0))
5436  /* both non-negative so cross positive X-axis */
5437  return 2 * y_sign;
5438  if (FPlt(x, 0.0) && FPle(prev_x, 0.0))
5439  /* both non-positive so do not cross positive X-axis */
5440  return 0;
5441 
5442  /* x and y cross axes, see URL above point_inside() */
5443  z = float8_mi(float8_mul(float8_mi(x, prev_x), y),
5444  float8_mul(float8_mi(y, prev_y), x));
5445  if (FPzero(z))
5446  return POINT_ON_POLYGON;
5447  if ((y_sign < 0 && FPlt(z, 0.0)) ||
5448  (y_sign > 0 && FPgt(z, 0.0)))
5449  return 0;
5450  return 2 * y_sign;
5451  }
5452  }
5453 }
#define POINT_ON_POLYGON
Definition: geo_ops.c:5337

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

2307 {
2308  LSEG *l1 = PG_GETARG_LSEG_P(0);
2309  LSEG *l2 = PG_GETARG_LSEG_P(1);
2310 
2311  PG_RETURN_FLOAT8(lseg_closept_lseg(NULL, l1, l2));
2312 }

References lseg_closept_lseg(), PG_GETARG_LSEG_P, and PG_RETURN_FLOAT8.

◆ lseg_eq()

Datum lseg_eq ( PG_FUNCTION_ARGS  )

Definition at line 2236 of file geo_ops.c.

2237 {
2238  LSEG *l1 = PG_GETARG_LSEG_P(0);
2239  LSEG *l2 = PG_GETARG_LSEG_P(1);
2240 
2241  PG_RETURN_BOOL(point_eq_point(&l1->p[0], &l2->p[0]) &&
2242  point_eq_point(&l1->p[1], &l2->p[1]));
2243 }

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

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

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

◆ lseg_gt()

Datum lseg_gt ( PG_FUNCTION_ARGS  )

Definition at line 2276 of file geo_ops.c.

2277 {
2278  LSEG *l1 = PG_GETARG_LSEG_P(0);
2279  LSEG *l2 = PG_GETARG_LSEG_P(1);
2280 
2281  PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]),
2282  point_dt(&l2->p[0], &l2->p[1])));
2283 }

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

◆ lseg_horizontal()

Datum lseg_horizontal ( PG_FUNCTION_ARGS  )

Definition at line 2227 of file geo_ops.c.

2228 {
2229  LSEG *lseg = PG_GETARG_LSEG_P(0);
2230 
2231  PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));
2232 }

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

◆ lseg_in()

Datum lseg_in ( PG_FUNCTION_ARGS  )

Definition at line 2065 of file geo_ops.c.

2066 {
2067  char *str = PG_GETARG_CSTRING(0);
2068  Node *escontext = fcinfo->context;
2069  LSEG *lseg = (LSEG *) palloc(sizeof(LSEG));
2070  bool isopen;
2071 
2072  if (!path_decode(str, true, 2, &lseg->p[0], &isopen, NULL, "lseg", str,
2073  escontext))
2074  PG_RETURN_NULL();
2075 
2076  PG_RETURN_LSEG_P(lseg);
2077 }

References LSEG::p, palloc(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_LSEG_P, PG_RETURN_NULL, and generate_unaccent_rules::str.

◆ lseg_inside_poly()

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

Definition at line 3866 of file geo_ops.c.

3867 {
3868  LSEG s,
3869  t;
3870  int i;
3871  bool res = true,
3872  intersection = false;
3873 
3874  /* since this function recurses, it could be driven to stack overflow */
3876 
3877  t.p[0] = *a;
3878  t.p[1] = *b;
3879  s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
3880 
3881  for (i = start; i < poly->npts && res; i++)
3882  {
3883  Point interpt;
3884 
3886 
3887  s.p[1] = poly->p[i];
3888 
3889  if (lseg_contain_point(&s, t.p))
3890  {
3891  if (lseg_contain_point(&s, t.p + 1))
3892  return true; /* t is contained by s */
3893 
3894  /* Y-cross */
3895  res = touched_lseg_inside_poly(t.p, t.p + 1, &s, poly, i + 1);
3896  }
3897  else if (lseg_contain_point(&s, t.p + 1))
3898  {
3899  /* Y-cross */
3900  res = touched_lseg_inside_poly(t.p + 1, t.p, &s, poly, i + 1);
3901  }
3902  else if (lseg_interpt_lseg(&interpt, &t, &s))
3903  {
3904  /*
3905  * segments are X-crossing, go to check each subsegment
3906  */
3907 
3908  intersection = true;
3909  res = lseg_inside_poly(t.p, &interpt, poly, i + 1);
3910  if (res)
3911  res = lseg_inside_poly(t.p + 1, &interpt, poly, i + 1);
3912  }
3913 
3914  s.p[0] = s.p[1];
3915  }
3916 
3917  if (res && !intersection)
3918  {
3919  Point p;
3920 
3921  /*
3922  * if X-intersection wasn't found, then check central point of tested
3923  * segment. In opposite case we already check all subsegments
3924  */
3925  p.x = float8_div(float8_pl(t.p[0].x, t.p[1].x), 2.0);
3926  p.y = float8_div(float8_pl(t.p[0].y, t.p[1].y), 2.0);
3927 
3928  res = point_inside(&p, poly->npts, poly->p);
3929  }
3930 
3931  return res;
3932 }
static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
Definition: geo_ops.c:3866
static bool lseg_contain_point(LSEG *lseg, Point *pt)
Definition: geo_ops.c:3109
static bool touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
Definition: geo_ops.c:3830
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
void check_stack_depth(void)
Definition: postgres.c:3531

References a, b, CHECK_FOR_INTERRUPTS, check_stack_depth(), float8_div(), float8_pl(), i, lseg_contain_point(), lseg_interpt_lseg(), POLYGON::npts, LSEG::p, POLYGON::p, point_inside(), res, touched_lseg_inside_poly(), Point::x, and Point::y.

Referenced by poly_contain_poly(), and touched_lseg_inside_poly().

◆ lseg_interpt()

Datum lseg_interpt ( PG_FUNCTION_ARGS  )

Definition at line 2361 of file geo_ops.c.

2362 {
2363  LSEG *l1 = PG_GETARG_LSEG_P(0);
2364  LSEG *l2 = PG_GETARG_LSEG_P(1);
2365  Point *result;
2366 
2367  result = (Point *) palloc(sizeof(Point));
2368 
2369  if (!lseg_interpt_lseg(result, l1, l2))
2370  PG_RETURN_NULL();
2371  PG_RETURN_POINT_P(result);
2372 }

References lseg_interpt_lseg(), palloc(), PG_GETARG_LSEG_P, PG_RETURN_NULL, and PG_RETURN_POINT_P.

Referenced by interpt_pp().

◆ lseg_interpt_line()

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

Definition at line 2675 of file geo_ops.c.

2676 {
2677  Point interpt;
2678  LINE tmp;
2679 
2680  /*
2681  * First, we promote the line segment to a line, because we know how to
2682  * find the intersection point of two lines. If they don't have an
2683  * intersection point, we are done.
2684  */
2685  line_construct(&tmp, &lseg->p[0], lseg_sl(lseg));
2686  if (!line_interpt_line(&interpt, &tmp, line))
2687  return false;
2688 
2689  /*
2690  * Then, we check whether the intersection point is actually on the line
2691  * segment.
2692  */
2693  if (!lseg_contain_point(lseg, &interpt))
2694  return false;
2695  if (result != NULL)
2696  {
2697  /*
2698  * If there is an intersection, then check explicitly for matching
2699  * endpoints since there may be rounding effects with annoying LSB
2700  * residue.
2701  */
2702  if (point_eq_point(&lseg->p[0], &interpt))
2703  *result = lseg->p[0];
2704  else if (point_eq_point(&lseg->p[1], &interpt))
2705  *result = lseg->p[1];
2706  else
2707  *result = interpt;
2708  }
2709 
2710  return true;
2711 }

References line_construct(), line_interpt_line(), lseg_contain_point(), lseg_sl(), LSEG::p, and point_eq_point().

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

2339 {
2340  Point interpt;
2341  LINE tmp;
2342 
2343  line_construct(&tmp, &l2->p[0], lseg_sl(l2));
2344  if (!lseg_interpt_line(&interpt, l1, &tmp))
2345  return false;
2346 
2347  /*
2348  * If the line intersection point isn't within l2, there is no valid
2349  * segment intersection point at all.
2350  */
2351  if (!lseg_contain_point(l2, &interpt))
2352  return false;
2353 
2354  if (result != NULL)
2355  *result = interpt;
2356 
2357  return true;
2358 }

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

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

2189 {
2190  LSEG *l1 = PG_GETARG_LSEG_P(0);
2191  LSEG *l2 = PG_GETARG_LSEG_P(1);
2192 
2193  PG_RETURN_BOOL(lseg_interpt_lseg(NULL, l1, l2));
2194 }

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

2166 {
2167  return point_invsl(&lseg->p[0], &lseg->p[1]);
2168 }

References LSEG::p, and point_invsl().

Referenced by lseg_perp().

◆ lseg_le()

Datum lseg_le ( PG_FUNCTION_ARGS  )

Definition at line 2266 of file geo_ops.c.

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

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

◆ lseg_length()

Datum lseg_length ( PG_FUNCTION_ARGS  )

Definition at line 2172 of file geo_ops.c.

2173 {
2174  LSEG *lseg = PG_GETARG_LSEG_P(0);
2175 
2176  PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1]));
2177 }

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

◆ lseg_lt()

Datum lseg_lt ( PG_FUNCTION_ARGS  )

Definition at line 2256 of file geo_ops.c.

2257 {
2258  LSEG *l1 = PG_GETARG_LSEG_P(0);
2259  LSEG *l2 = PG_GETARG_LSEG_P(1);
2260 
2261  PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]),
2262  point_dt(&l2->p[0], &l2->p[1])));
2263 }

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

◆ lseg_ne()

Datum lseg_ne ( PG_FUNCTION_ARGS  )

Definition at line 2246 of file geo_ops.c.

2247 {
2248  LSEG *l1 = PG_GETARG_LSEG_P(0);
2249  LSEG *l2 = PG_GETARG_LSEG_P(1);
2250 
2251  PG_RETURN_BOOL(!point_eq_point(&l1->p[0], &l2->p[0]) ||
2252  !point_eq_point(&l1->p[1], &l2->p[1]));
2253 }

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

2082 {
2083  LSEG *ls = PG_GETARG_LSEG_P(0);
2084 
2085  PG_RETURN_CSTRING(path_encode(PATH_OPEN, 2, &ls->p[0]));
2086 }

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

◆ lseg_parallel()

Datum lseg_parallel ( PG_FUNCTION_ARGS  )

Definition at line 2198 of file geo_ops.c.

2199 {
2200  LSEG *l1 = PG_GETARG_LSEG_P(0);
2201  LSEG *l2 = PG_GETARG_LSEG_P(1);
2202 
2203  PG_RETURN_BOOL(FPeq(lseg_sl(l1), lseg_sl(l2)));
2204 }

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

◆ lseg_perp()

Datum lseg_perp ( PG_FUNCTION_ARGS  )

Definition at line 2210 of file geo_ops.c.

2211 {
2212  LSEG *l1 = PG_GETARG_LSEG_P(0);
2213  LSEG *l2 = PG_GETARG_LSEG_P(1);
2214 
2216 }
static float8 lseg_invsl(LSEG *lseg)
Definition: geo_ops.c:2165

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

2093 {
2095  LSEG *lseg;
2096 
2097  lseg = (LSEG *) palloc(sizeof(LSEG));
2098 
2099  lseg->p[0].x = pq_getmsgfloat8(buf);
2100  lseg->p[0].y = pq_getmsgfloat8(buf);
2101  lseg->p[1].x = pq_getmsgfloat8(buf);
2102  lseg->p[1].y = pq_getmsgfloat8(buf);
2103 
2104  PG_RETURN_LSEG_P(lseg);
2105 }

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

◆ lseg_send()

Datum lseg_send ( PG_FUNCTION_ARGS  )

Definition at line 2111 of file geo_ops.c.

2112 {
2113  LSEG *ls = PG_GETARG_LSEG_P(0);
2115 
2116  pq_begintypsend(&buf);
2117  pq_sendfloat8(&buf, ls->p[0].x);
2118  pq_sendfloat8(&buf, ls->p[0].y);
2119  pq_sendfloat8(&buf, ls->p[1].x);
2120  pq_sendfloat8(&buf, ls->p[1].y);
2122 }

References buf, LSEG::p, PG_GETARG_LSEG_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), Point::x, and Point::y.

◆ lseg_sl()

static float8 lseg_sl ( LSEG lseg)
inlinestatic

Definition at line 2155 of file geo_ops.c.

2156 {
2157  return point_sl(&lseg->p[0], &lseg->p[1]);
2158 }

References LSEG::p, 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 2219 of file geo_ops.c.

2220 {
2221  LSEG *lseg = PG_GETARG_LSEG_P(0);
2222 
2223  PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));
2224 }

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

◆ make_bound_box()

static void make_bound_box ( POLYGON poly)
static

Definition at line 3376 of file geo_ops.c.

3377 {
3378  int i;
3379  float8 x1,
3380  y1,
3381  x2,
3382  y2;
3383 
3384  Assert(poly->npts > 0);
3385 
3386  x1 = x2 = poly->p[0].x;
3387  y2 = y1 = poly->p[0].y;
3388  for (i = 1; i < poly->npts; i++)
3389  {
3390  if (float8_lt(poly->p[i].x, x1))
3391  x1 = poly->p[i].x;
3392  if (float8_gt(poly->p[i].x, x2))
3393  x2 = poly->p[i].x;
3394  if (float8_lt(poly->p[i].y, y1))
3395  y1 = poly->p[i].y;
3396  if (float8_gt(poly->p[i].y, y2))
3397  y2 = poly->p[i].y;
3398  }
3399 
3400  poly->boundbox.low.x = x1;
3401  poly->boundbox.high.x = x2;
3402  poly->boundbox.low.y = y1;
3403  poly->boundbox.high.y = y2;
3404 }

References Assert(), POLYGON::boundbox, float8_gt(), float8_lt(), BOX::high, i, BOX::low, POLYGON::npts, POLYGON::p, Point::x, and Point::y.

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

◆ on_pb()

Datum on_pb ( PG_FUNCTION_ARGS  )

Definition at line 3137 of file geo_ops.c.

3138 {
3139  Point *pt = PG_GETARG_POINT_P(0);
3140  BOX *box = PG_GETARG_BOX_P(1);
3141 
3143 }

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

◆ on_pl()

Datum on_pl ( PG_FUNCTION_ARGS  )

Definition at line 3095 of file geo_ops.c.

3096 {
3097  Point *pt = PG_GETARG_POINT_P(0);
3098  LINE *line = PG_GETARG_LINE_P(1);
3099 
3101 }
static bool line_contain_point(LINE *line, Point *point)
Definition: geo_ops.c:3087

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

3167 {
3168  Point *pt = PG_GETARG_POINT_P(0);
3169  PATH *path = PG_GETARG_PATH_P(1);
3170  int i,
3171  n;
3172  float8 a,
3173  b;
3174 
3175  /*-- OPEN --*/
3176  if (!path->closed)
3177  {
3178  n = path->npts - 1;
3179  a = point_dt(pt, &path->p[0]);
3180  for (i = 0; i < n; i++)
3181  {
3182  b = point_dt(pt, &path->p[i + 1]);
3183  if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1])))
3184  PG_RETURN_BOOL(true);
3185  a = b;
3186  }
3187  PG_RETURN_BOOL(false);
3188  }
3189 
3190  /*-- CLOSED --*/
3191  PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
3192 }

References a, b, PATH::closed, 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 3117 of file geo_ops.c.

3118 {
3119  Point *pt = PG_GETARG_POINT_P(0);
3120  LSEG *lseg = PG_GETARG_LSEG_P(1);
3121 
3123 }

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

3225 {
3226  LSEG *lseg = PG_GETARG_LSEG_P(0);
3227  BOX *box = PG_GETARG_BOX_P(1);
3228 
3229  PG_RETURN_BOOL(box_contain_lseg(box, lseg));
3230 }
static bool box_contain_lseg(BOX *box, LSEG *lseg)
Definition: geo_ops.c:3217

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

◆ on_sl()

Datum on_sl ( PG_FUNCTION_ARGS  )

Definition at line 3201 of file geo_ops.c.

3202 {
3203  LSEG *lseg = PG_GETARG_LSEG_P(0);
3204  LINE *line = PG_GETARG_LINE_P(1);
3205 
3206  PG_RETURN_BOOL(line_contain_point(line, &lseg->p[0]) &&
3207  line_contain_point(line, &lseg->p[1]));
3208 }

References line_contain_point(), LSEG::p, 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 392 of file geo_ops.c.

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

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

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

References DELIM, ereturn, errcode(), errmsg(), LDELIM, RDELIM, single_decode(), generate_unaccent_rules::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 255 of file geo_ops.c.

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

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

Referenced by circle_out(), and path_encode().

◆ path_add()

Datum path_add ( PG_FUNCTION_ARGS  )

Definition at line 4348 of file geo_ops.c.

4349 {
4350  PATH *p1 = PG_GETARG_PATH_P(0);
4351  PATH *p2 = PG_GETARG_PATH_P(1);
4352  PATH *result;
4353  int size,
4354  base_size;
4355  int i;
4356 
4357  if (p1->closed || p2->closed)
4358  PG_RETURN_NULL();
4359 
4360  base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
4361  size = offsetof(PATH, p) + base_size;
4362 
4363  /* Check for integer overflow */
4364  if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
4365  size <= base_size)
4366  ereport(ERROR,
4367  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4368  errmsg("too many points requested")));
4369 
4370  result = (PATH *) palloc(size);
4371 
4372  SET_VARSIZE(result, size);
4373  result->npts = (p1->npts + p2->npts);
4374  result->closed = p1->closed;
4375  /* prevent instability in unused pad bytes */
4376  result->dummy = 0;
4377 
4378  for (i = 0; i < p1->npts; i++)
4379  {
4380  result->p[i].x = p1->p[i].x;
4381  result->p[i].y = p1->p[i].y;
4382  }
4383  for (i = 0; i < p2->npts; i++)
4384  {
4385  result->p[i + p1->npts].x = p2->p[i].x;
4386  result->p[i + p1->npts].y = p2->p[i].y;
4387  }
4388 
4389  PG_RETURN_PATH_P(result);
4390 }
#define PG_RETURN_PATH_P(x)
Definition: geo_decls.h:218
int32 dummy
Definition: geo_decls.h:120

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

◆ path_add_pt()

Datum path_add_pt ( PG_FUNCTION_ARGS  )

Definition at line 4396 of file geo_ops.c.

4397 {
4398  PATH *path = PG_GETARG_PATH_P_COPY(0);
4399  Point *point = PG_GETARG_POINT_P(1);
4400  int i;
4401 
4402  for (i = 0; i < path->npts; i++)
4403  point_add_point(&path->p[i], &path->p[i], point);
4404 
4405  PG_RETURN_PATH_P(path);
4406 }
#define PG_GETARG_PATH_P_COPY(n)
Definition: geo_decls.h:217

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

1381 {
1382  PATH *path = PG_GETARG_PATH_P(0);
1383  float8 area = 0.0;
1384  int i,
1385  j;
1386 
1387  if (!path->closed)
1388  PG_RETURN_NULL();
1389 
1390  for (i = 0; i < path->npts; i++)
1391  {
1392  j = (i + 1) % path->npts;
1393  area = float8_pl(area, float8_mul(path->p[i].x, path->p[j].y));
1394  area = float8_mi(area, float8_mul(path->p[i].y, path->p[j].x));
1395  }
1396 
1397  PG_RETURN_FLOAT8(float8_div(fabs(area), 2.0));
1398 }
int j
Definition: isn.c:74

References PATH::closed, 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 1627 of file geo_ops.c.

1628 {
1629  PATH *path = PG_GETARG_PATH_P_COPY(0);
1630 
1631  path->closed = true;
1632 
1633  PG_RETURN_PATH_P(path);
1634 }

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

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

References DELIM, ereturn, errcode(), errmsg(), i, LDELIM, LDELIM_EP, pair_decode(), RDELIM, RDELIM_EP, generate_unaccent_rules::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 1730 of file geo_ops.c.

1731 {
1732  PATH *p1 = PG_GETARG_PATH_P(0);
1733  PATH *p2 = PG_GETARG_PATH_P(1);
1734  float8 min = 0.0; /* initialize to keep compiler quiet */
1735  bool have_min = false;
1736  float8 tmp;
1737  int i,
1738  j;
1739  LSEG seg1,
1740  seg2;
1741 
1742  for (i = 0; i < p1->npts; i++)
1743  {
1744  int iprev;
1745 
1746  if (i > 0)
1747  iprev = i - 1;
1748  else
1749  {
1750  if (!p1->closed)
1751  continue;
1752  iprev = p1->npts - 1; /* include the closure segment */
1753  }
1754 
1755  for (j = 0; j < p2->npts; j++)
1756  {
1757  int jprev;
1758 
1759  if (j > 0)
1760  jprev = j - 1;
1761  else
1762  {
1763  if (!p2->closed)
1764  continue;
1765  jprev = p2->npts - 1; /* include the closure segment */
1766  }
1767 
1768  statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1769  statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1770 
1771  tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
1772  if (!have_min || float8_lt(tmp, min))
1773  {
1774  min = tmp;
1775  have_min = true;
1776  }
1777  }
1778  }
1779 
1780  if (!have_min)
1781  PG_RETURN_NULL();
1782 
1783  PG_RETURN_FLOAT8(min);
1784 }

References PATH::closed, float8_lt(), i, j, lseg_closept_lseg(), PATH::npts, PATH::p, p2, 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 4438 of file geo_ops.c.

4439 {
4440  PATH *path = PG_GETARG_PATH_P_COPY(0);
4441  Point *point = PG_GETARG_POINT_P(1);
4442  int i;
4443 
4444  for (i = 0; i < path->npts; i++)
4445  point_div_point(&path->p[i], &path->p[i], point);
4446 
4447  PG_RETURN_PATH_P(path);
4448 }

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

341 {
343  int i;
344 
346 
347  switch (path_delim)
348  {
349  case PATH_CLOSED:
351  break;
352  case PATH_OPEN:
354  break;
355  case PATH_NONE:
356  break;
357  }
358 
359  for (i = 0; i < npts; i++)
360  {
361  if (i > 0)
364  pair_encode(pt->x, pt->y, &str);
366  pt++;
367  }
368 
369  switch (path_delim)
370  {
371  case PATH_CLOSED:
373  break;
374  case PATH_OPEN:
376  break;
377  case PATH_NONE:
378  break;
379  }
380 
381  return str.data;
382 } /* path_encode() */
path_delim
Definition: geo_ops.c:74

References appendStringInfoChar(), DELIM, i, initStringInfo(), LDELIM, LDELIM_EP, pair_encode(), PATH_CLOSED, PATH_NONE, PATH_OPEN, RDELIM, RDELIM_EP, generate_unaccent_rules::str, Point::x, and Point::y.

◆ path_in()

Datum path_in ( PG_FUNCTION_ARGS  )

Definition at line 1402 of file geo_ops.c.

1403 {
1404  char *str = PG_GETARG_CSTRING(0);
1405  Node *escontext = fcinfo->context;
1406  PATH *path;
1407  bool isopen;
1408  char *s;
1409  int npts;
1410  int size;
1411  int base_size;
1412  int depth = 0;
1413 
1414  if ((npts = pair_count(str, ',')) <= 0)
1415  ereturn(escontext, (Datum) 0,
1416  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1417  errmsg("invalid input syntax for type %s: \"%s\"",
1418  "path", str)));
1419 
1420  s = str;
1421  while (isspace((unsigned char) *s))
1422  s++;
1423 
1424  /* skip single leading paren */
1425  if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
1426  {
1427  s++;
1428  depth++;
1429  }
1430 
1431  base_size = sizeof(path->p[0]) * npts;
1432  size = offsetof(PATH, p) + base_size;
1433 
1434  /* Check for integer overflow */
1435  if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
1436  ereturn(escontext, (Datum) 0,
1437  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1438  errmsg("too many points requested")));
1439 
1440  path = (PATH *) palloc(size);
1441 
1442  SET_VARSIZE(path, size);
1443  path->npts = npts;
1444 
1445  if (!path_decode(s, true, npts, &(path->p[0]), &isopen, &s, "path", str,
1446  escontext))
1447  PG_RETURN_NULL();
1448 
1449  if (depth >= 1)
1450  {
1451  if (*s++ != RDELIM)
1452  ereturn(escontext, (Datum) 0,
1453  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1454  errmsg("invalid input syntax for type %s: \"%s\"",
1455  "path", str)));
1456  while (isspace((unsigned char) *s))
1457  s++;
1458  }
1459  if (*s != '\0')
1460  ereturn(escontext, (Datum) 0,
1461  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1462  errmsg("invalid input syntax for type %s: \"%s\"",
1463  "path", str)));
1464 
1465  path->closed = (!isopen);
1466  /* prevent instability in unused pad bytes */
1467  path->dummy = 0;
1468 
1469  PG_RETURN_PATH_P(path);
1470 }
static int pair_count(char *s, char delim)
Definition: geo_ops.c:392

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

◆ path_inter()

Datum path_inter ( PG_FUNCTION_ARGS  )

Definition at line 1653 of file geo_ops.c.

1654 {
1655  PATH *p1 = PG_GETARG_PATH_P(0);
1656  PATH *p2 = PG_GETARG_PATH_P(1);
1657  BOX b1,
1658  b2;
1659  int i,
1660  j;
1661  LSEG seg1,
1662  seg2;
1663 
1664  Assert(p1->npts > 0 && p2->npts > 0);
1665 
1666  b1.high.x = b1.low.x = p1->p[0].x;
1667  b1.high.y = b1.low.y = p1->p[0].y;
1668  for (i = 1; i < p1->npts; i++)
1669  {
1670  b1.high.x = float8_max(p1->p[i].x, b1.high.x);
1671  b1.high.y = float8_max(p1->p[i].y, b1.high.y);
1672  b1.low.x = float8_min(p1->p[i].x, b1.low.x);
1673  b1.low.y = float8_min(p1->p[i].y, b1.low.y);
1674  }
1675  b2.high.x = b2.low.x = p2->p[0].x;
1676  b2.high.y = b2.low.y = p2->p[0].y;
1677  for (i = 1; i < p2->npts; i++)
1678  {
1679  b2.high.x = float8_max(p2->p[i].x, b2.high.x);
1680  b2.high.y = float8_max(p2->p[i].y, b2.high.y);
1681  b2.low.x = float8_min(p2->p[i].x, b2.low.x);
1682  b2.low.y = float8_min(p2->p[i].y, b2.low.y);
1683  }
1684  if (!box_ov(&b1, &b2))
1685  PG_RETURN_BOOL(false);
1686 
1687  /* pairwise check lseg intersections */
1688  for (i = 0; i < p1->npts; i++)
1689  {
1690  int iprev;
1691 
1692  if (i > 0)
1693  iprev = i - 1;
1694  else
1695  {
1696  if (!p1->closed)
1697  continue;
1698  iprev = p1->npts - 1; /* include the closure segment */
1699  }
1700 
1701  for (j = 0; j < p2->npts; j++)
1702  {
1703  int jprev;
1704 
1705  if (j > 0)
1706  jprev = j - 1;
1707  else
1708  {
1709  if (!p2->closed)
1710  continue;
1711  jprev = p2->npts - 1; /* include the closure segment */
1712  }
1713 
1714  statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1715  statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
1716  if (lseg_interpt_lseg(NULL, &seg1, &seg2))
1717  PG_RETURN_BOOL(true);
1718  }
1719  }
1720 
1721  /* if we dropped through, no two segs intersected */
1722  PG_RETURN_BOOL(false);
1723 }

References Assert(), box_ov(), PATH::closed, float8_max(), float8_min(), BOX::high, i, j, BOX::low, lseg_interpt_lseg(), PATH::npts, PATH::p, p2, PG_GETARG_PATH_P, PG_RETURN_BOOL, statlseg_construct(), Point::x, and Point::y.

◆ path_isclosed()

Datum path_isclosed ( PG_FUNCTION_ARGS  )

Definition at line 1602 of file geo_ops.c.

1603 {
1604  PATH *path = PG_GETARG_PATH_P(0);
1605 
1606  PG_RETURN_BOOL(path->closed);
1607 }

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_isopen()

Datum path_isopen ( PG_FUNCTION_ARGS  )

Definition at line 1610 of file geo_ops.c.

1611 {
1612  PATH *path = PG_GETARG_PATH_P(0);
1613 
1614  PG_RETURN_BOOL(!path->closed);
1615 }

References PATH::closed, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_length()

Datum path_length ( PG_FUNCTION_ARGS  )

Definition at line 1792 of file geo_ops.c.

1793 {
1794  PATH *path = PG_GETARG_PATH_P(0);
1795  float8 result = 0.0;
1796  int i;
1797 
1798  for (i = 0; i < path->npts; i++)
1799  {
1800  int iprev;
1801 
1802  if (i > 0)
1803  iprev = i - 1;
1804  else
1805  {
1806  if (!path->closed)
1807  continue;
1808  iprev = path->npts - 1; /* include the closure segment */
1809  }
1810 
1811  result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i]));
1812  }
1813 
1814  PG_RETURN_FLOAT8(result);
1815 }

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

◆ path_mul_pt()

Datum path_mul_pt ( PG_FUNCTION_ARGS  )

Definition at line 4425 of file geo_ops.c.

4426 {
4427  PATH *path = PG_GETARG_PATH_P_COPY(0);
4428  Point *point = PG_GETARG_POINT_P(1);
4429  int i;
4430 
4431  for (i = 0; i < path->npts; i++)
4432  point_mul_point(&path->p[i], &path->p[i], point);
4433 
4434  PG_RETURN_PATH_P(path);
4435 }

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

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

References PATH::npts, p2, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_ge()

Datum path_n_ge ( PG_FUNCTION_ARGS  )

Definition at line 1589 of file geo_ops.c.

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

References PATH::npts, p2, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_gt()

Datum path_n_gt ( PG_FUNCTION_ARGS  )

Definition at line 1562 of file geo_ops.c.

1563 {
1564  PATH *p1 = PG_GETARG_PATH_P(0);
1565  PATH *p2 = PG_GETARG_PATH_P(1);
1566 
1567  PG_RETURN_BOOL(p1->npts > p2->npts);
1568 }

References PATH::npts, p2, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_le()

Datum path_n_le ( PG_FUNCTION_ARGS  )

Definition at line 1580 of file geo_ops.c.

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

References PATH::npts, p2, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_n_lt()

Datum path_n_lt ( PG_FUNCTION_ARGS  )

Definition at line 1553 of file geo_ops.c.

1554 {
1555  PATH *p1 = PG_GETARG_PATH_P(0);
1556  PATH *p2 = PG_GETARG_PATH_P(1);
1557 
1558  PG_RETURN_BOOL(p1->npts < p2->npts);
1559 }

References PATH::npts, p2, PG_GETARG_PATH_P, and PG_RETURN_BOOL.

◆ path_npoints()

Datum path_npoints ( PG_FUNCTION_ARGS  )

Definition at line 1618 of file geo_ops.c.

1619 {
1620  PATH *path = PG_GETARG_PATH_P(0);
1621 
1622  PG_RETURN_INT32(path->npts);
1623 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References PATH::npts, PG_GETARG_PATH_P, and PG_RETURN_INT32.

◆ path_open()

Datum path_open ( PG_FUNCTION_ARGS  )

Definition at line 1637 of file geo_ops.c.

1638 {
1639  PATH *path = PG_GETARG_PATH_P_COPY(0);
1640 
1641  path->closed = false;
1642 
1643  PG_RETURN_PATH_P(path);
1644 }

References PATH::closed, PG_GETARG_PATH_P_COPY, and PG_RETURN_PATH_P.

◆ path_out()

Datum path_out ( PG_FUNCTION_ARGS  )

Definition at line 1474 of file geo_ops.c.

1475 {
1476  PATH *path = PG_GETARG_PATH_P(0);
1477 
1478  PG_RETURN_CSTRING(path_encode(path->closed ? PATH_CLOSED : PATH_OPEN, path->npts, path->p));
1479 }

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

4453 {
4454  PATH *path = PG_GETARG_PATH_P(0);
4455  POLYGON *poly;
4456  int size;
4457  int i;
4458 
4459  /* This is not very consistent --- other similar cases return NULL ... */
4460  if (!path->closed)
4461  ereport(ERROR,
4462  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4463  errmsg("open path cannot be converted to polygon")));
4464 
4465  /*
4466  * Never overflows: the old size fit in MaxAllocSize, and the new size is
4467  * just a small constant larger.
4468  */
4469  size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * path->npts;
4470  poly = (POLYGON *) palloc(size);
4471 
4472  SET_VARSIZE(poly, size);
4473  poly->npts = path->npts;
4474 
4475  for (i = 0; i < path->npts; i++)
4476  {
4477  poly->p[i].x = path->p[i].x;
4478  poly->p[i].y = path->p[i].y;
4479  }
4480 
4481  make_bound_box(poly);
4482 
4483  PG_RETURN_POLYGON_P(poly);
4484 }

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

◆ path_recv()

Datum path_recv ( PG_FUNCTION_ARGS  )

Definition at line 1488 of file geo_ops.c.

1489 {
1491  PATH *path;
1492  int closed;
1493  int32 npts;
1494  int32 i;
1495  int size;
1496 
1497  closed = pq_getmsgbyte(buf);
1498  npts = pq_getmsgint(buf, sizeof(int32));
1499  if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p)) / sizeof(Point)))
1500  ereport(ERROR,
1501  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1502  errmsg("invalid number of points in external \"path\" value")));
1503 
1504  size = offsetof(PATH, p) + sizeof(path->p[0]) * npts;
1505  path = (PATH *) palloc(size);
1506 
1507  SET_VARSIZE(path, size);
1508  path->npts = npts;
1509  path->closed = (closed ? 1 : 0);
1510  /* prevent instability in unused pad bytes */
1511  path->dummy = 0;
1512 
1513  for (i = 0; i < npts; i++)
1514  {
1515  path->p[i].x = pq_getmsgfloat8(buf);
1516  path->p[i].y = pq_getmsgfloat8(buf);
1517  }
1518 
1519  PG_RETURN_PATH_P(path);
1520 }
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:399

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

◆ path_send()

Datum path_send ( PG_FUNCTION_ARGS  )

Definition at line 1526 of file geo_ops.c.

1527 {
1528  PATH *path = PG_GETARG_PATH_P(0);
1530  int32 i;
1531 
1532  pq_begintypsend(&buf);
1533  pq_sendbyte(&buf, path->closed ? 1 : 0);
1534  pq_sendint32(&buf, path->npts);
1535  for (i = 0; i < path->npts; i++)
1536  {
1537  pq_sendfloat8(&buf, path->p[i].x);
1538  pq_sendfloat8(&buf, path->p[i].y);
1539  }
1541 }
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 4409 of file geo_ops.c.

4410 {
4411  PATH *path = PG_GETARG_PATH_P_COPY(0);
4412  Point *point = PG_GETARG_POINT_P(1);
4413  int i;
4414 
4415  for (i = 0; i < path->npts; i++)
4416  point_sub_point(&path->p[i], &path->p[i], point);
4417 
4418  PG_RETURN_PATH_P(path);
4419 }

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

◆ pg_hypot()

float8 pg_hypot ( float8  x,
float8  y 
)

Definition at line 5519 of file geo_ops.c.

5520 {
5521  float8 yx,
5522  result;
5523 
5524  /* Handle INF and NaN properly */
5525  if (isinf(x) || isinf(y))
5526  return get_float8_infinity();
5527 
5528  if (isnan(x) || isnan(y))
5529  return get_float8_nan();
5530 
5531  /* Else, drop any minus signs */
5532  x = fabs(x);
5533  y = fabs(y);
5534 
5535  /* Swap x and y if needed to make x the larger one */
5536  if (x < y)
5537  {
5538  float8 temp = x;
5539 
5540  x = y;
5541  y = temp;
5542  }
5543 
5544  /*
5545  * If y is zero, the hypotenuse is x. This test saves a few cycles in
5546  * such cases, but more importantly it also protects against
5547  * divide-by-zero errors, since now x >= y.
5548  */
5549  if (y == 0.0)
5550  return x;
5551 
5552  /* Determine the hypotenuse */
5553  yx = y / x;
5554  result = x * sqrt(1.0 + (yx * yx));
5555 
5556  if (unlikely(isinf(result)))
5558  if (unlikely(result == 0.0))
5560 
5561  return result;
5562 }
pg_noinline void float_overflow_error(void)
Definition: float.c:85
pg_noinline void float_underflow_error(void)
Definition: float.c:93

References float_overflow_error(), float_underflow_error(), get_float8_infinity(), get_float8_nan(), unlikely, x, and y.

◆ plist_same()

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

Definition at line 5457 of file geo_ops.c.

5458 {
5459  int i,
5460  ii,
5461  j;
5462 
5463  /* find match for first point */
5464  for (i = 0; i < npts; i++)
5465  {
5466  if (point_eq_point(&p2[i], &p1[0]))
5467  {
5468 
5469  /* match found? then look forward through remaining points */
5470  for (ii = 1, j = i + 1; ii < npts; ii++, j++)
5471  {
5472  if (j >= npts)
5473  j = 0;
5474  if (!point_eq_point(&p2[j], &p1[ii]))
5475  break;
5476  }
5477  if (ii == npts)
5478  return true;
5479 
5480  /* match not found forwards? then look backwards */
5481  for (ii = 1, j = i - 1; ii < npts; ii++, j--)
5482  {
5483  if (j < 0)
5484  j = (npts - 1);
5485  if (!point_eq_point(&p2[j], &p1[ii]))
5486  break;
5487  }
5488  if (ii == npts)
5489  return true;
5490  }
5491  }
5492 
5493  return false;
5494 }

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

Referenced by poly_same().

◆ point_above()

Datum point_above ( PG_FUNCTION_ARGS  )

Definition at line 1919 of file geo_ops.c.

1920 {
1921  Point *pt1 = PG_GETARG_POINT_P(0);
1922  Point *pt2 = PG_GETARG_POINT_P(1);
1923 
1924  PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
1925 }

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

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

◆ point_add()

Datum point_add ( PG_FUNCTION_ARGS  )

Definition at line 4119 of file geo_ops.c.

4120 {
4121  Point *p1 = PG_GETARG_POINT_P(0);
4122  Point *p2 = PG_GETARG_POINT_P(1);
4123  Point *result;
4124 
4125  result = (Point *) palloc(sizeof(Point));
4126 
4127  point_add_point(result, p1, p2);
4128 
4129  PG_RETURN_POINT_P(result);
4130 }

References p2, palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, and point_add_point().

◆ point_add_point()

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

Definition at line 4111 of file geo_ops.c.

4112 {
4113  point_construct(result,
4114  float8_pl(pt1->x, pt2->x),
4115  float8_pl(pt1->y, pt2->y));
4116 }

References float8_pl(), point_construct(), Point::x, and Point::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 1928 of file geo_ops.c.

1929 {
1930  Point *pt1 = PG_GETARG_POINT_P(0);
1931  Point *pt2 = PG_GETARG_POINT_P(1);
1932 
1933  PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
1934 }

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

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

◆ point_box()

Datum point_box ( PG_FUNCTION_ARGS  )

Definition at line 4302 of file geo_ops.c.

4303 {
4304  Point *pt = PG_GETARG_POINT_P(0);
4305  BOX *box;
4306 
4307  box = (BOX *) palloc(sizeof(BOX));
4308 
4309  box->high.x = pt->x;
4310  box->low.x = pt->x;
4311  box->high.y = pt->y;
4312  box->low.y = pt->y;
4313 
4314  PG_RETURN_BOX_P(box);
4315 }

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

◆ point_construct()

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

Definition at line 1884 of file geo_ops.c.

1885 {
1886  result->x = x;
1887  result->y = y;
1888 }

References x, Point::x, y, and Point::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 1993 of file geo_ops.c.

1994 {
1995  Point *pt1 = PG_GETARG_POINT_P(0);
1996  Point *pt2 = PG_GETARG_POINT_P(1);
1997 
1998  PG_RETURN_FLOAT8(point_dt(pt1, pt2));
1999 }

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

4197 {
4198  Point *p1 = PG_GETARG_POINT_P(0);
4199  Point *p2 = PG_GETARG_POINT_P(1);
4200  Point *result;
4201 
4202  result = (Point *) palloc(sizeof(Point));
4203 
4204  point_div_point(result, p1, p2);
4205 
4206  PG_RETURN_POINT_P(result);
4207 }

References p2, palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, and point_div_point().

◆ point_div_point()

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

Definition at line 4182 of file geo_ops.c.

4183 {
4184  float8 div;
4185 
4186  div = float8_pl(float8_mul(pt2->x, pt2->x), float8_mul(pt2->y, pt2->y));
4187 
4188  point_construct(result,
4189  float8_div(float8_pl(float8_mul(pt1->x, pt2->x),
4190  float8_mul(pt1->y, pt2->y)), div),
4191  float8_div(float8_mi(float8_mul(pt1->y, pt2->x),
4192  float8_mul(pt1->x, pt2->y)), div));
4193 }

References float8_div(), float8_mi(), float8_mul(), float8_pl(), point_construct(), Point::x, and Point::y.

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

◆ point_dt()

◆ point_eq()

Datum point_eq ( PG_FUNCTION_ARGS  )

Definition at line 1955 of file geo_ops.c.

1956 {
1957  Point *pt1 = PG_GETARG_POINT_P(0);
1958  Point *pt2 = PG_GETARG_POINT_P(1);
1959 
1960  PG_RETURN_BOOL(point_eq_point(pt1, pt2));
1961 }

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

1978 {
1979  /* If any NaNs are involved, insist on exact equality */
1980  if (unlikely(isnan(pt1->x) || isnan(pt1->y) ||
1981  isnan(pt2->x) || isnan(pt2->y)))
1982  return (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y));
1983 
1984  return (FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
1985 }

References float8_eq(), FPeq(), unlikely, Point::x, and Point::y.

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

1947 {
1948  Point *pt1 = PG_GETARG_POINT_P(0);
1949  Point *pt2 = PG_GETARG_POINT_P(1);
1950 
1951  PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));
1952 }

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

Referenced by getQuadrant().

◆ point_in()

Datum point_in ( PG_FUNCTION_ARGS  )

Definition at line 1831 of file geo_ops.c.

1832 {
1833  char *str = PG_GETARG_CSTRING(0);
1834  Point *point = (Point *) palloc(sizeof(Point));
1835 
1836  /* Ignore failure from pair_decode, since our return value won't matter */
1837  pair_decode(str, &point->x, &point->y, NULL, "point", str, fcinfo->context);
1838  PG_RETURN_POINT_P(point);
1839 }

References pair_decode(), palloc(), PG_GETARG_CSTRING, PG_RETURN_POINT_P, generate_unaccent_rules::str, Point::x, and Point::y.

◆ point_inside()

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

Definition at line 5340 of file geo_ops.c.

5341 {
5342  float8 x0,
5343  y0;
5344  float8 prev_x,
5345  prev_y;
5346  int i = 0;
5347  float8 x,
5348  y;
5349  int cross,
5350  total_cross = 0;
5351 
5352  Assert(npts > 0);
5353 
5354  /* compute first polygon point relative to single point */
5355  x0 = float8_mi(plist[0].x, p->x);
5356  y0 = float8_mi(plist[0].y, p->y);
5357 
5358  prev_x = x0;
5359  prev_y = y0;
5360  /* loop over polygon points and aggregate total_cross */
5361  for (i = 1; i < npts; i++)
5362  {
5363  /* compute next polygon point relative to single point */
5364  x = float8_mi(plist[i].x, p->x);
5365  y = float8_mi(plist[i].y, p->y);
5366 
5367  /* compute previous to current point crossing */
5368  if ((cross = lseg_crossing(x, y, prev_x, prev_y)) == POINT_ON_POLYGON)
5369  return 2;
5370  total_cross += cross;
5371 
5372  prev_x = x;
5373  prev_y = y;
5374  }
5375 
5376  /* now do the first point */
5377  if ((cross = lseg_crossing(x0, y0, prev_x, prev_y)) == POINT_ON_POLYGON)
5378  return 2;
5379  total_cross += cross;
5380 
5381  if (total_cross != 0)
5382  return 1;
5383  return 0;
5384 }
static int lseg_crossing(float8 x, float8 y, float8 prev_x, float8 prev_y)
Definition: geo_ops.c:5397

References Assert(), 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 2039 of file geo_ops.c.

2040 {
2041  if (FPeq(pt1->x, pt2->x))
2042  return 0.0;
2043  if (FPeq(pt1->y, pt2->y))
2044  return get_float8_infinity();
2045  return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y));
2046 }

References float8_div(), float8_mi(), FPeq(), get_float8_infinity(), Point::x, and Point::y.

Referenced by lseg_closept_point(), and lseg_invsl().

◆ point_left()

Datum point_left ( PG_FUNCTION_ARGS  )

Definition at line 1901 of file geo_ops.c.

1902 {
1903  Point *pt1 = PG_GETARG_POINT_P(0);
1904  Point *pt2 = PG_GETARG_POINT_P(1);
1905 
1906  PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));
1907 }

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

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

◆ point_mul()

Datum point_mul ( PG_FUNCTION_ARGS  )

Definition at line 4167 of file geo_ops.c.

4168 {
4169  Point *p1 = PG_GETARG_POINT_P(0);
4170  Point *p2 = PG_GETARG_POINT_P(1);
4171  Point *result;
4172 
4173  result = (Point *) palloc(sizeof(Point));
4174 
4175  point_mul_point(result, p1, p2);
4176 
4177  PG_RETURN_POINT_P(result);
4178 }

References p2, palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, and point_mul_point().

◆ point_mul_point()

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

Definition at line 4157 of file geo_ops.c.

4158 {
4159  point_construct(result,
4160  float8_mi(float8_mul(pt1->x, pt2->x),
4161  float8_mul(pt1->y, pt2->y)),
4162  float8_pl(float8_mul(pt1->x, pt2->y),
4163  float8_mul(pt1->y, pt2->x)));
4164 }

References float8_mi(), float8_mul(), float8_pl(), point_construct(), Point::x, and Point::y.

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

◆ point_ne()

Datum point_ne ( PG_FUNCTION_ARGS  )

Definition at line 1964 of file geo_ops.c.

1965 {
1966  Point *pt1 = PG_GETARG_POINT_P(0);
1967  Point *pt2 = PG_GETARG_POINT_P(1);
1968 
1969  PG_RETURN_BOOL(!point_eq_point(pt1, pt2));
1970 }

References PG_GETARG_POINT_P, PG_RETURN_BOOL, and point_eq_point().

◆ point_out()

Datum point_out ( PG_FUNCTION_ARGS  )

Definition at line 1842 of file geo_ops.c.

1843 {
1844  Point *pt = PG_GETARG_POINT_P(0);
1845 
1847 }

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

◆ point_recv()

Datum point_recv ( PG_FUNCTION_ARGS  )

Definition at line 1853 of file geo_ops.c.

1854 {
1856  Point *point;
1857 
1858  point = (Point *) palloc(sizeof(Point));
1859  point->x = pq_getmsgfloat8(buf);
1860  point->y = pq_getmsgfloat8(buf);
1861  PG_RETURN_POINT_P(point);
1862 }

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

◆ point_right()

Datum point_right ( PG_FUNCTION_ARGS  )

Definition at line 1910 of file geo_ops.c.

1911 {
1912  Point *pt1 = PG_GETARG_POINT_P(0);
1913  Point *pt2 = PG_GETARG_POINT_P(1);
1914 
1915  PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));
1916 }

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

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

◆ point_send()

Datum point_send ( PG_FUNCTION_ARGS  )

Definition at line 1868 of file geo_ops.c.

1869 {
1870  Point *pt = PG_GETARG_POINT_P(0);
1872 
1873  pq_begintypsend(&buf);
1874  pq_sendfloat8(&buf, pt->x);
1875  pq_sendfloat8(&buf, pt->y);
1877 }

References buf, PG_GETARG_POINT_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), Point::x, and Point::y.

◆ point_sl()

static float8 point_sl ( Point pt1,
Point pt2 
)
inlinestatic

Definition at line 2023 of file geo_ops.c.

2024 {
2025  if (FPeq(pt1->x, pt2->x))
2026  return get_float8_infinity();
2027  if (FPeq(pt1->y, pt2->y))
2028  return 0.0;
2029  return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x));
2030 }

References float8_div(), float8_mi(), FPeq(), get_float8_infinity(), Point::x, and Point::y.

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

◆ point_slope()

Datum point_slope ( PG_FUNCTION_ARGS  )

Definition at line 2008 of file geo_ops.c.

2009 {
2010  Point *pt1 = PG_GETARG_POINT_P(0);
2011  Point *pt2 = PG_GETARG_POINT_P(1);
2012 
2013  PG_RETURN_FLOAT8(point_sl(pt1, pt2));
2014 }

References PG_GETARG_POINT_P, PG_RETURN_FLOAT8, and point_sl().

◆ point_sub()

Datum point_sub ( PG_FUNCTION_ARGS  )

Definition at line 4142 of file geo_ops.c.

4143 {
4144  Point *p1 = PG_GETARG_POINT_P(0);
4145  Point *p2 = PG_GETARG_POINT_P(1);
4146  Point *result;
4147 
4148  result = (Point *) palloc(sizeof(Point));
4149 
4150  point_sub_point(result, p1, p2);
4151 
4152  PG_RETURN_POINT_P(result);
4153 }

References p2, palloc(), PG_GETARG_POINT_P, PG_RETURN_POINT_P, and point_sub_point().

◆ point_sub_point()

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

Definition at line 4134 of file geo_ops.c.

4135 {
4136  point_construct(result,
4137  float8_mi(pt1->x, pt2->x),
4138  float8_mi(pt1->y, pt2->y));
4139 }

References float8_mi(), point_construct(), Point::x, and Point::y.

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

◆ point_vert()

Datum point_vert ( PG_FUNCTION_ARGS  )

Definition at line 1937 of file geo_ops.c.

1938 {
1939  Point *pt1 = PG_GETARG_POINT_P(0);
1940  Point *pt2 = PG_GETARG_POINT_P(1);
1941 
1942  PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));
1943 }

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

Referenced by getQuadrant().

◆ points_box()

Datum points_box ( PG_FUNCTION_ARGS  )

Definition at line 4217 of file geo_ops.c.

4218 {
4219  Point *p1 = PG_GETARG_POINT_P(0);
4220  Point *p2 = PG_GETARG_POINT_P(1);
4221  BOX *result;
4222 
4223  result = (BOX *) palloc(sizeof(BOX));
4224 
4225  box_construct(result, p1, p2);
4226 
4227  PG_RETURN_BOX_P(result);
4228 }

References box_construct(), p2, palloc(), PG_GETARG_POINT_P, and PG_RETURN_BOX_P.

◆ poly_above()

Datum poly_above ( PG_FUNCTION_ARGS  )

Definition at line 3671 of file geo_ops.c.

3672 {
3673  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3674  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3675  bool result;
3676 
3677  result = polya->boundbox.low.y > polyb->boundbox.high.y;
3678 
3679  /*
3680  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3681  */
3682  PG_FREE_IF_COPY(polya, 0);
3683  PG_FREE_IF_COPY(polyb, 1);
3684 
3685  PG_RETURN_BOOL(result);
3686 }
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260

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

◆ poly_below()

Datum poly_below ( PG_FUNCTION_ARGS  )

Definition at line 3625 of file geo_ops.c.

3626 {
3627  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3628  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3629  bool result;
3630 
3631  result = polya->boundbox.high.y < polyb->boundbox.low.y;
3632 
3633  /*
3634  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3635  */
3636  PG_FREE_IF_COPY(polya, 0);
3637  PG_FREE_IF_COPY(polyb, 1);
3638 
3639  PG_RETURN_BOOL(result);
3640 }

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

◆ poly_box()

Datum poly_box ( PG_FUNCTION_ARGS  )

Definition at line 4519 of file geo_ops.c.

4520 {
4521  POLYGON *poly = PG_GETARG_POLYGON_P(0);
4522  BOX *box;
4523 
4524  box = (BOX *) palloc(sizeof(BOX));
4525  *box = poly->boundbox;
4526 
4527  PG_RETURN_BOX_P(box);
4528 }

References POLYGON::boundbox, palloc(), PG_GETARG_POLYGON_P, and PG_RETURN_BOX_P.

◆ poly_center()

Datum poly_center ( PG_FUNCTION_ARGS  )

Definition at line 4503 of file geo_ops.c.

4504 {
4505  POLYGON *poly = PG_GETARG_POLYGON_P(0);
4506  Point *result;
4507  CIRCLE circle;
4508 
4509  result = (Point *) palloc(sizeof(Point));
4510 
4511  poly_to_circle(&circle, poly);
4512  *result = circle.center;
4513 
4514  PG_RETURN_POINT_P(result);
4515 }
static void poly_to_circle(CIRCLE *result, POLYGON *poly)
Definition: geo_ops.c:5285

References CIRCLE::center, palloc(), PG_GETARG_POLYGON_P, PG_RETURN_POINT_P, and poly_to_circle().

◆ poly_circle()

Datum poly_circle ( PG_FUNCTION_ARGS  )

Definition at line 5307 of file geo_ops.c.

5308 {
5309  POLYGON *poly = PG_GETARG_POLYGON_P(0);
5310  CIRCLE *result;
5311 
5312  result = (CIRCLE *) palloc(sizeof(CIRCLE));
5313 
5314  poly_to_circle(result, poly);
5315 
5316  PG_RETURN_CIRCLE_P(result);
5317 }

References palloc(), PG_GETARG_POLYGON_P, PG_RETURN_CIRCLE_P, and poly_to_circle().

◆ poly_contain()

Datum poly_contain ( PG_FUNCTION_ARGS  )

Definition at line 3966 of file geo_ops.c.

3967 {
3968  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3969  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3970  bool result;
3971 
3972  result = poly_contain_poly(polya, polyb);
3973 
3974  /*
3975  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3976  */
3977  PG_FREE_IF_COPY(polya, 0);
3978  PG_FREE_IF_COPY(polyb, 1);
3979 
3980  PG_RETURN_BOOL(result);
3981 }
static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly)
Definition: geo_ops.c:3938

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

◆ poly_contain_poly()

static bool poly_contain_poly ( POLYGON contains_poly,
POLYGON contained_poly 
)
static

Definition at line 3938 of file geo_ops.c.

3939 {
3940  int i;
3941  LSEG s;
3942 
3943  Assert(contains_poly->npts > 0 && contained_poly->npts > 0);
3944 
3945  /*
3946  * Quick check to see if contained's bounding box is contained in
3947  * contains' bb.
3948  */
3949  if (!box_contain_box(&contains_poly->boundbox, &contained_poly->boundbox))
3950  return false;
3951 
3952  s.p[0] = contained_poly->p[contained_poly->npts - 1];
3953 
3954  for (i = 0; i < contained_poly->npts; i++)
3955  {
3956  s.p[1] = contained_poly->p[i];
3957  if (!lseg_inside_poly(s.p, s.p + 1, contains_poly, 0))
3958  return false;
3959  s.p[0] = s.p[1];
3960  }
3961 
3962  return true;
3963 }

References Assert(), POLYGON::boundbox, box_contain_box(), i, lseg_inside_poly(), POLYGON::npts, LSEG::p, and POLYGON::p.

Referenced by poly_contain(), and poly_contained().

◆ poly_contain_pt()

Datum poly_contain_pt ( PG_FUNCTION_ARGS  )

Definition at line 4008 of file geo_ops.c.

4009 {
4010  POLYGON *poly = PG_GETARG_POLYGON_P(0);
4011  Point *p = PG_GETARG_POINT_P(1);
4012 
4013  PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4014 }

References POLYGON::npts, POLYGON::p, 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 3988 of file geo_ops.c.

3989 {
3990  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3991  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3992  bool result;
3993 
3994  /* Just switch the arguments and pass it off to poly_contain */
3995  result = poly_contain_poly(polyb, polya);
3996 
3997  /*
3998  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3999  */
4000  PG_FREE_IF_COPY(polya, 0);
4001  PG_FREE_IF_COPY(polyb, 1);
4002 
4003  PG_RETURN_BOOL(result);
4004 }

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

◆ poly_distance()

Datum poly_distance ( PG_FUNCTION_ARGS  )

Definition at line 4027 of file geo_ops.c.

4028 {
4029  POLYGON *polya = PG_GETARG_POLYGON_P(0);
4030  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
4031  float8 min = 0.0; /* initialize to keep compiler quiet */
4032  bool have_min = false;
4033  float8 tmp;
4034  int i,
4035  j;
4036  LSEG seg1,
4037  seg2;
4038 
4039  /*
4040  * Distance is zero if polygons overlap. We must check this because the
4041  * path distance will not give the right answer if one poly is entirely
4042  * within the other.
4043  */
4044  if (poly_overlap_internal(polya, polyb))
4045  PG_RETURN_FLOAT8(0.0);
4046 
4047  /*
4048  * When they don't overlap, the distance calculation is identical to that
4049  * for closed paths (i.e., we needn't care about the fact that polygons
4050  * include their contained areas). See path_distance().
4051  */
4052  for (i = 0; i < polya->npts; i++)
4053  {
4054  int iprev;
4055 
4056  if (i > 0)
4057  iprev = i - 1;
4058  else
4059  iprev = polya->npts - 1;
4060 
4061  for (j = 0; j < polyb->npts; j++)
4062  {
4063  int jprev;
4064 
4065  if (j > 0)
4066  jprev = j - 1;
4067  else
4068  jprev = polyb->npts - 1;
4069 
4070  statlseg_construct(&seg1, &polya->p[iprev], &polya->p[i]);
4071  statlseg_construct(&seg2, &polyb->p[jprev], &polyb->p[j]);
4072 
4073  tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
4074  if (!have_min || float8_lt(tmp, min))
4075  {
4076  min = tmp;
4077  have_min = true;
4078  }
4079  }
4080  }
4081 
4082  if (!have_min)
4083  PG_RETURN_NULL();
4084 
4085  PG_RETURN_FLOAT8(min);
4086 }
static bool poly_overlap_internal(POLYGON *polya, POLYGON *polyb)
Definition: geo_ops.c:3744

References float8_lt(), i, j, lseg_closept_lseg(), POLYGON::npts, POLYGON::p, 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 3415 of file geo_ops.c.

3416 {
3417  char *str = PG_GETARG_CSTRING(0);
3418  Node *escontext = fcinfo->context;
3419  POLYGON *poly;
3420  int npts;
3421  int size;
3422  int base_size;
3423  bool isopen;
3424 
3425  if ((npts = pair_count(str, ',')) <= 0)
3426  ereturn(escontext, (Datum) 0,
3427  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3428  errmsg("invalid input syntax for type %s: \"%s\"",
3429  "polygon", str)));
3430 
3431  base_size = sizeof(poly->p[0]) * npts;
3432  size = offsetof(POLYGON, p) + base_size;
3433 
3434  /* Check for integer overflow */
3435  if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
3436  ereturn(escontext, (Datum) 0,
3437  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3438  errmsg("too many points requested")));
3439 
3440  poly = (POLYGON *) palloc0(size); /* zero any holes */
3441 
3442  SET_VARSIZE(poly, size);
3443  poly->npts = npts;
3444 
3445  if (!path_decode(str, false, npts, &(poly->p[0]), &isopen, NULL, "polygon",
3446  str, escontext))
3447  PG_RETURN_NULL();
3448 
3449  make_bound_box(poly);
3450 
3451  PG_RETURN_POLYGON_P(poly);
3452 }

References ereturn, errcode(), errmsg(), make_bound_box(), POLYGON::npts, POLYGON::p, pair_count(), palloc0(), path_decode(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_POLYGON_P, SET_VARSIZE, size, and generate_unaccent_rules::str.

◆ poly_left()

Datum poly_left ( PG_FUNCTION_ARGS  )

Definition at line 3533 of file geo_ops.c.

3534 {
3535  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3536  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3537  bool result;
3538 
3539  result = polya->boundbox.high.x < polyb->boundbox.low.x;
3540 
3541  /*
3542  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3543  */
3544  PG_FREE_IF_COPY(polya, 0);
3545  PG_FREE_IF_COPY(polyb, 1);
3546 
3547  PG_RETURN_BOOL(result);
3548 }

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

◆ poly_npoints()

Datum poly_npoints ( PG_FUNCTION_ARGS  )

Definition at line 4494 of file geo_ops.c.

4495 {
4496  POLYGON *poly = PG_GETARG_POLYGON_P(0);
4497 
4498  PG_RETURN_INT32(poly->npts);
4499 }

References POLYGON::npts, PG_GETARG_POLYGON_P, and PG_RETURN_INT32.

◆ poly_out()

Datum poly_out ( PG_FUNCTION_ARGS  )

Definition at line 3459 of file geo_ops.c.

3460 {
3461  POLYGON *poly = PG_GETARG_POLYGON_P(0);
3462 
3464 }

References POLYGON::npts, POLYGON::p, PATH_CLOSED, path_encode(), PG_GETARG_POLYGON_P, and PG_RETURN_CSTRING.

◆ poly_overabove()

Datum poly_overabove ( PG_FUNCTION_ARGS  )

Definition at line 3694 of file geo_ops.c.

3695 {
3696  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3697  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3698  bool result;
3699 
3700  result = polya->boundbox.low.y >= polyb->boundbox.low.y;
3701 
3702  /*
3703  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3704  */
3705  PG_FREE_IF_COPY(polya, 0);
3706  PG_FREE_IF_COPY(polyb, 1);
3707 
3708  PG_RETURN_BOOL(result);
3709 }

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

◆ poly_overbelow()

Datum poly_overbelow ( PG_FUNCTION_ARGS  )

Definition at line 3648 of file geo_ops.c.

3649 {
3650  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3651  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3652  bool result;
3653 
3654  result = polya->boundbox.high.y <= polyb->boundbox.high.y;
3655 
3656  /*
3657  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3658  */
3659  PG_FREE_IF_COPY(polya, 0);
3660  PG_FREE_IF_COPY(polyb, 1);
3661 
3662  PG_RETURN_BOOL(result);
3663 }

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

◆ poly_overlap()

Datum poly_overlap ( PG_FUNCTION_ARGS  )

Definition at line 3801 of file geo_ops.c.

3802 {
3803  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3804  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3805  bool result;
3806 
3807  result = poly_overlap_internal(polya, polyb);
3808 
3809  /*
3810  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3811  */
3812  PG_FREE_IF_COPY(polya, 0);
3813  PG_FREE_IF_COPY(polyb, 1);
3814 
3815  PG_RETURN_BOOL(result);
3816 }

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

◆ poly_overlap_internal()

static bool poly_overlap_internal ( POLYGON polya,
POLYGON polyb 
)
static

Definition at line 3744 of file geo_ops.c.

3745 {
3746  bool result;
3747 
3748  Assert(polya->npts > 0 && polyb->npts > 0);
3749 
3750  /* Quick check by bounding box */
3751  result = box_ov(&polya->boundbox, &polyb->boundbox);
3752 
3753  /*
3754  * Brute-force algorithm - try to find intersected edges, if so then
3755  * polygons are overlapped else check is one polygon inside other or not
3756  * by testing single point of them.
3757  */
3758  if (result)
3759  {
3760  int ia,
3761  ib;
3762  LSEG sa,
3763  sb;
3764 
3765  /* Init first of polya's edge with last point */
3766  sa.p[0] = polya->p[polya->npts - 1];
3767  result = false;
3768 
3769  for (ia = 0; ia < polya->npts && !result; ia++)
3770  {
3771  /* Second point of polya's edge is a current one */
3772  sa.p[1] = polya->p[ia];
3773 
3774  /* Init first of polyb's edge with last point */
3775  sb.p[0] = polyb->p[polyb->npts - 1];
3776 
3777  for (ib = 0; ib < polyb->npts && !result; ib++)
3778  {
3779  sb.p[1] = polyb->p[ib];
3780  result = lseg_interpt_lseg(NULL, &sa, &sb);
3781  sb.p[0] = sb.p[1];
3782  }
3783 
3784  /*
3785  * move current endpoint to the first point of next edge
3786  */
3787  sa.p[0] = sa.p[1];
3788  }
3789 
3790  if (!result)
3791  {
3792  result = (point_inside(polya->p, polyb->npts, polyb->p) ||
3793  point_inside(polyb->p, polya->npts, polya->p));
3794  }
3795  }
3796 
3797  return result;
3798 }

References Assert(), POLYGON::boundbox, box_ov(), lseg_interpt_lseg(), POLYGON::npts, LSEG::p, POLYGON::p, and point_inside().

Referenced by poly_distance(), and poly_overlap().

◆ poly_overleft()

Datum poly_overleft ( PG_FUNCTION_ARGS  )

Definition at line 3556 of file geo_ops.c.

3557 {
3558  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3559  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3560  bool result;
3561 
3562  result = polya->boundbox.high.x <= polyb->boundbox.high.x;
3563 
3564  /*
3565  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3566  */
3567  PG_FREE_IF_COPY(polya, 0);
3568  PG_FREE_IF_COPY(polyb, 1);
3569 
3570  PG_RETURN_BOOL(result);
3571 }

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

◆ poly_overright()

Datum poly_overright ( PG_FUNCTION_ARGS  )

Definition at line 3602 of file geo_ops.c.

3603 {
3604  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3605  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3606  bool result;
3607 
3608  result = polya->boundbox.low.x >= polyb->boundbox.low.x;
3609 
3610  /*
3611  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3612  */
3613  PG_FREE_IF_COPY(polya, 0);
3614  PG_FREE_IF_COPY(polyb, 1);
3615 
3616  PG_RETURN_BOOL(result);
3617 }

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

◆ poly_path()

Datum poly_path ( PG_FUNCTION_ARGS  )

Definition at line 4564 of file geo_ops.c.

4565 {
4566  POLYGON *poly = PG_GETARG_POLYGON_P(0);
4567  PATH *path;
4568  int size;
4569  int i;
4570 
4571  /*
4572  * Never overflows: the old size fit in MaxAllocSize, and the new size is
4573  * smaller by a small constant.
4574  */
4575  size = offsetof(PATH, p) + sizeof(path->p[0]) * poly->npts;
4576  path = (PATH *) palloc(size);
4577 
4578  SET_VARSIZE(path, size);
4579  path->npts = poly->npts;
4580  path->closed = true;
4581  /* prevent instability in unused pad bytes */
4582  path->dummy = 0;
4583 
4584  for (i = 0; i < poly->npts; i++)
4585  {
4586  path->p[i].x = poly->p[i].x;
4587  path->p[i].y = poly->p[i].y;
4588  }
4589 
4590  PG_RETURN_PATH_P(path);
4591 }

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

◆ poly_recv()

Datum poly_recv ( PG_FUNCTION_ARGS  )

Definition at line 3475 of file geo_ops.c.

3476 {
3478  POLYGON *poly;
3479  int32 npts;
3480  int32 i;
3481  int size;
3482 
3483  npts = pq_getmsgint(buf, sizeof(int32));
3484  if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p)) / sizeof(Point)))
3485  ereport(ERROR,
3486  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
3487  errmsg("invalid number of points in external \"polygon\" value")));
3488 
3489  size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * npts;
3490  poly = (POLYGON *) palloc0(size); /* zero any holes */
3491 
3492  SET_VARSIZE(poly, size);
3493  poly->npts = npts;
3494 
3495  for (i = 0; i < npts; i++)
3496  {
3497  poly->p[i].x = pq_getmsgfloat8(buf);
3498  poly->p[i].y = pq_getmsgfloat8(buf);
3499  }
3500 
3501  make_bound_box(poly);
3502 
3503  PG_RETURN_POLYGON_P(poly);
3504 }

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

◆ poly_right()

Datum poly_right ( PG_FUNCTION_ARGS  )

Definition at line 3579 of file geo_ops.c.

3580 {
3581  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3582  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3583  bool result;
3584 
3585  result = polya->boundbox.low.x > polyb->boundbox.high.x;
3586 
3587  /*
3588  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3589  */
3590  PG_FREE_IF_COPY(polya, 0);
3591  PG_FREE_IF_COPY(polyb, 1);
3592 
3593  PG_RETURN_BOOL(result);
3594 }

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

◆ poly_same()

Datum poly_same ( PG_FUNCTION_ARGS  )

Definition at line 3720 of file geo_ops.c.

3721 {
3722  POLYGON *polya = PG_GETARG_POLYGON_P(0);
3723  POLYGON *polyb = PG_GETARG_POLYGON_P(1);
3724  bool result;
3725 
3726  if (polya->npts != polyb->npts)
3727  result = false;
3728  else
3729  result = plist_same(polya->npts, polya->p, polyb->p);
3730 
3731  /*
3732  * Avoid leaking memory for toasted inputs ... needed for rtree indexes
3733  */
3734  PG_FREE_IF_COPY(polya, 0);
3735  PG_FREE_IF_COPY(polyb, 1);
3736 
3737  PG_RETURN_BOOL(result);
3738 }
static bool plist_same(int npts, Point *p1, Point *p2)
Definition: geo_ops.c:5457

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

◆ poly_send()

Datum poly_send ( PG_FUNCTION_ARGS  )

Definition at line 3510 of file geo_ops.c.

3511 {
3512  POLYGON *poly = PG_GETARG_POLYGON_P(0);
3514  int32 i;
3515 
3516  pq_begintypsend(&buf);
3517  pq_sendint32(&buf, poly->npts);
3518  for (i = 0; i < poly->npts; i++)
3519  {
3520  pq_sendfloat8(&buf, poly->p[i].x);
3521  pq_sendfloat8(&buf, poly->p[i].y);
3522  }
3524 }

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

◆ poly_to_circle()

static void poly_to_circle ( CIRCLE result,
POLYGON poly 
)
static

Definition at line 5285 of file geo_ops.c.

5286 {
5287  int i;
5288 
5289  Assert(poly->npts > 0);
5290 
5291  result->center.x = 0;
5292  result->center.y = 0;
5293  result->radius = 0;
5294 
5295  for (i = 0; i < poly->npts; i++)
5296  point_add_point(&result->center, &result->center, &poly->p[i]);
5297  result->center.x = float8_div(result->center.x, poly->npts);
5298  result->center.y = float8_div(result->center.y, poly->npts);
5299 
5300  for (i = 0; i < poly->npts; i++)
5301  result->radius = float8_pl(result->radius,
5302  point_dt(&poly->p[i], &result->center));
5303  result->radius = float8_div(result->radius, poly->npts);
5304 }

References Assert(), CIRCLE::center, float8_div(), float8_pl(), i, POLYGON::npts, POLYGON::p, point_add_point(), point_dt(), CIRCLE::radius, Point::x, and Point::y.

Referenced by poly_center(), and poly_circle().

◆ pt_contained_circle()

Datum pt_contained_circle ( PG_FUNCTION_ARGS  )

Definition at line 5094 of file geo_ops.c.

5095 {
5096  Point *point = PG_GETARG_POINT_P(0);
5097  CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
5098  float8 d;
5099 
5100  d = point_dt(&circle->center, point);
5101  PG_RETURN_BOOL(d <= circle->radius);
5102 }

References CIRCLE::center, 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 4017 of file geo_ops.c.

4018 {
4019  Point *p = PG_GETARG_POINT_P(0);
4020  POLYGON *poly = PG_GETARG_POLYGON_P(1);
4021 
4022  PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
4023 }

References POLYGON::npts, POLYGON::p, 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 194 of file geo_ops.c.

197 {
198  *x = float8in_internal(num, endptr_p, type_name, orig_string, escontext);
199  return (!SOFT_ERROR_OCCURRED(escontext));
200 } /* single_decode() */
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition: float.c:394
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52

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

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

References appendStringInfoString(), float8out_internal(), pfree(), generate_unaccent_rules::str, and x.

Referenced by circle_out().

◆ statlseg_construct()

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

Definition at line 2142 of file geo_ops.c.

2143 {
2144  lseg->p[0].x = pt1->x;
2145  lseg->p[0].y = pt1->y;
2146  lseg->p[1].x = pt2->x;
2147  lseg->p[1].y = pt2->y;
2148 }

References LSEG::p, Point::x, and Point::y.

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

3831 {
3832  /* point a is on s, b is not */
3833  LSEG t;
3834 
3835  t.p[0] = *a;
3836  t.p[1] = *b;
3837 
3838  if (point_eq_point(a, s->p))
3839  {
3840  if (lseg_contain_point(&t, s->p + 1))
3841  return lseg_inside_poly(b, s->p + 1, poly, start);
3842  }
3843  else if (point_eq_point(a, s->p + 1))
3844  {
3845  if (lseg_contain_point(&t, s->p))
3846  return lseg_inside_poly(b, s->p, poly, start);
3847  }
3848  else if (lseg_contain_point(&t, s->p))
3849  {
3850  return lseg_inside_poly(b, s->p, poly, start);
3851  }
3852  else if (lseg_contain_point(&t, s->p + 1))
3853  {
3854  return lseg_inside_poly(b, s->p + 1, poly, start);
3855  }
3856 
3857  return true; /* may be not true, but that will check later */
3858 }

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

Referenced by lseg_inside_poly().