1378{
1386
1387 int numbands = 0;
1388 int width = 0;
1389 int height = 0;
1390 int32_t srid = 0;
1392
1394 int hasnodata = 0;
1395 double nodataval = 0;
1396
1398 int allpoint = 0;
1399
1400 ArrayType *array;
1401 Oid etype;
1402 Datum *e;
1403 bool *nulls;
1404 int16 typlen;
1405 bool typbyval;
1406 char typalign;
1407 int n = 0;
1408
1409 HeapTupleHeader tup;
1410 bool isnull;
1411 Datum tupv;
1412
1414 uint8_t gtype;
1416
1417 int i = 0;
1418 uint32_t j = 0;
1419 int noerr = 1;
1420
1421
1422 if (PG_ARGISNULL(0))
1423 PG_RETURN_NULL();
1424 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
1425
1426
1428 if (!raster) {
1429 PG_FREE_IF_COPY(pgraster, 0);
1430 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not deserialize raster");
1431 PG_RETURN_NULL();
1432 }
1433
1434
1440
1441
1442 if (PG_ARGISNULL(1)) {
1443 elog(NOTICE, "Band index cannot be NULL. Value must be 1-based. Returning original raster");
1445 PG_RETURN_POINTER(pgraster);
1446 }
1447
1448 nband = PG_GETARG_INT32(1);
1449 if (nband < 1 || nband > numbands) {
1450 elog(NOTICE, "Band index is invalid. Value must be 1-based. Returning original raster");
1452 PG_RETURN_POINTER(pgraster);
1453 }
1454
1455
1459 if (hasnodata)
1461
1462
1463 if (PG_ARGISNULL(2)) {
1464 elog(NOTICE, "No values to set. Returning original raster");
1466 PG_RETURN_POINTER(pgraster);
1467 }
1468
1469 array = PG_GETARG_ARRAYTYPE_P(2);
1470 etype = ARR_ELEMTYPE(array);
1471 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1472
1473 deconstruct_array(
1474 array,
1475 etype,
1476 typlen, typbyval, typalign,
1477 &e, &nulls, &n
1478 );
1479
1480 if (!n) {
1481 elog(NOTICE, "No values to set. Returning original raster");
1483 PG_RETURN_POINTER(pgraster);
1484 }
1485
1486
1488 if (arg == NULL) {
1490 PG_FREE_IF_COPY(pgraster, 0);
1491 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not initialize argument structure");
1492 PG_RETURN_NULL();
1493 }
1494
1496 if (arg->
gv == NULL) {
1499 PG_FREE_IF_COPY(pgraster, 0);
1500 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not allocate memory for geomval array");
1501 PG_RETURN_NULL();
1502 }
1503
1504
1506 for (i = 0; i < n; i++) {
1507 if (nulls[i])
1508 continue;
1509
1514
1515
1516 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
1517 if (NULL == tup) {
1520 PG_FREE_IF_COPY(pgraster, 0);
1521 elog(ERROR, "RASTER_setPixelValuesGeomval: Invalid argument for geomval at index %d", i);
1522 PG_RETURN_NULL();
1523 }
1524
1525
1527 tupv = GetAttributeByName(tup, "geom", &isnull);
1528 if (isnull) {
1529 elog(NOTICE, "First argument (geom) of geomval at index %d is NULL. Skipping", i);
1530 continue;
1531 }
1532
1538 PG_FREE_IF_COPY(pgraster, 0);
1539 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not deserialize geometry of geomval at index %d", i);
1540 PG_RETURN_NULL();
1541 }
1542
1543
1545 elog(NOTICE, "First argument (geom) of geomval at index %d is an empty geometry. Skipping", i);
1546 continue;
1547 }
1548
1549
1551 elog(NOTICE, "Geometry provided for geomval at index %d does not have the same SRID as the raster: %d. Returning original raster", i, srid);
1554 PG_RETURN_POINTER(pgraster);
1555 }
1556
1557
1562 }
1563
1564
1566
1567
1569 allpoint++;
1570
1571
1574
1575
1578 NULL,
1579 0,
1580 NULL,
1581 NULL,
1582 NULL,
1583 NULL,
1584 NULL,
1585 NULL,
1586 NULL,
1587 &(gt[1]),
1588 &(gt[5]),
1589 NULL,
1590 NULL,
1591 &(gt[0]),
1592 &(gt[3]),
1593 &(gt[2]),
1594 &(gt[4]),
1595 NULL);
1596
1597 pfree(wkb);
1601 }
1602
1606 PG_FREE_IF_COPY(pgraster, 0);
1607 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not rasterize geometry of geomval at index %d", i);
1608 PG_RETURN_NULL();
1609 }
1610
1611
1613
1614
1616 tupv = GetAttributeByName(tup, "val", &isnull);
1617 if (isnull) {
1618 elog(NOTICE, "Second argument (val) of geomval at index %d is NULL. Treating as NODATA", i);
1620 }
1621 else
1623
1625 }
1626
1627
1630 if (arg->
gv == NULL) {
1633 PG_FREE_IF_COPY(pgraster, 0);
1634 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not reallocate memory for geomval array");
1635 PG_RETURN_NULL();
1636 }
1637 }
1638
1639
1640 if (!PG_ARGISNULL(3))
1643
1644
1646 POSTGIS_RT_DEBUG(3,
"keepnodata = TRUE and band is NODATA. Not doing anything");
1647 }
1648
1649 else if (allpoint == arg->
ngv) {
1650 double igt[6] = {0};
1651 double xy[2] = {0};
1653 int isnodata = 0;
1654
1658
1659 POSTGIS_RT_DEBUG(3,
"all geometries are points, using direct to pixel method");
1660
1661
1663
1664
1665 for (i = 0; i < arg->
ngv; i++) {
1666
1668
1669
1670 for (j = 0; j < coll->
ngeoms; j++) {
1673
1677 PG_FREE_IF_COPY(pgraster, 0);
1678 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not process coordinates of point");
1679 PG_RETURN_NULL();
1680 }
1681
1682
1683 if (
1684 (xy[0] < 0 || xy[0] >= width) ||
1685 (xy[1] < 0 || xy[1] >= height)
1686 ) {
1687 elog(NOTICE, "Point is outside raster extent. Skipping");
1688 continue;
1689 }
1690
1691
1695 PG_FREE_IF_COPY(pgraster, 0);
1696 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not get pixel value");
1697 PG_RETURN_NULL();
1698 }
1699
1700
1702 continue;
1703
1704
1707 else
1709
1713 PG_FREE_IF_COPY(pgraster, 0);
1714 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not set pixel value");
1715 PG_RETURN_NULL();
1716 }
1717 }
1718 }
1719 }
1720
1721 else {
1723
1725
1726
1728 if (itrset == NULL) {
1731 PG_FREE_IF_COPY(pgraster, 0);
1732 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not allocate memory for iterator arguments");
1733 PG_RETURN_NULL();
1734 }
1735
1736
1740
1741
1742 for (i = 0, j = 1; i < arg->
ngv; i++, j++) {
1744 itrset[j].
nband = 0;
1746 }
1747
1748
1750 itrset, arg->
ngv + 1,
1752 pixtype,
1753 hasnodata, nodataval,
1754 0, 0,
1755 NULL,
1756 arg,
1758 &_raster
1759 );
1760 pfree(itrset);
1761
1765 PG_FREE_IF_COPY(pgraster, 0);
1766 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not run raster iterator function");
1767 PG_RETURN_NULL();
1768 }
1769
1770
1772 if (_band == NULL) {
1776 PG_FREE_IF_COPY(pgraster, 0);
1777 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not get band from working raster");
1778 PG_RETURN_NULL();
1779 }
1780
1782 if (_band == NULL) {
1786 PG_FREE_IF_COPY(pgraster, 0);
1787 elog(ERROR, "RASTER_setPixelValuesGeomval: Could not replace band in output raster");
1788 PG_RETURN_NULL();
1789 }
1790
1793 }
1794
1796
1799 PG_FREE_IF_COPY(pgraster, 0);
1800
1802
1803 if (!pgrtn)
1804 PG_RETURN_NULL();
1805
1806 SET_VARSIZE(pgrtn, pgrtn->
size);
1807 PG_RETURN_POINTER(pgrtn);
1808}
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
void lwgeom_free(LWGEOM *geom)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
#define LWSIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
lwvarlena_t * lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
rt_errorstate rt_raster_get_inverse_geotransform_matrix(rt_raster raster, double *gt, double *igt)
Get 6-element array of raster inverse geotransform matrix.
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw, yw map point to a xr, yr raster point.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
rt_band rt_raster_replace_band(rt_raster raster, rt_band band, int index)
Replace band at provided index with new band.
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
rt_raster rt_raster_gdal_rasterize(const unsigned char *wkb, uint32_t wkb_len, const char *srs, uint32_t num_bands, rt_pixtype *pixtype, double *init, double *value, double *nodata, uint8_t *hasnodata, int *width, int *height, double *scale_x, double *scale_y, double *ul_xw, double *ul_yw, double *grid_xw, double *grid_yw, double *skew_x, double *skew_y, char **options)
Return a raster of the provided geometry.
void rt_band_destroy(rt_band band)
Destroy a raster band.
uint16_t rt_raster_get_num_bands(rt_raster raster)
uint16_t rt_raster_get_height(rt_raster raster)
rt_errorstate rt_raster_iterator(rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
uint16_t rt_raster_get_width(rt_raster raster)
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
static void rtpg_setvaluesgv_arg_destroy(rtpg_setvaluesgv_arg arg)
static int rtpg_setvalues_geomval_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
static rtpg_setvaluesgv_arg rtpg_setvaluesgv_arg_init()
#define POSTGIS_RT_DEBUG(level, msg)
#define POSTGIS_RT_DEBUGF(level, msg,...)
rtpg_setvaluesgv_geomval gv
struct rtpg_setvaluesgv_geomval_t::@28 pixval