]> granicus.if.org Git - postgis/commitdiff
Add ST_AsTIFF function
authorBborie Park <bkpark at ucdavis.edu>
Mon, 16 May 2011 19:50:38 +0000 (19:50 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Mon, 16 May 2011 19:50:38 +0000 (19:50 +0000)
- add SQL functions for ST_AsTIFF
- add regression tests

Associated ticket is #341

git-svn-id: http://svn.osgeo.org/postgis/trunk@7156 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/Makefile.in
raster/test/regress/rt_astiff.sql [new file with mode: 0644]
raster/test/regress/rt_astiff_expected [new file with mode: 0644]

index 35cf6373de772ca21c11db17b781f80023f9c1e4..52abfe38dc35840110d196ddb84225c6db3e29c8 100644 (file)
@@ -1081,6 +1081,167 @@ CREATE OR REPLACE FUNCTION st_asgdalraster(rast raster, format text)
        AS $$ SELECT st_asgdalraster($1, $2, NULL, st_srtext($1)) $$
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
+-----------------------------------------------------------------------
+-- ST_AsTIFF
+-----------------------------------------------------------------------
+-- Cannot be strict as "options" and "srs" can be NULL
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, options text[], srs text)
+       RETURNS bytea
+       AS $$
+       DECLARE
+               i int;
+               num_bands int;
+               nodata int;
+               last_nodata int;
+       BEGIN
+               num_bands := st_numbands($1);
+
+               -- TIFF only allows one NODATA value for ALL bands
+               FOR i IN 1..num_bands LOOP
+                       nodata := st_bandnodatavalue($1, i);
+                       IF last_nodata IS NULL THEN
+                               last_nodata := nodata;
+                       ELSEIF nodata != last_nodata THEN
+                               RAISE NOTICE 'The TIFF format only permits one NODATA value for all bands.  The value used will be the last band with a NODATA value.';
+                       END IF;
+               END LOOP;
+
+               RETURN st_asgdalraster($1, 'GTiff', $2, $3);
+       END;
+       $$ LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, options text[])
+       RETURNS bytea
+       AS $$ SELECT st_astiff($1, $2, st_srtext($1)) $$
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster)
+       RETURNS bytea
+       AS $$ SELECT st_astiff($1, NULL::text[], st_srtext($1)) $$
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], options text[], srs text)
+       RETURNS bytea
+       AS $$ SELECT st_astiff(st_band($1, $2), $3, $4) $$
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], options text[])
+       RETURNS bytea
+       AS $$
+       BEGIN
+               rast := st_band($1, $2);
+               RETURN st_astiff(rast, $3, st_srtext(rast));
+       END;
+       $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[])
+       RETURNS bytea
+       AS $$
+       BEGIN
+               rast := st_band($1, $2);
+               RETURN st_astiff(rast, NULL::text[], st_srtext(rast));
+       END;
+       $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
+-- Cannot be strict as "srs" can be NULL
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, compression text, srs text)
+       RETURNS bytea
+       AS $$
+       DECLARE
+               c_type text;
+               c_level int;
+               i int;
+               num_bands int;
+               options text[];
+       BEGIN
+               compression := trim(both from upper(compression));
+
+               IF length(compression) > 0 THEN
+                       -- JPEG
+                       IF position('JPEG' in compression) != 0 THEN
+                               c_type := 'JPEG';
+                               c_level := substring(compression from '[0-9]+$');
+
+                               IF c_level IS NOT NULL THEN
+                                       IF c_level > 100 THEN
+                                               c_level := 100;
+                                       ELSEIF c_level < 1 THEN
+                                               c_level := 1;
+                                       END IF;
+
+                                       options := array_append(options, 'JPEG_QUALITY=' || c_level);
+                               END IF;
+
+                               -- per band pixel type check
+                               num_bands := st_numbands($1);
+                               FOR i IN 1..num_bands LOOP
+                                       IF st_bandpixeltype($1, i) != '8BUI' THEN
+                                               RAISE EXCEPTION 'The pixel type of band % in the raster is not 8BUI.  JPEG compression can only be used with the 8BUI pixel type.', i;
+                                       END IF;
+                               END LOOP;
+
+                       -- DEFLATE
+                       ELSEIF position('DEFLATE' in compression) != 0 THEN
+                               c_type := 'DEFLATE';
+                               c_level := substring(compression from '[0-9]+$');
+
+                               IF c_level IS NOT NULL THEN
+                                       IF c_level > 9 THEN
+                                               c_level := 9;
+                                       ELSEIF c_level < 1 THEN
+                                               c_level := 1;
+                                       END IF;
+
+                                       options := array_append(options, 'ZLEVEL=' || c_level);
+                               END IF;
+
+                       ELSE
+                               c_type := compression;
+
+                               -- CCITT
+                               IF position('CCITT' in compression) THEN
+                                       -- per band pixel type check
+                                       num_bands := st_numbands($1);
+                                       FOR i IN 1..num_bands LOOP
+                                               IF st_bandpixeltype($1, i) != '1BB' THEN
+                                                       RAISE EXCEPTION 'The pixel type of band % in the raster is not 1BB.  CCITT compression can only be used with the 1BB pixel type.', i;
+                                               END IF;
+                                       END LOOP;
+                               END IF;
+
+                       END IF;
+
+                       -- compression type check
+                       IF ARRAY[c_type] <@ ARRAY['JPEG', 'LZW', 'PACKBITS', 'DEFLATE', 'CCITTRLE', 'CCITTFAX3', 'CCITTFAX4', 'NONE'] THEN
+                               options := array_append(options, 'COMPRESS=' || c_type);
+                       ELSE
+                               RAISE NOTICE 'Unknown compression type: %.  The outputted TIFF will not be COMPRESSED.', c_type;
+                       END IF;
+               END IF;
+
+               RETURN st_astiff($1, options, $4);
+       END;
+       $$ LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, compression text)
+       RETURNS bytea
+       AS $$ SELECT st_astiff($1, $2, st_srtext($1)) $$
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], compression text, srs text)
+       RETURNS bytea
+       AS $$ SELECT st_astiff(st_band($1, $2), $3, $4) $$
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], compression text)
+       RETURNS bytea
+       AS $$
+       BEGIN
+               rast := st_band($1, $2);
+               RETURN st_astiff(rast, $3, NULL::text[], st_srtext(rast));
+       END;
+       $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
 -----------------------------------------------------------------------
 -- MapAlgebra
 -----------------------------------------------------------------------
index dcfd840c5a21bd63933704182d5256471c558487..51843861c0462cdeb9c845585bb763f538c059f5 100644 (file)
@@ -43,6 +43,7 @@ TEST_FUNC = \
        rt_addband.sql \
        rt_band.sql \
        rt_asgdalraster.sql \
+       rt_astiff.sql \
        $(NULL)
 
 TEST_PROPS = \
diff --git a/raster/test/regress/rt_astiff.sql b/raster/test/regress/rt_astiff.sql
new file mode 100644 (file)
index 0000000..6f9a1c7
--- /dev/null
@@ -0,0 +1,91 @@
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '64BF', 123.4567, NULL)
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1)
+                                       , 1, '64BF', 1234.5678, NULL
+                               )
+                               , '64BF', 987.654321, NULL
+                       )
+                       , '64BF', 9876.54321, NULL
+               )
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+                                       , 1, '64BF', 1234.5678, -9999
+                               )
+                               , '64BF', 987.654321, -9999
+                       )
+                       , '64BF', 9876.54321, -9999
+               )
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+                                       , 1, '64BF', 1234.5678, -9999
+                               )
+                               , '64BF', 987.654321, -9999
+                       )
+                       , '64BF', 9876.54321, -9999
+               )
+               , ARRAY[3]
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+                                       , 1, '64BF', 1234.5678, -9999
+                               )
+                               , '64BF', 987.654321, -9999
+                       )
+                       , '64BF', 9876.54321, -1
+               )
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+                                       , 1, '64BF', 1234.5678, -1
+                               )
+                               , '64BF', 987.654321, -9999
+                       )
+                       , '64BF', 9876.54321, -9999
+               )
+       )
+);
+SELECT md5(
+       ST_AsTIFF(
+               ST_AddBand(
+                       ST_AddBand(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+                                       , 1, '64BF', 1234.5678, -9999
+                               )
+                               , '64BF', 987.654321, -9999
+                       )
+                       , '64BF', 9876.54321, -1
+               )
+               , 'JPEG90'
+       )
+);
diff --git a/raster/test/regress/rt_astiff_expected b/raster/test/regress/rt_astiff_expected
new file mode 100644 (file)
index 0000000..f046c10
--- /dev/null
@@ -0,0 +1,10 @@
+2fd5de5f94416f2999fc24fbc3974a4b
+4af1ca04adf045690fb60764cc93de75
+81de10108dd8eede75ef47c8f6f09bc5
+915b9a5f0b1baea454eef06a2431891b
+NOTICE:  The TIFF format only permits one NODATA value for all bands.  The value used will be the last band with a NODATA value.
+81de10108dd8eede75ef47c8f6f09bc5
+NOTICE:  The TIFF format only permits one NODATA value for all bands.  The value used will be the last band with a NODATA value.
+NOTICE:  The TIFF format only permits one NODATA value for all bands.  The value used will be the last band with a NODATA value.
+8f6e8ae14b92e32d4cf70c85ef67252e
+ERROR:  The pixel type of band 1 in the raster is not 8BUI.  JPEG compression can only be used with the 8BUI pixel type.