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 _rti_colormap_arg_destroy(_rti_colormap_arg arg) { int i = 0; if (arg->raster != NULL) { rt_band band = NULL; for (i = rt_raster_get_num_bands(arg->raster) - 1; i >= 0; i--) { band = rt_raster_get_band(arg->raster, i); if (band != NULL) rt_band_destroy(band); } rt_raster_destroy(arg->raster); } if (arg->nexpr) { for (i = 0; i < arg->nexpr; i++) { if (arg->expr[i] != NULL) rtdealloc(arg->expr[i]); } rtdealloc(arg->expr); } if (arg->npos) rtdealloc(arg->pos); rtdealloc(arg); arg = NULL; }
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_raster_clone() { rt_raster rast1; rt_raster rast2; rt_band band; int maxX = 5; int maxY = 5; double gt[6]; rast1 = rt_raster_new(maxX, maxY); CU_ASSERT(rast1 != NULL); rt_raster_set_offsets(rast1, 0, 0); rt_raster_set_scale(rast1, 1, -1); rt_raster_set_srid(rast1, 4326); band = cu_add_band(rast1, PT_32BUI, 1, 6); CU_ASSERT(band != NULL); /* clone without bands */ rast2 = rt_raster_clone(rast1, 0); CU_ASSERT(rast2 != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast2), 0); rt_raster_get_geotransform_matrix(rast2, gt); CU_ASSERT_EQUAL(rt_raster_get_srid(rast2), 4326); CU_ASSERT_DOUBLE_EQUAL(gt[0], 0, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(gt[1], 1, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(gt[2], 0, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(gt[3], 0, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(gt[4], 0, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(gt[5], -1, DBL_EPSILON); cu_free_raster(rast2); /* clone with bands */ rast2 = rt_raster_clone(rast1, 1); CU_ASSERT(rast2 != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast2), 1); cu_free_raster(rast2); cu_free_raster(rast1); }
void cu_free_raster(rt_raster raster) { uint16_t i; uint16_t nbands = rt_raster_get_num_bands(raster); for (i = 0; i < nbands; ++i) { rt_band band = rt_raster_get_band(raster, i); rt_band_destroy(band); } rt_raster_destroy(raster); raster = NULL; }
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); }
static void test_raster_metadata() { rt_raster raster = NULL; /* create raster */ raster = rt_raster_new(5, 5); CU_ASSERT(raster != NULL); /* # of bands */ CU_ASSERT_EQUAL(rt_raster_get_num_bands(raster), 0); /* has bands */ CU_ASSERT(!rt_raster_has_band(raster, 1)); /* upper-left corner */ rt_raster_set_offsets(raster, 30, -70); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_x_offset(raster), 30, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_y_offset(raster), -70, DBL_EPSILON); /* scale */ rt_raster_set_scale(raster, 10, -10); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_x_scale(raster), 10, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_y_scale(raster), -10, DBL_EPSILON); /* skew */ rt_raster_set_skews(raster, 0.0001, -0.05); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_x_skew(raster), 0.0001, DBL_EPSILON); CU_ASSERT_DOUBLE_EQUAL(rt_raster_get_y_skew(raster), -0.05, DBL_EPSILON); /* srid */ rt_raster_set_srid(raster, 4326); CU_ASSERT_EQUAL(rt_raster_get_srid(raster), 4326); rt_raster_set_srid(raster, 4269); CU_ASSERT_EQUAL(rt_raster_get_srid(raster), 4269); cu_free_raster(raster); }
static void test_gdal_to_raster() { rt_pixtype pixtype = PT_64BF; rt_band band = NULL; rt_raster raster; rt_raster rast; const uint32_t width = 100; const uint32_t height = 100; uint32_t x; uint32_t y; int v; double values[width][height]; int rtn = 0; double value; GDALDriverH gddrv = NULL; GDALDatasetH gdds = NULL; 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); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { values[x][y] = (((double) x * y) + (x + y) + (x + y * x)) / (x + y + 1); rt_band_set_pixel(band, x, y, values[x][y], NULL); } } gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv); CU_ASSERT(gddrv != NULL); CU_ASSERT(gdds != NULL); CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width); CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height); rast = rt_raster_from_gdal_dataset(gdds); CU_ASSERT(rast != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast), 1); band = rt_raster_get_band(rast, 0); CU_ASSERT(band != NULL); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { rtn = rt_band_get_pixel(band, x, y, &value, NULL); CU_ASSERT_EQUAL(rtn, ES_NONE); CU_ASSERT_DOUBLE_EQUAL(value, values[x][y], DBL_EPSILON); } } GDALClose(gdds); gdds = NULL; gddrv = NULL; cu_free_raster(rast); cu_free_raster(raster); raster = rt_raster_new(width, height); CU_ASSERT(raster != NULL); /* or we're out of virtual memory */ pixtype = PT_8BSI; band = cu_add_band(raster, pixtype, 1, 0); CU_ASSERT(band != NULL); v = -127; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { values[x][y] = v++; rt_band_set_pixel(band, x, y, values[x][y], NULL); if (v == 128) v = -127; } } gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv); CU_ASSERT(gddrv != NULL); CU_ASSERT(gdds != NULL); CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width); CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height); rast = rt_raster_from_gdal_dataset(gdds); CU_ASSERT(rast != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast), 1); band = rt_raster_get_band(rast, 0); CU_ASSERT(band != NULL); CU_ASSERT_EQUAL(rt_band_get_pixtype(band), PT_16BSI); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { rtn = rt_band_get_pixel(band, x, y, &value, NULL); CU_ASSERT_EQUAL(rtn, ES_NONE); CU_ASSERT_DOUBLE_EQUAL(value, values[x][y], 1.); } } GDALClose(gdds); cu_free_raster(rast); cu_free_raster(raster); }
/** * Returns a new raster with up to four 8BUI bands (RGBA) from * applying a colormap to the user-specified band of the * input raster. * * @param raster: input raster * @param nband: 0-based index of the band to process with colormap * @param colormap: rt_colormap object of colormap to apply to band * * @return new raster or NULL on error */ rt_raster rt_raster_colormap( rt_raster raster, int nband, rt_colormap colormap ) { _rti_colormap_arg arg = NULL; rt_raster rtnraster = NULL; rt_band band = NULL; int i = 0; int j = 0; int k = 0; assert(colormap != NULL); /* empty raster */ if (rt_raster_is_empty(raster)) return NULL; /* no colormap entries */ if (colormap->nentry < 1) { rterror("rt_raster_colormap: colormap must have at least one entry"); return NULL; } /* nband is valid */ if (!rt_raster_has_band(raster, nband)) { rterror("rt_raster_colormap: raster has no band at index %d", nband); return NULL; } band = rt_raster_get_band(raster, nband); if (band == NULL) { rterror("rt_raster_colormap: Could not get band at index %d", nband); return NULL; } /* init internal variables */ arg = _rti_colormap_arg_init(raster); if (arg == NULL) { rterror("rt_raster_colormap: Could not initialize internal variables"); return NULL; } /* handle NODATA */ if (rt_band_get_hasnodata_flag(band)) { arg->hasnodata = 1; rt_band_get_nodata(band, &(arg->nodataval)); } /* # of colors */ if (colormap->ncolor < 1) { rterror("rt_raster_colormap: At least one color must be provided"); _rti_colormap_arg_destroy(arg); return NULL; } else if (colormap->ncolor > 4) { rtinfo("More than four colors indicated. Using only the first four colors"); colormap->ncolor = 4; } /* find non-NODATA entries */ arg->npos = 0; arg->pos = rtalloc(sizeof(uint16_t) * colormap->nentry); if (arg->pos == NULL) { rterror("rt_raster_colormap: Could not allocate memory for valid entries"); _rti_colormap_arg_destroy(arg); return NULL; } for (i = 0, j = 0; i < colormap->nentry; i++) { /* special handling for NODATA entries */ if (colormap->entry[i].isnodata) { /* first NODATA entry found, use it */ if (arg->nodataentry == NULL) arg->nodataentry = &(colormap->entry[i]); else rtwarn("More than one colormap entry found for NODATA value. Only using first NOTDATA entry"); continue; } (arg->npos)++; arg->pos[j++] = i; } /* INTERPOLATE and only one non-NODATA entry */ if (colormap->method == CM_INTERPOLATE && arg->npos < 2) { rtinfo("Method INTERPOLATE requires at least two non-NODATA colormap entries. Using NEAREST instead"); colormap->method = CM_NEAREST; } /* NODATA entry but band has no NODATA value */ if (!arg->hasnodata && arg->nodataentry != NULL) { rtinfo("Band at index %d has no NODATA value. Ignoring NODATA entry", nband); arg->nodataentry = NULL; } /* allocate expr */ arg->nexpr = arg->npos; /* INTERPOLATE needs one less than the number of entries */ if (colormap->method == CM_INTERPOLATE) arg->nexpr -= 1; /* EXACT requires a no matching expression */ else if (colormap->method == CM_EXACT) arg->nexpr += 1; /* NODATA entry exists, add expression */ if (arg->nodataentry != NULL) arg->nexpr += 1; arg->expr = rtalloc(sizeof(rt_reclassexpr) * arg->nexpr); if (arg->expr == NULL) { rterror("rt_raster_colormap: Could not allocate memory for reclass expressions"); _rti_colormap_arg_destroy(arg); return NULL; } RASTER_DEBUGF(4, "nexpr = %d", arg->nexpr); RASTER_DEBUGF(4, "expr @ %p", arg->expr); for (i = 0; i < arg->nexpr; i++) { arg->expr[i] = rtalloc(sizeof(struct rt_reclassexpr_t)); if (arg->expr[i] == NULL) { rterror("rt_raster_colormap: Could not allocate memory for reclass expression"); _rti_colormap_arg_destroy(arg); return NULL; } } /* reclassify bands */ /* by # of colors */ for (i = 0; i < colormap->ncolor; i++) { k = 0; /* handle NODATA entry first */ if (arg->nodataentry != NULL) { arg->expr[k]->src.min = arg->nodataentry->value; arg->expr[k]->src.max = arg->nodataentry->value; arg->expr[k]->src.inc_min = 1; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_min = 0; arg->expr[k]->src.exc_max = 0; arg->expr[k]->dst.min = arg->nodataentry->color[i]; arg->expr[k]->dst.max = arg->nodataentry->color[i]; arg->expr[k]->dst.inc_min = 1; arg->expr[k]->dst.inc_max = 1; arg->expr[k]->dst.exc_min = 0; arg->expr[k]->dst.exc_max = 0; RASTER_DEBUGF(4, "NODATA expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->src.min, arg->expr[k]->src.max, arg->expr[k]->src.inc_min, arg->expr[k]->src.inc_max, arg->expr[k]->src.exc_min, arg->expr[k]->src.exc_max ); RASTER_DEBUGF(4, "NODATA expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->dst.min, arg->expr[k]->dst.max, arg->expr[k]->dst.inc_min, arg->expr[k]->dst.inc_max, arg->expr[k]->dst.exc_min, arg->expr[k]->dst.exc_max ); k++; } /* by non-NODATA entry */ for (j = 0; j < arg->npos; j++) { if (colormap->method == CM_INTERPOLATE) { if (j == arg->npos - 1) continue; arg->expr[k]->src.min = colormap->entry[arg->pos[j + 1]].value; arg->expr[k]->src.inc_min = 1; arg->expr[k]->src.exc_min = 0; arg->expr[k]->src.max = colormap->entry[arg->pos[j]].value; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_max = 0; arg->expr[k]->dst.min = colormap->entry[arg->pos[j + 1]].color[i]; arg->expr[k]->dst.max = colormap->entry[arg->pos[j]].color[i]; arg->expr[k]->dst.inc_min = 1; arg->expr[k]->dst.exc_min = 0; arg->expr[k]->dst.inc_max = 1; arg->expr[k]->dst.exc_max = 0; } else if (colormap->method == CM_NEAREST) { /* NOT last entry */ if (j != arg->npos - 1) { arg->expr[k]->src.min = ((colormap->entry[arg->pos[j]].value - colormap->entry[arg->pos[j + 1]].value) / 2.) + colormap->entry[arg->pos[j + 1]].value; arg->expr[k]->src.inc_min = 0; arg->expr[k]->src.exc_min = 0; } /* last entry */ else { arg->expr[k]->src.min = colormap->entry[arg->pos[j]].value; arg->expr[k]->src.inc_min = 1; arg->expr[k]->src.exc_min = 1; } /* NOT first entry */ if (j > 0) { arg->expr[k]->src.max = arg->expr[k - 1]->src.min; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_max = 0; } /* first entry */ else { arg->expr[k]->src.max = colormap->entry[arg->pos[j]].value; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_max = 1; } arg->expr[k]->dst.min = colormap->entry[arg->pos[j]].color[i]; arg->expr[k]->dst.inc_min = 1; arg->expr[k]->dst.exc_min = 0; arg->expr[k]->dst.max = colormap->entry[arg->pos[j]].color[i]; arg->expr[k]->dst.inc_max = 1; arg->expr[k]->dst.exc_max = 0; } else if (colormap->method == CM_EXACT) { arg->expr[k]->src.min = colormap->entry[arg->pos[j]].value; arg->expr[k]->src.inc_min = 1; arg->expr[k]->src.exc_min = 0; arg->expr[k]->src.max = colormap->entry[arg->pos[j]].value; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_max = 0; arg->expr[k]->dst.min = colormap->entry[arg->pos[j]].color[i]; arg->expr[k]->dst.inc_min = 1; arg->expr[k]->dst.exc_min = 0; arg->expr[k]->dst.max = colormap->entry[arg->pos[j]].color[i]; arg->expr[k]->dst.inc_max = 1; arg->expr[k]->dst.exc_max = 0; } RASTER_DEBUGF(4, "expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->src.min, arg->expr[k]->src.max, arg->expr[k]->src.inc_min, arg->expr[k]->src.inc_max, arg->expr[k]->src.exc_min, arg->expr[k]->src.exc_max ); RASTER_DEBUGF(4, "expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->dst.min, arg->expr[k]->dst.max, arg->expr[k]->dst.inc_min, arg->expr[k]->dst.inc_max, arg->expr[k]->dst.exc_min, arg->expr[k]->dst.exc_max ); k++; } /* EXACT has one last expression for catching all uncaught values */ if (colormap->method == CM_EXACT) { arg->expr[k]->src.min = 0; arg->expr[k]->src.inc_min = 1; arg->expr[k]->src.exc_min = 1; arg->expr[k]->src.max = 0; arg->expr[k]->src.inc_max = 1; arg->expr[k]->src.exc_max = 1; arg->expr[k]->dst.min = 0; arg->expr[k]->dst.inc_min = 1; arg->expr[k]->dst.exc_min = 0; arg->expr[k]->dst.max = 0; arg->expr[k]->dst.inc_max = 1; arg->expr[k]->dst.exc_max = 0; RASTER_DEBUGF(4, "expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->src.min, arg->expr[k]->src.max, arg->expr[k]->src.inc_min, arg->expr[k]->src.inc_max, arg->expr[k]->src.exc_min, arg->expr[k]->src.exc_max ); RASTER_DEBUGF(4, "expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)", k, arg->expr[k]->dst.min, arg->expr[k]->dst.max, arg->expr[k]->dst.inc_min, arg->expr[k]->dst.inc_max, arg->expr[k]->dst.exc_min, arg->expr[k]->dst.exc_max ); k++; } /* call rt_band_reclass */ arg->band = rt_band_reclass(band, PT_8BUI, 0, 0, arg->expr, arg->nexpr); if (arg->band == NULL) { rterror("rt_raster_colormap: Could not reclassify band"); _rti_colormap_arg_destroy(arg); return NULL; } /* add reclassified band to raster */ if (rt_raster_add_band(arg->raster, arg->band, rt_raster_get_num_bands(arg->raster)) < 0) { rterror("rt_raster_colormap: Could not add reclassified band to output raster"); _rti_colormap_arg_destroy(arg); return NULL; } } rtnraster = arg->raster; arg->raster = NULL; _rti_colormap_arg_destroy(arg); return rtnraster; }
Datum RASTER_dwithin(PG_FUNCTION_ARGS) { const int set_count = 2; rt_pgraster *pgrast[2]; int pgrastpos[2] = {-1, -1}; rt_raster rast[2] = {NULL}; uint32_t bandindex[2] = {0}; uint32_t hasbandindex[2] = {0}; double distance = 0; uint32_t i; uint32_t j; uint32_t k; uint32_t numBands; int rtn; int result; for (i = 0, j = 0; i < set_count; i++) { /* pgrast is null, return null */ if (PG_ARGISNULL(j)) { for (k = 0; k < i; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j)); pgrastpos[i] = j; j++; /* raster */ rast[i] = rt_raster_deserialize(pgrast[i], FALSE); if (!rast[i]) { for (k = 0; k <= i; k++) { if (k < i) rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } elog(ERROR, "RASTER_dwithin: Could not deserialize the %s raster", i < 1 ? "first" : "second"); PG_RETURN_NULL(); } /* numbands */ numBands = rt_raster_get_num_bands(rast[i]); if (numBands < 1) { elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second"); if (i > 0) i++; for (k = 0; k < i; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } /* band index */ if (!PG_ARGISNULL(j)) { bandindex[i] = PG_GETARG_INT32(j); if (bandindex[i] < 1 || bandindex[i] > numBands) { elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second"); if (i > 0) i++; for (k = 0; k < i; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } hasbandindex[i] = 1; } else hasbandindex[i] = 0; POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]); POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]); j++; } /* distance */ if (PG_ARGISNULL(4)) { elog(NOTICE, "Distance cannot be NULL. Returning NULL"); for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } distance = PG_GETARG_FLOAT8(4); if (distance < 0) { elog(NOTICE, "Distance cannot be less than zero. Returning NULL"); for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } /* hasbandindex must be balanced */ if ( (hasbandindex[0] && !hasbandindex[1]) || (!hasbandindex[0] && hasbandindex[1]) ) { elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided"); for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } PG_RETURN_NULL(); } /* SRID must match */ if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) { for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } elog(ERROR, "The two rasters provided have different SRIDs"); PG_RETURN_NULL(); } rtn = rt_raster_within_distance( rast[0], (hasbandindex[0] ? bandindex[0] - 1 : -1), rast[1], (hasbandindex[1] ? bandindex[1] - 1 : -1), distance, &result ); for (k = 0; k < set_count; k++) { rt_raster_destroy(rast[k]); PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]); } if (rtn != ES_NONE) { elog(ERROR, "RASTER_dwithin: Could not test that the two rasters are within the specified distance of each other"); PG_RETURN_NULL(); } PG_RETURN_BOOL(result); }