PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ rt_raster_get_perimeter()

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 value less than zero means all bands
**perimeter: pointer to perimeter
Returns
ES_NONE if success, ES_ERROR if error

Definition at line 182 of file rt_geometry.c.

185  {
186  rt_band band = NULL;
187  int numband = 0;
188  uint16_t *_nband = NULL;
189  int i = 0;
190  int j = 0;
191  uint16_t _trim[4] = {0};
192  uint16_t trim[4] = {0}; /* top, right, bottom, left */
193  int isset[4] = {0};
194  double gt[6] = {0.0};
195  int srid = SRID_UNKNOWN;
196 
197  POINTARRAY *pts = NULL;
198  POINT4D p4d;
199  POINTARRAY **rings = NULL;
200  LWPOLY* poly = NULL;
201 
202  assert(perimeter != NULL);
203 
204  *perimeter = NULL;
205 
206  /* empty raster, no perimeter */
208  return ES_NONE;
209 
210  /* raster metadata */
211  srid = rt_raster_get_srid(raster);
213  numband = rt_raster_get_num_bands(raster);
214 
215  RASTER_DEBUGF(3, "rt_raster_get_perimeter: raster is %dx%d", raster->width, raster->height);
216 
217  /* nband < 0 means all bands */
218  if (nband >= 0) {
219  if (nband >= numband) {
220  rterror("rt_raster_get_boundary: Band %d not found for raster", nband);
221  return ES_ERROR;
222  }
223 
224  numband = 1;
225  }
226  else
227  nband = -1;
228 
229  RASTER_DEBUGF(3, "rt_raster_get_perimeter: nband, numband = %d, %d", nband, numband);
230 
231  _nband = rtalloc(sizeof(uint16_t) * numband);
232  if (_nband == NULL) {
233  rterror("rt_raster_get_boundary: Could not allocate memory for band indices");
234  return ES_ERROR;
235  }
236 
237  if (nband < 0) {
238  for (i = 0; i < numband; i++)
239  _nband[i] = i;
240  }
241  else
242  _nband[0] = nband;
243 
244  for (i = 0; i < numband; i++) {
245  band = rt_raster_get_band(raster, _nband[i]);
246  if (band == NULL) {
247  rterror("rt_raster_get_boundary: Could not get band at index %d", _nband[i]);
248  rtdealloc(_nband);
249  return ES_ERROR;
250  }
251 
252  /* band is nodata */
254  continue;
255 
257  rterror("rt_raster_get_boundary: Could not get band perimeter");
258  rtdealloc(_nband);
259  return ES_ERROR;
260  }
261 
262  for (j = 0; j < 4; j++) {
263  if (!isset[j] || trim[j] < _trim[j]) {
264  _trim[j] = trim[j];
265  isset[j] = 1;
266  }
267  }
268  }
269 
270  /* no longer needed */
271  rtdealloc(_nband);
272 
273  /* check isset, just need to check one element */
274  if (!isset[0]) {
275  /* return NULL as bands are empty */
276  return ES_NONE;
277  }
278 
279  RASTER_DEBUGF(4, "trim = (%d, %d, %d, %d)",
280  trim[0], trim[1], trim[2], trim[3]);
281 
282  /* only one ring */
283  rings = (POINTARRAY **) rtalloc(sizeof (POINTARRAY*));
284  if (!rings) {
285  rterror("rt_raster_get_perimeter: Could not allocate memory for polygon ring");
286  return ES_ERROR;
287  }
288  rings[0] = ptarray_construct(0, 0, 5);
289  if (!rings[0]) {
290  rterror("rt_raster_get_perimeter: Could not construct point array");
291  return ES_ERROR;
292  }
293  pts = rings[0];
294 
295  /* Upper-left corner (first and last points) */
297  raster,
298  _trim[3], _trim[0],
299  &p4d.x, &p4d.y,
300  gt
301  );
302  ptarray_set_point4d(pts, 0, &p4d);
303  ptarray_set_point4d(pts, 4, &p4d);
304 
305  /* Upper-right corner (we go clockwise) */
307  raster,
308  raster->width - _trim[1], _trim[0],
309  &p4d.x, &p4d.y,
310  gt
311  );
312  ptarray_set_point4d(pts, 1, &p4d);
313 
314  /* Lower-right corner */
316  raster,
317  raster->width - _trim[1], raster->height - _trim[2],
318  &p4d.x, &p4d.y,
319  gt
320  );
321  ptarray_set_point4d(pts, 2, &p4d);
322 
323  /* Lower-left corner */
325  raster,
326  _trim[3], raster->height - _trim[2],
327  &p4d.x, &p4d.y,
328  gt
329  );
330  ptarray_set_point4d(pts, 3, &p4d);
331 
332  poly = lwpoly_construct(srid, 0, 1, rings);
333  *perimeter = lwpoly_as_lwgeom(poly);
334 
335  return ES_NONE;
336 }
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:320
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:62
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:43
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition: lwgeom_api.c:435
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:199
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:171
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_raster.c:755
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:356
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_band.c:714
@ ES_NONE
Definition: librtcore.h:180
@ ES_ERROR
Definition: librtcore.h:181
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
void rtdealloc(void *mem)
Definition: rt_context.c:186
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:706
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1334
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
band
Definition: ovdump.py:57
nband
Definition: pixval.py:52
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
gt
Definition: window.py:77
static char * trim(const char *input)
Definition: raster2pgsql.c:262
static rt_errorstate _rti_raster_get_band_perimeter(rt_band band, uint16_t *trim)
Definition: rt_geometry.c:39
double x
Definition: liblwgeom.h:355
double y
Definition: liblwgeom.h:355

References _rti_raster_get_band_perimeter(), ovdump::band, ES_ERROR, ES_NONE, window::gt, lwpoly_as_lwgeom(), lwpoly_construct(), pixval::nband, ptarray_construct(), ptarray_set_point4d(), rtrowdump::raster, 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(), POINT4D::x, and POINT4D::y.

Referenced by RASTER_convex_hull(), and test_raster_perimeter().

Here is the call graph for this function:
Here is the caller graph for this function: