PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ union_intersecting_pairs()

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

Definition at line 158 of file lwgeom_geos_cluster.c.

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

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(), and ST_ClusterIntersectingWin().

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