PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ geography_distance_cache_tolerance()

static int geography_distance_cache_tolerance ( FunctionCallInfoData *  fcinfo,
const GSERIALIZED g1,
const GSERIALIZED g2,
const SPHEROID s,
double  tolerance,
double *  distance 
)
static

Definition at line 156 of file geography_measurement_trees.c.

References circ_tree_distance_tree(), circ_tree_free(), circ_tree_get_point(), CircTreePIP(), CircTreeGeomCache::gcache, GetCircTreeGeomCache(), gserialized_get_type(), CircTreeGeomCache::index, LW_FAILURE, LW_SUCCESS, lwgeom_calculate_circ_tree(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_startpoint(), MULTIPOLYGONTYPE, POINTTYPE, POLYGONTYPE, POINT2D::x, POINT4D::x, POINT2D::y, and POINT4D::y.

Referenced by geography_distance_cache(), and geography_dwithin_cache().

157 {
158  CircTreeGeomCache* tree_cache = NULL;
159 
160  int type1 = gserialized_get_type(g1);
161  int type2 = gserialized_get_type(g2);
162 
163  Assert(distance);
164 
165  /* Two points? Get outa here... */
166  if ( type1 == POINTTYPE && type2 == POINTTYPE )
167  return LW_FAILURE;
168 
169  /* Fetch/build our cache, if appropriate, etc... */
170  tree_cache = GetCircTreeGeomCache(fcinfo, g1, g2);
171 
172  /* OK, we have an index at the ready! Use it for the one tree argument and */
173  /* fill in the other tree argument */
174  if ( tree_cache && tree_cache->gcache.argnum && tree_cache->index )
175  {
176  CIRC_NODE* circtree_cached = tree_cache->index;
177  CIRC_NODE* circtree = NULL;
178  const GSERIALIZED* g_cached;
179  const GSERIALIZED* g;
180  LWGEOM* lwgeom = NULL;
181  int geomtype_cached;
182  int geomtype;
183  POINT4D p4d;
184 
185  /* We need to dynamically build a tree for the uncached side of the function call */
186  if ( tree_cache->gcache.argnum == 1 )
187  {
188  g_cached = g1;
189  g = g2;
190  geomtype_cached = type1;
191  geomtype = type2;
192  }
193  else if ( tree_cache->gcache.argnum == 2 )
194  {
195  g_cached = g2;
196  g = g1;
197  geomtype_cached = type2;
198  geomtype = type1;
199  }
200  else
201  {
202  lwpgerror("geography_distance_cache this cannot happen!");
203  return LW_FAILURE;
204  }
205 
206  lwgeom = lwgeom_from_gserialized(g);
207  if ( geomtype_cached == POLYGONTYPE || geomtype_cached == MULTIPOLYGONTYPE )
208  {
209  lwgeom_startpoint(lwgeom, &p4d);
210  if ( CircTreePIP(circtree_cached, g_cached, &p4d) )
211  {
212  *distance = 0.0;
213  lwgeom_free(lwgeom);
214  return LW_SUCCESS;
215  }
216  }
217 
218  circtree = lwgeom_calculate_circ_tree(lwgeom);
219  if ( geomtype == POLYGONTYPE || geomtype == MULTIPOLYGONTYPE )
220  {
221  POINT2D p2d;
222  circ_tree_get_point(circtree_cached, &p2d);
223  p4d.x = p2d.x;
224  p4d.y = p2d.y;
225  if ( CircTreePIP(circtree, g, &p4d) )
226  {
227  *distance = 0.0;
228  circ_tree_free(circtree);
229  lwgeom_free(lwgeom);
230  return LW_SUCCESS;
231  }
232  }
233 
234  *distance = circ_tree_distance_tree(circtree_cached, circtree, s, tolerance);
235  circ_tree_free(circtree);
236  lwgeom_free(lwgeom);
237  return LW_SUCCESS;
238  }
239  else
240  {
241  return LW_FAILURE;
242  }
243 }
double x
Definition: liblwgeom.h:354
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
Note that p1 and p2 are pointers into an independent POINTARRAY, do not free them.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int circ_tree_get_point(const CIRC_NODE *node, POINT2D *pt)
Returns a POINT2D that is a vertex of the input shape.
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:2115
#define POLYGONTYPE
Definition: liblwgeom.h:86
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
#define LW_SUCCESS
Definition: liblwgeom.h:79
double circ_tree_distance_tree(const CIRC_NODE *n1, const CIRC_NODE *n2, const SPHEROID *spheroid, double threshold)
CIRC_NODE * lwgeom_calculate_circ_tree(const LWGEOM *lwgeom)
static CircTreeGeomCache * GetCircTreeGeomCache(FunctionCallInfoData *fcinfo, const GSERIALIZED *g1, const GSERIALIZED *g2)
#define LW_FAILURE
Definition: liblwgeom.h:78
static int CircTreePIP(const CIRC_NODE *tree1, const GSERIALIZED *g1, const POINT4D *in_point)
double x
Definition: liblwgeom.h:330
double y
Definition: liblwgeom.h:330
Datum distance(PG_FUNCTION_ARGS)
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:89
void circ_tree_free(CIRC_NODE *node)
Recurse from top of node tree and free all children.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
double y
Definition: liblwgeom.h:354
Here is the call graph for this function:
Here is the caller graph for this function: