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++)
539 LWDEBUG(3,
"Found collection inside second geometry collection, recursing");
569 LWDEBUGF(2,
"lw_dist3d_distribute_bruteforce is called with typ1=%d, type2=%d", lwg1->
type, lwg2->
type);
709 LWDEBUG(2,
"lw_dist3d_point_point is called");
725 LWDEBUG(2,
"lw_dist3d_point_line is called");
748 LWDEBUG(2,
"lw_dist3d_point_poly is called");
796 LWDEBUG(2,
"lw_dist3d_line_line is called");
806 LWDEBUG(2,
"lw_dist3d_line_poly is called");
839 int planedef1, planedef2;
840 LWDEBUG(2,
"lw_dist3d_poly_poly is called");
847 if (!planedef1 || !planedef2)
850 if (!planedef1 && !planedef2)
880 int planedef1, planedef2;
888 if (!planedef1 || !planedef2)
891 if (!planedef1 && !planedef2)
921 int planedef1, planedef2;
929 if (!planedef1 || !planedef2)
932 if (!planedef1 && !planedef2)
972 for (t = 1; t < pa->
npoints; t++)
997 if ((A->
x == B->
x) && (A->
y == B->
y) && (A->
z == B->
z))
1002 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)) /
1003 ((B->
x - A->
x) * (B->
x - A->
x) + (B->
y - A->
y) * (B->
y - A->
y) + (B->
z - A->
z) * (B->
z - A->
z));
1024 c.
x = A->
x +
r * (B->
x - A->
x);
1025 c.
y = A->
y +
r * (B->
y - A->
y);
1026 c.
z = A->
z +
r * (B->
z - A->
z);
1034 double dx = p2->
x - p1->
x;
1035 double dy = p2->
y - p1->
y;
1036 double dz = p2->
z - p1->
z;
1037 return sqrt(dx * dx + dy * dy + dz * dz);
1050 double dx = thep2->
x - thep1->
x;
1051 double dy = thep2->
y - thep1->
y;
1052 double dz = thep2->
z - thep1->
z;
1053 double dist = sqrt(dx * dx + dy * dy + dz * dz);
1055 "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)",
1099 for (t = 0; t < l1->
npoints; t++)
1102 for (u = 0; u < l2->
npoints; u++)
1112 for (t = 1; t < l1->
npoints; t++)
1116 for (u = 1; u < l2->
npoints; u++)
1122 4,
"mindist_ptarray_ptarray; seg %i * seg %i, dist = %g\n", t, u, dl->
distance);
1145 double a, b, c, d, e, D;
1148 if ((s1p1->
x == s1p2->
x) && (s1p1->
y == s1p2->
y) && (s1p1->
z == s1p2->
z))
1153 if ((s2p1->
x == s2p2->
x) && (s2p1->
y == s2p2->
y) && (s2p1->
z == s2p2->
z))
1181 if (D < 0.000000001)
1193 s1k = (b * e - c * d) / D;
1194 s2k = (a * e - b * d) / D;
1200 if (s1k <= 0.0 || s1k >= 1.0 || s2k <= 0.0 || s2k >= 1.0)
1227 p1.
x = s1p1->
x + s1k * (s1p2->
x - s1p1->
x);
1228 p1.
y = s1p1->
y + s1k * (s1p2->
y - s1p1->
y);
1229 p1.
z = s1p1->
z + s1k * (s1p2->
z - s1p1->
z);
1231 p2.
x = s2p1->
x + s2k * (s2p2->
x - s2p1->
x);
1232 p2.
y = s2p1->
y + s2k * (s2p2->
y - s2p1->
y);
1233 p2.
z = s2p1->
z + s2k * (s2p2->
z - s2p1->
z);
1257 for (i = 1; i < poly->
nrings; i++)
1298 POINT3DZ p1, p2, projp1, projp2, intersectionp;
1308 for (i = 1; i < pa->
npoints; i++)
1322 f = fabs(s1) / (fabs(s1) + fabs(s2));
1326 intersectionp.
x = projp1.
x + f * projp1_projp2.
x;
1327 intersectionp.
y = projp1.
y + f * projp1_projp2.
y;
1328 intersectionp.
z = projp1.
z + f * projp1_projp2.
z;
1335 for (k = 1; k < poly->
nrings; k++)
1347 dl->
p1.
x = intersectionp.
x;
1348 dl->
p1.
y = intersectionp.
y;
1349 dl->
p1.
z = intersectionp.
z;
1351 dl->
p2.
x = intersectionp.
x;
1352 dl->
p2.
y = intersectionp.
y;
1353 dl->
p2.
z = intersectionp.
z;
1365 for (j = 0; j < poly->
nrings; j++)
1378 POINT3DZ p1, p2, projp1, projp2, intersectionp;
1388 for (i = 1; i < pa->
npoints; i++)
1403 f = fabs(s1) / (fabs(s1) + fabs(s2));
1407 intersectionp.
x = projp1.
x + f * projp1_projp2.
x;
1408 intersectionp.
y = projp1.
y + f * projp1_projp2.
y;
1409 intersectionp.
z = projp1.
z + f * projp1_projp2.
z;
1419 dl->
p1.
x = intersectionp.
x;
1420 dl->
p1.
y = intersectionp.
y;
1421 dl->
p1.
z = intersectionp.
z;
1423 dl->
p2.
x = intersectionp.
x;
1424 dl->
p2.
y = intersectionp.
y;
1425 dl->
p2.
z = intersectionp.
z;
1453 const uint32_t POL_BREAKS = 3;
1460 uint32_t unique_points = pa->
npoints - 1;
1470 for (i = 0; i < unique_points; i++)
1479 pl->
pop.
x /= unique_points;
1480 pl->
pop.
y /= unique_points;
1481 pl->
pop.
z /= unique_points;
1486 for (i = 0; i < POL_BREAKS; i++)
1491 n1 = i * unique_points / POL_BREAKS;
1492 n2 = n1 + unique_points / POL_BREAKS;
1509 double vl = vp.
x * vp.
x + vp.
y * vp.
y + vp.
z * vp.
z;
1510 pl->
pv.
x += vp.
x / vl;
1511 pl->
pv.
y += vp.
y / vl;
1512 pl->
pv.
z += vp.
z / vl;
1537 f =
DOT(pl->
pv, v1);
1547 p0->
x = p->
x + pl->
pv.
x * f;
1548 p0->
y = p->
y + pl->
pv.
y * f;
1549 p0->
z = p->
z + pl->
pv.
z * f;
1578 if (memcmp(&first, &last,
sizeof(
POINT3DZ)))
1580 lwerror(
"pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1590 LWDEBUGF(2,
"pt_in_ring_3d called with point: %g %g %g", p->
x, p->
y, p->
z);
1596 if (fabs(plane->
pv.
z) >= fabs(plane->
pv.
x) &&
1597 fabs(plane->
pv.
z) >= fabs(plane->
pv.
y))
1600 for (i = 0; i < ring->
npoints - 1; i++)
1608 ((v1.
y <= p->
y) && (v2.
y > p->
y))
1610 || ((v1.
y > p->
y) && (v2.
y <= p->
y)))
1613 vt = (double)(p->
y - v1.
y) / (v2.
y - v1.
y);
1616 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1625 else if (fabs(plane->
pv.
y) >= fabs(plane->
pv.
x) &&
1626 fabs(plane->
pv.
y) >= fabs(plane->
pv.
z))
1629 for (i = 0; i < ring->
npoints - 1; i++)
1637 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1639 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1642 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1645 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1656 for (i = 0; i < ring->
npoints - 1; i++)
1664 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1666 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1669 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1672 if (p->
y < v1.
y + vt * (v2.
y - v1.
y))
1681 LWDEBUGF(3,
"pt_in_ring_3d returning %d", cn & 1);
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.