PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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 5036 of file lwgeom_topo.c.

5037{
5038 LWT_ELEMID id = 0;
5039 LWT_ISO_EDGE *elem;
5040 uint64_t num, i;
5041 int flds = LWT_COL_EDGE_EDGE_ID |
5045 LWGEOM *qp = lwpoint_as_lwgeom(pt);
5046
5047 id = lwt_GetFaceContainingPoint(topo, pt);
5048 if ( id == -1 ) {
5050 return -1;
5051 }
5052
5053 if ( id > 0 )
5054 {
5055 return id;
5056 }
5057
5058 if ( tol == 0 )
5059 {
5060 return id;
5061 }
5062
5063 LWDEBUG(1, "No face properly contains query point,"
5064 " looking for edges");
5065
5066 /* Not in a face, may be in universe or on edge, let's check
5067 * for distance */
5068 /* NOTE: we never pass a tolerance of 0 to avoid ever using
5069 * ST_Within, which doesn't include endpoints matches */
5070 elem = lwt_be_getEdgeWithinDistance2D(topo, pt, tol?tol:1e-5, &num, flds, 0);
5071 if (num == UINT64_MAX)
5072 {
5074 return -1;
5075 }
5076 for (i=0; i<num; ++i)
5077 {
5078 LWT_ISO_EDGE *e = &(elem[i]);
5079 LWT_ELEMID eface = 0;
5080 LWGEOM* geom;
5081 double dist;
5082
5083 if ( ! e->geom )
5084 {
5085 _lwt_release_edges(elem, num);
5086 lwnotice("Corrupted topology: edge %" LWTFMT_ELEMID
5087 " has null geometry", e->edge_id);
5088 continue;
5089 }
5090
5091 /* don't consider dangling edges */
5092 if ( e->face_left == e->face_right )
5093 {
5094 LWDEBUGF(1, "Edge %" LWTFMT_ELEMID
5095 " is dangling, won't consider it", e->edge_id);
5096 continue;
5097 }
5098
5099 geom = lwline_as_lwgeom(e->geom);
5100 dist = lwgeom_mindistance2d_tolerance(geom, qp, tol);
5101
5102 LWDEBUGF(1, "Distance from edge %" LWTFMT_ELEMID
5103 " is %g (tol=%g)", e->edge_id, dist, tol);
5104
5105 /* we won't consider edges too far */
5106 if ( dist > tol ) continue;
5107 if ( e->face_left == 0 ) {
5108 eface = e->face_right;
5109 }
5110 else if ( e->face_right == 0 ) {
5111 eface = e->face_left;
5112 }
5113 else {
5114 _lwt_release_edges(elem, num);
5115 lwerror("Two or more faces found");
5116 return -1;
5117 }
5118
5119 if ( id && id != eface )
5120 {
5121 _lwt_release_edges(elem, num);
5122 lwerror("Two or more faces found"
5123#if 0 /* debugging */
5124 " (%" LWTFMT_ELEMID
5125 " and %" LWTFMT_ELEMID ")", id, eface
5126#endif
5127 );
5128 return -1;
5129 }
5130 else id = eface;
5131 }
5132 if ( num ) _lwt_release_edges(elem, num);
5133
5134 return id;
5135}
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:372
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
Definition measures.c:222
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:367
#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_ISO_EDGE * lwt_be_getEdgeWithinDistance2D(LWT_TOPOLOGY *topo, const LWPOINT *pt, double dist, uint64_t *numelems, int fields, int64_t limit)
LWT_ELEMID lwt_GetFaceContainingPoint(LWT_TOPOLOGY *topo, const LWPOINT *pt)
Find the face-id of the face properly containing a given point.
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
LWT_ELEMID face_right
LWT_ELEMID face_left
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: