Ticket #339: st_band.3.patch
| File st_band.3.patch, 15.1 KB (added by dustymugs, 13 months ago) |
|---|
-
raster/rt_core/rt_api.c
diff -rupN postgis-old/raster/rt_core/rt_api.c postgis-new/raster/rt_core/rt_api.c
old new 3850 3850 return rt_raster_add_band(torast, newband, toindex); 3851 3851 } 3852 3852 3853 /** 3854 * Construct a new rt_raster from an existing rt_raster and an array 3855 * of band numbers 3856 * 3857 * @param raster : the source raster 3858 * @param bandNums : array of band numbers to extract from source raster 3859 * and add to the new raster (0 based) 3860 * @param count : number of elements in bandNums 3861 * 3862 * @return a new rt_raster or 0 on error 3863 */ 3864 rt_raster 3865 rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count) { 3866 rt_raster rast = NULL; 3867 int i = 0; 3868 int idx; 3869 int32_t flag; 3870 3871 assert(NULL != raster); 3872 assert(NULL != bandNums); 3873 3874 RASTER_DEBUGF(3, "rt_raster_from_band: source raster has %d bands", 3875 rt_raster_get_num_bands(raster)); 3876 3877 /* create new raster */ 3878 rast = rt_raster_new(raster->width, raster->height); 3879 if (!rast) { 3880 rterror("rt_raster_from_band: Out of memory allocating new raster\n"); 3881 return 0; 3882 } 3883 3884 /* copy bands */ 3885 for (i = 0; i < count; i++) { 3886 idx = bandNums[i]; 3887 flag = rt_raster_copy_band(rast, raster, idx, i); 3888 3889 if (flag < 0) { 3890 rterror("rt_raster_from_band: Unable to copy band\n"); 3891 rt_raster_destroy(rast); 3892 return 0; 3893 } 3894 3895 RASTER_DEBUGF(3, "rt_raster_from_band: band created at index %d", 3896 flag); 3897 } 3898 3899 RASTER_DEBUGF(3, "rt_raster_from_band: new raster has %d bands", 3900 rt_raster_get_num_bands(rast)); 3901 return rast; 3902 } 3903 -
raster/rt_core/rt_api.h
diff -rupN postgis-old/raster/rt_core/rt_api.h postgis-new/raster/rt_core/rt_api.h
old new 757 757 int32_t rt_raster_copy_band(rt_raster torast, 758 758 rt_raster fromrast, int fromindex, int toindex); 759 759 760 /** 761 * Construct a new rt_raster from an existing rt_raster and an array 762 * of band numbers 763 * 764 * @param raster : the source raster 765 * @param bandNums : array of band numbers to extract from source raster 766 * and add to the new raster (0 based) 767 * @param count : number of elements in bandNums 768 * 769 * @return a new rt_raster or 0 on error 770 */ 771 rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, 772 int count); 773 774 760 775 /*- utilities -------------------------------------------------------*/ 761 776 762 777 /* -
raster/rt_pg/rt_pg.c
diff -rupN postgis-old/raster/rt_pg/rt_pg.c postgis-new/raster/rt_pg/rt_pg.c
old new 49 49 #include "rt_api.h" 50 50 #include "../raster_config.h" 51 51 52 #include <utils/lsyscache.h> /* for get_typlenbyvalalign */ 53 #include <utils/array.h> /* for ArrayType */ 54 #include <catalog/pg_type.h> /* for INT2OID, INT4OID, FLOAT4OID, FLOAT8OID and TEXTOID */ 55 52 56 #define POSTGIS_RASTER_WARN_ON_TRUNCATION 53 57 54 58 /* … … 180 184 /* Raster analysis */ 181 185 Datum RASTER_mapAlgebra(PG_FUNCTION_ARGS); 182 186 187 /* create new raster from existing raster's bands */ 188 Datum RASTER_band(PG_FUNCTION_ARGS); 189 183 190 184 191 /* Replace function taken from 185 192 * http://ubuntuforums.org/showthread.php?s=aa6f015109fd7e4c7e30d2fd8b717497&t=141670&page=3 … … 2617 2624 PG_RETURN_POINTER(pgraster); 2618 2625 } 2619 2626 2627 /** 2628 * Return new raster from selected bands of existing raster through ST_Band. 2629 * second argument is an array of band numbers (1 based) 2630 */ 2631 PG_FUNCTION_INFO_V1(RASTER_band); 2632 Datum RASTER_band(PG_FUNCTION_ARGS) 2633 { 2634 rt_pgraster *pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 2635 rt_pgraster *pgrast; 2636 rt_raster raster; 2637 rt_raster rast; 2638 2639 bool skip = FALSE; 2640 ArrayType *array; 2641 Oid etype; 2642 Datum *e; 2643 bool *nulls; 2644 int16 typlen; 2645 bool typbyval; 2646 char typalign; 2647 int ndims = 1; 2648 int *dims; 2649 int *lbs; 2650 2651 uint32_t *bandNums; 2652 uint32 idx = 0; 2653 int n; 2654 int i = 0; 2655 int j = 0; 2656 2657 raster = rt_raster_deserialize(pgraster); 2658 if (!raster) { 2659 elog(ERROR, "RASTER_band: Could not deserialize raster"); 2660 PG_RETURN_NULL(); 2661 } 2662 2663 /* process bandNums */ 2664 if (PG_ARGISNULL(1)) { 2665 elog(NOTICE, "Band number(s) not provided. Returning original raster"); 2666 skip = TRUE; 2667 } 2668 do { 2669 if (skip) break; 2670 2671 array = PG_GETARG_ARRAYTYPE_P(1); 2672 etype = ARR_ELEMTYPE(array); 2673 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign); 2674 2675 switch (etype) { 2676 case INT2OID: 2677 case INT4OID: 2678 break; 2679 default: 2680 elog(ERROR, "RASTER_band: Invalid data type for band number(s)"); 2681 rt_raster_destroy(raster); 2682 PG_RETURN_NULL(); 2683 break; 2684 } 2685 2686 ndims = ARR_NDIM(array); 2687 dims = ARR_DIMS(array); 2688 lbs = ARR_LBOUND(array); 2689 2690 deconstruct_array(array, etype, typlen, typbyval, typalign, &e, 2691 &nulls, &n); 2692 2693 bandNums = (uint32_t *) palloc(sizeof(uint32_t) * n); 2694 for (i = 0, j = 0; i < n; i++) { 2695 if (nulls[i]) continue; 2696 2697 switch (etype) { 2698 case INT2OID: 2699 idx = (uint32_t) DatumGetInt16(e[i]); 2700 break; 2701 case INT4OID: 2702 idx = (uint32_t) DatumGetInt32(e[i]); 2703 break; 2704 } 2705 2706 POSTGIS_RT_DEBUGF(3, "band idx (before): %d", idx); 2707 if (idx > pgraster->numBands || idx < 1) { 2708 elog(NOTICE, "Invalid band index (must use 1-based). Returning original raster"); 2709 pfree(bandNums); 2710 skip = TRUE; 2711 } 2712 if (skip) break; 2713 2714 bandNums[j] = idx - 1; 2715 POSTGIS_RT_DEBUGF(3, "bandNums[%d] = %d", j, bandNums[j]); 2716 j++; 2717 } 2718 2719 if (skip || j < 1) { 2720 pfree(bandNums); 2721 skip = TRUE; 2722 } 2723 } 2724 while (0); 2725 2726 if (!skip) { 2727 rast = rt_raster_from_band(raster, bandNums, j); 2728 pfree(bandNums); 2729 rt_raster_destroy(raster); 2730 if (!rast) { 2731 elog(ERROR, "RASTER_band: Could not create new raster"); 2732 PG_RETURN_NULL(); 2733 } 2734 2735 pgrast = rt_raster_serialize(rast); 2736 } 2737 else { 2738 pgrast = pgraster; 2739 } 2740 2741 if (!pgrast) 2742 PG_RETURN_NULL(); 2743 2744 SET_VARSIZE(pgrast, pgrast->size); 2745 PG_RETURN_POINTER(pgrast); 2746 } 2747 2620 2748 /* ---------------------------------------------------------------- */ 2621 2749 /* Memory allocation / error reporting hooks */ 2622 2750 /* ---------------------------------------------------------------- */ -
raster/rt_pg/rtpostgis.sql.in.c
diff -rupN postgis-old/raster/rt_pg/rtpostgis.sql.in.c postgis-new/raster/rt_pg/rtpostgis.sql.in.c
old new 229 229 LANGUAGE 'SQL' IMMUTABLE STRICT; 230 230 231 231 ----------------------------------------------------------------------- 232 -- Constructor ST_Band 233 ----------------------------------------------------------------------- 234 CREATE OR REPLACE FUNCTION st_band(rast raster, nbands int[]) 235 RETURNS RASTER 236 AS 'MODULE_PATHNAME', 'RASTER_band' 237 LANGUAGE 'C' IMMUTABLE STRICT; 238 239 CREATE OR REPLACE FUNCTION st_band(rast raster, nband int) 240 RETURNS RASTER 241 AS $$ SELECT st_band($1, ARRAY[$2]) $$ 242 LANGUAGE 'SQL' IMMUTABLE STRICT; 243 244 CREATE OR REPLACE FUNCTION st_band(rast raster, nbands text) 245 RETURNS RASTER 246 AS $$ SELECT st_band($1, regexp_split_to_array(regexp_replace($2, '[[:space:]]', '', 'g'), ',')::int[]) $$ 247 LANGUAGE 'SQL' IMMUTABLE STRICT; 248 249 CREATE OR REPLACE FUNCTION st_band(rast raster, nbands text, delimiter char) 250 RETURNS RASTER 251 AS $$ SELECT st_band($1, regexp_split_to_array(regexp_replace($2, '[[:space:]]', '', 'g'), $3)::int[]) $$ 252 LANGUAGE 'SQL' IMMUTABLE STRICT; 253 254 CREATE OR REPLACE FUNCTION st_band(rast raster) 255 RETURNS RASTER 256 AS $$ SELECT st_band($1, ARRAY[1]) $$ 257 LANGUAGE 'SQL' IMMUTABLE STRICT; 258 259 ----------------------------------------------------------------------- 232 260 -- MapAlgebra 233 261 ----------------------------------------------------------------------- 234 262 -- This function can not be STRICT, because nodatavalueexpr can be NULL (could be just '' though) -
raster/test/core/testapi.c
diff -rupN postgis-old/raster/test/core/testapi.c postgis-new/raster/test/core/testapi.c
old new 972 972 CHECK_EQUALS(flag, 1); 973 973 } 974 974 975 static void testRasterFromBand(rt_raster raster) { 976 uint32_t bandNums[] = {1,3}; 977 int lenBandNums = 2; 978 rt_raster rast; 979 980 rast = rt_raster_from_band(raster, bandNums, lenBandNums); 981 assert(rast); 982 983 CHECK(rast); 984 CHECK(!rt_raster_is_empty(rast)); 985 CHECK(!rt_raster_has_no_band(rast, 1)); 986 987 rt_raster_destroy(rast); 988 } 989 975 990 int 976 991 main() 977 992 { … … 1278 1293 printf("Testing band hasnodata flag\n"); 1279 1294 testBandHasNoData(band_64BF); 1280 1295 1296 printf("Testing rt_raster_from_band\n"); 1297 testRasterFromBand(raster); 1298 printf("Successfully tested rt_raster_from_band\n"); 1299 1300 1281 1301 deepRelease(raster); 1282 1302 1283 1303 return EXIT_SUCCESS; -
raster/test/regress/Makefile.in
diff -rupN postgis-old/raster/test/regress/Makefile.in postgis-new/raster/test/regress/Makefile.in
old new 41 41 create_rt_box2d_test.sql \ 42 42 rt_box2d.sql \ 43 43 rt_addband.sql \ 44 rt_band.sql \ 44 45 $(NULL) 45 46 46 47 TEST_PROPS = \ -
raster/test/regress/rt_band.sql
diff -rupN postgis-old/raster/test/regress/rt_band.sql postgis-new/raster/test/regress/rt_band.sql
old new 1 SELECT ST_Value(ST_Band(ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '64BF', 123.4567, NULL), ARRAY[1]), 3, 3); 2 SELECT ST_Value(ST_Band(ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '64BF', 1234.567, NULL), 1), 3, 3); 3 SELECT ST_Value(ST_Band(ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '64BF', 1234.567, NULL)), 3, 3); 4 SELECT ST_Value( 5 ST_Band( 6 ST_AddBand( 7 ST_AddBand( 8 ST_AddBand( 9 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 10 , 1, '64BF', 1234.5678, NULL 11 ) 12 , '64BF', 987.654321, NULL 13 ) 14 , '64BF', 9876.54321, NULL 15 ), 16 ARRAY[1] 17 ), 18 3, 3); 19 SELECT ST_Value( 20 ST_Band( 21 ST_AddBand( 22 ST_AddBand( 23 ST_AddBand( 24 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 25 , 1, '64BF', 1234.5678, NULL 26 ) 27 , '64BF', 987.654321, NULL 28 ) 29 , '64BF', 9876.54321, NULL 30 ), 31 ARRAY[2] 32 ), 33 3, 3); 34 SELECT ST_Value( 35 ST_Band( 36 ST_AddBand( 37 ST_AddBand( 38 ST_AddBand( 39 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 40 , 1, '64BF', 1234.5678, NULL 41 ) 42 , '64BF', 987.654321, NULL 43 ) 44 , '64BF', 9876.54321, NULL 45 ), 46 ARRAY[3] 47 ), 48 3, 3); 49 SELECT ST_Value( 50 ST_Band( 51 ST_AddBand( 52 ST_AddBand( 53 ST_AddBand( 54 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 55 , 1, '64BF', 1234.5678, NULL 56 ) 57 , '64BF', 987.654321, NULL 58 ) 59 , '64BF', 9876.54321, NULL 60 ), 61 1 62 ), 63 3, 3); 64 SELECT ST_Value( 65 ST_Band( 66 ST_AddBand( 67 ST_AddBand( 68 ST_AddBand( 69 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 70 , 1, '64BF', 1234.5678, NULL 71 ) 72 , '64BF', 987.654321, NULL 73 ) 74 , '64BF', 9876.54321, NULL 75 ), 76 2 77 ), 78 3, 3); 79 SELECT ST_Value( 80 ST_Band( 81 ST_AddBand( 82 ST_AddBand( 83 ST_AddBand( 84 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 85 , 1, '64BF', 1234.5678, NULL 86 ) 87 , '64BF', 987.654321, NULL 88 ) 89 , '64BF', 9876.54321, NULL 90 ), 91 3 92 ), 93 3, 3); 94 SELECT ST_Value( 95 ST_Band( 96 ST_AddBand( 97 ST_AddBand( 98 ST_AddBand( 99 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 100 , 1, '64BF', 1234.5678, NULL 101 ) 102 , '64BF', 987.654321, NULL 103 ) 104 , '64BF', 9876.54321, NULL 105 ) 106 ), 107 3, 3); 108 SELECT ST_Value( 109 ST_Band( 110 ST_AddBand( 111 ST_AddBand( 112 ST_AddBand( 113 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 114 , 1, '64BF', 1234.5678, NULL 115 ) 116 , '64BF', 987.654321, NULL 117 ) 118 , '64BF', 9876.54321, NULL 119 ), 120 ARRAY[1,3] 121 ), 122 1, 3, 3); 123 SELECT ST_Value( 124 ST_Band( 125 ST_AddBand( 126 ST_AddBand( 127 ST_AddBand( 128 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 129 , 1, '64BF', 1234.5678, NULL 130 ) 131 , '64BF', 987.654321, NULL 132 ) 133 , '64BF', 9876.54321, NULL 134 ), 135 ARRAY[1,3] 136 ), 137 2, 3, 3); 138 SELECT ST_Value( 139 ST_Band( 140 ST_AddBand( 141 ST_AddBand( 142 ST_AddBand( 143 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 144 , 1, '64BF', 1234.5678, NULL 145 ) 146 , '64BF', 987.654321, NULL 147 ) 148 , '64BF', 9876.54321, NULL 149 ), 150 ARRAY[2,3] 151 ), 152 1, 3, 3); 153 SELECT ST_Value( 154 ST_Band( 155 ST_AddBand( 156 ST_AddBand( 157 ST_AddBand( 158 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 159 , 1, '64BF', 1234.5678, NULL 160 ) 161 , '64BF', 987.654321, NULL 162 ) 163 , '64BF', 9876.54321, NULL 164 ), 165 ARRAY[1,1] 166 ), 167 2, 3, 3); 168 SELECT ST_NumBands( 169 ST_Band( 170 ST_AddBand( 171 ST_AddBand( 172 ST_AddBand( 173 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 174 , 1, '64BF', 1234.5678, NULL 175 ) 176 , '64BF', 987.654321, NULL 177 ) 178 , '64BF', 9876.54321, NULL 179 ), 180 ARRAY[1,1,3,3] 181 ) 182 ); 183 SELECT ST_NumBands( 184 ST_Band( 185 ST_AddBand( 186 ST_AddBand( 187 ST_AddBand( 188 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 189 , 1, '64BF', 1234.5678, NULL 190 ) 191 , '64BF', 987.654321, NULL 192 ) 193 , '64BF', 9876.54321, NULL 194 ), 195 ARRAY[1,1,3] 196 ) 197 ); 198 SELECT ST_NumBands( 199 ST_Band( 200 ST_AddBand( 201 ST_AddBand( 202 ST_AddBand( 203 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 204 , 1, '64BF', 1234.5678, NULL 205 ) 206 , '64BF', 987.654321, NULL 207 ) 208 , '64BF', 9876.54321, NULL 209 ), 210 ARRAY[1,2] 211 ) 212 ); 213 SELECT ST_NumBands( 214 ST_Band( 215 ST_AddBand( 216 ST_AddBand( 217 ST_AddBand( 218 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 219 , 1, '64BF', 1234.5678, NULL 220 ) 221 , '64BF', 987.654321, NULL 222 ) 223 , '64BF', 9876.54321, NULL 224 ), 225 ARRAY[3] 226 ) 227 ); 228 SELECT ST_NumBands( 229 ST_Band( 230 ST_AddBand( 231 ST_AddBand( 232 ST_AddBand( 233 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 234 , 1, '64BF', 1234.5678, NULL 235 ) 236 , '64BF', 987.654321, NULL 237 ) 238 , '64BF', 9876.54321, NULL 239 ), 240 2 241 ) 242 ); 243 SELECT ST_NumBands( 244 ST_Band( 245 ST_AddBand( 246 ST_AddBand( 247 ST_AddBand( 248 ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) 249 , 1, '64BF', 1234.5678, NULL 250 ) 251 , '64BF', 987.654321, NULL 252 ) 253 , '64BF', 9876.54321, NULL 254 ) 255 ) 256 ); -
raster/test/regress/rt_band_expected
diff -rupN postgis-old/raster/test/regress/rt_band_expected postgis-new/raster/test/regress/rt_band_expected
old new 1 123.4567 2 1234.567 3 1234.567 4 1234.5678 5 987.654321 6 9876.54321 7 1234.5678 8 987.654321 9 9876.54321 10 1234.5678 11 1234.5678 12 9876.54321 13 987.654321 14 1234.5678 15 4 16 3 17 2 18 1 19 1 20 1
