PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ lwt_GetFaceByPoint()

LWT_ELEMID lwt_GetFaceByPoint ( LWT_TOPOLOGY topo,
const LWPOINT pt,
double  tol 
)

Find the face-id of a face containing a given point.

Parameters
topothe topology to operate on
pointthe point to use for query
tolmax distance around the given point to look for a containing face
Returns
a face identifier if one is found (0 if universe), -1 on error (multiple faces within distance or point on node or edge). The liblwgeom error handler will be invoked in case of error.

Definition at line 4919 of file lwgeom_topo.c.

4920 {
4921  LWT_ELEMID id = 0;
4922  LWT_ISO_EDGE *elem;
4923  uint64_t num, i;
4924  int flds = LWT_COL_EDGE_EDGE_ID |
4928  LWGEOM *qp = lwpoint_as_lwgeom(pt);
4929 
4930  id = lwt_GetFaceContainingPoint(topo, pt);
4931  if ( id == -1 ) {
4932  PGTOPO_BE_ERROR();
4933  return -1;
4934  }
4935 
4936  if ( id > 0 )
4937  {
4938  return id;
4939  }
4940 
4941  if ( tol == 0 )
4942  {
4943  return id;
4944  }
4945 
4946  LWDEBUG(1, "No face properly contains query point,"
4947  " looking for edges");
4948 
4949  /* Not in a face, may be in universe or on edge, let's check
4950  * for distance */
4951  /* NOTE: we never pass a tolerance of 0 to avoid ever using
4952  * ST_Within, which doesn't include endpoints matches */
4953  elem = lwt_be_getEdgeWithinDistance2D(topo, pt, tol?tol:1e-5, &num, flds, 0);
4954  if (num == UINT64_MAX)
4955  {
4956  PGTOPO_BE_ERROR();
4957  return -1;
4958  }
4959  for (i=0; i<num; ++i)
4960  {
4961  LWT_ISO_EDGE *e = &(elem[i]);
4962  LWT_ELEMID eface = 0;
4963  LWGEOM* geom;
4964  double dist;
4965 
4966  if ( ! e->geom )
4967  {
4968  _lwt_release_edges(elem, num);
4969  lwnotice("Corrupted topology: edge %" LWTFMT_ELEMID
4970  " has null geometry", e->edge_id);
4971  continue;
4972  }
4973 
4974  /* don't consider dangling edges */
4975  if ( e->face_left == e->face_right )
4976  {
4977  LWDEBUGF(1, "Edge %" LWTFMT_ELEMID
4978  " is dangling, won't consider it", e->edge_id);
4979  continue;
4980  }
4981 
4982  geom = lwline_as_lwgeom(e->geom);
4983  dist = lwgeom_mindistance2d_tolerance(geom, qp, tol);
4984 
4985  LWDEBUGF(1, "Distance from edge %" LWTFMT_ELEMID
4986  " is %g (tol=%g)", e->edge_id, dist, tol);
4987 
4988  /* we won't consider edges too far */
4989  if ( dist > tol ) continue;
4990  if ( e->face_left == 0 ) {
4991  eface = e->face_right;
4992  }
4993  else if ( e->face_right == 0 ) {
4994  eface = e->face_left;
4995  }
4996  else {
4997  _lwt_release_edges(elem, num);
4998  lwerror("Two or more faces found");
4999  return -1;
5000  }
5001 
5002  if ( id && id != eface )
5003  {
5004  _lwt_release_edges(elem, num);
5005  lwerror("Two or more faces found"
5006 #if 0 /* debugging */
5007  " (%" LWTFMT_ELEMID
5008  " and %" LWTFMT_ELEMID ")", id, eface
5009 #endif
5010  );
5011  return -1;
5012  }
5013  else id = eface;
5014  }
5015  if ( num ) _lwt_release_edges(elem, num);
5016 
5017  return id;
5018 }
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:344
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
Definition: measures.c:210
#define LWT_COL_EDGE_FACE_RIGHT
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_FACE_LEFT
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_GEOM
#define PGTOPO_BE_ERROR()
#define LWTFMT_ELEMID
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:106
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_ELEMID lwt_GetFaceContainingPoint(LWT_TOPOLOGY *topo, const LWPOINT *pt)
Find the face-id of the face properly containing a given point.
Definition: lwgeom_topo.c:7669
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:460
LWT_ISO_EDGE * lwt_be_getEdgeWithinDistance2D(LWT_TOPOLOGY *topo, const LWPOINT *pt, double dist, uint64_t *numelems, int fields, int64_t limit)
Definition: lwgeom_topo.c:245
LWT_ELEMID face_right
LWT_ELEMID face_left
LWLINE * geom
LWT_ELEMID edge_id

References _lwt_release_edges(), LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, LWT_ISO_EDGE::geom, LWDEBUG, LWDEBUGF, lwerror(), lwgeom_mindistance2d_tolerance(), lwline_as_lwgeom(), lwnotice(), lwpoint_as_lwgeom(), lwt_be_getEdgeWithinDistance2D(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_FACE_LEFT, LWT_COL_EDGE_FACE_RIGHT, LWT_COL_EDGE_GEOM, lwt_GetFaceContainingPoint(), LWTFMT_ELEMID, and PGTOPO_BE_ERROR.

Here is the call graph for this function: