PostGIS 3.6.2dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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 int32_t 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 */
207 if (rt_raster_is_empty(raster))
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 */
253 if (rt_band_get_isnodata_flag(band) != 0)
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}
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition lwpoly.c:43
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:369
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition lwgeom.c:329
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:51
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition rt_context.c:191
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:637
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition rt_raster.c:360
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:306
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition rt_band.c:865
@ ES_NONE
Definition librtcore.h:182
@ ES_ERROR
Definition librtcore.h:183
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition rt_raster.c:376
void rtdealloc(void *mem)
Definition rt_context.c:206
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition rt_raster.c:588
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition rt_raster.c:1240
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition rt_raster.c:385
nband
Definition pixval.py:54
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition rtrowdump.py:121
static char * trim(const char *input)
static rt_errorstate _rti_raster_get_band_perimeter(rt_band band, uint16_t *trim)
Definition rt_geometry.c:39
double x
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414

References _rti_raster_get_band_perimeter(), ES_ERROR, ES_NONE, lwpoly_as_lwgeom(), lwpoly_construct(), 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(), 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: