PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ _lwt_GetEqualEdge()

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

Definition at line 5091 of file lwgeom_topo.c.

5092 {
5093  LWT_ELEMID id;
5094  LWT_ISO_EDGE *edges;
5095  uint64_t num, i;
5096  const GBOX *qbox = lwgeom_get_bbox( lwline_as_lwgeom(edge) );
5097  GEOSGeometry *edgeg;
5098  const int flds = LWT_COL_EDGE_EDGE_ID|LWT_COL_EDGE_GEOM;
5099 
5100  edges = lwt_be_getEdgeWithinBox2D( topo, qbox, &num, flds, 0 );
5101  if (num == UINT64_MAX)
5102  {
5103  PGTOPO_BE_ERROR();
5104  return -1;
5105  }
5106  if ( num )
5107  {
5108  initGEOS(lwnotice, lwgeom_geos_error);
5109 
5110  edgeg = LWGEOM2GEOS( lwline_as_lwgeom(edge), 0 );
5111  if ( ! edgeg )
5112  {
5113  _lwt_release_edges(edges, num);
5114  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5115  return -1;
5116  }
5117  for (i=0; i<num; ++i)
5118  {
5119  LWT_ISO_EDGE *e = &(edges[i]);
5120  LWGEOM *g = lwline_as_lwgeom(e->geom);
5121  GEOSGeometry *gg;
5122  int equals;
5123  gg = LWGEOM2GEOS( g, 0 );
5124  if ( ! gg )
5125  {
5126  GEOSGeom_destroy(edgeg);
5127  _lwt_release_edges(edges, num);
5128  lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
5129  return -1;
5130  }
5131  equals = GEOSEquals(gg, edgeg);
5132  GEOSGeom_destroy(gg);
5133  if ( equals == 2 )
5134  {
5135  GEOSGeom_destroy(edgeg);
5136  _lwt_release_edges(edges, num);
5137  lwerror("GEOSEquals exception: %s", lwgeom_geos_errmsg);
5138  return -1;
5139  }
5140  if ( equals )
5141  {
5142  id = e->edge_id;
5143  /* Check if direction also matches */
5144  if ( forward )
5145  {
5146  /* If input line is closed, we use winding order */
5147  if ( lwline_is_closed(edge) )
5148  {
5149  if ( ptarray_isccw(edge->points) == ptarray_isccw(e->geom->points) )
5150  {
5151  *forward = 1;
5152  }
5153  else
5154  {
5155  *forward = 0;
5156  }
5157  }
5158  else
5159  {
5160  /* Input line is not closed, checking fist point is enough */
5161  if (
5162  memcmp(
5163  getPoint_internal(edge->points, 0),
5164  getPoint_internal(e->geom->points, 0),
5165  sizeof(POINT2D)
5166  ) == 0
5167  )
5168  {
5169  *forward = 1;
5170  }
5171  else
5172  {
5173  *forward = 0;
5174  }
5175  }
5176  }
5177  GEOSGeom_destroy(edgeg);
5178  _lwt_release_edges(edges, num);
5179  return id;
5180  }
5181  }
5182  GEOSGeom_destroy(edgeg);
5183  _lwt_release_edges(edges, num);
5184  }
5185 
5186  return 0;
5187 }
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:1051
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_GEOM
#define PGTOPO_BE_ERROR()
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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:173
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:460
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: lwinline.h:75
POINTARRAY * points
Definition: liblwgeom.h:483
LWLINE * geom
LWT_ELEMID edge_id

References _lwt_release_edges(), 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_COL_EDGE_EDGE_ID, LWT_COL_EDGE_GEOM, PGTOPO_BE_ERROR, LWLINE::points, and ptarray_isccw().

Referenced by _lwt_AddLineEdge(), and _lwt_SnapEdgeToExistingNode().

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