コード例 #1
0
ファイル: lwmpoint.c プロジェクト: nextgis-borsch/postgis
LWGEOM*
lwmpoint_remove_repeated_points(const LWMPOINT *mpoint, double tolerance)
{
	uint32_t nnewgeoms;
	uint32_t i, j;
	LWGEOM **newgeoms;
	LWGEOM *lwpt1, *lwpt2;

	newgeoms = lwalloc(sizeof(LWGEOM *)*mpoint->ngeoms);
	nnewgeoms = 0;
	for (i=0; i<mpoint->ngeoms; ++i)
	{
		lwpt1 = (LWGEOM*)mpoint->geoms[i];
		/* Brute force, may be optimized by building an index */
		int seen=0;
		for (j=0; j<nnewgeoms; ++j)
		{
			lwpt2 = (LWGEOM*)newgeoms[j];
			if ( lwgeom_mindistance2d(lwpt1, lwpt2) <= tolerance )
			{
				seen=1;
				break;
			}
		}
		if ( seen ) continue;
		newgeoms[nnewgeoms++] = lwgeom_clone_deep(lwpt1);
	}

	return (LWGEOM*)lwcollection_construct(mpoint->type,
	                                       mpoint->srid,
										   mpoint->bbox ? gbox_copy(mpoint->bbox) : NULL,
	                                       nnewgeoms, newgeoms);

}
コード例 #2
0
ファイル: lwmpoint.c プロジェクト: bnordgren/postgis
LWGEOM*
lwmpoint_remove_repeated_points(LWMPOINT *mpoint)
{
	uint32_t nnewgeoms;
	uint32_t i, j;
	LWGEOM **newgeoms;

	newgeoms = lwalloc(sizeof(LWGEOM *)*mpoint->ngeoms);
	nnewgeoms = 0;
	for (i=0; i<mpoint->ngeoms; ++i)
	{
		/* Brute force, may be optimized by building an index */
		int seen=0;
		for (j=0; j<nnewgeoms; ++j)
		{
			if ( lwpoint_same((LWPOINT*)newgeoms[j],
			                  (LWPOINT*)mpoint->geoms[i]) )
			{
				seen=1;
				break;
			}
		}
		if ( seen ) continue;
		newgeoms[nnewgeoms++] = (LWGEOM*)lwpoint_clone(mpoint->geoms[i]);
	}

	return (LWGEOM*)lwcollection_construct(mpoint->type,
	                                       mpoint->srid, mpoint->bbox ? gbox_copy(mpoint->bbox) : NULL,
	                                       nnewgeoms, newgeoms);

}
コード例 #3
0
ファイル: lwgeom_box.c プロジェクト: greenplum-db/postgis
Datum BOX2D_in(PG_FUNCTION_ARGS)
{
	char *str = PG_GETARG_CSTRING(0);
	int nitems;
	double tmp;
	GBOX box;
	
	gbox_init(&box);

	if (strstr(str,"BOX(") !=  str )
	{
		elog(ERROR,"box2d parser - doesnt start with BOX(");
		PG_RETURN_NULL();
	}
	nitems = sscanf(str,"BOX(%lf %lf,%lf %lf)", &box.xmin, &box.ymin, &box.xmax, &box.ymax);
	if (nitems != 4)
	{
		elog(ERROR,"box2d parser - couldnt parse.  It should look like: BOX(xmin ymin,xmax ymax)");
		PG_RETURN_NULL();
	}

	if (box.xmin > box.xmax)
	{
		tmp = box.xmin;
		box.xmin = box.xmax;
		box.xmax = tmp;
	}
	if (box.ymin > box.ymax)
	{
		tmp = box.ymin;
		box.ymin = box.ymax;
		box.ymax = tmp;
	}
	PG_RETURN_POINTER(gbox_copy(&box));
}
コード例 #4
0
ファイル: lwgeom_box.c プロジェクト: gbroccolo/postgis
Datum BOX2D_in(PG_FUNCTION_ARGS)
{
	char *str = PG_GETARG_CSTRING(0);
	int nitems;
	double tmp;
	GBOX box;
	int i;
	
	gbox_init(&box);

	for(i = 0; str[i]; i++) {
	  str[i] = tolower(str[i]);
	}
	
	nitems = sscanf(str,"box(%lf %lf,%lf %lf)", &box.xmin, &box.ymin, &box.xmax, &box.ymax);
	if (nitems != 4)
	{
		elog(ERROR,"box2d parser - couldnt parse.  It should look like: BOX(xmin ymin,xmax ymax)");
		PG_RETURN_NULL();
	}

	if (box.xmin > box.xmax)
	{
		tmp = box.xmin;
		box.xmin = box.xmax;
		box.xmax = tmp;
	}
	if (box.ymin > box.ymax)
	{
		tmp = box.ymin;
		box.ymin = box.ymax;
		box.ymax = tmp;
	}
	PG_RETURN_POINTER(gbox_copy(&box));
}
コード例 #5
0
ファイル: g_serialized.c プロジェクト: NianYue/pipelinedb
LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g)
{
	uint8_t g_flags = 0;
	int32_t g_srid = 0;
	uint32_t g_type = 0;
	uint8_t *data_ptr = NULL;
	LWGEOM *lwgeom = NULL;
	GBOX bbox;
	size_t g_size = 0;

	assert(g);

	g_srid = gserialized_get_srid(g);
	g_flags = g->flags;
	g_type = gserialized_get_type(g);
	LWDEBUGF(4, "Got type %d (%s), srid=%d", g_type, lwtype_name(g_type), g_srid);

	data_ptr = (uint8_t*)g->data;
	if ( FLAGS_GET_BBOX(g_flags) )
		data_ptr += gbox_serialized_size(g_flags);

	lwgeom = lwgeom_from_gserialized_buffer(data_ptr, g_flags, &g_size);

	if ( ! lwgeom ) 
		lwerror("lwgeom_from_gserialized: unable create geometry"); /* Ooops! */

	lwgeom->type = g_type;
	lwgeom->flags = g_flags;

	if ( gserialized_read_gbox_p(g, &bbox) == LW_SUCCESS )
	{
		lwgeom->bbox = gbox_copy(&bbox);
	}
	else if ( lwgeom_needs_bbox(lwgeom) && (lwgeom_calculate_gbox(lwgeom, &bbox) == LW_SUCCESS) )
	{
		lwgeom->bbox = gbox_copy(&bbox);
	}
	else
	{
		lwgeom->bbox = NULL;
	}

	lwgeom_set_srid(lwgeom, g_srid);

	return lwgeom;
}
コード例 #6
0
ファイル: lwpoly.c プロジェクト: sensorseverywhere/se
/* @brief Clone LWLINE object. Serialized point lists are not copied.
 *
 * @see ptarray_clone 
 */
