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

◆ lwt_GetFaceByPoint()

LWT_ELEMID lwt_GetFaceByPoint ( LWT_TOPOLOGY topo,
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 4751 of file lwgeom_topo.c.

4752{
4753 LWT_ELEMID id = 0;
4754 LWT_ISO_EDGE *elem;
4755 uint64_t num, i;
4756 int flds = LWT_COL_EDGE_EDGE_ID |
4760 LWGEOM *qp = lwpoint_as_lwgeom(pt);
4761
4762 id = lwt_be_getFaceContainingPoint(topo, pt);
4763 if ( id == -2 ) {
4764 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
4765 return -1;
4766 }
4767
4768 if ( id > 0 )
4769 {
4770 return id;
4771 }
4772 id = 0; /* or it'll be -1 for not found */
4773
4774 LWDEBUG(1, "No face properly contains query point,"
4775 " looking for edges");
4776
4777 /* Not in a face, may be in universe or on edge, let's check
4778 * for distance */
4779 /* NOTE: we never pass a tolerance of 0 to avoid ever using
4780 * ST_Within, which doesn't include endpoints matches */
4781 elem = lwt_be_getEdgeWithinDistance2D(topo, pt, tol?tol:1e-5, &num, flds, 0);
4782 if (num == UINT64_MAX)
4783 {
4784 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
4785 return -1;
4786 }
4787 for (i=0; i<num; ++i)
4788 {
4789 LWT_ISO_EDGE *e = &(elem[i]);
4790 LWT_ELEMID eface = 0;
4791 LWGEOM* geom;
4792 double dist;
4793
4794 if ( ! e->geom )
4795 {
4796 _lwt_release_edges(elem, num);
4797 lwnotice("Corrupted topology: edge %" LWTFMT_ELEMID
4798 " has null geometry", e->edge_id);
4799 continue;
4800 }
4801
4802 /* don't consider dangling edges */
4803 if ( e->face_left == e->face_right )
4804 {
4805 LWDEBUGF(1, "Edge %" LWTFMT_ELEMID
4806 " is dangling, won't consider it", e->edge_id);
4807 continue;
4808 }
4809
4810 geom = lwline_as_lwgeom(e->geom);
4811 dist = lwgeom_mindistance2d_tolerance(geom, qp, tol);
4812
4813 LWDEBUGF(1, "Distance from edge %" LWTFMT_ELEMID
4814 " is %g (tol=%g)", e->edge_id, dist, tol);
4815
4816 /* we won't consider edges too far */
4817 if ( dist > tol ) continue;
4818 if ( e->face_left == 0 ) {
4819 eface = e->face_right;
4820 }
4821 else if ( e->face_right == 0 ) {
4822 eface = e->face_left;
4823 }
4824 else {
4825 _lwt_release_edges(elem, num);
4826 lwerror("Two or more faces found");
4827 return -1;
4828 }
4829
4830 if ( id && id != eface )
4831 {
4832 _lwt_release_edges(elem, num);
4833 lwerror("Two or more faces found"
4834#if 0 /* debugging */
4835 " (%" LWTFMT_ELEMID
4836 " and %" LWTFMT_ELEMID ")", id, eface
4837#endif
4838 );
4839 return -1;
4840 }
4841 else id = eface;
4842 }
4843 if ( num ) _lwt_release_edges(elem, num);
4844
4845 return id;
4846}
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:326
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
Definition measures.c:207
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:321
#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 LWDEBUG(level, msg)
Definition lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
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
LWT_ELEMID lwt_be_getFaceContainingPoint(LWT_TOPOLOGY *topo, LWPOINT *pt)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
LWT_ISO_EDGE * lwt_be_getEdgeWithinDistance2D(LWT_TOPOLOGY *topo, LWPOINT *pt, double dist, uint64_t *numelems, int fields, int64_t limit)
#define LWTFMT_ELEMID
Definition lwgeom_topo.c:43
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
LWT_ELEMID face_right
LWT_ELEMID face_left
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::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_be_getFaceContainingPoint(), lwt_be_lastErrorMessage(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_FACE_LEFT, LWT_COL_EDGE_FACE_RIGHT, LWT_COL_EDGE_GEOM, and LWTFMT_ELEMID.

Here is the call graph for this function: