Esempio n. 1
0
/**
This function is used to create a vertical line used for cases where one if the 
geometries lacks z-values. The vertical line crosses the 2d point that is closest 
and the z-range is from maxz to minz in the geoemtrie that has z values.
*/
static 
LWGEOM* create_v_line(const LWGEOM *lwgeom,double x, double y, int srid)
{
	
	LWPOINT *lwpoints[2];
	GBOX gbox;
	int rv = lwgeom_calculate_gbox(lwgeom, &gbox);
	
	if ( rv == LW_FAILURE )
		return NULL;
	
	lwpoints[0] = lwpoint_make3dz(srid, x, y, gbox.zmin);
	lwpoints[1] = lwpoint_make3dz(srid, x, y, gbox.zmax);
	
	 return (LWGEOM *)lwline_from_ptarray(srid, 2, lwpoints);		
}
Esempio 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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}