Datum LWGEOM_snaptogrid(PG_FUNCTION_ARGS)
{
	Datum datum;
	GSERIALIZED *in_geom;
	LWGEOM *in_lwgeom;
	GSERIALIZED *out_geom = NULL;
	LWGEOM *out_lwgeom;
	gridspec grid;
	/* BOX3D box3d; */

	if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
	datum = PG_GETARG_DATUM(0);
	in_geom = (GSERIALIZED *)PG_DETOAST_DATUM(datum);

	if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
	grid.ipx = PG_GETARG_FLOAT8(1);

	if ( PG_ARGISNULL(2) ) PG_RETURN_NULL();
	grid.ipy = PG_GETARG_FLOAT8(2);

	if ( PG_ARGISNULL(3) ) PG_RETURN_NULL();
	grid.xsize = PG_GETARG_FLOAT8(3);

	if ( PG_ARGISNULL(4) ) PG_RETURN_NULL();
	grid.ysize = PG_GETARG_FLOAT8(4);

	/* Do not support gridding Z and M values for now */
	grid.ipz=grid.ipm=grid.zsize=grid.msize=0;

	/* Return input geometry if grid is null */
	if ( grid_isNull(&grid) )
	{
		PG_RETURN_POINTER(in_geom);
	}

	in_lwgeom = lwgeom_from_gserialized(in_geom);

	POSTGIS_DEBUGF(3, "SnapToGrid got a %s", lwtype_name(in_lwgeom->type));

	out_lwgeom = lwgeom_grid(in_lwgeom, &grid);
	if ( out_lwgeom == NULL ) PG_RETURN_NULL();

	/* COMPUTE_BBOX TAINTING */
	if ( in_lwgeom->bbox ) lwgeom_add_bbox(out_lwgeom);


	POSTGIS_DEBUGF(3, "SnapToGrid made a %s", lwtype_name(out_lwgeom->type));

	out_geom = geometry_serialize(out_lwgeom);

	PG_RETURN_POINTER(out_geom);
}
Datum LWGEOM_snaptogrid(PG_FUNCTION_ARGS)
{
	LWGEOM *in_lwgeom;
	GSERIALIZED *out_geom = NULL;
	LWGEOM *out_lwgeom;
	gridspec grid;

	GSERIALIZED *in_geom = PG_GETARG_GSERIALIZED_P(0);

	/* Set grid values to zero to start */
	memset(&grid, 0, sizeof(gridspec));

	grid.ipx = PG_GETARG_FLOAT8(1);
	grid.ipy = PG_GETARG_FLOAT8(2);
	grid.xsize = PG_GETARG_FLOAT8(3);
	grid.ysize = PG_GETARG_FLOAT8(4);

	/* Return input geometry if input geometry is empty */
	if ( gserialized_is_empty(in_geom) )
	{
		PG_RETURN_POINTER(in_geom);
	}
	
	/* Return input geometry if input grid is meaningless */
	if ( grid.xsize==0 && grid.ysize==0 && grid.zsize==0 && grid.msize==0 )
	{
		PG_RETURN_POINTER(in_geom);
	}

	in_lwgeom = lwgeom_from_gserialized(in_geom);

	POSTGIS_DEBUGF(3, "SnapToGrid got a %s", lwtype_name(in_lwgeom->type));

	out_lwgeom = lwgeom_grid(in_lwgeom, &grid);
	if ( out_lwgeom == NULL ) PG_RETURN_NULL();

	/* COMPUTE_BBOX TAINTING */
	if ( in_lwgeom->bbox ) 
		lwgeom_add_bbox(out_lwgeom);


	POSTGIS_DEBUGF(3, "SnapToGrid made a %s", lwtype_name(out_lwgeom->type));

	out_geom = geometry_serialize(out_lwgeom);

	PG_RETURN_POINTER(out_geom);
}
Exemple #3
0
static void test_grid(void)
{
	gridspec grid;
	static char *wkt = "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))";
	LWGEOM *geom = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_ALL);
	LWGEOM *geomgrid;
	char *str;
	
	grid.ipx = grid.ipy = 0;
	grid.xsize = grid.ysize = 20;

	geomgrid = lwgeom_grid(geom, &grid);
	str = lwgeom_to_ewkt(geomgrid);
	CU_ASSERT_STRING_EQUAL(str, "MULTIPOLYGON EMPTY");
	lwfree(str);
	lwgeom_free(geom);
	lwgeom_free(geomgrid);		
}
LWCOLLECTION *
lwcollection_grid(LWCOLLECTION *coll, gridspec *grid)
{
	uint32 i;
	LWGEOM **geoms;
	uint32 ngeoms=0;

	geoms = palloc(coll->ngeoms * sizeof(LWGEOM *));

	for (i=0; i<coll->ngeoms; i++)
	{
		LWGEOM *g = lwgeom_grid(coll->geoms[i], grid);
		if ( g ) geoms[ngeoms++] = g;
	}

	if ( ! ngeoms ) return lwcollection_construct_empty(COLLECTIONTYPE, coll->srid, 0, 0);

	return lwcollection_construct(coll->type, coll->srid,
	                              NULL, ngeoms, geoms);
}
Datum LWGEOM_snaptogrid_pointoff(PG_FUNCTION_ARGS)
{
	Datum datum;
	GSERIALIZED *in_geom, *in_point;
	LWGEOM *in_lwgeom;
	LWPOINT *in_lwpoint;
	GSERIALIZED *out_geom = NULL;
	LWGEOM *out_lwgeom;
	gridspec grid;
	/* BOX3D box3d; */
	POINT4D offsetpoint;

	if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
	datum = PG_GETARG_DATUM(0);
	in_geom = (GSERIALIZED *)PG_DETOAST_DATUM(datum);

	if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
	datum = PG_GETARG_DATUM(1);
	in_point = (GSERIALIZED *)PG_DETOAST_DATUM(datum);
	in_lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(in_point));
	if ( in_lwpoint == NULL )
	{
		lwerror("Offset geometry must be a point");
	}

	if ( PG_ARGISNULL(2) ) PG_RETURN_NULL();
	grid.xsize = PG_GETARG_FLOAT8(2);

	if ( PG_ARGISNULL(3) ) PG_RETURN_NULL();
	grid.ysize = PG_GETARG_FLOAT8(3);

	if ( PG_ARGISNULL(4) ) PG_RETURN_NULL();
	grid.zsize = PG_GETARG_FLOAT8(4);

	if ( PG_ARGISNULL(5) ) PG_RETURN_NULL();
	grid.msize = PG_GETARG_FLOAT8(5);

	/* Take offsets from point geometry */
	getPoint4d_p(in_lwpoint->point, 0, &offsetpoint);
	grid.ipx = offsetpoint.x;
	grid.ipy = offsetpoint.y;
	if (FLAGS_GET_Z(in_lwpoint->flags) ) grid.ipz = offsetpoint.z;
	else grid.ipz=0;
	if (FLAGS_GET_M(in_lwpoint->flags) ) grid.ipm = offsetpoint.m;
	else grid.ipm=0;

#if POSTGIS_DEBUG_LEVEL >= 4
	grid_print(&grid);
#endif

	/* Return input geometry if grid is null */
	if ( grid_isNull(&grid) )
	{
		PG_RETURN_POINTER(in_geom);
	}

	in_lwgeom = lwgeom_from_gserialized(in_geom);

	POSTGIS_DEBUGF(3, "SnapToGrid got a %s", lwtype_name(in_lwgeom->type));

	out_lwgeom = lwgeom_grid(in_lwgeom, &grid);
	if ( out_lwgeom == NULL ) PG_RETURN_NULL();

	/* COMPUTE_BBOX TAINTING */
	if ( in_lwgeom->bbox ) lwgeom_add_bbox(out_lwgeom);

	POSTGIS_DEBUGF(3, "SnapToGrid made a %s", lwtype_name(out_lwgeom->type));

	out_geom = geometry_serialize(out_lwgeom);

	PG_RETURN_POINTER(out_geom);
}