예제 #1
0
파일: g_box.c 프로젝트: ahinz/postgis
static int lwcircstring_calculate_gbox_cartesian(LWCIRCSTRING *curve, GBOX *gbox)
{
	uint8_t flags = gflags(FLAGS_GET_Z(curve->flags), FLAGS_GET_M(curve->flags), 0);
	GBOX tmp;
	POINT4D p1, p2, p3;
	int i;

	if ( ! curve ) return LW_FAILURE;
	if ( curve->points->npoints < 3 ) return LW_FAILURE;

	tmp.flags = flags;

	/* Initialize */
	gbox->xmin = gbox->ymin = gbox->zmin = gbox->mmin = MAXFLOAT;
	gbox->xmax = gbox->ymax = gbox->zmax = gbox->mmax = -1 * MAXFLOAT;

	for ( i = 2; i < curve->points->npoints; i += 2 )
	{
		getPoint4d_p(curve->points, i-2, &p1);
		getPoint4d_p(curve->points, i-1, &p2);
		getPoint4d_p(curve->points, i, &p3);

		if (lw_arc_calculate_gbox_cartesian(&p1, &p2, &p3, &tmp) == LW_FAILURE)
			continue;

		gbox_merge(&tmp, gbox);
	}

	return LW_SUCCESS;
}
예제 #2
0
static GBOX*
parse_geohash(char *geohash, int precision)
{
	GBOX *box = NULL;
	double lat[2], lon[2];

	POSTGIS_DEBUG(2, "parse_geohash called.");

	if (NULL == geohash)
	{
		geohash_lwpgerror("invalid GeoHash representation", 2);
	}

	decode_geohash_bbox(geohash, lat, lon, precision);

	POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash sw: %.20f, %.20f", lon[0], lat[0]);
	POSTGIS_DEBUGF(2, "ST_Box2dFromGeoHash ne: %.20f, %.20f", lon[1], lat[1]);

	box = gbox_new(gflags(0, 0, 1));

	box->xmin = lon[0];
	box->ymin = lat[0];

	box->xmax = lon[1];
	box->ymax = lat[1];

	POSTGIS_DEBUG(2, "parse_geohash finished.");
	return box;
}
예제 #3
0
파일: g_box.c 프로젝트: ahinz/postgis
/**
* Warning, this function is only good for x/y/z boxes, used
* in unit testing of geodetic box generation.
*/
GBOX* gbox_from_string(const char *str)
{
	const char *ptr = str;
	char *nextptr;
	char *gbox_start = strstr(str, "GBOX((");
	GBOX *gbox = gbox_new(gflags(0,0,1));
	if ( ! gbox_start ) return NULL; /* No header found */
	ptr += 6;
	gbox->xmin = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	ptr = nextptr + 1;
	gbox->ymin = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	ptr = nextptr + 1;
	gbox->zmin = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	ptr = nextptr + 3;
	gbox->xmax = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	ptr = nextptr + 1;
	gbox->ymax = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	ptr = nextptr + 1;
	gbox->zmax = strtod(ptr, &nextptr);
	if ( ptr == nextptr ) return NULL; /* No double found */
	return gbox;
}
예제 #4
0
파일: g_box.c 프로젝트: Vlczech/vtapi
static int lwcircstring_calculate_gbox(LWCIRCSTRING *curve, GBOX *gbox)
{
	uchar flags = gflags(TYPE_HASZ(curve->type), TYPE_HASM(curve->type), 0);
	GBOX tmp;
	POINT4D p1, p2, p3;
	int i;

	if ( ! curve ) return G_FAILURE;
	if ( curve->points->npoints < 3 ) return G_FAILURE;

	tmp.flags = flags;

	/* Initialize */
	gbox->xmin = gbox->ymin = gbox->zmin = gbox->mmin = MAXFLOAT;
	gbox->xmax = gbox->ymax = gbox->zmax = gbox->mmax = -1 * MAXFLOAT;

	for ( i = 2; i < curve->points->npoints; i += 2 )
	{
		getPoint4d_p(curve->points, i-2, &p1);
		getPoint4d_p(curve->points, i-1, &p2);
		getPoint4d_p(curve->points, i, &p3);

		if (lwcircle_calculate_gbox(p1, p2, p3, &tmp) == G_FAILURE)
			continue;

		gbox_merge(&tmp, gbox);
	}

	return G_SUCCESS;
}
예제 #5
0
LWPOINT *
lwpoint_construct_empty(int srid, char hasz, char hasm)
{
	LWPOINT *result = lwalloc(sizeof(LWPOINT));
	result->type = POINTTYPE;
	result->flags = gflags(hasz, hasm, 0);
	result->srid = srid;
	result->point = ptarray_construct(hasz, hasm, 0);
	result->bbox = NULL;
	return result;
}
예제 #6
0
파일: ptarray.c 프로젝트: TesseractG/lwgeom
/**
* Build a new #POINTARRAY, but on top of someone else's ordinate array. 
* Flag as read-only, so that ptarray_free() does not free the serialized_ptlist
*/
POINTARRAY* ptarray_construct_reference_data(char hasz, char hasm, uint32_t npoints, uint8_t *ptlist)
{
	POINTARRAY *pa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY));
	LWDEBUGF(5, "hasz = %d, hasm = %d, npoints = %d, ptlist = %p", hasz, hasm, npoints, ptlist);
	pa->flags = gflags(hasz, hasm, 0);
	FLAGS_SET_READONLY(pa->flags, 1); /* We don't own this memory, so we can't alter or free it. */
	pa->npoints = npoints;
	pa->maxpoints = npoints;
	pa->serialized_pointlist = ptlist;
	return pa;
}
예제 #7
0
LWCIRCSTRING *
lwcircstring_construct_empty(int srid, char hasz, char hasm)
{
	LWCIRCSTRING *result = lwalloc(sizeof(LWCIRCSTRING));
	result->type = CIRCSTRINGTYPE;
	result->flags = gflags(hasz,hasm,0);
	result->srid = srid;
	result->points = ptarray_construct_empty(hasz, hasm, 1);
	result->bbox = NULL;
	return result;
}
예제 #8
0
LWTRIANGLE*
lwtriangle_construct_empty(int srid, char hasz, char hasm)
{
	LWTRIANGLE *result = lwalloc(sizeof(LWTRIANGLE));
	result->type = TRIANGLETYPE;
	result->flags = gflags(hasz,hasm,0);
	result->srid = srid;
	result->points = ptarray_construct_empty(hasz, hasm, 1);
	result->bbox = NULL;
	return result;
}
예제 #9
0
LWPOLY*
lwpoly_construct_empty(int srid, char hasz, char hasm)
{
	LWPOLY *result = lwalloc(sizeof(LWPOLY));
	result->type = POLYGONTYPE;
	result->flags = gflags(hasz,hasm,0);
	result->srid = srid;
	result->nrings = 0;
	result->maxrings = 1; /* Allocate room for ring, just in case. */
	result->rings = lwalloc(result->maxrings * sizeof(POINTARRAY*));
	result->bbox = NULL;
	return result;
}
예제 #10
0
LWCOLLECTION *
lwcollection_construct(uint8_t type, int srid, GBOX *bbox,
                       uint32_t ngeoms, LWGEOM **geoms)
{
	LWCOLLECTION *ret;
	int hasz, hasm;
#ifdef CHECK_LWGEOM_ZM
	char zm;
	uint32_t i;
#endif

	LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, srid, bbox, ngeoms, geoms);

	if( ! lwtype_is_collection(type) )
		lwerror("Non-collection type specified in collection constructor!");

	hasz = 0;
	hasm = 0;
	if ( ngeoms > 0 )
	{
		hasz = FLAGS_GET_Z(geoms[0]->flags);
		hasm = FLAGS_GET_M(geoms[0]->flags);
#ifdef CHECK_LWGEOM_ZM
		zm = FLAGS_GET_ZM(geoms[0]->flags);

		LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);

		for (i=1; i<ngeoms; i++)
		{
			LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);

			if ( zm != FLAGS_GET_ZM(geoms[i]->flags) )
				lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, FLAGS_GET_ZM(geoms[i]->flags));
		}
#endif
	}


	ret = lwalloc(sizeof(LWCOLLECTION));
	ret->type = type;
	ret->flags = gflags(hasz,hasm,0);
	FLAGS_SET_BBOX(ret->flags, bbox?1:0);
	ret->srid = srid;
	ret->ngeoms = ngeoms;
	ret->maxgeoms = ngeoms;
	ret->geoms = geoms;
	ret->bbox = bbox;

	return ret;
}
예제 #11
0
LWCURVEPOLY *
lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
{
	LWCURVEPOLY *ret;

	ret = (LWCURVEPOLY *)lwalloc(sizeof(LWCURVEPOLY));
	ret->type = CURVEPOLYTYPE;
	ret->flags = gflags(hasz, hasm, 0);
	ret->srid = srid;
	ret->nrings = 0;
	ret->maxrings = 1; /* Allocate room for sub-members, just in case. */
	ret->rings = (LWGEOM **)lwalloc(ret->maxrings * sizeof(LWGEOM*));
	ret->bbox = NULL;

	return ret;
}
예제 #12
0
Datum BOX2D_construct(PG_FUNCTION_ARGS)
{
	GSERIALIZED *pgmin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	GSERIALIZED *pgmax = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
	GBOX *result;
	LWPOINT *minpoint, *maxpoint;
	double min, max, tmp;

	minpoint = (LWPOINT*)lwgeom_from_gserialized(pgmin);
	maxpoint = (LWPOINT*)lwgeom_from_gserialized(pgmax);

	if ( (minpoint->type != POINTTYPE) || (maxpoint->type != POINTTYPE) )
	{
		elog(ERROR, "GBOX_construct: arguments must be points");
		PG_RETURN_NULL();
	}

	error_if_srid_mismatch(minpoint->srid, maxpoint->srid);

	result = gbox_new(gflags(0, 0, 0));

	/* Process X min/max */
	min = lwpoint_get_x(minpoint);
	max = lwpoint_get_x(maxpoint);
	if ( min > max ) 
	{
		tmp = min;
		min = max;
		max = tmp;
	}
	result->xmin = min;
	result->xmax = max;

	/* Process Y min/max */
	min = lwpoint_get_y(minpoint);
	max = lwpoint_get_y(maxpoint);
	if ( min > max ) 
	{
		tmp = min;
		min = max;
		max = tmp;
	}
	result->ymin = min;
	result->ymax = max;

	PG_RETURN_POINTER(result);
}
예제 #13
0
LWCOLLECTION *
lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
{
	LWCOLLECTION *ret;
	if( ! lwtype_is_collection(type) )
		lwerror("Non-collection type specified in collection constructor!");

	ret = lwalloc(sizeof(LWCOLLECTION));
	ret->type = type;
	ret->flags = gflags(hasz,hasm,0);
	ret->srid = srid;
	ret->ngeoms = 0;
	ret->maxgeoms = 1; /* Allocate room for sub-members, just in case. */
	ret->geoms = lwalloc(ret->maxgeoms * sizeof(LWGEOM*));
	ret->bbox = NULL;

	return ret;
}
예제 #14
0
파일: g_box.c 프로젝트: ahinz/postgis
int ptarray_calculate_gbox_cartesian(const POINTARRAY *pa, GBOX *gbox )
{
	int i;
	POINT4D p;
	int has_z, has_m;

	if ( ! pa ) return LW_FAILURE;
	if ( ! gbox ) return LW_FAILURE;
	if ( pa->npoints < 1 ) return LW_FAILURE;

	has_z = FLAGS_GET_Z(pa->flags);
	has_m = FLAGS_GET_M(pa->flags);
	gbox->flags = gflags(has_z, has_m, 0);
	LWDEBUGF(4, "ptarray_calculate_gbox Z: %d M: %d", has_z, has_m);

	getPoint4d_p(pa, 0, &p);
	gbox->xmin = gbox->xmax = p.x;
	gbox->ymin = gbox->ymax = p.y;
	if ( has_z )
		gbox->zmin = gbox->zmax = p.z;
	if ( has_m )
		gbox->mmin = gbox->mmax = p.m;

	for ( i = 1 ; i < pa->npoints; i++ )
	{
		getPoint4d_p(pa, i, &p);
		gbox->xmin = FP_MIN(gbox->xmin, p.x);
		gbox->xmax = FP_MAX(gbox->xmax, p.x);
		gbox->ymin = FP_MIN(gbox->ymin, p.y);
		gbox->ymax = FP_MAX(gbox->ymax, p.y);
		if ( has_z )
		{
			gbox->zmin = FP_MIN(gbox->zmin, p.z);
			gbox->zmax = FP_MAX(gbox->zmax, p.z);
		}
		if ( has_m )
		{
			gbox->mmin = FP_MIN(gbox->mmin, p.m);
			gbox->mmax = FP_MAX(gbox->mmax, p.m);
		}
	}
	return LW_SUCCESS;
}
예제 #15
0
파일: ptarray.c 프로젝트: TesseractG/lwgeom
POINTARRAY*
ptarray_construct_copy_data(char hasz, char hasm, uint32_t npoints, const uint8_t *ptlist)
{
	POINTARRAY *pa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY));

	pa->flags = gflags(hasz, hasm, 0);
	pa->npoints = npoints;
	pa->maxpoints = npoints;

	if ( npoints > 0 )
	{
		pa->serialized_pointlist = (uint8_t *)lwalloc(ptarray_point_size(pa) * npoints);
		memcpy(pa->serialized_pointlist, ptlist, ptarray_point_size(pa) * npoints);
	}
	else
	{
		pa->serialized_pointlist = NULL;
	}

	return pa;
}
예제 #16
0
파일: ptarray.c 프로젝트: gbroccolo/postgis
POINTARRAY*
ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
{
	POINTARRAY *pa = lwalloc(sizeof(POINTARRAY));
	pa->serialized_pointlist = NULL;
	
	/* Set our dimsionality info on the bitmap */
	pa->flags = gflags(hasz, hasm, 0);
	
	/* We will be allocating a bit of room */
	pa->npoints = 0;
	pa->maxpoints = maxpoints;
	
	/* Allocate the coordinate array */
	if ( maxpoints > 0 )
		pa->serialized_pointlist = lwalloc(maxpoints * ptarray_point_size(pa));
	else 
		pa->serialized_pointlist = NULL;

	return pa;
}
예제 #17
0
/* construct a new LWPOLY.  arrays (points/points per ring) will NOT be copied
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWPOLY*
lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
{
	LWPOLY *result;
	int hasz, hasm;
#ifdef CHECK_POLY_RINGS_ZM
	char zm;
	uint32_t i;
#endif

	if ( nrings < 1 ) lwerror("lwpoly_construct: need at least 1 ring");

	hasz = FLAGS_GET_Z(points[0]->flags);
	hasm = FLAGS_GET_M(points[0]->flags);

#ifdef CHECK_POLY_RINGS_ZM
	zm = FLAGS_GET_ZM(points[0]->flags);
	for (i=1; i<nrings; i++)
	{
		if ( zm != FLAGS_GET_ZM(points[i]->flags) )
			lwerror("lwpoly_construct: mixed dimensioned rings");
	}
#endif

	result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
	result->type = POLYGONTYPE;
	result->flags = gflags(hasz, hasm, 0);
	FLAGS_SET_BBOX(result->flags, bbox?1:0);
	result->srid = srid;
	result->nrings = nrings;
	result->maxrings = nrings;
	result->rings = points;
	result->bbox = bbox;

	return result;
}
예제 #18
0
파일: lwspheroid.c 프로젝트: Vlczech/vtapi
static double ptarray_area_spheroid(const POINTARRAY *pa, const SPHEROID *spheroid)
{
	GEOGRAPHIC_POINT a, b;
	POINT2D p;
	int i;
	double area = 0.0;
	GBOX gbox2d;
	int in_south = LW_FALSE;
	double delta_lon_tolerance;
	double latitude_min;

	gbox2d.flags = gflags(0, 0, 0);

	/* Return zero on non-sensical inputs */
	if ( ! pa || pa->npoints < 4 )
		return 0.0;

	/* Get the raw min/max values for the latitudes */
	ptarray_calculate_gbox(pa, &gbox2d);

	if ( signum(gbox2d.ymin) != signum(gbox2d.ymax) )
		lwerror("ptarray_area_spheroid: cannot handle ptarray that crosses equator");

	/* Geodetic bbox < 0.0 implies geometry is entirely in southern hemisphere */
	if ( gbox2d.ymax < 0.0 )
		in_south = LW_TRUE;

	LWDEBUGF(4, "gbox2d.ymax %.12g", gbox2d.ymax);

	/* Tolerance for strip area calculation */
	if ( in_south )
	{
		delta_lon_tolerance = (90.0 / (fabs(gbox2d.ymin) / 8.0) - 2.0) / 10000.0;
		latitude_min = deg2rad(fabs(gbox2d.ymax));
	}
	else
	{
		delta_lon_tolerance = (90.0 / (fabs(gbox2d.ymax) / 8.0) - 2.0) / 10000.0;
		latitude_min = deg2rad(gbox2d.ymin);
	}

	/* Initialize first point */
	getPoint2d_p(pa, 0, &p);
	geographic_point_init(p.x, p.y, &a);

	for ( i = 1; i < pa->npoints; i++ )
	{
		GEOGRAPHIC_POINT a1, b1;
		double strip_area = 0.0;
		double delta_lon = 0.0;
		LWDEBUGF(4, "edge #%d", i);

		getPoint2d_p(pa, i, &p);
		geographic_point_init(p.x, p.y, &b);

		a1 = a;
		b1 = b;

		/* Flip into north if in south */
		if ( in_south )
		{
			a1.lat = -1.0 * a1.lat;
			b1.lat = -1.0 * b1.lat;
		}

		LWDEBUGF(4, "in_south %d", in_south);

		LWDEBUGF(4, "crosses_dateline(a, b) %d", crosses_dateline(&a, &b) );

		if ( crosses_dateline(&a, &b) )
		{
			double shift;

			if ( a1.lon > 0.0 )
				shift = (M_PI - a1.lon) + 0.088; /* About 5deg more */
			else
				shift = (M_PI - b1.lon) + 0.088; /* About 5deg more */

			LWDEBUGF(4, "shift: %.8g", shift);
			LWDEBUGF(4, "before shift a1(%.8g %.8g) b1(%.8g %.8g)", a1.lat, a1.lon, b1.lat, b1.lon);
			point_shift(&a1, shift);
			point_shift(&b1, shift);
			LWDEBUGF(4, "after shift a1(%.8g %.8g) b1(%.8g %.8g)", a1.lat, a1.lon, b1.lat, b1.lon);
			
		}


		delta_lon = fabs(b1.lon - a1.lon);

		LWDEBUGF(4, "a1(%.18g %.18g) b1(%.18g %.18g)", a1.lat, a1.lon, b1.lat, b1.lon);
		LWDEBUGF(4, "delta_lon %.18g", delta_lon);
		LWDEBUGF(4, "delta_lon_tolerance %.18g", delta_lon_tolerance);

		if ( delta_lon > 0.0 )
		{
			if ( delta_lon < delta_lon_tolerance )
			{
				strip_area = spheroid_striparea(&a1, &b1, latitude_min, spheroid);
				LWDEBUGF(4, "strip_area %.12g", strip_area);
				area += strip_area;
			}
			else
			{
				GEOGRAPHIC_POINT p, q;
				double step = floor(delta_lon / delta_lon_tolerance);
				double distance = spheroid_distance(&a1, &b1, spheroid);
				double pDistance = 0.0;
				int j = 0;
				LWDEBUGF(4, "step %.18g", step);
				LWDEBUGF(4, "distance %.18g", distance);
				step = distance / step;
				LWDEBUGF(4, "step %.18g", step);
				p = a1;
				while (pDistance < (distance - step * 1.01))
				{
					double azimuth = spheroid_direction(&p, &b1, spheroid);
					j++;
					LWDEBUGF(4, "  iteration %d", j);
					LWDEBUGF(4, "  azimuth %.12g", azimuth);
					pDistance = pDistance + step;
					LWDEBUGF(4, "  pDistance %.12g", pDistance);
					spheroid_project(&p, spheroid, step, azimuth, &q);
					strip_area = spheroid_striparea(&p, &q, latitude_min, spheroid);
					LWDEBUGF(4, "  strip_area %.12g", strip_area);
					area += strip_area;
					LWDEBUGF(4, "  area %.12g", area);
					p.lat = q.lat;
					p.lon = q.lon;
				}
				strip_area = spheroid_striparea(&p, &b1, latitude_min, spheroid);
				area += strip_area;
			}
		}

		/* B gets incremented in the next loop, so we save the value here */
		a = b;
	}
	return fabs(area);
}