46 v->
x = (v1->
y * v2->
z) - (v1->
z * v2->
y);
47 v->
y = (v1->
z * v2->
x) - (v1->
x * v2->
z);
48 v->
z = (v1->
x * v2->
y) - (v1->
y * v2->
x);
99 LWDEBUG(2,
"lw_dist3d_distanceline is called");
100 double x1, x2, y1, y2, z1, z2,
x,
y;
101 double initdistance = (mode ==
DIST_MIN ? DBL_MAX : -1.0);
117 "One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
129 lwerror(
"Some unspecified error.");
143 lwerror(
"Some unspecified error.");
158 lwerror(
"Some unspecified error.");
169 lwerror(
"Some unspecified error.");
176 LWDEBUG(3,
"didn't find geometries to measure between, returning null");
206 double initdistance = DBL_MAX;
213 LWDEBUG(2,
"lw_dist3d_distancepoint is called");
222 "One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
234 lwerror(
"Some unspecified error.");
249 lwerror(
"Some unspecified error.");
265 lwerror(
"Some unspecified error.");
276 lwerror(
"Some unspecified error.");
282 LWDEBUG(3,
"didn't find geometries to measure between, returning null");
315 "One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
319 LWDEBUG(2,
"lwgeom_maxdistance3d_tolerance is called");
327 lwerror(
"Some unspecified error.");
382 for (uint32_t i = 0; i < c->
ngeoms; i++)
390 is_inside = !is_inside;
404 is_inside = !is_inside;
422 AFFINE aff = {1, 0, cx, 0, 1, cy, 0, 0, 1, 0, 0, 0};
444 assert(tolerance >= 0);
448 "One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
468 lwerror(
"Some unspecified error.");
495 LWDEBUGF(2,
"lw_dist3d_recursive is called with type1=%d, type2=%d", lwg1->
type, lwg2->
type);
499 LWDEBUG(3,
"First geometry is collection");
505 LWDEBUG(3,
"Second geometry is collection");
510 for (i = 0; i < n1; i++)
522 LWDEBUG(3,
"Found collection inside first geometry collection, recursing");
527 for (j = 0; j < n2; j++)
536 LWDEBUG(3,
"Found collection inside second geometry collection, recursing");
566 LWDEBUGF(2,
"lw_dist3d_distribute_bruteforce is called with typ1=%d, type2=%d", lwg1->
type, lwg2->
type);
706 LWDEBUG(2,
"lw_dist3d_point_point is called");
722 LWDEBUG(2,
"lw_dist3d_point_line is called");
745 LWDEBUG(2,
"lw_dist3d_point_poly is called");
793 LWDEBUG(2,
"lw_dist3d_line_line is called");
803 LWDEBUG(2,
"lw_dist3d_line_poly is called");
836 int planedef1, planedef2;
837 LWDEBUG(2,
"lw_dist3d_poly_poly is called");
844 if (!planedef1 || !planedef2)
847 if (!planedef1 && !planedef2)
877 int planedef1, planedef2;
885 if (!planedef1 || !planedef2)
888 if (!planedef1 && !planedef2)
918 int planedef1, planedef2;
926 if (!planedef1 || !planedef2)
929 if (!planedef1 && !planedef2)
969 for (t = 1; t < pa->
npoints; t++)
994 if ((A->
x == B->
x) && (A->
y == B->
y) && (A->
z == B->
z))
999 r = ((p->
x - A->
x) * (B->
x - A->
x) + (p->
y - A->
y) * (B->
y - A->
y) + (p->
z - A->
z) * (B->
z - A->
z)) /
1000 ((B->
x - A->
x) * (B->
x - A->
x) + (B->
y - A->
y) * (B->
y - A->
y) + (B->
z - A->
z) * (B->
z - A->
z));
1021 c.
x = A->
x +
r * (B->
x - A->
x);
1022 c.
y = A->
y +
r * (B->
y - A->
y);
1023 c.
z = A->
z +
r * (B->
z - A->
z);
1031 double dx = p2->
x - p1->
x;
1032 double dy = p2->
y - p1->
y;
1033 double dz = p2->
z - p1->
z;
1034 return sqrt(dx * dx + dy * dy + dz * dz);
1047 double dx = thep2->
x - thep1->
x;
1048 double dy = thep2->
y - thep1->
y;
1049 double dz = thep2->
z - thep1->
z;
1050 double dist = sqrt(dx * dx + dy * dy + dz * dz);
1052 "lw_dist3d_pt_pt called (with points: p1.x=%f, p1.y=%f,p1.z=%f,p2.x=%f, p2.y=%f,p2.z=%f)",
1096 for (t = 0; t < l1->
npoints; t++)
1099 for (u = 0; u < l2->
npoints; u++)
1109 for (t = 1; t < l1->
npoints; t++)
1113 for (u = 1; u < l2->
npoints; u++)
1119 4,
"mindist_ptarray_ptarray; seg %i * seg %i, dist = %g\n", t, u, dl->
distance);
1142 double a, b, c, d, e, D;
1145 if ((s1p1->
x == s1p2->
x) && (s1p1->
y == s1p2->
y) && (s1p1->
z == s1p2->
z))
1150 if ((s2p1->
x == s2p2->
x) && (s2p1->
y == s2p2->
y) && (s2p1->
z == s2p2->
z))
1178 if (D < 0.000000001)
1190 s1k = (b * e - c * d) / D;
1191 s2k = (a * e - b * d) / D;
1197 if (s1k <= 0.0 || s1k >= 1.0 || s2k <= 0.0 || s2k >= 1.0)
1224 p1.
x = s1p1->
x + s1k * (s1p2->
x - s1p1->
x);
1225 p1.
y = s1p1->
y + s1k * (s1p2->
y - s1p1->
y);
1226 p1.
z = s1p1->
z + s1k * (s1p2->
z - s1p1->
z);
1228 p2.
x = s2p1->
x + s2k * (s2p2->
x - s2p1->
x);
1229 p2.
y = s2p1->
y + s2k * (s2p2->
y - s2p1->
y);
1230 p2.
z = s2p1->
z + s2k * (s2p2->
z - s2p1->
z);
1254 for (i = 1; i < poly->
nrings; i++)
1295 POINT3DZ p1, p2, projp1, projp2, intersectionp;
1305 for (i = 1; i < pa->
npoints; i++)
1319 f = fabs(s1) / (fabs(s1) + fabs(s2));
1323 intersectionp.
x = projp1.
x + f * projp1_projp2.
x;
1324 intersectionp.
y = projp1.
y + f * projp1_projp2.
y;
1325 intersectionp.
z = projp1.
z + f * projp1_projp2.
z;
1332 for (k = 1; k < poly->
nrings; k++)
1344 dl->
p1.
x = intersectionp.
x;
1345 dl->
p1.
y = intersectionp.
y;
1346 dl->
p1.
z = intersectionp.
z;
1348 dl->
p2.
x = intersectionp.
x;
1349 dl->
p2.
y = intersectionp.
y;
1350 dl->
p2.
z = intersectionp.
z;
1362 for (j = 0; j < poly->
nrings; j++)
1375 POINT3DZ p1, p2, projp1, projp2, intersectionp;
1385 for (i = 1; i < pa->
npoints; i++)
1400 f = fabs(s1) / (fabs(s1) + fabs(s2));
1404 intersectionp.
x = projp1.
x + f * projp1_projp2.
x;
1405 intersectionp.
y = projp1.
y + f * projp1_projp2.
y;
1406 intersectionp.
z = projp1.
z + f * projp1_projp2.
z;
1416 dl->
p1.
x = intersectionp.
x;
1417 dl->
p1.
y = intersectionp.
y;
1418 dl->
p1.
z = intersectionp.
z;
1420 dl->
p2.
x = intersectionp.
x;
1421 dl->
p2.
y = intersectionp.
y;
1422 dl->
p2.
z = intersectionp.
z;
1450 const uint32_t POL_BREAKS = 3;
1457 uint32_t unique_points = pa->
npoints - 1;
1467 for (i = 0; i < unique_points; i++)
1476 pl->
pop.
x /= unique_points;
1477 pl->
pop.
y /= unique_points;
1478 pl->
pop.
z /= unique_points;
1483 for (i = 0; i < POL_BREAKS; i++)
1488 n1 = i * unique_points / POL_BREAKS;
1489 n2 = n1 + unique_points / POL_BREAKS;
1506 double vl = vp.
x * vp.
x + vp.
y * vp.
y + vp.
z * vp.
z;
1507 pl->
pv.
x += vp.
x / vl;
1508 pl->
pv.
y += vp.
y / vl;
1509 pl->
pv.
z += vp.
z / vl;
1534 f =
DOT(pl->
pv, v1);
1544 p0->
x = p->
x + pl->
pv.
x * f;
1545 p0->
y = p->
y + pl->
pv.
y * f;
1546 p0->
z = p->
z + pl->
pv.
z * f;
1575 if (memcmp(&first, &last,
sizeof(
POINT3DZ)))
1577 lwerror(
"pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1587 LWDEBUGF(2,
"pt_in_ring_3d called with point: %g %g %g", p->
x, p->
y, p->
z);
1593 if (fabs(plane->
pv.
z) >= fabs(plane->
pv.
x) &&
1594 fabs(plane->
pv.
z) >= fabs(plane->
pv.
y))
1597 for (i = 0; i < ring->
npoints - 1; i++)
1605 ((v1.
y <= p->
y) && (v2.
y > p->
y))
1607 || ((v1.
y > p->
y) && (v2.
y <= p->
y)))
1610 vt = (double)(p->
y - v1.
y) / (v2.
y - v1.
y);
1613 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1622 else if (fabs(plane->
pv.
y) >= fabs(plane->
pv.
x) &&
1623 fabs(plane->
pv.
y) >= fabs(plane->
pv.
z))
1626 for (i = 0; i < ring->
npoints - 1; i++)
1634 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1636 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1639 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1642 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1653 for (i = 0; i < ring->
npoints - 1; i++)
1661 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1663 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1666 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1669 if (p->
y < v1.
y + vt * (v2.
y - v1.
y))
1678 LWDEBUGF(3,
"pt_in_ring_3d returning %d", cn & 1);
char result[OUT_DOUBLE_BUFFER_SIZE]
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
LWLINE * lwline_from_ptarray(int32_t srid, uint32_t npoints, LWPOINT **points)
void lwgeom_free(LWGEOM *geom)
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
LWPOINT * lwpoint_make3dz(int32_t srid, double x, double y, double z)
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
LWCOLLECTION * lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, double to, double offset)
Given a geometry clip based on the from/to range of one of its ordinates (x, y, z,...
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
void lwcollection_free(LWCOLLECTION *col)
#define FLAGS_GET_SOLID(flags)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
double lwgeom_maxdistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling max distance calculations and dfullywithin calculations.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
#define LW_TRUE
Return types for functions with status returns.
#define LW_INSIDE
Constants for point-in-polygon return values.
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return 1 if the point is inside the POINTARRAY, -1 if it is outside, and 0 if it is on the boundary.
int lwpoly_contains_point(const LWPOLY *poly, const POINT2D *pt)
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
double lwrandom_uniform(void)
int lw_dist3d_pt_tri(POINT3DZ *p, LWTRIANGLE *tri, PLANE3D *plane, POINT3DZ *projp, DISTPTS3D *dl)
int pt_in_ring_3d(const POINT3DZ *p, const POINTARRAY *ring, PLANE3D *plane)
pt_in_ring_3d(): crossing number test for a point in a polygon input: p = a point,...
int lw_dist3d_pt_ptarray(POINT3DZ *p, POINTARRAY *pa, DISTPTS3D *dl)
search all the segments of pointarray to see which one is closest to p Returns distance between point...
int lw_dist3d_line_tri(LWLINE *line, LWTRIANGLE *tri, DISTPTS3D *dl)
line to triangle calculation
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...
double lwgeom_maxdistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d max distance calculations and dfullywithin calculations.
int lw_dist3d_tri_tri(LWTRIANGLE *tri1, LWTRIANGLE *tri2, DISTPTS3D *dl)
triangle to triangle calculation
int lw_dist3d_point_point(LWPOINT *point1, LWPOINT *point2, DISTPTS3D *dl)
point to point calculation
int lw_dist3d_seg_seg(POINT3DZ *s1p1, POINT3DZ *s1p2, POINT3DZ *s2p1, POINT3DZ *s2p2, DISTPTS3D *dl)
Finds the two closest points on two linesegments.
LWGEOM * lwgeom_furthest_line_3d(LWGEOM *lw1, LWGEOM *lw2)
static int lwgeom_solid_contains_lwgeom(const LWGEOM *solid, const LWGEOM *g)
LWGEOM * lwgeom_closest_point_3d(const LWGEOM *lw1, const LWGEOM *lw2)
int define_plane(POINTARRAY *pa, PLANE3D *pl)
int lw_dist3d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3D *dl)
This function distributes the brute-force for 3D so far the only type, tasks depending on type.
int lw_dist3d_point_tri(LWPOINT *point, LWTRIANGLE *tri, DISTPTS3D *dl)
static int get_3dvector_from_points(POINT3DZ *p1, POINT3DZ *p2, VECTOR3D *v)
static int get_3dcross_product(VECTOR3D *v1, VECTOR3D *v2, VECTOR3D *v)
int lw_dist3d_pt_poly(POINT3DZ *p, LWPOLY *poly, PLANE3D *plane, POINT3DZ *projp, DISTPTS3D *dl)
Checking if the point projected on the plane of the polygon actually is inside that polygon.
int lw_dist3d_poly_tri(LWPOLY *poly, LWTRIANGLE *tri, DISTPTS3D *dl)
polygon to triangle calculation
double distance3d_pt_pt(const POINT3D *p1, const POINT3D *p2)
int lw_dist3d_pt_pt(POINT3DZ *thep1, POINT3DZ *thep2, DISTPTS3D *dl)
Compares incoming points and stores the points closest to each other or most far away from each other...
int lw_dist3d_pt_seg(POINT3DZ *p, POINT3DZ *A, POINT3DZ *B, DISTPTS3D *dl)
If searching for min distance, this one finds the closest point on segment A-B from p.
double lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d min distance calculations and dwithin calculations.
int lw_dist3d_poly_poly(LWPOLY *poly1, LWPOLY *poly2, DISTPTS3D *dl)
polygon to polygon calculation
int lw_dist3d_ptarray_tri(POINTARRAY *pa, LWTRIANGLE *tri, PLANE3D *plane, DISTPTS3D *dl)
Computes pointarray to triangle distance.
int lw_dist3d_line_line(LWLINE *line1, LWLINE *line2, DISTPTS3D *dl)
line to line calculation
LWGEOM * lw_dist3d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int32_t srid, int mode)
Function initializing 3dclosestpoint calculations.
int lw_dist3d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly, PLANE3D *plane, DISTPTS3D *dl)
Computes pointarray to polygon distance.
static int gbox_contains_3d(const GBOX *g1, const GBOX *g2)
LWGEOM * lw_dist3d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int32_t srid, int mode)
Function initializing 3dshortestline and 3dlongestline calculations.
double lwgeom_maxdistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d max distance calculation.
int lw_dist3d_point_poly(LWPOINT *point, LWPOLY *poly, DISTPTS3D *dl)
Computes point to polygon distance For mindistance that means: 1) find the plane of the polygon 2) pr...
int lw_dist3d_point_line(LWPOINT *point, LWLINE *line, DISTPTS3D *dl)
point to line calculation
double project_point_on_plane(POINT3DZ *p, PLANE3D *pl, POINT3DZ *p0)
Finds a point on a plane from where the original point is perpendicular to the plane.
int lw_dist3d_line_poly(LWLINE *line, LWPOLY *poly, DISTPTS3D *dl)
line to polygon calculation
int lw_dist3d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3D *dl)
This is a recursive function delivering every possible combination of subgeometries.
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
int lw_dist3d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2, DISTPTS3D *dl)
Finds all combinations of segments between two pointarrays.
double lwgeom_mindistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d min distance calculation.
LWGEOM * lw_dist2d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int32_t srid, int mode)
Function initializing shortestline and longestline calculations.
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...
LWGEOM * lw_dist2d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int32_t srid, int mode)
Function initializing closestpoint calculations.
Structure used in distance-calculations.
Structure used in distance-calculations.