From 07164382cb95b153c5e2e0a61319c71320c0f65f Mon Sep 17 00:00:00 2001 From: Bborie Park Date: Fri, 13 Jul 2012 23:28:57 +0000 Subject: [PATCH] Addition of ST_BandSurface and regressions tests. Ticket is #1911 git-svn-id: http://svn.osgeo.org/postgis/trunk@10058 b70326c6-7e19-0410-871a-916f4a2858ee --- raster/rt_pg/rt_pg.c | 63 +++++++++ raster/rt_pg/rtpostgis.sql.in.c | 9 ++ raster/test/regress/Makefile.in | 3 +- raster/test/regress/rt_bandsurface.sql | 144 ++++++++++++++++++++ raster/test/regress/rt_bandsurface_expected | 8 ++ 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 raster/test/regress/rt_bandsurface.sql create mode 100644 raster/test/regress/rt_bandsurface_expected diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index a8f6c386a..ad2170651 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -202,6 +202,9 @@ Datum RASTER_setPixelValue(PG_FUNCTION_ARGS); /* Get pixel geographical shape */ Datum RASTER_getPixelPolygons(PG_FUNCTION_ARGS); +/* Get raster band's surface */ +Datum RASTER_getBandSurface(PG_FUNCTION_ARGS); + /* Get pixels of value */ Datum RASTER_pixelOfValue(PG_FUNCTION_ARGS); @@ -2741,6 +2744,66 @@ Datum RASTER_getPixelPolygons(PG_FUNCTION_ARGS) } } +/** + * Get raster band's surface + */ +PG_FUNCTION_INFO_V1(RASTER_getBandSurface); +Datum RASTER_getBandSurface(PG_FUNCTION_ARGS) +{ + rt_pgraster *pgraster = NULL; + rt_raster raster = NULL; + int num_bands = 0; + int nband = 1; + LWMPOLY *surface = NULL; + GSERIALIZED *rtn = NULL; + + /* raster */ + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + + raster = rt_raster_deserialize(pgraster, FALSE); + if (!raster) { + elog(ERROR, "RASTER_getBandSurface: Could not deserialize raster"); + PG_FREE_IF_COPY(pgraster, 0); + PG_RETURN_NULL(); + } + + /* num_bands */ + num_bands = rt_raster_get_num_bands(raster); + if (num_bands < 1) { + elog(NOTICE, "Raster provided has no bands"); + rt_raster_destroy(raster); + PG_FREE_IF_COPY(pgraster, 0); + PG_RETURN_NULL(); + } + + /* band index is 1-based */ + if (!PG_ARGISNULL(1)) + nband = PG_GETARG_INT32(1); + if (nband < 1 || nband > num_bands) { + elog(NOTICE, "Invalid band index (must use 1-based). Returning NULL"); + rt_raster_destroy(raster); + PG_FREE_IF_COPY(pgraster, 0); + PG_RETURN_NULL(); + } + + /* get band surface */ + surface = rt_raster_surface(raster, nband - 1); + rt_raster_destroy(raster); + PG_FREE_IF_COPY(pgraster, 0); + + if (surface == NULL) { + elog(ERROR, "RASTER_getBandSurface: Could not get raster band's surface"); + PG_RETURN_NULL(); + } + + rtn = geometry_serialize(lwmpoly_as_lwgeom(surface)); + lwmpoly_free(surface); + + PG_RETURN_POINTER(rtn); +} + /** * Get pixels of value */ diff --git a/raster/rt_pg/rtpostgis.sql.in.c b/raster/rt_pg/rtpostgis.sql.in.c index 3c0dbe58d..a025010c1 100644 --- a/raster/rt_pg/rtpostgis.sql.in.c +++ b/raster/rt_pg/rtpostgis.sql.in.c @@ -2592,6 +2592,15 @@ CREATE OR REPLACE FUNCTION st_pixelascentroid(rast raster, x integer, y integer) AS $$ SELECT ST_Centroid(geom) FROM _st_pixelaspolygons($1, NULL, $2, $3) $$ LANGUAGE 'sql' IMMUTABLE STRICT; +----------------------------------------------------------------------- +-- ST_BandSurface +----------------------------------------------------------------------- + +CREATE OR REPLACE FUNCTION st_bandsurface(rast raster, nband integer DEFAULT 1) + RETURNS geometry + AS 'MODULE_PATHNAME','RASTER_getBandSurface' + LANGUAGE 'c' IMMUTABLE STRICT; + ----------------------------------------------------------------------- -- Raster Utility Functions ----------------------------------------------------------------------- diff --git a/raster/test/regress/Makefile.in b/raster/test/regress/Makefile.in index 17f1d8c40..78fa1bbea 100644 --- a/raster/test/regress/Makefile.in +++ b/raster/test/regress/Makefile.in @@ -85,7 +85,8 @@ TEST_BANDPROPS = \ rt_pixelofvalue \ rt_pixelaspolygons \ rt_pixelaspoints \ - rt_pixelascentroids + rt_pixelascentroids \ + rt_bandsurface TEST_UTILITY = \ rt_utility \ diff --git a/raster/test/regress/rt_bandsurface.sql b/raster/test/regress/rt_bandsurface.sql new file mode 100644 index 000000000..46b1ee605 --- /dev/null +++ b/raster/test/regress/rt_bandsurface.sql @@ -0,0 +1,144 @@ +DROP TABLE IF EXISTS raster_surface; +CREATE TABLE raster_surface ( + rast raster +); +CREATE OR REPLACE FUNCTION make_test_raster() + RETURNS void + AS $$ + DECLARE + width int := 5; + height int := 5; + x int; + y int; + rast raster; + BEGIN + rast := ST_MakeEmptyRaster(width, height, 0, 0, 1, -1, 0, 0, 0); + rast := ST_AddBand(rast, 1, '32BUI', 1, 0); + + INSERT INTO raster_surface VALUES (rast); + + RETURN; + END; + $$ LANGUAGE 'plpgsql'; +SELECT make_test_raster(); +DROP FUNCTION make_test_raster(); + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM raster_surface; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + rast, 1, 1, 1, 0 + ) AS rast + FROM raster_surface +) foo; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + ST_SetValue( + rast, 1, 1, 1, 0 + ), + 1, 2, 2, 0 + ) AS rast + FROM raster_surface +) foo; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + ST_SetValue( + ST_SetValue( + rast, 1, 1, 1, 0 + ), + 1, 2, 2, 0 + ), + 1, 3, 3, 0 + ) AS rast + FROM raster_surface +) foo; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + rast, 1, 1, 1, 0 + ), + 1, 2, 2, 0 + ), + 1, 3, 3, 0 + ), + 1, 4, 4, 0 + ) AS rast + FROM raster_surface +) foo; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + rast, 1, 1, 1, 0 + ), + 1, 2, 2, 0 + ), + 1, 3, 3, 0 + ), + 1, 4, 4, 0 + ), + 1, 5, 5, 0 + ) AS rast + FROM raster_surface +) foo; + +SELECT + ST_AsText(ST_BandSurface(rast)) +FROM ( + SELECT + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + ST_SetValue( + rast, 1, 1, 1, 0 + ), + 1, 2, 2, 0 + ), + 1, 3, 3, 0 + ), + 1, 4, 4, 0 + ), + 1, 5, 5, 0 + ), + 1, 5, 1, 0 + ), + 1, 4, 2, 0 + ), + 1, 2, 4, 0 + ), + 1, 1, 5, 0 + ) AS rast + FROM raster_surface +) foo; + +DROP TABLE IF EXISTS raster_surface; diff --git a/raster/test/regress/rt_bandsurface_expected b/raster/test/regress/rt_bandsurface_expected new file mode 100644 index 000000000..dda23658f --- /dev/null +++ b/raster/test/regress/rt_bandsurface_expected @@ -0,0 +1,8 @@ +NOTICE: table "raster_surface" does not exist, skipping +MULTIPOLYGON(((0 0,1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,5 -5,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1,0 0))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,5 -5,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1,1 -1,1 0))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,5 -5,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1,1 -1,1 0),(1 -1,1 -2,2 -2,2 -1,1 -1))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,5 -5,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1,1 -1,1 0),(1 -1,1 -2,2 -2,2 -1,1 -1),(2 -2,2 -3,3 -3,3 -2,2 -2))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,5 -5,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1,1 -1,1 0),(1 -1,1 -2,2 -2,2 -1,1 -1),(2 -2,2 -3,3 -3,3 -2,2 -2),(3 -3,3 -4,4 -4,4 -3,3 -3))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,5 0,5 -1,5 -2,5 -3,5 -4,4 -4,4 -3,3 -3,3 -2,2 -2,2 -1,1 -1,1 0)),((0 -1,1 -1,1 -2,2 -2,2 -3,3 -3,3 -4,4 -4,4 -5,3 -5,2 -5,1 -5,0 -5,0 -4,0 -3,0 -2,0 -1))) +MULTIPOLYGON(((1 0,2 0,3 0,4 0,4 -1,3 -1,3 -2,2 -2,2 -1,1 -1,1 0)),((0 -1,1 -1,1 -2,2 -2,2 -3,1 -3,1 -4,0 -4,0 -3,0 -2,0 -1)),((4 -1,5 -1,5 -2,5 -3,5 -4,4 -4,4 -3,3 -3,3 -2,4 -2,4 -1)),((2 -3,3 -3,3 -4,4 -4,4 -5,3 -5,2 -5,1 -5,1 -4,2 -4,2 -3))) -- 2.40.0