Ticket #339: st_band.patch
| File st_band.patch, 14.9 KB (added by dustymugs, 13 months ago) |
|---|
-
raster/test/core/testapi.c
972 972 CHECK_EQUALS(flag, 1); 973 973 } 974 974 975 static void testRasterFromBand(rt_context ctx, rt_raster raster) { 976 uint32_t bandNums[] = {1,3}; 977 int lenBandNums = 2; 978 rt_raster rast; 979 980 rast = rt_raster_from_band(ctx, raster, bandNums, lenBandNums); 981 assert(rast); 982 983 CHECK(rast); 984 CHECK(!rt_raster_is_empty(ctx, rast)); 985 CHECK(!rt_raster_has_no_band(ctx, rast, 1)); 986 987 rt_raster_destroy(ctx, rast); 988 } 989 975 990 int 976 991 main() 977 992 { … … 1282 1297 printf("Testing band hasnodata flag\n"); 1283 1298 testBandHasNoData(ctx, band_64BF); 1284 1299 1300 printf("Testing rt_raster_from_band\n"); 1301 testRasterFromBand(ctx, raster); 1302 printf("Successfully tested rt_raster_from_band\n"); 1303 1285 1304 deepRelease(ctx, raster); 1286 1305 rt_context_destroy(ctx); 1287 1306 -
raster/test/regress/Makefile.in
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_expected
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 -
raster/test/regress/rt_band.sql
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/rt_pg/rtpostgis.sql.in.c
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/rt_pg/rt_pg.c
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 and TEXTOID */ 55 52 56 #define POSTGIS_RASTER_WARN_ON_TRUNCATION 53 57 54 58 /* … … 158 162 /* Raster analysis */ 159 163 Datum RASTER_mapAlgebra(PG_FUNCTION_ARGS); 160 164 165 /* create new raster from existing raster's bands */ 166 Datum RASTER_band(PG_FUNCTION_ARGS); 161 167 168 162 169 /* Replace function taken from http://ubuntuforums.org/showthread.php?s=aa6f015109fd7e4c7e30d2fd8b717497&t=141670&page=3 */ 163 170 /* --------------------------------------------------------------------------- 164 171 Name : replace - Search & replace a substring by another one. … … 2677 2684 PG_RETURN_POINTER(pgraster); 2678 2685 } 2679 2686 2687 /** 2688 * Return new raster from selected bands of existing raster through ST_Band. 2689 * second argument is an array of band numbers (1 based) 2690 */ 2691 PG_FUNCTION_INFO_V1(RASTER_band); 2692 Datum RASTER_band(PG_FUNCTION_ARGS) 2693 { 2694 rt_pgraster *pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 2695 rt_pgraster *pgrast; 2696 rt_raster raster; 2697 rt_raster rast; 2698 rt_context ctx = get_rt_context(fcinfo); 2699 2700 ArrayType *array; 2701 Oid etype; 2702 Datum *e; 2703 bool *nulls; 2704 int16 typlen; 2705 bool typbyval; 2706 char typalign; 2707 int ndims = 1; 2708 int *dims; 2709 int *lbs; 2710 2711 uint32_t *bandNums; 2712 uint32 idx = 0; 2713 int n; 2714 int i = 0; 2715 int j = 0; 2716 2717 raster = rt_raster_deserialize(ctx, pgraster); 2718 if (!raster) { 2719 elog(ERROR, "RASTER_band: Could not deserialize raster"); 2720 rt_context_destroy(ctx); 2721 PG_RETURN_NULL(); 2722 } 2723 2724 /* process bandNums */ 2725 if (PG_ARGISNULL(1)) { 2726 elog(ERROR, "RASTER_band: Band number must be provided"); 2727 rt_raster_destroy(ctx, raster); 2728 rt_context_destroy(ctx); 2729 PG_RETURN_NULL(); 2730 } 2731 2732 array = PG_GETARG_ARRAYTYPE_P(1); 2733 etype = ARR_ELEMTYPE(array); 2734 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign); 2735 2736 switch (etype) { 2737 case INT2OID: 2738 case INT4OID: 2739 break; 2740 default: 2741 elog(ERROR, "RASTER_band: Invalid data type for band numbers"); 2742 rt_raster_destroy(ctx, raster); 2743 rt_context_destroy(ctx); 2744 PG_RETURN_NULL(); 2745 break; 2746 } 2747 2748 ndims = ARR_NDIM(array); 2749 dims = ARR_DIMS(array); 2750 lbs = ARR_LBOUND(array); 2751 2752 deconstruct_array(array, etype, typlen, typbyval, typalign, &e, 2753 &nulls, &n); 2754 2755 bandNums = (uint32_t *) palloc(sizeof(uint32_t) * n); 2756 for (i = 0, j = 0; i < n; i++) { 2757 if (nulls[i]) 2758 continue; 2759 2760 switch (etype) { 2761 case INT2OID: 2762 idx = (uint32_t) DatumGetInt16(e[i]); 2763 break; 2764 case INT4OID: 2765 idx = (uint32_t) DatumGetInt32(e[i]); 2766 break; 2767 } 2768 2769 POSTGIS_RT_DEBUGF(3, "band idx (before): %d", idx); 2770 if (idx > pgraster->numBands || idx < 1) { 2771 pfree(bandNums); 2772 elog(ERROR, "RASTER_band: Invalid band number provided"); 2773 rt_raster_destroy(ctx, raster); 2774 rt_context_destroy(ctx); 2775 PG_RETURN_NULL(); 2776 } 2777 2778 bandNums[j] = idx - 1; 2779 POSTGIS_RT_DEBUGF(3, "bandNums[%d] = %d", j, bandNums[j]); 2780 j++; 2781 } 2782 2783 rast = rt_raster_from_band(ctx, raster, bandNums, j); 2784 pfree(bandNums); 2785 rt_raster_destroy(ctx, raster); 2786 if (!rast) { 2787 elog(ERROR, "RASTER_band: Could not create new raster"); 2788 rt_context_destroy(ctx); 2789 PG_RETURN_NULL(); 2790 } 2791 2792 pgrast = rt_raster_serialize(ctx, rast); 2793 rt_context_destroy(ctx); 2794 if (!pgrast) 2795 PG_RETURN_NULL(); 2796 2797 SET_VARSIZE(pgrast, pgrast->size); 2798 PG_RETURN_POINTER(pgrast); 2799 } 2800 2680 2801 /* ---------------------------------------------------------------- */ 2681 2802 /* Memory allocation / error reporting hooks */ 2682 2803 /* ---------------------------------------------------------------- */ -
raster/rt_core/rt_api.c
3618 3618 return rt_raster_add_band(ctx, torast, newband, toindex); 3619 3619 } 3620 3620 3621 /** 3622 * Construct a new rt_raster from an existing rt_raster and an array 3623 * of band numbers 3624 * 3625 * @param ctx : context, for thread safety 3626 * @param raster : the source raster 3627 * @param bandNums : array of band numbers to extract from source raster 3628 * and add to the new raster (0 based) 3629 * @param count : number of elements in bandNums 3630 * @return a new rt_raster or 0 on error 3631 * 3632 */ 3633 rt_raster 3634 rt_raster_from_band(rt_context ctx, rt_raster raster, 3635 uint32_t *bandNums, int count) { 3636 rt_raster rast = NULL; 3637 int i = 0; 3638 int idx; 3639 int32_t flag; 3640 3641 assert(NULL != ctx); 3642 assert(NULL != raster); 3643 assert(NULL != bandNums); 3644 3645 RASTER_DEBUGF(3, "rt_raster_from_band: source raster has %d bands", 3646 rt_raster_get_num_bands(ctx, raster)); 3647 3648 /* create new raster */ 3649 rast = rt_raster_new(ctx, raster->width, raster->height); 3650 if (!rast) { 3651 ctx->err("rt_raster_from_band: Out of memory allocating new raster\n"); 3652 return 0; 3653 } 3654 3655 /* copy bands */ 3656 for (i = 0; i < count; i++) { 3657 idx = bandNums[i]; 3658 flag = rt_raster_copy_band(ctx, rast, raster, idx, i); 3659 3660 if (flag < 0) { 3661 ctx->err("rt_raster_from_band: Unable to copy band\n"); 3662 rt_raster_destroy(ctx, rast); 3663 return 0; 3664 } 3665 3666 RASTER_DEBUGF(3, "rt_raster_from_band: band created at index %d", 3667 flag); 3668 } 3669 3670 RASTER_DEBUGF(3, "rt_raster_from_band: new raster has %d bands", 3671 rt_raster_get_num_bands(ctx, rast)); 3672 return rast; 3673 } -
raster/rt_core/rt_api.h
737 737 int32_t rt_raster_copy_band(rt_context ctx, rt_raster torast, 738 738 rt_raster fromrast, int fromindex, int toindex); 739 739 740 /** 741 * Construct a new rt_raster from an existing rt_raster and an array 742 * of band numbers 743 * 744 * @param ctx : context, for thread safety 745 * @param raster : the source raster 746 * @param bandNums : array of band numbers to extract from source raster 747 * and add to the new raster (0 based) 748 * @param count : number of elements in bandNums 749 * @return a new rt_raster or 0 on error 750 * 751 */ 752 rt_raster rt_raster_from_band(rt_context ctx, rt_raster raster, 753 uint32_t *bandNums, int count); 754 740 755 /*- utilities -------------------------------------------------------*/ 741 756 742 757 /* Set of functions to clamp double to int of different size
