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);
563 lwerror(
"unspecified error in function lw_dist3d_distribute_bruteforce");
588 LWDEBUG(2,
"lw_dist3d_point_point is called");
604 LWDEBUG(2,
"lw_dist3d_point_line is called");
626 LWDEBUG(2,
"lw_dist3d_point_poly is called");
632 LWDEBUG(3,
"looking for maxdistance");
659 LWDEBUG(2,
"lw_dist3d_line_line is called");
671 LWDEBUG(2,
"lw_dist3d_line_poly is called");
694 int planedef1, planedef2;
695 LWDEBUG(2,
"lw_dist3d_poly_poly is called");
704 if (!planedef1 || !planedef2)
706 if (!planedef1 && !planedef2)
746 LWDEBUG(2,
"lw_dist3d_pt_ptarray is called");
775 if ( ( A->
x == B->
x) && (A->
y == B->
y) && (A->
z == B->
z) )
781 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) );
810 c.
x=A->
x + r * (B->
x-A->
x);
811 c.
y=A->
y + r * (B->
y-A->
y);
812 c.
z=A->
z + r * (B->
z-A->
z);
820 double dx = p2->
x - p1->
x;
821 double dy = p2->
y - p1->
y;
822 double dz = p2->
z - p1->
z;
823 return sqrt ( dx*dx + dy*dy + dz*dz);
837 double dx = thep2->
x - thep1->
x;
838 double dy = thep2->
y - thep1->
y;
839 double dz = thep2->
z - thep1->
z;
840 double dist = sqrt ( dx*dx + dy*dy + dz*dz);
841 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 );
886 LWDEBUGF(4,
"maxdist_ptarray_ptarray; seg %i * seg %i, dist = %g\n",t,u,dl->
distance);
887 LWDEBUGF(3,
" seg%d-seg%d dist: %f, mindist: %f",
904 LWDEBUGF(4,
"mindist_ptarray_ptarray; seg %i * seg %i, dist = %g\n",t,u,dl->
distance);
905 LWDEBUGF(3,
" seg%d-seg%d dist: %f, mindist: %f",
926 double a, b, c, d, e, D;
929 if ( ( s1p1->
x == s1p2->
x) && (s1p1->
y == s1p2->
y) && (s1p1->
z == s1p2->
z) )
934 if ( ( s2p1->
x == s2p2->
x) && (s2p1->
y == s2p2->
y) && (s2p1->
z == s2p2->
z) )
977 s1k = (b*e - c*d) / D;
978 s2k = (a*e - b*d) / D;
982 if(s1k<0.0||s1k>1.0||s2k<0.0||s2k>1.0)
1019 p1.
x=s1p1->
x+s1k*(s1p2->
x-s1p1->
x);
1020 p1.
y=s1p1->
y+s1k*(s1p2->
y-s1p1->
y);
1021 p1.
z=s1p1->
z+s1k*(s1p2->
z-s1p1->
z);
1023 p2.
x=s2p1->
x+s2k*(s2p2->
x-s2p1->
x);
1024 p2.
y=s2p1->
y+s2k*(s2p2->
y-s2p1->
y);
1025 p2.
z=s2p1->
z+s2k*(s2p2->
z-s2p1->
z);
1047 LWDEBUG(2,
"lw_dist3d_point_poly called");
1052 for (i=1; i<poly->
nrings; i++)
1057 LWDEBUG(3,
" inside an hole");
1089 &p1, plane, &projp1);
1111 f=fabs(s1)/(fabs(s1)+fabs(s2));
1115 intersectionp.
x=projp1.
x+f*projp1_projp2.
x;
1116 intersectionp.
y=projp1.
y+f*projp1_projp2.
y;
1117 intersectionp.
z=projp1.
z+f*projp1_projp2.
z;
1123 for (k=1;k<poly->
nrings; k++)
1135 dl->
p1.
x=intersectionp.
x;
1136 dl->
p1.
y=intersectionp.
y;
1137 dl->
p1.
z=intersectionp.
z;
1139 dl->
p2.
x=intersectionp.
x;
1140 dl->
p2.
y=intersectionp.
y;
1141 dl->
p2.
z=intersectionp.
z;
1154 for (j=0;j<poly->
nrings;j++)
1183 for (i = 0; i < unique_points; i++)
1192 pl->
pop.
x /= unique_points;
1193 pl->
pop.
y /= unique_points;
1194 pl->
pop.
z /= unique_points;
1199 for (i = 0; i < POL_BREAKS; i++)
1204 n1 = i * unique_points / POL_BREAKS;
1205 n2 = n1 + unique_points / POL_BREAKS;
1222 double vl = vp.
x * vp.
x + vp.
y * vp.
y + vp.
z * vp.
z;
1223 pl->
pv.
x += vp.
x / vl;
1224 pl->
pv.
y += vp.
y / vl;
1225 pl->
pv.
z += vp.
z / vl;
1250 f =
DOT(pl->
pv, v1);
1260 p0->
x = p->
x + pl->
pv.
x * f;
1261 p0->
y = p->
y + pl->
pv.
y * f;
1262 p0->
z = p->
z + pl->
pv.
z * f;
1294 if ( memcmp(&first, &last,
sizeof(
POINT3DZ)) )
1296 lwerror(
"pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1297 first.
x, first.
y, first.
z, last.
x, last.
y, last.
z);
1301 LWDEBUGF(2,
"pt_in_ring_3d called with point: %g %g %g", p->
x, p->
y, p->
z);
1308 if(fabs(plane->
pv.
z)>=fabs(plane->
pv.
x)&&fabs(plane->
pv.
z)>=fabs(plane->
pv.
y))
1310 for (i=0; i<ring->
npoints-1; i++)
1319 ((v1.
y <= p->
y) && (v2.
y > p->
y))
1321 || ((v1.
y > p->
y) && (v2.
y <= p->
y))
1325 vt = (double)(p->
y - v1.
y) / (v2.
y - v1.
y);
1328 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1337 else if(fabs(plane->
pv.
y)>=fabs(plane->
pv.
x)&&fabs(plane->
pv.
y)>=fabs(plane->
pv.
z))
1339 for (i=0; i<ring->
npoints-1; i++)
1348 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1350 || ((v1.
z > p->
z) && (v2.
z <= p->
z))
1354 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1357 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1368 for (i=0; i<ring->
npoints-1; i++)
1377 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1379 || ((v1.
z > p->
z) && (v2.
z <= p->
z))
1383 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1386 if (p->
y < v1.
y + vt * (v2.
y - v1.
y))
1395 LWDEBUGF(3,
"pt_in_ring_3d returning %d", cn&1);
LWGEOM * lw_dist2d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing closestpoint calculations.
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
int lw_dist3d_line_poly(LWLINE *line, LWPOLY *poly, DISTPTS3D *dl)
line to polygon 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...
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
double lwgeom_maxdistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling max distance calculations and dfyllywithin calculations.
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
LWLINE * lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
int lw_dist3d_poly_poly(LWPOLY *poly1, LWPOLY *poly2, DISTPTS3D *dl)
polygon to polygon calculation
double distance3d_pt_pt(const POINT3D *p1, const POINT3D *p2)
#define LWDEBUG(level, msg)
Structure used in distance-calculations.
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
int lw_dist3d_seg_seg(POINT3DZ *s1p1, POINT3DZ *s1p2, POINT3DZ *s2p1, POINT3DZ *s2p2, DISTPTS3D *dl)
Finds the two closest points on two linesegments.
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.
LWGEOM * lw_dist2d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing shortestline and longestline calculations.
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...
LWGEOM * lwgeom_closest_point_3d(const LWGEOM *lw1, const LWGEOM *lw2)
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...
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
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 getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
LWGEOM * lw_dist3d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing 3dshortestline and 3dlongestline calculations.
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...
Datum intersects(PG_FUNCTION_ARGS)
#define LW_TRUE
Return types for functions with status returns.
int lw_dist3d_pt_pt(POINT3DZ *thep1, POINT3DZ *thep2, DISTPTS3D *dl)
Compares incomming points and stores the points closest to each other or most far away from each othe...
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
LWGEOM * lw_dist3d_distancepoint(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
Function initializing 3dclosestpoint calculations.
LWPOINT * lwpoint_make3dz(int srid, double x, double y, double z)
static int get_3dvector_from_points(POINT3DZ *p1, POINT3DZ *p2, VECTOR3D *v)
LWGEOM * lwgeom_furthest_line_3d(LWGEOM *lw1, LWGEOM *lw2)
double lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d min distance calculations and dwithin calculations.
int lw_dist3d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3D *dl)
This is a recursive function delivering every possible combination of subgeometries.
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_line(LWPOINT *point, LWLINE *line, DISTPTS3D *dl)
point to line calculation
int define_plane(POINTARRAY *pa, PLANE3D *pl)
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, pa = vertex points of a ring V[n+1] with V[n]=V[0] plane=the plane that the vertex points are lying on returns: 0 = outside, 1 = inside
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
int lw_dist3d_point_point(LWPOINT *point1, LWPOINT *point2, DISTPTS3D *dl)
point to point calculation
double lwgeom_maxdistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d max distance calculation.
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...
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_mindistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d min distance calculation.
int lw_dist3d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2, DISTPTS3D *dl)
Finds all combinationes of segments between two pointarrays.
int lw_dist3d_line_line(LWLINE *line1, LWLINE *line2, DISTPTS3D *dl)
line to line calculation
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Structure used in distance-calculations.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
#define LWDEBUGF(level, msg,...)
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...
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
int lw_dist3d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly, PLANE3D *plane, DISTPTS3D *dl)
Computes pointarray to polygon distance.
static int get_3dcross_product(VECTOR3D *v1, VECTOR3D *v2, VECTOR3D *v)