61 return h1 < h2 ? -1 : (h1 > h2 ? 1 : 0);
87 const POINT2D *p1, *p2, *p3, *q1, *q2, *q3;
117 lwerror(
"%s: unsupported segment type", __func__);
149 lwerror(
"%s: unsupported segment type", __func__);
182 lwerror(
"%s: unsupported segment type", __func__);
220 if (p1->
y < p2->
y && side == -1 && q->
y != p2->
y)
226 if (p1->
y > p2->
y && side == 1 && q->
y != p2->
y)
232 if (p1->
y == p2->
y && q->
x < p1->
x)
241 int arc_side, seg_side;
256 if (seg_side == arc_side)
259 if (p1->
y < p3->
y && seg_side == -1 && q->
y != p3->
y)
265 if (p1->
y > p3->
y && seg_side == 1 && q->
y != p3->
y)
273 if (p1->
y < p3->
y && seg_side == 1 && q->
y != p3->
y)
279 if (p1->
y > p3->
y && seg_side == -1 && q->
y != p3->
y)
364 int contained = (edge_crossing_count % 2 == 1);
370 return on_boundary ? 0 : -1 * contained;
374 return contained || on_boundary;
386 if (pt->
y < node->
ymin || pt->
y > node->
ymax ||
512 if ((p1->
x == p2->
x) && (p1->
y == p2->
y))
527 if ((p1->
x == p2->
x) && (p2->
x == p3->
x) &&
528 (p1->
y == p2->
y) && (p2->
y == p3->
y))
536 lwerror(
"%s: unsupported seg_type - %d", __func__, seg_type);
559 lwerror(
"%s: call on leaf node", __func__);
603 while (num_nodes > 1)
607 for (i = 0; i < num_nodes; i++)
634 int num_edges = 0, i = 0, j = 0;
653 num_edges = (pa->
npoints - 1)/2;
656 lwerror(
"%s: unsupported seg_type - %d", __func__, seg_type);
661 for (i = 0; i < num_edges; i++)
711 printf(
"%*s----\n", depth,
"");
712 printf(
"%*stype: %d\n", depth,
"", node->
type);
713 printf(
"%*sgeom_type: %d\n", depth,
"", node->
geom_type);
714 printf(
"%*sbox: %g %g, %g %g\n", depth,
"", node->
xmin, node->
ymin, node->
xmax, node->
ymax);
717 printf(
"%*sseg_type: %d\n", depth,
"", node->
l.
seg_type);
718 printf(
"%*sseg_num: %d\n", depth,
"", node->
l.
seg_num);
756 for (i = 0; i < lwpoly->
nrings; i++)
783 for (i = 0; i < lwcol->
nrings; i++)
832 for (i = 0; i < lwcol->
ngeoms; i++)
899 if (!node)
return NULL;
920 #if POSTGIS_DEBUG_LEVEL >= 4
925 snprintf(buf, 256,
"(%.9g %.9g,%.9g %.9g)",
939 #if POSTGIS_DEBUG_LEVEL >= 4
940 char *n1_str = rect_node_to_str(n1);
941 char *n2_str = rect_node_to_str(n2);
949 LWDEBUG(4,
" interaction found");
1023 static inline double
1028 return dx*dx + dy*dy;
1031 static inline double
1041 static inline double
1053 else if (top && right)
1055 else if (bottom && left)
1057 else if (bottom && right)
1077 static inline double
1084 double dx = xmax - xmin;
1085 double dy = ymax - ymin;
1087 return sqrt(dx*dx + dy*dy);
1102 const POINT2D *p1, *p2, *p3, *q1, *q2, *q3;
1136 lwerror(
"%s: unsupported segment type", __func__);
1174 lwerror(
"%s: unsupported segment type", __func__);
1205 lwerror(
"%s: unsupported segment type", __func__);
1210 lwerror(
"%s: unsupported segment type", __func__);
1230 if (n1->
d < n2->
d)
return -1;
1231 else if (n1->
d > n2->
d)
return 1;
1303 LWDEBUGF(4,
"pruning pair %p, %p", n1, n2);
1309 if (max < state->max_dist)
1321 double d_min = FLT_MAX;
1328 d_min =
FP_MIN(d_min, min);
1336 d_min =
FP_MIN(d_min, min);
1346 d_min =
FP_MIN(d_min, min);
int lw_arc_calculate_gbox_cartesian_2d(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, GBOX *gbox)
uint64_t gbox_get_sortable_hash(const GBOX *g)
Return a sortable key based on the center point of the GBOX.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
void lwgeom_free(LWGEOM *geom)
double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define POLYHEDRALSURFACETYPE
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
#define LW_TRUE
Return types for functions with status returns.
LWPOLY * lwpoly_construct_envelope(int srid, double x1, double y1, double x2, double y2)
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
int lw_segment_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2)
returns the kind of CG_SEGMENT_INTERSECTION_TYPE behavior of lineseg 1 (constructed from p1 and p2) a...
int lw_arc_side(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, const POINT2D *Q)
int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2)
Returns true if P is between A1/A2.
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static int rect_tree_intersects_tree_recursive(RECT_NODE *n1, RECT_NODE *n2)
char * rect_tree_to_wkt(const RECT_NODE *node)
static double distance_sq(double x1, double y1, double x2, double y2)
static int rect_leaf_node_intersects(RECT_NODE_LEAF *n1, RECT_NODE_LEAF *n2)
static double rect_node_max_distance(const RECT_NODE *n1, const RECT_NODE *n2)
static int rect_node_intersects(const RECT_NODE *n1, const RECT_NODE *n2)
static RECT_NODE * rect_tree_from_lwline(const LWGEOM *lwgeom)
RECT_NODE * rect_tree_from_lwgeom(const LWGEOM *lwgeom)
Create a tree index on top an LWGEOM.
static int rect_leaf_node_segment_side(RECT_NODE_LEAF *node, const POINT2D *q, int *on_boundary)
RECT_NODE * rect_tree_from_ptarray(const POINTARRAY *pa, int geom_type)
static double rect_tree_distance_tree_recursive(RECT_NODE *n1, RECT_NODE *n2, RECT_TREE_DISTANCE_STATE *state)
static RECT_NODE * rect_tree_from_lwcurvepoly(const LWGEOM *lwgeom)
static RECT_NODE * rect_tree_from_lwpoint(const LWGEOM *lwgeom)
void rect_tree_printf(const RECT_NODE *node, int depth)
static RECT_NODE_SEG_TYPE lwgeomTypeArc[]
static RECT_NODE * rect_nodes_merge(RECT_NODE **nodes, uint32_t num_nodes)
static double rect_node_min_distance(const RECT_NODE *n1, const RECT_NODE *n2)
int rect_tree_contains_point(RECT_NODE *node, const POINT2D *pt)
LWGEOM * rect_tree_to_lwgeom(const RECT_NODE *node)
void rect_tree_free(RECT_NODE *node)
Recurse from top of node tree and free all children.
static int rect_tree_is_area(const RECT_NODE *node)
static double distance(double x1, double y1, double x2, double y2)
static int rect_tree_ring_contains_point(RECT_NODE *node, const POINT2D *pt, int *on_boundary)
static const POINT2D * rect_tree_get_point(const RECT_NODE *node)
static RECT_NODE * rect_tree_from_lwpoly(const LWGEOM *lwgeom)
static double rect_leaf_node_distance(const RECT_NODE_LEAF *n1, const RECT_NODE_LEAF *n2, RECT_TREE_DISTANCE_STATE *state)
static int rect_node_cmp(const void *pn1, const void *pn2)
static void rect_node_internal_add_node(RECT_NODE *node, RECT_NODE *add)
static int rect_tree_area_contains_point(RECT_NODE *node, const POINT2D *pt)
double rect_tree_distance_tree(RECT_NODE *n1, RECT_NODE *n2, double threshold)
Return the distance between two RECT_NODE trees.
static int rect_tree_node_sort_cmp(const void *a, const void *b)
static RECT_NODE * rect_node_internal_new(const RECT_NODE *seed)
static int rect_node_is_leaf(const RECT_NODE *node)
int rect_tree_intersects_tree(RECT_NODE *n1, RECT_NODE *n2)
Test if two RECT_NODE trees intersect one another.
static RECT_NODE * rect_tree_from_lwcollection(const LWGEOM *lwgeom)
static void rect_node_to_p2d(const RECT_NODE *n, POINT2D *pt)
static RECT_NODE * rect_node_leaf_new(const POINTARRAY *pa, int seg_num, int geom_type)
static int rect_node_bounds_point(RECT_NODE *node, const POINT2D *pt)
static void rect_tree_node_sort(RECT_NODE *n1, RECT_NODE *n2)
@ RECT_NODE_INTERNAL_TYPE
@ RECT_NODE_RING_EXTERIOR
@ RECT_NODE_RING_INTERIOR
int lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, DISTPTS *dl)
int lw_dist2d_pt_seg(const POINT2D *p, const POINT2D *A, const POINT2D *B, DISTPTS *dl)
lw_dist2d_comp from p to line A->B This one is now sending every occasion to lw_dist2d_pt_pt Before i...
int lw_dist2d_seg_seg(const POINT2D *A, const POINT2D *B, const POINT2D *C, const POINT2D *D, DISTPTS *dl)
Finds the shortest distance between two segments.
int lw_dist2d_seg_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, DISTPTS *dl)
Calculate the shortest distance between an arc and an edge.
void lw_dist2d_distpts_init(DISTPTS *dl, int mode)
int lw_dist2d_arc_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, DISTPTS *dl)
int lw_dist2d_pt_pt(const POINT2D *thep1, const POINT2D *thep2, DISTPTS *dl)
Compares incoming points and stores the points closest to each other or most far away from each other...
Structure used in distance-calculations.
struct rect_node * nodes[RECT_NODE_SIZE]
RECT_NODE_RING_TYPE ring_type
RECT_NODE_SEG_TYPE seg_type