PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ geography_distance_cache_tolerance()

static int geography_distance_cache_tolerance ( FunctionCallInfo  fcinfo,
SHARED_GSERIALIZED *  shared_g1,
SHARED_GSERIALIZED *  shared_g2,
const SPHEROID s,
double  tolerance,
double *  distance 
)
static

Definition at line 157 of file geography_measurement_trees.c.

163 {
164  const GSERIALIZED *g1 = shared_gserialized_get(shared_g1);
165  const GSERIALIZED *g2 = shared_gserialized_get(shared_g2);
166  CircTreeGeomCache* tree_cache = NULL;
167 
168  int type1 = gserialized_get_type(g1);
169  int type2 = gserialized_get_type(g2);
170 
171  Assert(distance);
172 
173  /* Two points? Get outa here... */
174  if ( type1 == POINTTYPE && type2 == POINTTYPE )
175  return LW_FAILURE;
176 
177  /* Fetch/build our cache, if appropriate, etc... */
178  tree_cache = GetCircTreeGeomCache(fcinfo, shared_g1, shared_g2);
179 
180  /* OK, we have an index at the ready! Use it for the one tree argument and */
181  /* fill in the other tree argument */
182  if ( tree_cache && tree_cache->gcache.argnum && tree_cache->index )
183  {
184  CIRC_NODE* circtree_cached = tree_cache->index;
185  CIRC_NODE* circtree = NULL;
186  const GSERIALIZED* g_cached;
187  const GSERIALIZED* g;
188  LWGEOM* lwgeom = NULL;
189  int geomtype_cached;
190  int geomtype;
191  POINT4D p4d;
192 
193  /* We need to dynamically build a tree for the uncached side of the function call */
194  if ( tree_cache->gcache.argnum == 1 )
195  {
196  g_cached = g1;
197  g = g2;
198  geomtype_cached = type1;
199  geomtype = type2;
200  }
201  else if ( tree_cache->gcache.argnum == 2 )
202  {
203  g_cached = g2;
204  g = g1;
205  geomtype_cached = type2;
206  geomtype = type1;
207  }
208  else
209  {
210  lwpgerror("geography_distance_cache this cannot happen!");
211  return LW_FAILURE;
212  }
213 
214  lwgeom = lwgeom_from_gserialized(g);
215  if ( geomtype_cached == POLYGONTYPE || geomtype_cached == MULTIPOLYGONTYPE )
216  {
217  lwgeom_startpoint(lwgeom, &p4d);
218  if ( CircTreePIP(circtree_cached, g_cached, &p4d) )
219  {
220  *distance = 0.0;
221  lwgeom_free(lwgeom);
222  return LW_SUCCESS;
223  }
224  }
225 
226  circtree = lwgeom_calculate_circ_tree(lwgeom);
227  if ( geomtype == POLYGONTYPE || geomtype == MULTIPOLYGONTYPE )
228  {
229  POINT2D p2d;
230  circ_tree_get_point(circtree_cached, &p2d);
231  p4d.x = p2d.x;
232  p4d.y = p2d.y;
233  if ( CircTreePIP(circtree, g, &p4d) )
234  {
235  *distance = 0.0;
236  circ_tree_free(circtree);
237  lwgeom_free(lwgeom);
238  return LW_SUCCESS;
239  }
240  }
241 
242  *distance = circ_tree_distance_tree(circtree_cached, circtree, s, tolerance);
243  circ_tree_free(circtree);
244  lwgeom_free(lwgeom);
245  return LW_SUCCESS;
246  }
247  else
248  {
249  return LW_FAILURE;
250  }
251 }
char * s
Definition: cu_in_wkt.c:23
static CircTreeGeomCache * GetCircTreeGeomCache(FunctionCallInfo fcinfo, SHARED_GSERIALIZED *g1, SHARED_GSERIALIZED *g2)
static int CircTreePIP(const CIRC_NODE *tree1, const GSERIALIZED *g1, const POINT4D *in_point)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:89
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:2135
#define LW_FAILURE
Definition: liblwgeom.h:96
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
#define LW_SUCCESS
Definition: liblwgeom.h:97
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
#define POLYGONTYPE
Definition: liblwgeom.h:104
double circ_tree_distance_tree(const CIRC_NODE *n1, const CIRC_NODE *n2, const SPHEROID *spheroid, double threshold)
int circ_tree_get_point(const CIRC_NODE *node, POINT2D *pt)
Returns a POINT2D that is a vertex of the input shape.
void circ_tree_free(CIRC_NODE *node)
Recurse from top of node tree and free all children.
CIRC_NODE * lwgeom_calculate_circ_tree(const LWGEOM *lwgeom)
static double distance(double x1, double y1, double x2, double y2)
Definition: lwtree.c:1032
double y
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:414
double y
Definition: liblwgeom.h:414
Note that p1 and p2 are pointers into an independent POINTARRAY, do not free them.

References circ_tree_distance_tree(), circ_tree_free(), circ_tree_get_point(), CircTreePIP(), distance(), 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, s, POINT2D::x, POINT4D::x, POINT2D::y, and POINT4D::y.

Referenced by geography_distance_cache(), and geography_dwithin_cache().

Here is the call graph for this function:
Here is the caller graph for this function: