PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ _lwt_GetEqualEdge()

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

Definition at line 5280 of file lwgeom_topo.c.

5281 {
5282  LWT_ELEMID id;
5283  LWT_ISO_EDGE *edges;
5284  uint64_t num, i;
5285  const GBOX *qbox = lwgeom_get_bbox( lwline_as_lwgeom(edge) );
5286  GEOSGeometry *edgeg;
5287  const int flds = LWT_COL_EDGE_EDGE_ID|LWT_COL_EDGE_GEOM;
5288 
5289  edges = lwt_be_getEdgeWithinBox2D( topo, qbox, &num, flds, 0 );
5290  if (num == UINT64_MAX)
5291  {
5292  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
5293  return -1;
5294  }
5295  if ( num )
5296  {
5297  initGEOS(lwnotice, lwgeom_geos_error);
5298 
5299  edgeg = LWGEOM2GEOS( lwline_as_lwgeom(edge), 0 );
5300  if ( ! edgeg )
5301  {
5302  _lwt_release_edges(edges, num);
5303  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5304  return -1;
5305  }
5306  for (i=0; i<num; ++i)
5307  {
5308  LWT_ISO_EDGE *e = &(edges[i]);
5309  LWGEOM *g = lwline_as_lwgeom(e->geom);
5310  GEOSGeometry *gg;
5311  int equals;
5312  gg = LWGEOM2GEOS( g, 0 );
5313  if ( ! gg )
5314  {
5315  GEOSGeom_destroy(edgeg);
5316  _lwt_release_edges(edges, num);
5317  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5318  return -1;
5319  }
5320  equals = GEOSEquals(gg, edgeg);
5321  GEOSGeom_destroy(gg);
5322  if ( equals == 2 )
5323  {
5324  GEOSGeom_destroy(edgeg);
5325  _lwt_release_edges(edges, num);
5326  lwerror("GEOSEquals exception: %s", lwgeom_geos_errmsg);
5327  return -1;
5328  }
5329  if ( equals )
5330  {
5331  id = e->edge_id;
5332  /* Check if direction also matches */
5333  if ( forward )
5334  {
5335  /* If input line is closed, we use winding order */
5336  if ( lwline_is_closed(edge) )
5337  {
5338  if ( ptarray_isccw(edge->points) == ptarray_isccw(e->geom->points) )
5339  {
5340  *forward = 1;
5341  }
5342  else
5343  {
5344  *forward = 0;
5345  }
5346  }
5347  else
5348  {
5349  /* Input line is not closed, checking fist point is enough */
5350  if (
5351  memcmp(
5352  getPoint_internal(edge->points, 0),
5353  getPoint_internal(e->geom->points, 0),
5354  sizeof(POINT2D)
5355  ) == 0
5356  )
5357  {
5358  *forward = 1;
5359  }
5360  else
5361  {
5362  *forward = 0;
5363  }
5364  }
5365  }
5366  GEOSGeom_destroy(edgeg);
5367  _lwt_release_edges(edges, num);
5368  return id;
5369  }
5370  }
5371  GEOSGeom_destroy(edgeg);
5372  _lwt_release_edges(edges, num);
5373  }
5374 
5375  return 0;
5376 }
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:1047
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:125
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:184
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:471
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: lwinline.h:77
POINTARRAY * points
Definition: liblwgeom.h:483
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: