Ejemplo n.º 1
0
/**
	Function handling 3d min distance calculations and dwithin calculations.
	The difference is just the tolerance.
*/
double
lwgeom_mindistance3d_tolerance(LWGEOM *lw1, LWGEOM *lw2, double tolerance)
{
	DISTPTS3D thedl;
	LWDEBUG(2, "lwgeom_mindistance3d_tolerance is called");
	thedl.mode = DIST_MIN;
	thedl.distance= MAXFLOAT;
	thedl.tolerance = tolerance;
	if (lw_dist3d_recursive(lw1, lw2, &thedl))
	{
		return thedl.distance;
	}
	/*should never get here. all cases ought to be error handled earlier*/
	lwerror("Some unspecified error.");
	return MAXFLOAT;
}
Ejemplo n.º 2
0
/**
Function initializing 3dshortestline and 3dlongestline calculations.
*/
LWGEOM *
lw_dist3d_distanceline(LWGEOM *lw1, LWGEOM *lw2,int srid,int mode)
{
	double x1,x2,y1,y2, z1, z2;
	double initdistance = ( mode == DIST_MIN ? MAXFLOAT : -1.0);
	DISTPTS3D thedl;
	LWPOINT *lwpoints[2];
	LWGEOM *result;

	thedl.mode = mode;
	thedl.distance = initdistance;
	thedl.tolerance = 0.0;

	LWDEBUG(2, "lw_dist3d_distanceline is called");
	if (!lw_dist3d_recursive(lw1, lw2, &thedl))
	{
		/*should never get here. all cases ought to be error handled earlier*/
		lwerror("Some unspecified error.");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}

	/*if thedl.distance is unchanged there where only empty geometries input*/
	if (thedl.distance == initdistance)
	{
		LWDEBUG(3, "didn't find geometries to measure between, returning null");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}
	else
	{
		x1=thedl.p1.x;
		y1=thedl.p1.y;
		z1=thedl.p1.z;
		x2=thedl.p2.x;
		y2=thedl.p2.y;
		z2=thedl.p2.z;


		lwpoints[0] = lwpoint_make3dz(srid, x1, y1, z1);
		lwpoints[1] = lwpoint_make3dz(srid, x2, y2, z2);

		result = (LWGEOM *)lwline_from_lwpointarray(srid, 2, lwpoints);
	}

	return result;
}
Ejemplo n.º 3
0
/**
	Function handling 3d min distance calculations and dwithin calculations.
	The difference is just the tolerance.
*/
double
lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
{
	if(!lwgeom_has_z(lw1) || !lwgeom_has_z(lw2))
	{
		lwnotice("One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
		
		return lwgeom_mindistance2d_tolerance(lw1, lw2, tolerance);	
	}
	DISTPTS3D thedl;
	LWDEBUG(2, "lwgeom_mindistance3d_tolerance is called");
	thedl.mode = DIST_MIN;
	thedl.distance= FLT_MAX;
	thedl.tolerance = tolerance;
	if (lw_dist3d_recursive(lw1, lw2, &thedl))
	{
		return thedl.distance;
	}
	/*should never get here. all cases ought to be error handled earlier*/
	lwerror("Some unspecified error.");
	return FLT_MAX;
}
Ejemplo n.º 4
0
/**
Function initializing 3dclosestpoint calculations.
*/
LWGEOM *
lw_dist3d_distancepoint(LWGEOM *lw1, LWGEOM *lw2,int srid,int mode)
{
	double x,y,z;
	DISTPTS3D thedl;
	double initdistance = MAXFLOAT;
	LWGEOM *result;

	thedl.mode = mode;
	thedl.distance= initdistance;
	thedl.tolerance = 0;

	LWDEBUG(2, "lw_dist3d_distancepoint is called");

	if (!lw_dist3d_recursive(lw1, lw2, &thedl))
	{
		/*should never get here. all cases ought to be error handled earlier*/
		lwerror("Some unspecified error.");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}

	if (thedl.distance == initdistance)
	{
		LWDEBUG(3, "didn't find geometries to measure between, returning null");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}
	else
	{
		x=thedl.p1.x;
		y=thedl.p1.y;
		z=thedl.p1.z;
		result = (LWGEOM *)lwpoint_make3dz(srid, x, y, z);
	}

	return result;
}
Ejemplo n.º 5
0
/**
Function initializing 3dshortestline and 3dlongestline calculations.
*/
LWGEOM *
lw_dist3d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
{
	LWDEBUG(2, "lw_dist3d_distanceline is called");
	double x1,x2,y1,y2, z1, z2, x, y;
	double initdistance = ( mode == DIST_MIN ? FLT_MAX : -1.0);
	DISTPTS3D thedl;
	LWPOINT *lwpoints[2];
	LWGEOM *result;

	thedl.mode = mode;
	thedl.distance = initdistance;
	thedl.tolerance = 0.0;

	/*Check if we really have 3D geoemtries*/
	/*If not, send it to 2D-calculations which will give the same result*/
	/*as an infinite z-value at one or two of the geometries*/
	if(!lwgeom_has_z(lw1) || !lwgeom_has_z(lw2))
	{
		
		lwnotice("One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
		
		if(!lwgeom_has_z(lw1) && !lwgeom_has_z(lw2))
			return lw_dist2d_distanceline(lw1, lw2, srid, mode);	
		
		DISTPTS thedl2d;
		thedl2d.mode = mode;
		thedl2d.distance = initdistance;
		thedl2d.tolerance = 0.0;
		if (!lw_dist2d_comp( lw1,lw2,&thedl2d))
		{
			/*should never get here. all cases ought to be error handled earlier*/
			lwerror("Some unspecified error.");
			result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
		}
		LWGEOM *vertical_line;
		if(!lwgeom_has_z(lw1))
		{
			x=thedl2d.p1.x;
			y=thedl2d.p1.y;

			vertical_line = create_v_line(lw2,x,y,srid);
			if (!lw_dist3d_recursive(vertical_line, lw2, &thedl))
			{
				/*should never get here. all cases ought to be error handled earlier*/
				lwfree(vertical_line);
				lwerror("Some unspecified error.");
				result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
			}			
			lwfree(vertical_line);	
		}	
		if(!lwgeom_has_z(lw2))
		{
			x=thedl2d.p2.x;
			y=thedl2d.p2.y;			
			
			vertical_line = create_v_line(lw1,x,y,srid);
			if (!lw_dist3d_recursive(lw1, vertical_line, &thedl))
			{
				/*should never get here. all cases ought to be error handled earlier*/
				lwfree(vertical_line);
				lwerror("Some unspecified error.");
				return (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
			}	
			lwfree(vertical_line);		
		}			
				
	}
	else
	{		
		if (!lw_dist3d_recursive(lw1, lw2, &thedl))
		{
			/*should never get here. all cases ought to be error handled earlier*/
			lwerror("Some unspecified error.");
			result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
		}
	}
	/*if thedl.distance is unchanged there where only empty geometries input*/
	if (thedl.distance == initdistance)
	{
		LWDEBUG(3, "didn't find geometries to measure between, returning null");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}
	else
	{
		x1=thedl.p1.x;
		y1=thedl.p1.y;
		z1=thedl.p1.z;
		x2=thedl.p2.x;
		y2=thedl.p2.y;
		z2=thedl.p2.z;

		lwpoints[0] = lwpoint_make3dz(srid, x1, y1, z1);
		lwpoints[1] = lwpoint_make3dz(srid, x2, y2, z2);

		result = (LWGEOM *)lwline_from_ptarray(srid, 2, lwpoints);
	}

	return result;
}
Ejemplo n.º 6
0
/**
This is a recursive function delivering every possible combination of subgeometries
*/
int lw_dist3d_recursive(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS3D *dl)
{
	int i, j;
	int n1=1;
	int n2=1;
	LWGEOM *g1 = NULL;
	LWGEOM *g2 = NULL;
	LWCOLLECTION *c1 = NULL;
	LWCOLLECTION *c2 = NULL;

	LWDEBUGF(2, "lw_dist3d_recursive is called with type1=%d, type2=%d", lwg1->type, lwg2->type);

	if (lwgeom_is_collection(lwg1))
	{
		LWDEBUG(3, "First geometry is collection");
		c1 = lwgeom_as_lwcollection(lwg1);
		n1 = c1->ngeoms;
	}
	if (lwgeom_is_collection(lwg2))
	{
		LWDEBUG(3, "Second geometry is collection");
		c2 = lwgeom_as_lwcollection(lwg2);
		n2 = c2->ngeoms;
	}

	for ( i = 0; i < n1; i++ )
	{

		if (lwgeom_is_collection(lwg1))
		{
			g1 = c1->geoms[i];
		}
		else
		{
			g1 = (LWGEOM*)lwg1;
		}

		if (lwgeom_is_empty(g1)) return LW_TRUE;

		if (lwgeom_is_collection(g1))
		{
			LWDEBUG(3, "Found collection inside first geometry collection, recursing");
			if (!lw_dist3d_recursive(g1, lwg2, dl)) return LW_FALSE;
			continue;
		}
		for ( j = 0; j < n2; j++ )
		{
			if (lwgeom_is_collection(lwg2))
			{
				g2 = c2->geoms[j];
			}
			else
			{
				g2 = (LWGEOM*)lwg2;
			}
			if (lwgeom_is_collection(g2))
			{
				LWDEBUG(3, "Found collection inside second geometry collection, recursing");
				if (!lw_dist3d_recursive(g1, g2, dl)) return LW_FALSE;
				continue;
			}


			/*If one of geometries is empty, return. True here only means continue searching. False would have stoped the process*/
			if (lwgeom_is_empty(g1)||lwgeom_is_empty(g2)) return LW_TRUE;


			if (!lw_dist3d_distribute_bruteforce(g1, g2, dl)) return LW_FALSE;
			if (dl->distance<=dl->tolerance && dl->mode == DIST_MIN) return LW_TRUE; /*just a check if  the answer is already given*/
		}
	}
	return LW_TRUE;
}