PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ union_intersecting_pairs()

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

Definition at line 155 of file lwgeom_geos_cluster.c.

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().

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