PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ union_intersecting_pairs()

static int union_intersecting_pairs ( GEOSGeometry **  geoms,
uint32_t  num_geoms,
UNIONFIND uf 
)
static

Definition at line 159 of file lwgeom_geos_cluster.c.

160 {
161  uint32_t p, i;
162  struct STRTree tree;
163  struct QueryContext cxt =
164  {
165  .items_found = NULL,
166  .num_items_found = 0,
167  .items_found_size = 0
168  };
169  int success = LW_SUCCESS;
170 
171  if (num_geoms <= 1)
172  return LW_SUCCESS;
173 
174  tree = make_strtree((void**) geoms, num_geoms, LW_FALSE);
175  if (tree.tree == NULL)
176  {
177  destroy_strtree(&tree);
178  return LW_FAILURE;
179  }
180 
181  for (p = 0; p < num_geoms; p++)
182  {
183  const GEOSPreparedGeometry* prep = NULL;
184 
185  if (!geoms[p] || GEOSisEmpty(geoms[p]))
186  continue;
187 
188  cxt.num_items_found = 0;
189  GEOSSTRtree_query(tree.tree, geoms[p], &query_accumulate, &cxt);
190 
191  for (i = 0; i < cxt.num_items_found; i++)
192  {
193  uint32_t q = *((uint32_t*) cxt.items_found[i]);
194 
195  if (p != q && UF_find(uf, p) != UF_find(uf, q))
196  {
197  int geos_type = GEOSGeomTypeId(geoms[p]);
198  int geos_result;
199 
200  /* Don't build prepared a geometry around a Point or MultiPoint -
201  * there are some problems in the implementation, and it's not clear
202  * there would be a performance benefit in any case. (See #3433)
203  */
204  if (geos_type != GEOS_POINT && geos_type != GEOS_MULTIPOINT)
205  {
206  /* Lazy initialize prepared geometry */
207  if (prep == NULL)
208  {
209  prep = GEOSPrepare(geoms[p]);
210  }
211  geos_result = GEOSPreparedIntersects(prep, geoms[q]);
212  }
213  else
214  {
215  geos_result = GEOSIntersects(geoms[p], geoms[q]);
216  }
217  if (geos_result > 1)
218  {
219  success = LW_FAILURE;
220  break;
221  }
222  else if (geos_result)
223  {
224  UF_union(uf, p, q);
225  }
226  }
227  }
228 
229  if (prep)
230  GEOSPreparedGeom_destroy(prep);
231 
232  if (!success)
233  break;
234  }
235 
236  if (cxt.items_found)
237  lwfree(cxt.items_found);
238 
239  destroy_strtree(&tree);
240  return success;
241 }
#define LW_FALSE
Definition: liblwgeom.h:77
#define LW_FAILURE
Definition: liblwgeom.h:79
#define LW_SUCCESS
Definition: liblwgeom.h:80
void lwfree(void *mem)
Definition: lwutil.c:244
static void query_accumulate(void *item, void *userdata)
static struct STRTree make_strtree(void **geoms, uint32_t num_geoms, char is_lwgeom)
Make a GEOSSTRtree that stores a pointer to a variable containing the array index of the input geoms.
static void destroy_strtree(struct STRTree *tree)
Clean up STRTree after use.
uint32_t UF_find(UNIONFIND *uf, uint32_t i)
Definition: lwunionfind.c:61
void UF_union(UNIONFIND *uf, uint32_t i, uint32_t j)
Definition: lwunionfind.c:84
uint32_t num_items_found
GEOSSTRtree * tree
unsigned int uint32_t
Definition: uthash.h:78

References destroy_strtree(), QueryContext::items_found, LW_FAILURE, LW_FALSE, LW_SUCCESS, lwfree(), make_strtree(), QueryContext::num_items_found, query_accumulate(), STRTree::tree, UF_find(), and UF_union().

Referenced by cluster_intersecting().

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