PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum RASTER_dwithin ( PG_FUNCTION_ARGS  )

Definition at line 14140 of file rt_pg.c.

References distance(), ES_NONE, FALSE, rt_raster_serialized_t::numBands, POSTGIS_RT_DEBUGF, rtpixdump::rast, result, rt_raster_deserialize(), rt_raster_destroy(), rt_raster_get_num_bands(), rt_raster_get_srid(), and rt_raster_within_distance().

14141 {
14142  const int set_count = 2;
14143  rt_pgraster *pgrast[2];
14144  int pgrastpos[2] = {-1, -1};
14145  rt_raster rast[2] = {NULL};
14146  uint32_t bandindex[2] = {0};
14147  uint32_t hasbandindex[2] = {0};
14148  double distance = 0;
14149 
14150  uint32_t i;
14151  uint32_t j;
14152  uint32_t k;
14153  uint32_t numBands;
14154  int rtn;
14155  int result;
14156 
14157  for (i = 0, j = 0; i < set_count; i++) {
14158  /* pgrast is null, return null */
14159  if (PG_ARGISNULL(j)) {
14160  for (k = 0; k < i; k++) {
14161  rt_raster_destroy(rast[k]);
14162  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14163  }
14164  PG_RETURN_NULL();
14165  }
14166  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
14167  pgrastpos[i] = j;
14168  j++;
14169 
14170  /* raster */
14171  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
14172  if (!rast[i]) {
14173  for (k = 0; k <= i; k++) {
14174  if (k < i)
14175  rt_raster_destroy(rast[k]);
14176  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14177  }
14178  elog(ERROR, "RASTER_dwithin: Could not deserialize the %s raster", i < 1 ? "first" : "second");
14179  PG_RETURN_NULL();
14180  }
14181 
14182  /* numbands */
14183  numBands = rt_raster_get_num_bands(rast[i]);
14184  if (numBands < 1) {
14185  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
14186  if (i > 0) i++;
14187  for (k = 0; k < i; k++) {
14188  rt_raster_destroy(rast[k]);
14189  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14190  }
14191  PG_RETURN_NULL();
14192  }
14193 
14194  /* band index */
14195  if (!PG_ARGISNULL(j)) {
14196  bandindex[i] = PG_GETARG_INT32(j);
14197  if (bandindex[i] < 1 || bandindex[i] > numBands) {
14198  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
14199  if (i > 0) i++;
14200  for (k = 0; k < i; k++) {
14201  rt_raster_destroy(rast[k]);
14202  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14203  }
14204  PG_RETURN_NULL();
14205  }
14206  hasbandindex[i] = 1;
14207  }
14208  else
14209  hasbandindex[i] = 0;
14210  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
14211  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
14212  j++;
14213  }
14214 
14215  /* distance */
14216  if (PG_ARGISNULL(4)) {
14217  elog(NOTICE, "Distance cannot be NULL. Returning NULL");
14218  for (k = 0; k < set_count; k++) {
14219  rt_raster_destroy(rast[k]);
14220  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14221  }
14222  PG_RETURN_NULL();
14223  }
14224 
14225  distance = PG_GETARG_FLOAT8(4);
14226  if (distance < 0) {
14227  elog(NOTICE, "Distance cannot be less than zero. Returning NULL");
14228  for (k = 0; k < set_count; k++) {
14229  rt_raster_destroy(rast[k]);
14230  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14231  }
14232  PG_RETURN_NULL();
14233  }
14234 
14235  /* hasbandindex must be balanced */
14236  if (
14237  (hasbandindex[0] && !hasbandindex[1]) ||
14238  (!hasbandindex[0] && hasbandindex[1])
14239  ) {
14240  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
14241  for (k = 0; k < set_count; k++) {
14242  rt_raster_destroy(rast[k]);
14243  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14244  }
14245  PG_RETURN_NULL();
14246  }
14247 
14248  /* SRID must match */
14249  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
14250  for (k = 0; k < set_count; k++) {
14251  rt_raster_destroy(rast[k]);
14252  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14253  }
14254  elog(ERROR, "The two rasters provided have different SRIDs");
14255  PG_RETURN_NULL();
14256  }
14257 
14259  rast[0], (hasbandindex[0] ? bandindex[0] - 1 : -1),
14260  rast[1], (hasbandindex[1] ? bandindex[1] - 1 : -1),
14261  distance,
14262  &result
14263  );
14264  for (k = 0; k < set_count; k++) {
14265  rt_raster_destroy(rast[k]);
14266  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
14267  }
14268 
14269  if (rtn != ES_NONE) {
14270  elog(ERROR, "RASTER_dwithin: Could not test that the two rasters are within the specified distance of each other");
14271  PG_RETURN_NULL();
14272  }
14273 
14274  PG_RETURN_BOOL(result);
14275 }
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_api.c:5677
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
tuple rast
Definition: rtpixdump.py:62
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_api.c:5661
char ** result
Definition: liblwgeom.h:218
rt_errorstate rt_raster_within_distance(rt_raster rast1, int nband1, rt_raster rast2, int nband2, double distance, int *dwithin)
Return ES_ERROR if error occurred in function.
Definition: rt_api.c:12590
Datum distance(PG_FUNCTION_ARGS)
#define FALSE
Definition: dbfopen.c:169
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_api.c:8350

Here is the call graph for this function: