57 v->
x=(v1->
y*v2->
z)-(v1->
z*v2->
y);
58 v->
y=(v1->
z*v2->
x)-(v1->
x*v2->
z);
59 v->
z=(v1->
x*v2->
y)-(v1->
y*v2->
x);
112 LWDEBUG(2,
"lw_dist3d_distanceline is called");
113 double x1,x2,y1,y2, z1, z2,
x,
y;
114 double initdistance = ( mode ==
DIST_MIN ? FLT_MAX : -1.0);
129 lwnotice(
"One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
141 lwerror(
"Some unspecified error.");
155 lwerror(
"Some unspecified error.");
170 lwerror(
"Some unspecified error.");
182 lwerror(
"Some unspecified error.");
189 LWDEBUG(3,
"didn't find geometries to measure between, returning null");
219 double initdistance = FLT_MAX;
226 LWDEBUG(2,
"lw_dist3d_distancepoint is called");
233 lwnotice(
"One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
246 lwerror(
"Some unspecified error.");
261 lwerror(
"Some unspecified error.");
277 lwerror(
"Some unspecified error.");
289 lwerror(
"Some unspecified error.");
295 LWDEBUG(3,
"didn't find geometries to measure between, returning null");
316 LWDEBUG(2,
"lwgeom_maxdistance3d is called");
330 lwnotice(
"One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
335 LWDEBUG(2,
"lwgeom_maxdistance3d_tolerance is called");
344 lwerror(
"Some unspecified error.");
354 LWDEBUG(2,
"lwgeom_mindistance3d is called");
367 lwnotice(
"One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
372 LWDEBUG(2,
"lwgeom_mindistance3d_tolerance is called");
381 lwerror(
"Some unspecified error.");
409 LWDEBUGF(2,
"lw_dist3d_recursive is called with type1=%d, type2=%d", lwg1->
type, lwg2->
type);
413 LWDEBUG(3,
"First geometry is collection");
419 LWDEBUG(3,
"Second geometry is collection");
424 for ( i = 0; i < n1; i++ )
440 LWDEBUG(3,
"Found collection inside first geometry collection, recursing");
444 for ( j = 0; j < n2; j++ )
456 LWDEBUG(3,
"Found collection inside second geometry collection, recursing");
486 LWDEBUGF(2,
"lw_dist3d_distribute_bruteforce is called with typ1=%d, type2=%d", lwg1->
type, lwg2->
type);
585 LWDEBUG(2,
"lw_dist3d_point_point is called");
601 LWDEBUG(2,
"lw_dist3d_point_line is called");
623 LWDEBUG(2,
"lw_dist3d_point_poly is called");
629 LWDEBUG(3,
"looking for maxdistance");
656 LWDEBUG(2,
"lw_dist3d_line_line is called");
668 LWDEBUG(2,
"lw_dist3d_line_poly is called");
691 int planedef1, planedef2;
692 LWDEBUG(2,
"lw_dist3d_poly_poly is called");
701 if (!planedef1 || !planedef2)
703 if (!planedef1 && !planedef2)
743 LWDEBUG(2,
"lw_dist3d_pt_ptarray is called");
772 if ( ( A->
x == B->
x) && (A->
y == B->
y) && (A->
z == B->
z) )
778 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) )/( (B->
x-A->
x)*(B->
x-A->
x) +(B->
y-A->
y)*(B->
y-A->
y)+(B->
z-A->
z)*(B->
z-A->
z) );
807 c.
x=A->
x +
r * (B->
x-A->
x);
808 c.
y=A->
y +
r * (B->
y-A->
y);
809 c.
z=A->
z +
r * (B->
z-A->
z);
817 double dx = p2->
x - p1->
x;
818 double dy = p2->
y - p1->
y;
819 double dz = p2->
z - p1->
z;
820 return sqrt ( dx*dx + dy*dy + dz*dz);
834 double dx = thep2->
x - thep1->
x;
835 double dy = thep2->
y - thep1->
y;
836 double dz = thep2->
z - thep1->
z;
837 double dist = sqrt ( dx*dx + dy*dy + dz*dz);
838 LWDEBUGF(2,
"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)",thep1->
x,thep1->
y,thep1->
z,thep2->
x,thep2->
y,thep2->
z );
883 LWDEBUGF(4,
"maxdist_ptarray_ptarray; seg %i * seg %i, dist = %g\n",t,u,dl->
distance);
884 LWDEBUGF(3,
" seg%d-seg%d dist: %f, mindist: %f",
901 LWDEBUGF(4,
"mindist_ptarray_ptarray; seg %i * seg %i, dist = %g\n",t,u,dl->
distance);
902 LWDEBUGF(3,
" seg%d-seg%d dist: %f, mindist: %f",
923 double a, b, c, d, e, D;
926 if ( ( s1p1->
x == s1p2->
x) && (s1p1->
y == s1p2->
y) && (s1p1->
z == s1p2->
z) )
931 if ( ( s2p1->
x == s2p2->
x) && (s2p1->
y == s2p2->
y) && (s2p1->
z == s2p2->
z) )
974 s1k = (b*e - c*d) / D;
975 s2k = (a*e - b*d) / D;
979 if(s1k<0.0||s1k>1.0||s2k<0.0||s2k>1.0)
1016 p1.
x=s1p1->
x+s1k*(s1p2->
x-s1p1->
x);
1017 p1.
y=s1p1->
y+s1k*(s1p2->
y-s1p1->
y);
1018 p1.
z=s1p1->
z+s1k*(s1p2->
z-s1p1->
z);
1020 p2.
x=s2p1->
x+s2k*(s2p2->
x-s2p1->
x);
1021 p2.
y=s2p1->
y+s2k*(s2p2->
y-s2p1->
y);
1022 p2.
z=s2p1->
z+s2k*(s2p2->
z-s2p1->
z);
1044 LWDEBUG(2,
"lw_dist3d_point_poly called");
1049 for (i=1; i<poly->
nrings; i++)
1054 LWDEBUG(3,
" inside an hole");
1079 POINT3DZ p1, p2,projp1, projp2, intersectionp;
1084 &p1, plane, &projp1);
1106 f=fabs(s1)/(fabs(s1)+fabs(s2));
1110 intersectionp.
x=projp1.
x+f*projp1_projp2.
x;
1111 intersectionp.
y=projp1.
y+f*projp1_projp2.
y;
1112 intersectionp.
z=projp1.
z+f*projp1_projp2.
z;
1118 for (k=1;k<poly->
nrings; k++)
1130 dl->
p1.
x=intersectionp.
x;
1131 dl->
p1.
y=intersectionp.
y;
1132 dl->
p1.
z=intersectionp.
z;
1134 dl->
p2.
x=intersectionp.
x;
1135 dl->
p2.
y=intersectionp.
y;
1136 dl->
p2.
z=intersectionp.
z;
1149 for (j=0;j<poly->
nrings;j++)
1177 for (i = 0; i < unique_points; i++)
1186 pl->
pop.
x /= unique_points;
1187 pl->
pop.
y /= unique_points;
1188 pl->
pop.
z /= unique_points;
1193 for (i = 0; i < POL_BREAKS; i++)
1198 n1 = i * unique_points / POL_BREAKS;
1199 n2 = n1 + unique_points / POL_BREAKS;
1216 double vl = vp.
x * vp.
x + vp.
y * vp.
y + vp.
z * vp.
z;
1217 pl->
pv.
x += vp.
x / vl;
1218 pl->
pv.
y += vp.
y / vl;
1219 pl->
pv.
z += vp.
z / vl;
1244 f =
DOT(pl->
pv, v1);
1254 p0->
x = p->
x + pl->
pv.
x * f;
1255 p0->
y = p->
y + pl->
pv.
y * f;
1256 p0->
z = p->
z + pl->
pv.
z * f;
1288 if ( memcmp(&first, &last,
sizeof(
POINT3DZ)) )
1290 lwerror(
"pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1291 first.
x, first.
y, first.
z, last.
x, last.
y, last.
z);
1295 LWDEBUGF(2,
"pt_in_ring_3d called with point: %g %g %g", p->
x, p->
y, p->
z);
1302 if(fabs(plane->
pv.
z)>=fabs(plane->
pv.
x)&&fabs(plane->
pv.
z)>=fabs(plane->
pv.
y))
1304 for (i=0; i<ring->
npoints-1; i++)
1313 ((v1.
y <= p->
y) && (v2.
y > p->
y))
1315 || ((v1.
y > p->
y) && (v2.
y <= p->
y))
1319 vt = (double)(p->
y - v1.
y) / (v2.
y - v1.
y);
1322 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1331 else if(fabs(plane->
pv.
y)>=fabs(plane->
pv.
x)&&fabs(plane->
pv.
y)>=fabs(plane->
pv.
z))
1333 for (i=0; i<ring->
npoints-1; i++)
1342 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1344 || ((v1.
z > p->
z) && (v2.
z <= p->
z))
1348 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1351 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1362 for (i=0; i<ring->
npoints-1; i++)
1371 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1373 || ((v1.
z > p->
z) && (v2.
z <= p->
z))
1377 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1380 if (p->
y < v1.
y + vt * (v2.
y - v1.
y))
1389 LWDEBUGF(3,
"pt_in_ring_3d returning %d", cn&1);
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
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.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
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...
LWLINE * lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
LWPOINT * lwpoint_make3dz(int srid, double x, double y, double z)
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.
Datum intersects(PG_FUNCTION_ARGS)
#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.
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...
static LWGEOM * create_v_line(const LWGEOM *lwgeom, double x, double y, int 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_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)
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.
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.
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_line_line(LWLINE *line1, LWLINE *line2, DISTPTS3D *dl)
line to line calculation
int lw_dist3d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly, PLANE3D *plane, DISTPTS3D *dl)
Computes pointarray to polygon distance.
LWGEOM * lw_dist3d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int 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)proj...
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
LWGEOM * lw_dist3d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing 3dclosestpoint calculations.
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.
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_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing shortestline and longestline calculations.
LWGEOM * lw_dist2d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing closestpoint calculations.
Structure used in distance-calculations.
Structure used in distance-calculations.