PostGIS  2.1.10dev-r@@SVN_REVISION@@
rt_errorstate rt_raster_get_perimeter ( rt_raster  raster,
int  nband,
LWGEOM **  perimeter 
)

Get raster perimeter.

The perimeter is a 4 vertices (5 to be closed) single ring polygon bearing the raster's rotation and using projection coordinates.

Parameters
raster: the raster to get info from
nband: the band for the perimeter. 0-based
**perimeter: pointer to perimeter
Returns
ES_NONE if success, ES_ERROR if error

The perimeter is a 4 vertices (5 to be closed) single ring polygon bearing the raster's rotation and using projection coordinates.

Parameters
raster: the raster to get info from
nband: the band for the perimeter. 0-based value less than zero means all bands
**perimeter: pointer to perimeter
Returns
ES_NONE if success, ES_ERROR if error

Definition at line 14683 of file rt_api.c.

References _rti_raster_get_band_perimeter(), ovdump::band, ES_ERROR, ES_NONE, window::gt, rt_raster_t::height, lwpoly_as_lwgeom(), lwpoly_construct(), pixval::nband, ptarray_construct(), ptarray_set_point4d(), RASTER_DEBUGF, rt_band_get_isnodata_flag(), rt_raster_cell_to_geopoint(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_get_num_bands(), rt_raster_get_srid(), rt_raster_is_empty(), rtalloc(), rtdealloc(), rterror(), SRID_UNKNOWN, trim(), rt_raster_t::width, POINT4D::x, and POINT4D::y.

Referenced by RASTER_convex_hull(), and test_raster_perimeter().

14686  {
14687  rt_band band = NULL;
14688  int numband = 0;
14689  uint16_t *_nband = NULL;
14690  int i = 0;
14691  int j = 0;
14692  uint16_t _trim[4] = {0};
14693  uint16_t trim[4] = {0}; /* top, right, bottom, left */
14694  int isset[4] = {0};
14695  double gt[6] = {0.0};
14696  int srid = SRID_UNKNOWN;
14697 
14698  POINTARRAY *pts = NULL;
14699  POINT4D p4d;
14700  POINTARRAY **rings = NULL;
14701  LWPOLY* poly = NULL;
14702 
14703  assert(perimeter != NULL);
14704 
14705  *perimeter = NULL;
14706 
14707  /* empty raster, no perimeter */
14708  if (rt_raster_is_empty(raster))
14709  return ES_NONE;
14710 
14711  /* raster metadata */
14712  srid = rt_raster_get_srid(raster);
14714  numband = rt_raster_get_num_bands(raster);
14715 
14716  RASTER_DEBUGF(3, "rt_raster_get_perimeter: raster is %dx%d", raster->width, raster->height);
14717 
14718  /* nband < 0 means all bands */
14719  if (nband >= 0) {
14720  if (nband >= numband) {
14721  rterror("rt_raster_get_boundary: Band %d not found for raster", nband);
14722  return ES_ERROR;
14723  }
14724 
14725  numband = 1;
14726  }
14727  else
14728  nband = -1;
14729 
14730  RASTER_DEBUGF(3, "rt_raster_get_perimeter: nband, numband = %d, %d", nband, numband);
14731 
14732  _nband = rtalloc(sizeof(uint16_t) * numband);
14733  if (_nband == NULL) {
14734  rterror("rt_raster_get_boundary: Could not allocate memory for band indices");
14735  return ES_ERROR;
14736  }
14737 
14738  if (nband < 0) {
14739  for (i = 0; i < numband; i++)
14740  _nband[i] = i;
14741  }
14742  else
14743  _nband[0] = nband;
14744 
14745  for (i = 0; i < numband; i++) {
14746  band = rt_raster_get_band(raster, _nband[i]);
14747  if (band == NULL) {
14748  rterror("rt_raster_get_boundary: Could not get band at index %d", _nband[i]);
14749  rtdealloc(_nband);
14750  return ES_ERROR;
14751  }
14752 
14753  /* band is nodata */
14754  if (rt_band_get_isnodata_flag(band) != 0)
14755  continue;
14756 
14757  if (_rti_raster_get_band_perimeter(band, trim) != ES_NONE) {
14758  rterror("rt_raster_get_boundary: Could not get band perimeter");
14759  rtdealloc(_nband);
14760  return ES_ERROR;
14761  }
14762 
14763  for (j = 0; j < 4; j++) {
14764  if (!isset[j] || trim[j] < _trim[j]) {
14765  _trim[j] = trim[j];
14766  isset[j] = 1;
14767  }
14768  }
14769  }
14770 
14771  /* no longer needed */
14772  rtdealloc(_nband);
14773 
14774  /* check isset, just need to check one element */
14775  if (!isset[0]) {
14776  /* return NULL as bands are empty */
14777  return ES_NONE;
14778  }
14779 
14780  RASTER_DEBUGF(4, "trim = (%d, %d, %d, %d)",
14781  trim[0], trim[1], trim[2], trim[3]);
14782 
14783  /* only one ring */
14784  rings = (POINTARRAY **) rtalloc(sizeof (POINTARRAY*));
14785  if (!rings) {
14786  rterror("rt_raster_get_perimeter: Could not allocate memory for polygon ring");
14787  return ES_ERROR;
14788  }
14789  rings[0] = ptarray_construct(0, 0, 5);
14790  if (!rings[0]) {
14791  rterror("rt_raster_get_perimeter: Could not construct point array");
14792  return ES_ERROR;
14793  }
14794  pts = rings[0];
14795 
14796  /* Upper-left corner (first and last points) */
14798  raster,
14799  _trim[3], _trim[0],
14800  &p4d.x, &p4d.y,
14801  gt
14802  );
14803  ptarray_set_point4d(pts, 0, &p4d);
14804  ptarray_set_point4d(pts, 4, &p4d);
14805 
14806  /* Upper-right corner (we go clockwise) */
14808  raster,
14809  raster->width - _trim[1], _trim[0],
14810  &p4d.x, &p4d.y,
14811  gt
14812  );
14813  ptarray_set_point4d(pts, 1, &p4d);
14814 
14815  /* Lower-right corner */
14817  raster,
14818  raster->width - _trim[1], raster->height - _trim[2],
14819  &p4d.x, &p4d.y,
14820  gt
14821  );
14822  ptarray_set_point4d(pts, 2, &p4d);
14823 
14824  /* Lower-left corner */
14826  raster,
14827  _trim[3], raster->height - _trim[2],
14828  &p4d.x, &p4d.y,
14829  gt
14830  );
14831  ptarray_set_point4d(pts, 3, &p4d);
14832 
14833  poly = lwpoly_construct(srid, 0, 1, rings);
14834  *perimeter = lwpoly_as_lwgeom(poly);
14835 
14836  return ES_NONE;
14837 }
void ptarray_set_point4d(POINTARRAY *pa, int n, const POINT4D *p4d)
Definition: lwgeom_api.c:501
double x
Definition: liblwgeom.h:308
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_api.c:5677
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition: ptarray.c:49
void rtdealloc(void *mem)
Definition: rt_api.c:882
tuple gt
Definition: window.py:79
tuple band
Definition: ovdump.py:57
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_api.c:5661
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_api.c:2042
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:239
uint16_t height
Definition: rt_api.h:2227
rt_errorstate rt_raster_cell_to_geopoint(rt_raster raster, double xr, double yr, double *xw, double *yw, double *gt)
Convert an xr, yr raster point to an xw, yw point on map.
Definition: rt_api.c:6054
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_api.c:6005
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
static rt_errorstate _rti_raster_get_band_perimeter(rt_band band, uint16_t *trim)
Definition: rt_api.c:14540
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:29
tuple nband
Definition: pixval.py:52
uint16_t width
Definition: rt_api.h:2226
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
void * rtalloc(size_t size)
Raster core memory management functions.
Definition: rt_api.c:867
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_api.c:5686
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_api.c:8550
static char * trim(const char *input)
Definition: raster2pgsql.c:263
double y
Definition: liblwgeom.h:308

Here is the call graph for this function:

Here is the caller graph for this function: