rt_band cu_add_band(rt_raster raster, rt_pixtype pixtype, int hasnodata, double nodataval) { void* mem = NULL; int32_t bandNum = 0; size_t datasize = 0; rt_band band = NULL; uint16_t width = 0; uint16_t height = 0; width = rt_raster_get_width(raster); height = rt_raster_get_height(raster); datasize = rt_pixtype_size(pixtype) * width * height; mem = rtalloc(datasize); CU_ASSERT(mem != NULL); if (hasnodata) memset(mem, nodataval, datasize); else memset(mem, 0, datasize); band = rt_band_new_inline(width, height, pixtype, hasnodata, nodataval, mem); CU_ASSERT(band != NULL); rt_band_set_ownsdata_flag(band, 1); bandNum = rt_raster_add_band(raster, band, rt_raster_get_num_bands(raster)); CU_ASSERT(bandNum >= 0); return band; }
static void test_raster_replace_band() { rt_raster raster; rt_band band; rt_band rband; void* mem; size_t datasize; uint16_t width; uint16_t height; double nodata; raster = rt_raster_new(10, 10); CU_ASSERT(raster != NULL); /* or we're out of virtual memory */ band = cu_add_band(raster, PT_8BUI, 0, 0); CU_ASSERT(band != NULL); band = cu_add_band(raster, PT_8BUI, 1, 255); CU_ASSERT(band != NULL); width = rt_raster_get_width(raster); height = rt_raster_get_height(raster); datasize = rt_pixtype_size(PT_8BUI) * width * height; mem = rtalloc(datasize); band = rt_band_new_inline(width, height, PT_8BUI, 1, 1, mem); CU_ASSERT(band != NULL); rt_band_set_ownsdata_flag(band, 1); rband = rt_raster_replace_band(raster, band, 0); CU_ASSERT(rband != NULL); rt_band_get_nodata(rt_raster_get_band(raster, 0), &nodata); CU_ASSERT_DOUBLE_EQUAL(nodata, 1, DBL_EPSILON); rt_band_destroy(rband); cu_free_raster(raster); }
static void test_gdal_warp() { rt_pixtype pixtype = PT_64BF; rt_band band = NULL; rt_raster raster; rt_raster rast; uint32_t x; uint32_t width = 100; uint32_t y; uint32_t height = 100; double value = 0; char src_srs[] = "PROJCS[\"unnamed\",GEOGCS[\"unnamed ellipse\",DATUM[\"unknown\",SPHEROID[\"unnamed\",6370997,0]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],PROJECTION[\"Lambert_Azimuthal_Equal_Area\"],PARAMETER[\"latitude_of_center\",45],PARAMETER[\"longitude_of_center\",-100],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1],AUTHORITY[\"EPSG\",\"2163\"]]"; char dst_srs[] = "PROJCS[\"NAD83 / California Albers\",GEOGCS[\"NAD83\",DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],AUTHORITY[\"EPSG\",\"6269\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4269\"]],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PROJECTION[\"Albers_Conic_Equal_Area\"],PARAMETER[\"standard_parallel_1\",34],PARAMETER[\"standard_parallel_2\",40.5],PARAMETER[\"latitude_of_center\",0],PARAMETER[\"longitude_of_center\",-120],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",-4000000],AUTHORITY[\"EPSG\",\"3310\"],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]"; raster = rt_raster_new(width, height); CU_ASSERT(raster != NULL); /* or we're out of virtual memory */ band = cu_add_band(raster, pixtype, 1, 0); CU_ASSERT(band != NULL); rt_raster_set_offsets(raster, -500000, 600000); rt_raster_set_scale(raster, 1000, -1000); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { rt_band_set_pixel(band, x, y, (((double) x * y) + (x + y) + (x + y * x)) / (x + y + 1), NULL); } } rast = rt_raster_gdal_warp( raster, src_srs, dst_srs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, GRA_NearestNeighbour, -1 ); CU_ASSERT(rast != NULL); CU_ASSERT_EQUAL(rt_raster_get_width(rast), 122); CU_ASSERT_EQUAL(rt_raster_get_height(rast), 116); CU_ASSERT_NOT_EQUAL(rt_raster_get_num_bands(rast), 0); band = rt_raster_get_band(rast, 0); CU_ASSERT(band != NULL); CU_ASSERT(rt_band_get_hasnodata_flag(band)); rt_band_get_nodata(band, &value); CU_ASSERT_DOUBLE_EQUAL(value, 0., DBL_EPSILON); CU_ASSERT_EQUAL(rt_band_get_pixel(band, 0, 0, &value, NULL), ES_NONE); CU_ASSERT_DOUBLE_EQUAL(value, 0., DBL_EPSILON); cu_free_raster(rast); cu_free_raster(raster); }
static void test_gdal_rasterize() { rt_raster raster; char srs[] = "PROJCS[\"unnamed\",GEOGCS[\"unnamed ellipse\",DATUM[\"unknown\",SPHEROID[\"unnamed\",6370997,0]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],PROJECTION[\"Lambert_Azimuthal_Equal_Area\"],PARAMETER[\"latitude_of_center\",45],PARAMETER[\"longitude_of_center\",-100],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1],AUTHORITY[\"EPSG\",\"2163\"]]"; const char wkb_hex[] = "010300000001000000050000000000000080841ec100000000600122410000000080841ec100000000804f22410000000040e81dc100000000804f22410000000040e81dc100000000600122410000000080841ec10000000060012241"; const char *pos = wkb_hex; unsigned char *wkb = NULL; int wkb_len = 0; int i; double scale_x = 100; double scale_y = -100; rt_pixtype pixtype[] = {PT_8BUI}; double init[] = {0}; double value[] = {1}; double nodata[] = {0}; uint8_t nodata_mask[] = {1}; /* hex to byte */ wkb_len = (int) ceil(((double) strlen(wkb_hex)) / 2); wkb = (unsigned char *) rtalloc(sizeof(unsigned char) * wkb_len); for (i = 0; i < wkb_len; i++) { sscanf(pos, "%2hhx", &wkb[i]); pos += 2; } raster = rt_raster_gdal_rasterize( wkb, wkb_len, srs, 1, pixtype, init, value, nodata, nodata_mask, NULL, NULL, &scale_x, &scale_y, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); CU_ASSERT(raster != NULL); CU_ASSERT_EQUAL(rt_raster_get_width(raster), 100); CU_ASSERT_EQUAL(rt_raster_get_height(raster), 100); CU_ASSERT_NOT_EQUAL(rt_raster_get_num_bands(raster), 0); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_x_offset(raster), -500000, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_y_offset(raster), 600000, DBL_EPSILON); rtdealloc(wkb); cu_free_raster(raster); }
/** * n-raster iterator. * The raster returned should be freed by the caller * * @param itrset : set of rt_iterator objects. * @param itrcount : number of objects in itrset. * @param extenttype : type of extent for the output raster. * @param customextent : raster specifying custom extent. * is only used if extenttype is ET_CUSTOM. * @param pixtype : the desired pixel type of the output raster's band. * @param hasnodata : indicates if the band has nodata value * @param nodataval : the nodata value, will be appropriately * truncated to fit the pixtype size. * @param distancex : the number of pixels around the specified pixel * along the X axis * @param distancey : the number of pixels around the specified pixel * along the Y axis * @param mask : the object of mask * @param userarg : pointer to any argument that is passed as-is to callback. * @param callback : callback function for actual processing of pixel values. * @param *rtnraster : return one band raster from iterator process * * The callback function _must_ have the following signature. * * int FNAME(rt_iterator_arg arg, void *userarg, double *value, int *nodata) * * The callback function _must_ return zero (error) or non-zero (success) * indicating whether the function ran successfully. * The parameters passed to the callback function are as follows. * * - rt_iterator_arg arg: struct containing pixel values, NODATA flags and metadata * - void *userarg: NULL or calling function provides to rt_raster_iterator() for use by callback function * - double *value: value of pixel to be burned by rt_raster_iterator() * - int *nodata: flag (0 or 1) indicating that pixel to be burned is NODATA * * @return ES_NONE on success, ES_ERROR on error */ rt_errorstate rt_raster_iterator( rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int (*callback)( rt_iterator_arg arg, void *userarg, double *value, int *nodata ), rt_raster *rtnraster ) { /* output raster */ rt_raster rtnrast = NULL; /* output raster's band */ rt_band rtnband = NULL; /* working raster */ rt_raster rast = NULL; _rti_iterator_arg _param = NULL; int allnull = 0; int allempty = 0; int aligned = 0; double offset[4] = {0.}; rt_pixel npixels; int i = 0; int status = 0; int inextent = 0; int x = 0; int y = 0; int _x = 0; int _y = 0; int _width = 0; int _height = 0; double minval; double value; int isnodata; int nodata; RASTER_DEBUG(3, "Starting..."); assert(itrset != NULL && itrcount > 0); assert(rtnraster != NULL); /* init rtnraster to NULL */ *rtnraster = NULL; /* check that callback function is not NULL */ if (callback == NULL) { rterror("rt_raster_iterator: Callback function not provided"); return ES_ERROR; } /* check that custom extent is provided if extenttype = ET_CUSTOM */ if (extenttype == ET_CUSTOM && rt_raster_is_empty(customextent)) { rterror("rt_raster_iterator: Custom extent cannot be empty if extent type is ET_CUSTOM"); return ES_ERROR; } /* check that pixtype != PT_END */ if (pixtype == PT_END) { rterror("rt_raster_iterator: Pixel type cannot be PT_END"); return ES_ERROR; } /* initialize _param */ if ((_param = _rti_iterator_arg_init()) == NULL) { rterror("rt_raster_iterator: Could not initialize internal variables"); return ES_ERROR; } /* fill _param */ if (!_rti_iterator_arg_populate(_param, itrset, itrcount, distancex, distancey, &allnull, &allempty)) { rterror("rt_raster_iterator: Could not populate for internal variables"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } /* shortcut if all null, return NULL */ if (allnull == itrcount) { RASTER_DEBUG(3, "all rasters are NULL, returning NULL"); _rti_iterator_arg_destroy(_param); return ES_NONE; } /* shortcut if all empty, return empty raster */ else if (allempty == itrcount) { RASTER_DEBUG(3, "all rasters are empty, returning empty raster"); _rti_iterator_arg_destroy(_param); rtnrast = rt_raster_new(0, 0); if (rtnrast == NULL) { rterror("rt_raster_iterator: Could not create empty raster"); return ES_ERROR; } rt_raster_set_scale(rtnrast, 0, 0); *rtnraster = rtnrast; return ES_NONE; } /* check that all rasters are aligned */ RASTER_DEBUG(3, "checking alignment of all rasters"); rast = NULL; /* find raster to use as reference */ /* use custom if provided */ if (extenttype == ET_CUSTOM) { RASTER_DEBUG(4, "using custom extent as reference raster"); rast = customextent; } /* use first valid one in _param->raster */ else { for (i = 0; i < itrcount; i++) { if (!_param->isempty[i]) { RASTER_DEBUGF(4, "using raster at index %d as reference raster", i); rast = _param->raster[i]; break; } } } /* no rasters found, SHOULD NEVER BE HERE! */ if (rast == NULL) { rterror("rt_raster_iterator: Could not find reference raster to use for alignment tests"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } do { aligned = 1; /* check custom first if set. also skip if rasters are the same */ if (extenttype == ET_CUSTOM && rast != customextent) { if (rt_raster_same_alignment(rast, customextent, &aligned, NULL) != ES_NONE) { rterror("rt_raster_iterator: Could not test for alignment between reference raster and custom extent"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } RASTER_DEBUGF(5, "custom extent alignment: %d", aligned); if (!aligned) break; } for (i = 0; i < itrcount; i++) { /* skip NULL rasters and if rasters are the same */ if (_param->isempty[i] || rast == _param->raster[i]) continue; if (rt_raster_same_alignment(rast, _param->raster[i], &aligned, NULL) != ES_NONE) { rterror("rt_raster_iterator: Could not test for alignment between reference raster and raster %d", i); _rti_iterator_arg_destroy(_param); return ES_ERROR; } RASTER_DEBUGF(5, "raster at index %d alignment: %d", i, aligned); /* abort checking since a raster isn't aligned */ if (!aligned) break; } } while (0); /* not aligned, error */ if (!aligned) { rterror("rt_raster_iterator: The set of rasters provided (custom extent included, if appropriate) do not have the same alignment"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } /* use extenttype to build output raster (no bands though) */ i = -1; switch (extenttype) { case ET_INTERSECTION: case ET_UNION: /* make copy of first "real" raster */ rtnrast = rtalloc(sizeof(struct rt_raster_t)); if (rtnrast == NULL) { rterror("rt_raster_iterator: Could not allocate memory for output raster"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } for (i = 0; i < itrcount; i++) { if (!_param->isempty[i]) { memcpy(rtnrast, _param->raster[i], sizeof(struct rt_raster_serialized_t)); break; } } rtnrast->numBands = 0; rtnrast->bands = NULL; /* get extent of output raster */ rast = NULL; for (i = i + 1; i < itrcount; i++) { if (_param->isempty[i]) continue; status = rt_raster_from_two_rasters(rtnrast, _param->raster[i], extenttype, &rast, NULL); rtdealloc(rtnrast); if (rast == NULL || status != ES_NONE) { rterror("rt_raster_iterator: Could not compute %s extent of rasters", extenttype == ET_UNION ? "union" : "intersection" ); _rti_iterator_arg_destroy(_param); return ES_ERROR; } else if (rt_raster_is_empty(rast)) { rtinfo("rt_raster_iterator: Computed raster for %s extent is empty", extenttype == ET_UNION ? "union" : "intersection" ); _rti_iterator_arg_destroy(_param); *rtnraster = rast; return ES_NONE; } rtnrast = rast; rast = NULL; } break; /* first, second and last have similar checks and continue into custom */ case ET_FIRST: i = 0; case ET_SECOND: if (i < 0) { if (itrcount < 2) i = 0; else i = 1; } case ET_LAST: if (i < 0) i = itrcount - 1; /* input raster is null, return NULL */ if (_param->raster[i] == NULL) { RASTER_DEBUGF(3, "returning NULL as %s raster is NULL and extent type is ET_%s", (i == 0 ? "first" : (i == 1 ? "second" : "last")), (i == 0 ? "FIRST" : (i == 1 ? "SECOND" : "LAST")) ); _rti_iterator_arg_destroy(_param); return ES_NONE; } /* input raster is empty, return empty raster */ else if (_param->isempty[i]) { RASTER_DEBUGF(3, "returning empty raster as %s raster is empty and extent type is ET_%s", (i == 0 ? "first" : (i == 1 ? "second" : "last")), (i == 0 ? "FIRST" : (i == 1 ? "SECOND" : "LAST")) ); _rti_iterator_arg_destroy(_param); rtnrast = rt_raster_new(0, 0); if (rtnrast == NULL) { rterror("rt_raster_iterator: Could not create empty raster"); return ES_ERROR; } rt_raster_set_scale(rtnrast, 0, 0); *rtnraster = rtnrast; return ES_NONE; } /* copy the custom extent raster */ case ET_CUSTOM: rtnrast = rtalloc(sizeof(struct rt_raster_t)); if (rtnrast == NULL) { rterror("rt_raster_iterator: Could not allocate memory for output raster"); _rti_iterator_arg_destroy(_param); return ES_ERROR; } switch (extenttype) { case ET_CUSTOM: memcpy(rtnrast, customextent, sizeof(struct rt_raster_serialized_t)); break; /* first, second, last */ default: memcpy(rtnrast, _param->raster[i], sizeof(struct rt_raster_serialized_t)); break; } rtnrast->numBands = 0; rtnrast->bands = NULL; break; } _width = rt_raster_get_width(rtnrast); _height = rt_raster_get_height(rtnrast); RASTER_DEBUGF(4, "rtnrast (width, height, ulx, uly, scalex, scaley, skewx, skewy, srid) = (%d, %d, %f, %f, %f, %f, %f, %f, %d)", _width, _height, rt_raster_get_x_offset(rtnrast), rt_raster_get_y_offset(rtnrast), rt_raster_get_x_scale(rtnrast), rt_raster_get_y_scale(rtnrast), rt_raster_get_x_skew(rtnrast), rt_raster_get_y_skew(rtnrast), rt_raster_get_srid(rtnrast) ); /* init values and NODATA for use with empty rasters */ if (!_rti_iterator_arg_empty_init(_param)) { rterror("rt_raster_iterator: Could not initialize empty values and NODATA"); _rti_iterator_arg_destroy(_param); rt_raster_destroy(rtnrast); return ES_ERROR; } /* create output band */ if (rt_raster_generate_new_band( rtnrast, pixtype, nodataval, hasnodata, nodataval, 0 ) < 0) { rterror("rt_raster_iterator: Could not add new band to output raster"); _rti_iterator_arg_destroy(_param); rt_raster_destroy(rtnrast); return ES_ERROR; } /* get output band */ rtnband = rt_raster_get_band(rtnrast, 0); if (rtnband == NULL) { rterror("rt_raster_iterator: Could not get new band from output raster"); _rti_iterator_arg_destroy(_param); rt_raster_destroy(rtnrast); return ES_ERROR; } /* output band's minimum value */ minval = rt_band_get_min_value(rtnband); /* initialize argument for callback function */ if (!_rti_iterator_arg_callback_init(_param)) { rterror("rt_raster_iterator: Could not initialize callback function argument"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } /* fill _param->offset */ for (i = 0; i < itrcount; i++) { if (_param->isempty[i]) continue; status = rt_raster_from_two_rasters(rtnrast, _param->raster[i], ET_FIRST, &rast, offset); rtdealloc(rast); if (status != ES_NONE) { rterror("rt_raster_iterator: Could not compute raster offsets"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } _param->offset[i][0] = offset[2]; _param->offset[i][1] = offset[3]; RASTER_DEBUGF(4, "rast %d offset: %f %f", i, offset[2], offset[3]); } /* loop over each pixel (POI) of output raster */ /* _x,_y are for output raster */ /* x,y are for input raster */ for (_y = 0; _y < _height; _y++) { for (_x = 0; _x < _width; _x++) { RASTER_DEBUGF(4, "iterating output pixel (x, y) = (%d, %d)", _x, _y); _param->arg->dst_pixel[0] = _x; _param->arg->dst_pixel[1] = _y; /* loop through each input raster */ for (i = 0; i < itrcount; i++) { RASTER_DEBUGF(4, "raster %d", i); /* empty raster OR band does not exist and flag set to use NODATA OR band is NODATA */ if ( _param->isempty[i] || (_param->band.rtband[i] == NULL && itrset[i].nbnodata) || _param->band.isnodata[i] ) { RASTER_DEBUG(4, "empty raster, band does not exist or band is NODATA. using empty values and NODATA"); x = _x; y = _y; _param->arg->values[i] = _param->empty.values; _param->arg->nodata[i] = _param->empty.nodata; continue; } /* input raster's X,Y */ x = _x - (int) _param->offset[i][0]; y = _y - (int) _param->offset[i][1]; RASTER_DEBUGF(4, "source pixel (x, y) = (%d, %d)", x, y); _param->arg->src_pixel[i][0] = x; _param->arg->src_pixel[i][1] = y; /* neighborhood */ npixels = NULL; status = 0; if (distancex > 0 && distancey > 0) { RASTER_DEBUG(4, "getting neighborhood"); status = rt_band_get_nearest_pixel( _param->band.rtband[i], x, y, distancex, distancey, 1, &npixels ); if (status < 0) { rterror("rt_raster_iterator: Could not get pixel neighborhood"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } } /* get value of POI */ /* get pixel's value */ if ( (x >= 0 && x < _param->width[i]) && (y >= 0 && y < _param->height[i]) ) { RASTER_DEBUG(4, "getting value of POI"); if (rt_band_get_pixel( _param->band.rtband[i], x, y, &value, &isnodata ) != ES_NONE) { rterror("rt_raster_iterator: Could not get the pixel value of band"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } inextent = 1; } /* outside band extent, set to NODATA */ else { RASTER_DEBUG(4, "Outside band extent, setting value to NODATA"); /* has NODATA, use NODATA */ if (_param->band.hasnodata[i]) value = _param->band.nodataval[i]; /* no NODATA, use min possible value */ else value = _param->band.minval[i]; inextent = 0; isnodata = 1; } /* add pixel to neighborhood */ status++; if (status > 1) npixels = (rt_pixel) rtrealloc(npixels, sizeof(struct rt_pixel_t) * status); else npixels = (rt_pixel) rtalloc(sizeof(struct rt_pixel_t)); if (npixels == NULL) { rterror("rt_raster_iterator: Could not reallocate memory for neighborhood"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } npixels[status - 1].x = x; npixels[status - 1].y = y; npixels[status - 1].nodata = 1; npixels[status - 1].value = value; /* set nodata flag */ if ((!_param->band.hasnodata[i] && inextent) || !isnodata) { npixels[status - 1].nodata = 0; } RASTER_DEBUGF(4, "value, nodata: %f, %d", value, npixels[status - 1].nodata); /* convert set of rt_pixel to 2D array */ status = rt_pixel_set_to_array( npixels, status,mask, x, y, distancex, distancey, &(_param->arg->values[i]), &(_param->arg->nodata[i]), NULL, NULL ); rtdealloc(npixels); if (status != ES_NONE) { rterror("rt_raster_iterator: Could not create 2D array of neighborhood"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } } /* callback */ RASTER_DEBUG(4, "calling callback function"); value = 0; nodata = 0; status = callback(_param->arg, userarg, &value, &nodata); /* free memory from callback */ _rti_iterator_arg_callback_clean(_param); /* handle callback status */ if (status == 0) { rterror("rt_raster_iterator: Callback function returned an error"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } /* burn value to pixel */ status = 0; if (!nodata) { status = rt_band_set_pixel(rtnband, _x, _y, value, NULL); RASTER_DEBUGF(4, "burning pixel (%d, %d) with value: %f", _x, _y, value); } else if (!hasnodata) { status = rt_band_set_pixel(rtnband, _x, _y, minval, NULL); RASTER_DEBUGF(4, "burning pixel (%d, %d) with minval: %f", _x, _y, minval); } else { RASTER_DEBUGF(4, "NOT burning pixel (%d, %d)", _x, _y); } if (status != ES_NONE) { rterror("rt_raster_iterator: Could not set pixel value"); _rti_iterator_arg_destroy(_param); rt_band_destroy(rtnband); rt_raster_destroy(rtnrast); return ES_ERROR; } } } /* lots of cleanup */ _rti_iterator_arg_destroy(_param); *rtnraster = rtnrast; return ES_NONE; }
static int _rti_iterator_arg_populate( _rti_iterator_arg _param, rt_iterator itrset, uint16_t itrcount, uint16_t distancex, uint16_t distancey, int *allnull, int *allempty ) { int i = 0; int hasband = 0; _param->count = itrcount; _param->distance.x = distancex; _param->distance.y = distancey; _param->dimension.columns = distancex * 2 + 1; _param->dimension.rows = distancey * 2 + 1; /* allocate memory for children */ _param->raster = rtalloc(sizeof(rt_raster) * itrcount); _param->isempty = rtalloc(sizeof(int) * itrcount); _param->width = rtalloc(sizeof(int) * itrcount); _param->height = rtalloc(sizeof(int) * itrcount); _param->offset = rtalloc(sizeof(double *) * itrcount); _param->band.rtband = rtalloc(sizeof(rt_band) * itrcount); _param->band.hasnodata = rtalloc(sizeof(int) * itrcount); _param->band.isnodata = rtalloc(sizeof(int) * itrcount); _param->band.nodataval = rtalloc(sizeof(double) * itrcount); _param->band.minval = rtalloc(sizeof(double) * itrcount); if ( _param->raster == NULL || _param->isempty == NULL || _param->width == NULL || _param->height == NULL || _param->offset == NULL || _param->band.rtband == NULL || _param->band.hasnodata == NULL || _param->band.isnodata == NULL || _param->band.nodataval == NULL || _param->band.minval == NULL ) { rterror("_rti_iterator_arg_populate: Could not allocate memory for children of _rti_iterator_arg"); return 0; } *allnull = 0; *allempty = 0; /* check input rasters not empty, band # is valid copy raster pointers and set flags */ for (i = 0; i < itrcount; i++) { /* initialize elements */ _param->raster[i] = NULL; _param->isempty[i] = 0; _param->width[i] = 0; _param->height[i] = 0; _param->offset[i] = NULL; _param->band.rtband[i] = NULL; _param->band.hasnodata[i] = 0; _param->band.isnodata[i] = 0; _param->band.nodataval[i] = 0; _param->band.minval[i] = 0; /* set isempty */ if (itrset[i].raster == NULL) { _param->isempty[i] = 1; (*allnull)++; (*allempty)++; continue; } else if (rt_raster_is_empty(itrset[i].raster)) { _param->isempty[i] = 1; (*allempty)++; continue; } /* check band number */ hasband = rt_raster_has_band(itrset[i].raster, itrset[i].nband); if (!hasband) { if (!itrset[i].nbnodata) { rterror("_rti_iterator_arg_populate: Band %d not found for raster %d", itrset[i].nband, i); return 0; } else { RASTER_DEBUGF(4, "Band %d not found for raster %d. Using NODATA", itrset[i].nband, i); } } _param->raster[i] = itrset[i].raster; if (hasband) { _param->band.rtband[i] = rt_raster_get_band(itrset[i].raster, itrset[i].nband); if (_param->band.rtband[i] == NULL) { rterror("_rti_iterator_arg_populate: Could not get band %d for raster %d", itrset[i].nband, i); return 0; } /* hasnodata */ _param->band.hasnodata[i] = rt_band_get_hasnodata_flag(_param->band.rtband[i]); /* hasnodata = TRUE */ if (_param->band.hasnodata[i]) { /* nodataval */ rt_band_get_nodata(_param->band.rtband[i], &(_param->band.nodataval[i])); /* isnodata */ _param->band.isnodata[i] = rt_band_get_isnodata_flag(_param->band.rtband[i]); } /* hasnodata = FALSE */ else { /* minval */ _param->band.minval[i] = rt_band_get_min_value(_param->band.rtband[i]); } } /* width, height */ _param->width[i] = rt_raster_get_width(_param->raster[i]); _param->height[i] = rt_raster_get_height(_param->raster[i]); /* init offset */ _param->offset[i] = rtalloc(sizeof(double) * 2); if (_param->offset[i] == NULL) { rterror("_rti_iterator_arg_populate: Could not allocate memory for offsets"); return 0; } } return 1; }