LWPOLY *
lwpoly_clone(const LWPOLY *g)
{
	int i;
	LWPOLY *ret = lwalloc(sizeof(LWPOLY));
	memcpy(ret, g, sizeof(LWPOLY));
	ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings);
	for ( i = 0; i < g->nrings; i++ ) {
		ret->rings[i] = ptarray_clone(g->rings[i]);
	}
	if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
	return ret;
}
コード例 #7
0
ファイル: lwpoint.c プロジェクト: sensorseverywhere/se
/* @brief Clone LWPOINT object. Serialized point lists are not copied.
 *
 * @see ptarray_clone 
 */
LWPOINT *
lwpoint_clone(const LWPOINT *g)
{
	LWPOINT *ret = lwalloc(sizeof(LWPOINT));

	LWDEBUG(2, "lwpoint_clone called");

	memcpy(ret, g, sizeof(LWPOINT));

	ret->point = ptarray_clone(g->point);

	if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
	return ret;
}
コード例 #8
0
ファイル: lwpoly.c プロジェクト: sensorseverywhere/se
/* Deep clone LWPOLY object. POINTARRAY are copied, as is ring array */
LWPOLY *
lwpoly_clone_deep(const LWPOLY *g)
{
	int i;
	LWPOLY *ret = lwalloc(sizeof(LWPOLY));
	memcpy(ret, g, sizeof(LWPOLY));
	if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
	ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings);
	for ( i = 0; i < ret->nrings; i++ )
	{
		ret->rings[i] = ptarray_clone_deep(g->rings[i]);
	}
	FLAGS_SET_READONLY(ret->flags,0);
	return ret;
}
コード例 #9
0
ファイル: lwgeom_box.c プロジェクト: gbroccolo/postgis
Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
	GBOX gbox;

	if ( gserialized_get_gbox_p(geom, &gbox) == LW_FAILURE )
		PG_RETURN_NULL();

	/* Strip out higher dimensions */
	FLAGS_SET_Z(gbox.flags, 0);
	FLAGS_SET_M(gbox.flags, 0);

	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(gbox_copy(&gbox));
}
コード例 #10
0
ファイル: lwcollection.c プロジェクト: ahinz/postgis
LWGEOM*
lwcollection_remove_repeated_points(LWCOLLECTION *coll)
{
	uint32_t i;
	LWGEOM **newgeoms;

	newgeoms = lwalloc(sizeof(LWGEOM *)*coll->ngeoms);
	for (i=0; i<coll->ngeoms; i++)
	{
		newgeoms[i] = lwgeom_remove_repeated_points(coll->geoms[i]);
	}

	return (LWGEOM*)lwcollection_construct(coll->type,
	                                       coll->srid, coll->bbox ? gbox_copy(coll->bbox) : NULL,
	                                       coll->ngeoms, newgeoms);
}
コード例 #11
0
ファイル: lwpoly.c プロジェクト: sensorseverywhere/se
LWGEOM*
lwpoly_remove_repeated_points(LWPOLY *poly)
{
	uint32_t i;
	POINTARRAY **newrings;

	newrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
	for (i=0; i<poly->nrings; i++)
	{
		newrings[i] = ptarray_remove_repeated_points(poly->rings[i]);
	}

	return (LWGEOM*)lwpoly_construct(poly->srid,
	                                 poly->bbox ? gbox_copy(poly->bbox) : NULL,
	                                 poly->nrings, newrings);

}
コード例 #12
0
ファイル: lwgeom_box.c プロジェクト: greenplum-db/postgis
Datum LWGEOM_to_BOX2D(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
	GBOX gbox;

	/* Cannot box empty! */
	if ( lwgeom_is_empty(lwgeom) )
		PG_RETURN_NULL(); 

	/* Cannot calculate box? */
	if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE )
		PG_RETURN_NULL();
		
	/* Strip out higher dimensions */
	FLAGS_SET_Z(gbox.flags, 0);
	FLAGS_SET_M(gbox.flags, 0);

	PG_RETURN_POINTER(gbox_copy(&gbox));
}
コード例 #13
0
ファイル: lwcollection.c プロジェクト: ahinz/postgis
/**
* @brief Deep clone #LWCOLLECTION object. #POINTARRAY are copied.
*/
LWCOLLECTION *
lwcollection_clone_deep(const LWCOLLECTION *g)
{
	uint32_t i;
	LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
	memcpy(ret, g, sizeof(LWCOLLECTION));
	if ( g->ngeoms > 0 )
	{
		ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
		for (i=0; i<g->ngeoms; i++)
		{
			ret->geoms[i] = lwgeom_clone_deep(g->geoms[i]);
		}
		if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
	}
	else
	{
		ret->bbox = NULL; /* empty collection */
		ret->geoms = NULL;
	}
	return ret;
}
コード例 #14
0
ファイル: lwcollection.c プロジェクト: ahinz/postgis
/**
* Takes a potentially heterogeneous collection and returns a homogeneous
* collection consisting only of the specified type.
*/
LWCOLLECTION* lwcollection_extract(LWCOLLECTION *col, int type)
{
	int i = 0;
	LWGEOM **geomlist;
	LWCOLLECTION *outcol;
	int geomlistsize = 16;
	int geomlistlen = 0;
	uint8_t outtype;

	if ( ! col ) return NULL;

	switch (type)
	{
	case POINTTYPE:
		outtype = MULTIPOINTTYPE;
		break;
	case LINETYPE:
		outtype = MULTILINETYPE;
		break;
	case POLYGONTYPE:
		outtype = MULTIPOLYGONTYPE;
		break;
	default:
		lwerror("Only POLYGON, LINESTRING and POINT are supported by lwcollection_extract. %s requested.", lwtype_name(type));
		return NULL;
	}

	geomlist = lwalloc(sizeof(LWGEOM*) * geomlistsize);

	/* Process each sub-geometry */
	for ( i = 0; i < col->ngeoms; i++ )
	{
		int subtype = col->geoms[i]->type;
		/* Don't bother adding empty sub-geometries */
		if ( lwgeom_is_empty(col->geoms[i]) )
		{
			continue;
		}
		/* Copy our sub-types into the output list */
		if ( subtype == type )
		{
			/* We've over-run our buffer, double the memory segment */
			if ( geomlistlen == geomlistsize )
			{
				geomlistsize *= 2;
				geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
			}
			geomlist[geomlistlen] = lwgeom_clone(col->geoms[i]);
			geomlistlen++;
		}
		/* Recurse into sub-collections */
		if ( lwtype_is_collection( subtype ) )
		{
			int j = 0;
			LWCOLLECTION *tmpcol = lwcollection_extract((LWCOLLECTION*)col->geoms[i], type);
			for ( j = 0; j < tmpcol->ngeoms; j++ )
			{
				/* We've over-run our buffer, double the memory segment */
				if ( geomlistlen == geomlistsize )
				{
					geomlistsize *= 2;
					geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
				}
				geomlist[geomlistlen] = tmpcol->geoms[j];
				geomlistlen++;
			}
			lwfree(tmpcol);
		}
	}

	if ( geomlistlen > 0 )
	{
		GBOX gbox;
		outcol = lwcollection_construct(outtype, col->srid, NULL, geomlistlen, geomlist);
		lwgeom_calculate_gbox((LWGEOM *) outcol, &gbox);
		outcol->bbox = gbox_copy(&gbox);
	}
	else
	{
		lwfree(geomlist);
		outcol = lwcollection_construct_empty(outtype, col->srid, FLAGS_GET_Z(col->flags), FLAGS_GET_M(col->flags));
	}

	return outcol;
}
コード例 #15
0
ファイル: lwhomogenize.c プロジェクト: sensorseverywhere/se
/*
** Given a generic geometry, return the "simplest" form.
**
** eg:
**     LINESTRING() => LINESTRING()
**
**     MULTILINESTRING(with a single line) => LINESTRING()
**
**     GEOMETRYCOLLECTION(MULTILINESTRING()) => MULTILINESTRING()
**
**     GEOMETRYCOLLECTION(MULTILINESTRING(), MULTILINESTRING(), POINT())
**      => GEOMETRYCOLLECTION(MULTILINESTRING(), POINT())
*/
LWGEOM *
lwgeom_homogenize(const LWGEOM *geom)
{
	LWGEOM *hgeom;

	/* EMPTY Geometry */
	if (lwgeom_is_empty(geom)) 
	{
		if( lwgeom_is_collection(geom) )
		{
			return lwcollection_as_lwgeom(lwcollection_construct_empty(geom->type, geom->srid, lwgeom_has_z(geom), lwgeom_has_m(geom)));
		}
		
		return lwgeom_clone(geom);
	}

	switch (geom->type)
	{

		/* Return simple geometries untouched */
		case POINTTYPE:
		case LINETYPE:
		case CIRCSTRINGTYPE:
		case COMPOUNDTYPE:
		case TRIANGLETYPE:
		case CURVEPOLYTYPE:
		case POLYGONTYPE:
			return lwgeom_clone(geom);

		/* Process homogeneous geometries lightly */
		case MULTIPOINTTYPE:
		case MULTILINETYPE:
		case MULTIPOLYGONTYPE:
		case MULTICURVETYPE:
		case MULTISURFACETYPE:
		case POLYHEDRALSURFACETYPE:
		case TINTYPE:
		{
			LWCOLLECTION *col = (LWCOLLECTION*)geom;

			/* Strip single-entry multi-geometries down to singletons */
			if ( col->ngeoms == 1 )
			{
				hgeom = lwgeom_clone((LWGEOM*)(col->geoms[0]));
				hgeom->srid = geom->srid;
				if (geom->bbox)
					hgeom->bbox = gbox_copy(geom->bbox);
				return hgeom;
			}

			/* Return proper multigeometry untouched */
			return lwgeom_clone(geom);
		}
	
		/* Work on anonymous collections separately */
		case COLLECTIONTYPE: 
			return lwcollection_homogenize((LWCOLLECTION *) geom);
	}

	/* Unknown type */
	lwerror("lwgeom_homogenize: Geometry Type not supported (%i)",
	        lwtype_name(geom->type));

	return NULL; /* Never get here! */
}
コード例 #16
0
ファイル: lwgeom_ogc.c プロジェクト: gravitystorm/postgis
Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	GSERIALIZED *result;
	POINTARRAY *extring;
	LWGEOM *lwgeom;
	LWLINE *line;
	GBOX *bbox=NULL;
	int type = gserialized_get_type(geom);

	POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called.");

	if ( (type != POLYGONTYPE) &&
	     (type != CURVEPOLYTYPE) &&
	     (type != TRIANGLETYPE))
	{
		elog(ERROR, "ExteriorRing: geom is not a polygon");
		PG_RETURN_NULL();
	}
	
	lwgeom = lwgeom_from_gserialized(geom);
	
	if( lwgeom_is_empty(lwgeom) )
	{
		line = lwline_construct_empty(lwgeom->srid,
		                              lwgeom_has_z(lwgeom),
		                              lwgeom_has_m(lwgeom));
		result = geometry_serialize(lwline_as_lwgeom(line));
	}
	else if ( lwgeom->type == POLYGONTYPE )
	{
		LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);

		/* Ok, now we have a polygon. Here is its exterior ring. */
		extring = poly->rings[0];

		/*
		* This is a LWLINE constructed by exterior ring POINTARRAY
		* If the input geom has a bbox, use it for
		* the output geom, as exterior ring makes it up !
		*/
		if ( poly->bbox ) 
			bbox = gbox_copy(poly->bbox);

		line = lwline_construct(poly->srid, bbox, extring);
		result = geometry_serialize((LWGEOM *)line);

		lwgeom_release((LWGEOM *)line);
	}
	else if ( lwgeom->type == TRIANGLETYPE )
	{
		LWTRIANGLE *triangle = lwgeom_as_lwtriangle(lwgeom);

		/*
		* This is a LWLINE constructed by exterior ring POINTARRAY
		* If the input geom has a bbox, use it for
		* the output geom, as exterior ring makes it up !
		*/
		if ( triangle->bbox ) 
			bbox = gbox_copy(triangle->bbox);
		line = lwline_construct(triangle->srid, bbox, triangle->points);

		result = geometry_serialize((LWGEOM *)line);

		lwgeom_release((LWGEOM *)line);
	}
	else
	{
		LWCURVEPOLY *curvepoly = lwgeom_as_lwcurvepoly(lwgeom);
		result = geometry_serialize(curvepoly->rings[0]);
	}

	lwgeom_free(lwgeom);
	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(result);
}