PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ lw_dist3d_distancepoint()

LWGEOM* lw_dist3d_distancepoint ( const LWGEOM lw1,
const LWGEOM lw2,
int32_t  srid,
int  mode 
)

Function initializing 3dclosestpoint calculations.

Definition at line 201 of file measures3d.c.

202 {
203 
204  double x, y, z;
205  DISTPTS3D thedl;
206  double initdistance = DBL_MAX;
207  LWGEOM *result;
208 
209  thedl.mode = mode;
210  thedl.distance = initdistance;
211  thedl.tolerance = 0;
212 
213  LWDEBUG(2, "lw_dist3d_distancepoint is called");
214 
215  /* Check if we really have 3D geometries
216  * If not, send it to 2D-calculations which will give the same result
217  * as an infinite z-value at one or two of the geometries
218  */
219  if (!lwgeom_has_z(lw1) || !lwgeom_has_z(lw2))
220  {
221  lwnotice(
222  "One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
223 
224  if (!lwgeom_has_z(lw1) && !lwgeom_has_z(lw2))
225  return lw_dist2d_distancepoint(lw1, lw2, srid, mode);
226 
227  DISTPTS thedl2d;
228  thedl2d.mode = mode;
229  thedl2d.distance = initdistance;
230  thedl2d.tolerance = 0.0;
231  if (!lw_dist2d_comp(lw1, lw2, &thedl2d))
232  {
233  /* should never get here. all cases ought to be error handled earlier */
234  lwerror("Some unspecified error.");
235  return (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
236  }
237 
238  LWGEOM *vertical_line;
239  if (!lwgeom_has_z(lw1))
240  {
241  x = thedl2d.p1.x;
242  y = thedl2d.p1.y;
243 
244  vertical_line = create_v_line(lw2, x, y, srid);
245  if (!lw_dist3d_recursive(vertical_line, lw2, &thedl))
246  {
247  /* should never get here. all cases ought to be error handled earlier */
248  lwfree(vertical_line);
249  lwerror("Some unspecified error.");
250  return (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
251  }
252  lwfree(vertical_line);
253  }
254 
255  if (!lwgeom_has_z(lw2))
256  {
257  x = thedl2d.p2.x;
258  y = thedl2d.p2.y;
259 
260  vertical_line = create_v_line(lw1, x, y, srid);
261  if (!lw_dist3d_recursive(lw1, vertical_line, &thedl))
262  {
263  /* should never get here. all cases ought to be error handled earlier */
264  lwfree(vertical_line);
265  lwerror("Some unspecified error.");
266  result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
267  }
268  lwfree(vertical_line);
269  }
270  }
271  else
272  {
273  if (!lw_dist3d_recursive(lw1, lw2, &thedl))
274  {
275  /* should never get here. all cases ought to be error handled earlier */
276  lwerror("Some unspecified error.");
277  result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
278  }
279  }
280  if (thedl.distance == initdistance)
281  {
282  LWDEBUG(3, "didn't find geometries to measure between, returning null");
283  result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
284  }
285  else
286  {
287  x = thedl.p1.x;
288  y = thedl.p1.y;
289  z = thedl.p1.z;
290  result = (LWGEOM *)lwpoint_make3dz(srid, x, y, z);
291  }
292 
293  return result;
294 }
#define COLLECTIONTYPE
Definition: liblwgeom.h:122
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:916
void lwfree(void *mem)
Definition: lwutil.c:242
LWPOINT * lwpoint_make3dz(int32_t srid, double x, double y, double z)
Definition: lwpoint.c:173
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwcollection.c:92
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
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
static LWGEOM * create_v_line(const LWGEOM *lwgeom, double x, double y, int32_t srid)
This function is used to create a vertical line used for cases where one if the geometries lacks z-va...
Definition: measures3d.c:59
int lw_dist3d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3D *dl)
This is a recursive function delivering every possible combination of subgeometries.
Definition: measures3d.c:485
int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl)
This function just deserializes geometries Bboxes is not checked here since it is the subgeometries b...
Definition: measures.c:236
LWGEOM * lw_dist2d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int32_t srid, int mode)
Function initializing closestpoint calculations.
Definition: measures.c:128
POINT3DZ p1
Definition: measures3d.h:41
double distance
Definition: measures3d.h:40
int mode
Definition: measures3d.h:43
double tolerance
Definition: measures3d.h:47
Structure used in distance-calculations.
Definition: measures3d.h:39
POINT2D p1
Definition: measures.h:52
POINT2D p2
Definition: measures.h:53
double tolerance
Definition: measures.h:56
int mode
Definition: measures.h:54
double distance
Definition: measures.h:51
Structure used in distance-calculations.
Definition: measures.h:50
double y
Definition: liblwgeom.h:376
double x
Definition: liblwgeom.h:376
double z
Definition: liblwgeom.h:382
double x
Definition: liblwgeom.h:382
double y
Definition: liblwgeom.h:382

References COLLECTIONTYPE, create_v_line(), DISTPTS::distance, DISTPTS3D::distance, lw_dist2d_comp(), lw_dist2d_distancepoint(), lw_dist3d_recursive(), lwcollection_construct_empty(), LWDEBUG, lwerror(), lwfree(), lwgeom_has_z(), lwnotice(), lwpoint_make3dz(), DISTPTS::mode, DISTPTS3D::mode, DISTPTS::p1, DISTPTS3D::p1, DISTPTS::p2, DISTPTS::tolerance, DISTPTS3D::tolerance, POINT2D::x, POINT3DZ::x, pixval::x, POINT2D::y, POINT3DZ::y, pixval::y, and POINT3DZ::z.

Referenced by lwgeom_closest_point_3d().

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