PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ _lwt_GetEqualEdge()

static LWT_ELEMID _lwt_GetEqualEdge ( LWT_TOPOLOGY topo,
LWLINE edge,
int *  forward 
)
static

Definition at line 5421 of file lwgeom_topo.c.

5422 {
5423  LWT_ELEMID id;
5424  LWT_ISO_EDGE *edges;
5425  uint64_t num, i;
5426  const GBOX *qbox = lwgeom_get_bbox( lwline_as_lwgeom(edge) );
5427  GEOSGeometry *edgeg;
5428  const int flds = LWT_COL_EDGE_EDGE_ID|LWT_COL_EDGE_GEOM;
5429 
5430  edges = lwt_be_getEdgeWithinBox2D( topo, qbox, &num, flds, 0 );
5431  if (num == UINT64_MAX)
5432  {
5433  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
5434  return -1;
5435  }
5436  if ( num )
5437  {
5438  initGEOS(lwnotice, lwgeom_geos_error);
5439 
5440  edgeg = LWGEOM2GEOS( lwline_as_lwgeom(edge), 0 );
5441  if ( ! edgeg )
5442  {
5443  _lwt_release_edges(edges, num);
5444  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5445  return -1;
5446  }
5447  for (i=0; i<num; ++i)
5448  {
5449  LWT_ISO_EDGE *e = &(edges[i]);
5450  LWGEOM *g = lwline_as_lwgeom(e->geom);
5451  GEOSGeometry *gg;
5452  int equals;
5453  gg = LWGEOM2GEOS( g, 0 );
5454  if ( ! gg )
5455  {
5456  GEOSGeom_destroy(edgeg);
5457  _lwt_release_edges(edges, num);
5458  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5459  return -1;
5460  }
5461  equals = GEOSEquals(gg, edgeg);
5462  GEOSGeom_destroy(gg);
5463  if ( equals == 2 )
5464  {
5465  GEOSGeom_destroy(edgeg);
5466  _lwt_release_edges(edges, num);
5467  lwerror("GEOSEquals exception: %s", lwgeom_geos_errmsg);
5468  return -1;
5469  }
5470  if ( equals )
5471  {
5472  id = e->edge_id;
5473  /* Check if direction also matches */
5474  if ( forward )
5475  {
5476  /* If input line is closed, we use winding order */
5477  if ( lwline_is_closed(edge) )
5478  {
5479  if ( ptarray_isccw(edge->points) == ptarray_isccw(e->geom->points) )
5480  {
5481  *forward = 1;
5482  }
5483  else
5484  {
5485  *forward = 0;
5486  }
5487  }
5488  else
5489  {
5490  /* Input line is not closed, checking fist point is enough */
5491  if (
5492  memcmp(
5493  getPoint_internal(edge->points, 0),
5494  getPoint_internal(e->geom->points, 0),
5495  sizeof(POINT2D)
5496  ) == 0
5497  )
5498  {
5499  *forward = 1;
5500  }
5501  else
5502  {
5503  *forward = 0;
5504  }
5505  }
5506  }
5507  GEOSGeom_destroy(edgeg);
5508  _lwt_release_edges(edges, num);
5509  return id;
5510  }
5511  }
5512  GEOSGeom_destroy(edgeg);
5513  _lwt_release_edges(edges, num);
5514  }
5515 
5516  return 0;
5517 }
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void lwgeom_geos_error(const char *fmt,...)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition: lwgeom.c:743
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:445
int ptarray_isccw(const POINTARRAY *pa)
Definition: ptarray.c:1034
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_GEOM
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
Definition: lwgeom_topo.c:119
static LWT_ISO_EDGE * lwt_be_getEdgeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
Definition: lwgeom_topo.c:178
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:465
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: lwinline.h:77
POINTARRAY * points
Definition: liblwgeom.h:498
LWLINE * geom
LWT_ELEMID edge_id
const LWT_BE_IFACE * be_iface

References _lwt_release_edges(), LWT_TOPOLOGY_T::be_iface, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::geom, getPoint_internal(), lwerror(), LWGEOM2GEOS(), lwgeom_geos_errmsg, lwgeom_geos_error(), lwgeom_get_bbox(), lwline_as_lwgeom(), lwline_is_closed(), lwnotice(), lwt_be_getEdgeWithinBox2D(), lwt_be_lastErrorMessage(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_GEOM, LWLINE::points, and ptarray_isccw().

Referenced by _lwt_AddLineEdge().

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