PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ CircTreePIP()

static int CircTreePIP ( const CIRC_NODE tree1,
const GSERIALIZED g1,
const POINT4D in_point 
)
static

Definition at line 104 of file geography_measurement_trees.c.

References circ_tree_contains_point(), circ_tree_get_point_outside(), gbox_contains_point3d(), gbox_pt_outside(), geog2cart(), geographic_point_init(), gserialized_get_gbox_p(), gserialized_get_type(), LW_FAILURE, LW_FALSE, lwgeom_calculate_gbox_geodetic(), lwgeom_free(), lwgeom_from_gserialized(), MULTIPOLYGONTYPE, POLYGONTYPE, POINT2D::x, POINT4D::x, POINT2D::y, and POINT4D::y.

Referenced by geography_distance_cache_tolerance(), and geography_tree_distance().

105 {
106  int tree1_type = gserialized_get_type(g1);
107  GBOX gbox1;
108  GEOGRAPHIC_POINT in_gpoint;
109  POINT3D in_point3d;
110 
111  POSTGIS_DEBUGF(3, "tree1_type=%d", tree1_type);
112 
113  /* If the tree'ed argument is a polygon, do the P-i-P using the tree-based P-i-P */
114  if ( tree1_type == POLYGONTYPE || tree1_type == MULTIPOLYGONTYPE )
115  {
116  POSTGIS_DEBUG(3, "tree is a polygon, using tree PiP");
117  /* Need a gbox to calculate an outside point */
118  if ( LW_FAILURE == gserialized_get_gbox_p(g1, &gbox1) )
119  {
120  LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
121  POSTGIS_DEBUG(3, "unable to read gbox from gserialized, calculating from scratch");
122  lwgeom_calculate_gbox_geodetic(lwgeom1, &gbox1);
123  lwgeom_free(lwgeom1);
124  }
125 
126  /* Flip the candidate point into geographics */
127  geographic_point_init(in_point->x, in_point->y, &in_gpoint);
128  geog2cart(&in_gpoint, &in_point3d);
129 
130  /* If the candidate isn't in the tree box, it's not in the tree area */
131  if ( ! gbox_contains_point3d(&gbox1, &in_point3d) )
132  {
133  POSTGIS_DEBUG(3, "in_point3d is not inside the tree gbox, CircTreePIP returning FALSE");
134  return LW_FALSE;
135  }
136  /* The candidate point is in the box, so it *might* be inside the tree */
137  else
138  {
139  POINT2D pt2d_outside; /* latlon */
140  POINT2D pt2d_inside;
141  pt2d_inside.x = in_point->x;
142  pt2d_inside.y = in_point->y;
143  /* Calculate a definitive outside point */
144  if (gbox_pt_outside(&gbox1, &pt2d_outside) == LW_FAILURE)
145  if (circ_tree_get_point_outside(tree1, &pt2d_outside) == LW_FAILURE)
146  lwpgerror("%s: Unable to generate outside point!", __func__);
147 
148  POSTGIS_DEBUGF(3, "p2d_inside=POINT(%g %g) p2d_outside=POINT(%g %g)", pt2d_inside.x, pt2d_inside.y, pt2d_outside.x, pt2d_outside.y);
149  /* Test the candidate point for strict containment */
150  POSTGIS_DEBUG(3, "calling circ_tree_contains_point for PiP test");
151  return circ_tree_contains_point(tree1, &pt2d_inside, &pt2d_outside, 0, NULL);
152  }
153  }
154  else
155  {
156  POSTGIS_DEBUG(3, "tree1 not polygonal, so CircTreePIP returning FALSE");
157  return LW_FALSE;
158  }
159 }
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box)
Read the bounding box off a serialization and calculate one if it is not already there.
Definition: g_serialized.c:642
double x
Definition: liblwgeom.h:352
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:86
int lwgeom_calculate_gbox_geodetic(const LWGEOM *geom, GBOX *gbox)
Calculate the geodetic bounding box for an LWGEOM.
Definition: lwgeodetic.c:3012
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
#define POLYGONTYPE
Definition: liblwgeom.h:87
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
int gbox_contains_point3d(const GBOX *gbox, const POINT3D *pt)
Return true if the point is inside the gbox.
Definition: g_box.c:259
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:52
int circ_tree_contains_point(const CIRC_NODE *node, const POINT2D *pt, const POINT2D *pt_outside, int level, int *on_boundary)
Walk the tree and count intersections between the stab line and the edges.
#define LW_FAILURE
Definition: liblwgeom.h:79
double x
Definition: liblwgeom.h:328
#define LW_FALSE
Definition: liblwgeom.h:77
int circ_tree_get_point_outside(const CIRC_NODE *node, POINT2D *pt)
double y
Definition: liblwgeom.h:328
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesion coordinates on unit sphere.
Definition: lwgeodetic.c:400
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
Definition: lwgeodetic.c:180
int gbox_pt_outside(const GBOX *gbox, POINT2D *pt_outside)
Calculate a spherical point that falls outside the geocentric gbox.
Definition: lwgeodetic.c:1548
double y
Definition: liblwgeom.h:352
Here is the call graph for this function:
Here is the caller graph for this function: