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

◆ RASTER_mapAlgebra2()

Datum RASTER_mapAlgebra2 ( PG_FUNCTION_ARGS  )

Definition at line 6249 of file rtpg_mapalgebra.c.

6250{
6251 const uint32_t set_count = 2;
6252 rt_pgraster *pgrast[2] = { NULL, NULL };
6253 int pgrastpos[2] = {-1, -1};
6254 rt_pgraster *pgrtn;
6255 rt_raster rast[2] = {NULL};
6256 int _isempty[2] = {0};
6257 uint32_t bandindex[2] = {0};
6258 rt_raster _rast[2] = {NULL};
6259 rt_band _band[2] = {NULL};
6260 int _hasnodata[2] = {0};
6261 double _nodataval[2] = {0};
6262 double _offset[4] = {0.};
6263 double _rastoffset[2][4] = {{0.}};
6264 int _haspixel[2] = {0};
6265 double _pixel[2] = {0};
6266 int _pos[2][2] = {{0}};
6267 uint16_t _dim[2][2] = {{0}};
6268
6269 char *pixtypename = NULL;
6270 rt_pixtype pixtype = PT_END;
6271 char *extenttypename = NULL;
6272 rt_extenttype extenttype = ET_INTERSECTION;
6273
6274 rt_raster raster = NULL;
6275 rt_band band = NULL;
6276 uint16_t dim[2] = {0};
6277 int haspixel = 0;
6278 double pixel = 0.;
6279 double nodataval = 0;
6280 double gt[6] = {0.};
6281
6282 Oid calltype = InvalidOid;
6283
6284 const uint32_t spi_count = 3;
6285 uint16_t spi_exprpos[3] = {4, 7, 8};
6286 uint32_t spi_argcount[3] = {0};
6287 char *expr = NULL;
6288 char *sql = NULL;
6289 SPIPlanPtr spi_plan[3] = {NULL};
6290 uint16_t spi_empty = 0;
6291 Oid *argtype = NULL;
6292 uint8_t argpos[3][8] = {{0}};
6293 char *argkw[] = {"[rast1.x]", "[rast1.y]", "[rast1.val]", "[rast1]", "[rast2.x]", "[rast2.y]", "[rast2.val]", "[rast2]"};
6294 Datum values[ARGKWCOUNT];
6295 char nulls[ARGKWCOUNT];
6296 TupleDesc tupdesc;
6297 SPITupleTable *tuptable = NULL;
6298 HeapTuple tuple;
6299 Datum datum;
6300 bool isnull = FALSE;
6301 int hasargval[3] = {0};
6302 double argval[3] = {0.};
6303 int hasnodatanodataval = 0;
6304 double nodatanodataval = 0;
6305 int isnodata = 0;
6306
6307 Oid ufc_noid = InvalidOid;
6308 FmgrInfo ufl_info;
6309 LOCAL_FCINFO(ufc_info, FUNC_MAX_ARGS); /* Could be optimized */
6310
6311 int ufc_nullcount = 0;
6312
6313 int idx = 0;
6314 uint32_t i = 0;
6315 uint32_t j = 0;
6316 uint32_t k = 0;
6317 uint32_t x = 0;
6318 uint32_t y = 0;
6319 int _x = 0;
6320 int _y = 0;
6321 int err;
6322 int aligned = 0;
6323 int len = 0;
6324
6325 POSTGIS_RT_DEBUG(3, "Starting RASTER_mapAlgebra2");
6326
6327 for (i = 0, j = 0; i < set_count; i++) {
6328 if (!PG_ARGISNULL(j)) {
6329 pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
6330 pgrastpos[i] = j;
6331 j++;
6332
6333 /* raster */
6334 rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
6335 if (!rast[i]) {
6336 for (k = 0; k <= i; k++) {
6337 if (k < i && rast[k] != NULL)
6338 rt_raster_destroy(rast[k]);
6339 if (pgrastpos[k] != -1)
6340 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6341 }
6342 elog(ERROR, "RASTER_mapAlgebra2: Could not deserialize the %s raster", i < 1 ? "first" : "second");
6343 PG_RETURN_NULL();
6344 }
6345
6346 /* empty */
6347 _isempty[i] = rt_raster_is_empty(rast[i]);
6348
6349 /* band index */
6350 if (!PG_ARGISNULL(j)) {
6351 bandindex[i] = PG_GETARG_INT32(j);
6352 }
6353 j++;
6354 }
6355 else {
6356 _isempty[i] = 1;
6357 j += 2;
6358 }
6359
6360 POSTGIS_RT_DEBUGF(3, "_isempty[%d] = %d", i, _isempty[i]);
6361 }
6362
6363 /* both rasters are NULL */
6364 if (rast[0] == NULL && rast[1] == NULL) {
6365 elog(NOTICE, "The two rasters provided are NULL. Returning NULL");
6366 for (k = 0; k < set_count; k++) {
6367 if (pgrastpos[k] != -1)
6368 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6369 }
6370 PG_RETURN_NULL();
6371 }
6372
6373 /* both rasters are empty */
6374 if (_isempty[0] && _isempty[1]) {
6375 elog(NOTICE, "The two rasters provided are empty. Returning empty raster");
6376
6377 raster = rt_raster_new(0, 0);
6378 if (raster == NULL) {
6379 for (k = 0; k < set_count; k++) {
6380 if (rast[k] != NULL)
6381 rt_raster_destroy(rast[k]);
6382 if (pgrastpos[k] != -1)
6383 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6384 }
6385 elog(ERROR, "RASTER_mapAlgebra2: Could not create empty raster");
6386 PG_RETURN_NULL();
6387 }
6388 rt_raster_set_scale(raster, 0, 0);
6389
6390 pgrtn = rt_raster_serialize(raster);
6391 rt_raster_destroy(raster);
6392 if (!pgrtn)
6393 PG_RETURN_NULL();
6394
6395 SET_VARSIZE(pgrtn, pgrtn->size);
6396 PG_RETURN_POINTER(pgrtn);
6397 }
6398
6399 /* replace the empty or NULL raster with one matching the other */
6400 if (
6401 (rast[0] == NULL || _isempty[0]) ||
6402 (rast[1] == NULL || _isempty[1])
6403 ) {
6404 /* first raster is empty */
6405 if (rast[0] == NULL || _isempty[0]) {
6406 i = 0;
6407 j = 1;
6408 }
6409 /* second raster is empty */
6410 else {
6411 i = 1;
6412 j = 0;
6413 }
6414
6415 _rast[j] = rast[j];
6416
6417 /* raster is empty, destroy it */
6418 if (_rast[i] != NULL)
6419 rt_raster_destroy(_rast[i]);
6420
6421 _dim[i][0] = rt_raster_get_width(_rast[j]);
6422 _dim[i][1] = rt_raster_get_height(_rast[j]);
6423 _dim[j][0] = rt_raster_get_width(_rast[j]);
6424 _dim[j][1] = rt_raster_get_height(_rast[j]);
6425
6426 _rast[i] = rt_raster_new(
6427 _dim[j][0],
6428 _dim[j][1]
6429 );
6430 if (_rast[i] == NULL) {
6431 rt_raster_destroy(_rast[j]);
6432 for (k = 0; k < set_count; k++) {
6433 if (pgrastpos[k] != -1)
6434 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6435 }
6436 elog(ERROR, "RASTER_mapAlgebra2: Could not create NODATA raster");
6437 PG_RETURN_NULL();
6438 }
6439 rt_raster_set_srid(_rast[i], rt_raster_get_srid(_rast[j]));
6440
6443 }
6444 else {
6445 _rast[0] = rast[0];
6446 _dim[0][0] = rt_raster_get_width(_rast[0]);
6447 _dim[0][1] = rt_raster_get_height(_rast[0]);
6448
6449 _rast[1] = rast[1];
6450 _dim[1][0] = rt_raster_get_width(_rast[1]);
6451 _dim[1][1] = rt_raster_get_height(_rast[1]);
6452 }
6453
6454 /* SRID must match */
6455 /*
6456 if (rt_raster_get_srid(_rast[0]) != rt_raster_get_srid(_rast[1])) {
6457 elog(NOTICE, "The two rasters provided have different SRIDs. Returning NULL");
6458 for (k = 0; k < set_count; k++) {
6459 if (_rast[k] != NULL)
6460 rt_raster_destroy(_rast[k]);
6461 if (pgrastpos[k] != -1)
6462 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6463 }
6464 PG_RETURN_NULL();
6465 }
6466 */
6467
6468 /* same alignment */
6469 if (rt_raster_same_alignment(_rast[0], _rast[1], &aligned, NULL) != ES_NONE) {
6470 for (k = 0; k < set_count; k++) {
6471 if (_rast[k] != NULL)
6472 rt_raster_destroy(_rast[k]);
6473 if (pgrastpos[k] != -1)
6474 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6475 }
6476 elog(ERROR, "RASTER_mapAlgebra2: Could not test for alignment on the two rasters");
6477 PG_RETURN_NULL();
6478 }
6479 if (!aligned) {
6480 elog(NOTICE, "The two rasters provided do not have the same alignment. Returning NULL");
6481 for (k = 0; k < set_count; k++) {
6482 if (_rast[k] != NULL)
6483 rt_raster_destroy(_rast[k]);
6484 if (pgrastpos[k] != -1)
6485 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6486 }
6487 PG_RETURN_NULL();
6488 }
6489
6490 /* pixel type */
6491 if (!PG_ARGISNULL(5)) {
6492 pixtypename = text_to_cstring(PG_GETARG_TEXT_P(5));
6493 /* Get the pixel type index */
6494 pixtype = rt_pixtype_index_from_name(pixtypename);
6495 if (pixtype == PT_END ) {
6496 for (k = 0; k < set_count; k++) {
6497 if (_rast[k] != NULL)
6498 rt_raster_destroy(_rast[k]);
6499 if (pgrastpos[k] != -1)
6500 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6501 }
6502 elog(ERROR, "RASTER_mapAlgebra2: Invalid pixel type: %s", pixtypename);
6503 PG_RETURN_NULL();
6504 }
6505 }
6506
6507 /* extent type */
6508 if (!PG_ARGISNULL(6)) {
6509 extenttypename = rtpg_strtoupper(rtpg_trim(text_to_cstring(PG_GETARG_TEXT_P(6))));
6510 extenttype = rt_util_extent_type(extenttypename);
6511 }
6512 POSTGIS_RT_DEBUGF(3, "extenttype: %d %s", extenttype, extenttypename);
6513
6514 /* computed raster from extent type */
6516 _rast[0], _rast[1],
6517 extenttype,
6518 &raster, _offset
6519 );
6520 if (err != ES_NONE) {
6521 for (k = 0; k < set_count; k++) {
6522 if (_rast[k] != NULL)
6523 rt_raster_destroy(_rast[k]);
6524 if (pgrastpos[k] != -1)
6525 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6526 }
6527 elog(ERROR, "RASTER_mapAlgebra2: Could not get output raster of correct extent");
6528 PG_RETURN_NULL();
6529 }
6530
6531 /* copy offsets */
6532 _rastoffset[0][0] = _offset[0];
6533 _rastoffset[0][1] = _offset[1];
6534 _rastoffset[1][0] = _offset[2];
6535 _rastoffset[1][1] = _offset[3];
6536
6537 /* get output raster dimensions */
6538 dim[0] = rt_raster_get_width(raster);
6539 dim[1] = rt_raster_get_height(raster);
6540
6541 i = 2;
6542 /* handle special cases for extent */
6543 switch (extenttype) {
6544 case ET_FIRST:
6545 i = 0;
6546 /* fall through */
6547 case ET_SECOND:
6548 if (i > 1)
6549 i = 1;
6550
6551 if (
6552 _isempty[i] && (
6553 (extenttype == ET_FIRST && i == 0) ||
6554 (extenttype == ET_SECOND && i == 1)
6555 )
6556 ) {
6557 elog(NOTICE, "The %s raster is NULL. Returning NULL", (i != 1 ? "FIRST" : "SECOND"));
6558 for (k = 0; k < set_count; k++) {
6559 if (_rast[k] != NULL)
6560 rt_raster_destroy(_rast[k]);
6561 if (pgrastpos[k] != -1)
6562 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6563 }
6564 rt_raster_destroy(raster);
6565 PG_RETURN_NULL();
6566 }
6567
6568 /* specified band not found */
6569 if (!rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6570 elog(NOTICE, "The %s raster does not have the band at index %d. Returning no band raster of correct extent",
6571 (i != 1 ? "FIRST" : "SECOND"), bandindex[i]
6572 );
6573
6574 for (k = 0; k < set_count; k++) {
6575 if (_rast[k] != NULL)
6576 rt_raster_destroy(_rast[k]);
6577 if (pgrastpos[k] != -1)
6578 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6579 }
6580
6581 pgrtn = rt_raster_serialize(raster);
6582 rt_raster_destroy(raster);
6583 if (!pgrtn) PG_RETURN_NULL();
6584
6585 SET_VARSIZE(pgrtn, pgrtn->size);
6586 PG_RETURN_POINTER(pgrtn);
6587 }
6588 break;
6589 case ET_UNION:
6590 break;
6591 case ET_INTERSECTION:
6592 /* no intersection */
6593 if (
6594 _isempty[0] || _isempty[1] ||
6595 !dim[0] || !dim[1]
6596 ) {
6597 elog(NOTICE, "The two rasters provided have no intersection. Returning no band raster");
6598
6599 /* raster has dimension, replace with no band raster */
6600 if (dim[0] || dim[1]) {
6601 rt_raster_destroy(raster);
6602
6603 raster = rt_raster_new(0, 0);
6604 if (raster == NULL) {
6605 for (k = 0; k < set_count; k++) {
6606 if (_rast[k] != NULL)
6607 rt_raster_destroy(_rast[k]);
6608 if (pgrastpos[k] != -1)
6609 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6610 }
6611 elog(ERROR, "RASTER_mapAlgebra2: Could not create no band raster");
6612 PG_RETURN_NULL();
6613 }
6614
6615 rt_raster_set_scale(raster, 0, 0);
6616 rt_raster_set_srid(raster, rt_raster_get_srid(_rast[0]));
6617 }
6618
6619 for (k = 0; k < set_count; k++) {
6620 if (_rast[k] != NULL)
6621 rt_raster_destroy(_rast[k]);
6622 if (pgrastpos[k] != -1)
6623 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6624 }
6625
6626 pgrtn = rt_raster_serialize(raster);
6627 rt_raster_destroy(raster);
6628 if (!pgrtn) PG_RETURN_NULL();
6629
6630 SET_VARSIZE(pgrtn, pgrtn->size);
6631 PG_RETURN_POINTER(pgrtn);
6632 }
6633 break;
6634 case ET_LAST:
6635 case ET_CUSTOM:
6636 for (k = 0; k < set_count; k++) {
6637 if (_rast[k] != NULL)
6638 rt_raster_destroy(_rast[k]);
6639 if (pgrastpos[k] != -1)
6640 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6641 }
6642 elog(ERROR, "RASTER_mapAlgebra2: ET_LAST and ET_CUSTOM are not implemented");
6643 PG_RETURN_NULL();
6644 break;
6645 }
6646
6647 /* both rasters do not have specified bands */
6648 if (
6649 (!_isempty[0] && !rt_raster_has_band(_rast[0], bandindex[0] - 1)) &&
6650 (!_isempty[1] && !rt_raster_has_band(_rast[1], bandindex[1] - 1))
6651 ) {
6652 elog(NOTICE, "The two rasters provided do not have the respectively specified band indices. Returning no band raster of correct extent");
6653
6654 for (k = 0; k < set_count; k++) {
6655 if (_rast[k] != NULL)
6656 rt_raster_destroy(_rast[k]);
6657 if (pgrastpos[k] != -1)
6658 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6659 }
6660
6661 pgrtn = rt_raster_serialize(raster);
6662 rt_raster_destroy(raster);
6663 if (!pgrtn) PG_RETURN_NULL();
6664
6665 SET_VARSIZE(pgrtn, pgrtn->size);
6666 PG_RETURN_POINTER(pgrtn);
6667 }
6668
6669 /* get bands */
6670 for (i = 0; i < set_count; i++) {
6671 if (_isempty[i] || !rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6672 _hasnodata[i] = 1;
6673 _nodataval[i] = 0;
6674
6675 continue;
6676 }
6677
6678 _band[i] = rt_raster_get_band(_rast[i], bandindex[i] - 1);
6679 if (_band[i] == NULL) {
6680 for (k = 0; k < set_count; k++) {
6681 if (_rast[k] != NULL)
6682 rt_raster_destroy(_rast[k]);
6683 if (pgrastpos[k] != -1)
6684 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6685 }
6686 rt_raster_destroy(raster);
6687 elog(ERROR, "RASTER_mapAlgebra2: Could not get band %d of the %s raster",
6688 bandindex[i],
6689 (i < 1 ? "FIRST" : "SECOND")
6690 );
6691 PG_RETURN_NULL();
6692 }
6693
6694 _hasnodata[i] = rt_band_get_hasnodata_flag(_band[i]);
6695 if (_hasnodata[i])
6696 rt_band_get_nodata(_band[i], &(_nodataval[i]));
6697 }
6698
6699 /* pixtype is PT_END, get pixtype based upon extent */
6700 if (pixtype == PT_END) {
6701 if ((extenttype == ET_SECOND && !_isempty[1]) || _isempty[0])
6702 pixtype = rt_band_get_pixtype(_band[1]);
6703 else
6704 pixtype = rt_band_get_pixtype(_band[0]);
6705 }
6706
6707 /* nodata value for new band */
6708 if (extenttype == ET_SECOND && !_isempty[1] && _hasnodata[1]) {
6709 nodataval = _nodataval[1];
6710 }
6711 else if (!_isempty[0] && _hasnodata[0]) {
6712 nodataval = _nodataval[0];
6713 }
6714 else if (!_isempty[1] && _hasnodata[1]) {
6715 nodataval = _nodataval[1];
6716 }
6717 else {
6718 elog(NOTICE, "Neither raster provided has a NODATA value for the specified band indices. NODATA value set to minimum possible for %s", rt_pixtype_name(pixtype));
6719 nodataval = rt_pixtype_get_min_value(pixtype);
6720 }
6721
6722 /* add band to output raster */
6724 raster,
6725 pixtype,
6726 nodataval,
6727 1, nodataval,
6728 0
6729 ) < 0) {
6730 for (k = 0; k < set_count; k++) {
6731 if (_rast[k] != NULL)
6732 rt_raster_destroy(_rast[k]);
6733 if (pgrastpos[k] != -1)
6734 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6735 }
6736 rt_raster_destroy(raster);
6737 elog(ERROR, "RASTER_mapAlgebra2: Could not add new band to output raster");
6738 PG_RETURN_NULL();
6739 }
6740
6741 /* get output band */
6742 band = rt_raster_get_band(raster, 0);
6743 if (band == NULL) {
6744 for (k = 0; k < set_count; k++) {
6745 if (_rast[k] != NULL)
6746 rt_raster_destroy(_rast[k]);
6747 if (pgrastpos[k] != -1)
6748 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6749 }
6750 rt_raster_destroy(raster);
6751 elog(ERROR, "RASTER_mapAlgebra2: Could not get newly added band of output raster");
6752 PG_RETURN_NULL();
6753 }
6754
6755 POSTGIS_RT_DEBUGF(4, "offsets = (%d, %d, %d, %d)",
6756 (int) _rastoffset[0][0],
6757 (int) _rastoffset[0][1],
6758 (int) _rastoffset[1][0],
6759 (int) _rastoffset[1][1]
6760 );
6761
6762 POSTGIS_RT_DEBUGF(4, "metadata = (%f, %f, %d, %d, %f, %f, %f, %f, %d)",
6763 rt_raster_get_x_offset(raster),
6764 rt_raster_get_y_offset(raster),
6765 rt_raster_get_width(raster),
6766 rt_raster_get_height(raster),
6767 rt_raster_get_x_scale(raster),
6768 rt_raster_get_y_scale(raster),
6769 rt_raster_get_x_skew(raster),
6770 rt_raster_get_y_skew(raster),
6771 rt_raster_get_srid(raster)
6772 );
6773
6774 /*
6775 determine who called this function
6776 Arg 4 will either be text or regprocedure
6777 */
6778 POSTGIS_RT_DEBUG(3, "checking parameter type for arg 4");
6779 calltype = get_fn_expr_argtype(fcinfo->flinfo, 4);
6780
6781 switch(calltype) {
6782 case TEXTOID: {
6783 POSTGIS_RT_DEBUG(3, "arg 4 is \"expression\"!");
6784
6785 /* connect SPI */
6786 if (SPI_connect() != SPI_OK_CONNECT) {
6787 for (k = 0; k < set_count; k++) {
6788 if (_rast[k] != NULL)
6789 rt_raster_destroy(_rast[k]);
6790 if (pgrastpos[k] != -1)
6791 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6792 }
6793 rt_raster_destroy(raster);
6794 elog(ERROR, "RASTER_mapAlgebra2: Could not connect to the SPI manager");
6795 PG_RETURN_NULL();
6796 }
6797
6798 /* reset hasargval */
6799 memset(hasargval, 0, sizeof(int) * spi_count);
6800
6801 /*
6802 process expressions
6803
6804 spi_exprpos elements are:
6805 4 - expression => spi_plan[0]
6806 7 - nodata1expr => spi_plan[1]
6807 8 - nodata2expr => spi_plan[2]
6808 */
6809 for (i = 0; i < spi_count; i++) {
6810 if (!PG_ARGISNULL(spi_exprpos[i])) {
6811 char *tmp = NULL;
6812 char place[5] = "$1";
6813 expr = text_to_cstring(PG_GETARG_TEXT_P(spi_exprpos[i]));
6814 POSTGIS_RT_DEBUGF(3, "raw expr #%d: %s", i, expr);
6815
6816 for (j = 0, k = 1; j < ARGKWCOUNT; j++) {
6817 /* attempt to replace keyword with placeholder */
6818 len = 0;
6819 tmp = rtpg_strreplace(expr, argkw[j], place, &len);
6820 pfree(expr);
6821 expr = tmp;
6822
6823 if (len) {
6824 spi_argcount[i]++;
6825 argpos[i][j] = k++;
6826
6827 sprintf(place, "$%d", k);
6828 }
6829 else
6830 argpos[i][j] = 0;
6831 }
6832
6833 len = strlen("SELECT (") + strlen(expr) + strlen(")::double precision");
6834 sql = (char *) palloc(len + 1);
6835 if (sql == NULL) {
6836
6837 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6838 SPI_finish();
6839
6840 for (k = 0; k < set_count; k++) {
6841 if (_rast[k] != NULL)
6842 rt_raster_destroy(_rast[k]);
6843 if (pgrastpos[k] != -1)
6844 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6845 }
6846 rt_raster_destroy(raster);
6847
6848 elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for expression parameter %d", spi_exprpos[i]);
6849 PG_RETURN_NULL();
6850 }
6851
6852 memcpy(sql, "SELECT (", strlen("SELECT ("));
6853 memcpy(sql + strlen("SELECT ("), expr, strlen(expr));
6854 memcpy(sql + strlen("SELECT (") + strlen(expr), ")::double precision", strlen(")::double precision"));
6855 sql[len] = '\0';
6856
6857 POSTGIS_RT_DEBUGF(3, "sql #%d: %s", i, sql);
6858
6859 /* create prepared plan */
6860 if (spi_argcount[i]) {
6861 argtype = (Oid *) palloc(spi_argcount[i] * sizeof(Oid));
6862 if (argtype == NULL) {
6863
6864 pfree(sql);
6865 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6866 SPI_finish();
6867
6868 for (k = 0; k < set_count; k++) {
6869 if (_rast[k] != NULL)
6870 rt_raster_destroy(_rast[k]);
6871 if (pgrastpos[k] != -1)
6872 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6873 }
6874 rt_raster_destroy(raster);
6875
6876 elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for prepared plan argtypes of expression parameter %d", spi_exprpos[i]);
6877 PG_RETURN_NULL();
6878 }
6879
6880 /* specify datatypes of parameters */
6881 for (j = 0, k = 0; j < ARGKWCOUNT; j++) {
6882 if (argpos[i][j] < 1) continue;
6883
6884 /* positions are INT4 */
6885 if (
6886 (strstr(argkw[j], "[rast1.x]") != NULL) ||
6887 (strstr(argkw[j], "[rast1.y]") != NULL) ||
6888 (strstr(argkw[j], "[rast2.x]") != NULL) ||
6889 (strstr(argkw[j], "[rast2.y]") != NULL)
6890 ) {
6891 argtype[k] = INT4OID;
6892 }
6893 /* everything else is FLOAT8 */
6894 else {
6895 argtype[k] = FLOAT8OID;
6896 }
6897
6898 k++;
6899 }
6900
6901 spi_plan[i] = SPI_prepare(sql, spi_argcount[i], argtype);
6902 pfree(argtype);
6903
6904 if (spi_plan[i] == NULL) {
6905
6906 pfree(sql);
6907 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6908 SPI_finish();
6909
6910 for (k = 0; k < set_count; k++) {
6911 if (_rast[k] != NULL)
6912 rt_raster_destroy(_rast[k]);
6913 if (pgrastpos[k] != -1)
6914 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6915 }
6916 rt_raster_destroy(raster);
6917
6918 elog(ERROR, "RASTER_mapAlgebra2: Could not create prepared plan of expression parameter %d", spi_exprpos[i]);
6919 PG_RETURN_NULL();
6920 }
6921 }
6922 /* no args, just execute query */
6923 else {
6924 err = SPI_execute(sql, TRUE, 0);
6925 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
6926
6927 pfree(sql);
6928 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6929 SPI_finish();
6930
6931 for (k = 0; k < set_count; k++) {
6932 if (_rast[k] != NULL)
6933 rt_raster_destroy(_rast[k]);
6934 if (pgrastpos[k] != -1)
6935 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6936 }
6937 rt_raster_destroy(raster);
6938
6939 elog(ERROR, "RASTER_mapAlgebra2: Could not evaluate expression parameter %d", spi_exprpos[i]);
6940 PG_RETURN_NULL();
6941 }
6942
6943 /* get output of prepared plan */
6944 tupdesc = SPI_tuptable->tupdesc;
6945 tuptable = SPI_tuptable;
6946 tuple = tuptable->vals[0];
6947
6948 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
6949 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
6950
6951 pfree(sql);
6952 if (SPI_tuptable) SPI_freetuptable(tuptable);
6953 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6954 SPI_finish();
6955
6956 for (k = 0; k < set_count; k++) {
6957 if (_rast[k] != NULL)
6958 rt_raster_destroy(_rast[k]);
6959 if (pgrastpos[k] != -1)
6960 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6961 }
6962 rt_raster_destroy(raster);
6963
6964 elog(ERROR, "RASTER_mapAlgebra2: Could not get result of expression parameter %d", spi_exprpos[i]);
6965 PG_RETURN_NULL();
6966 }
6967
6968 if (!isnull) {
6969 hasargval[i] = 1;
6970 argval[i] = DatumGetFloat8(datum);
6971 }
6972
6973 if (SPI_tuptable) SPI_freetuptable(tuptable);
6974 }
6975
6976 pfree(sql);
6977 }
6978 else
6979 spi_empty++;
6980 }
6981
6982 /* nodatanodataval */
6983 if (!PG_ARGISNULL(9)) {
6984 hasnodatanodataval = 1;
6985 nodatanodataval = PG_GETARG_FLOAT8(9);
6986 }
6987 else
6988 hasnodatanodataval = 0;
6989 break;
6990 }
6991 case REGPROCEDUREOID: {
6992 POSTGIS_RT_DEBUG(3, "arg 4 is \"userfunction\"!");
6993 if (!PG_ARGISNULL(4)) {
6994
6995 ufc_nullcount = 0;
6996 ufc_noid = PG_GETARG_OID(4);
6997
6998 /* get function info */
6999 fmgr_info(ufc_noid, &ufl_info);
7000
7001 /* function cannot return set */
7002 err = 0;
7003 if (ufl_info.fn_retset) {
7004 err = 1;
7005 }
7006 /* function should have correct # of args */
7007 else if (ufl_info.fn_nargs < 3 || ufl_info.fn_nargs > 4) {
7008 err = 2;
7009 }
7010
7011 /*
7012 TODO: consider adding checks of the userfunction parameters
7013 should be able to use get_fn_expr_argtype() of fmgr.c
7014 */
7015
7016 if (err > 0) {
7017 for (k = 0; k < set_count; k++) {
7018 if (_rast[k] != NULL)
7019 rt_raster_destroy(_rast[k]);
7020 if (pgrastpos[k] != -1)
7021 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7022 }
7023 rt_raster_destroy(raster);
7024
7025 if (err > 1)
7026 elog(ERROR, "RASTER_mapAlgebra2: Function provided must have three or four input parameters");
7027 else
7028 elog(ERROR, "RASTER_mapAlgebra2: Function provided must return double precision not resultset");
7029 PG_RETURN_NULL();
7030 }
7031
7032 if (func_volatile(ufc_noid) == 'v') {
7033 elog(NOTICE, "Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
7034 }
7035
7036 /* prep function call data */
7037 InitFunctionCallInfoData(
7038 *ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
7039 ufc_info->args[0].isnull = FALSE;
7040 ufc_info->args[1].isnull = FALSE;
7041 ufc_info->args[2].isnull = FALSE;
7042 if (ufl_info.fn_nargs == 4)
7043 ufc_info->args[3].isnull = FALSE;
7044
7045 if (ufl_info.fn_nargs != 4)
7046 k = 2;
7047 else
7048 k = 3;
7049 if (!PG_ARGISNULL(7))
7050 {
7051 ufc_info->args[k].value = PG_GETARG_DATUM(7);
7052 }
7053 else
7054 {
7055 ufc_info->args[k].value = (Datum)NULL;
7056 ufc_info->args[k].isnull = TRUE;
7057 ufc_nullcount++;
7058 }
7059 }
7060 break;
7061 }
7062 default:
7063 for (k = 0; k < set_count; k++) {
7064 if (_rast[k] != NULL)
7065 rt_raster_destroy(_rast[k]);
7066 if (pgrastpos[k] != -1)
7067 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7068 }
7069 rt_raster_destroy(raster);
7070 elog(ERROR, "RASTER_mapAlgebra2: Invalid data type for expression or userfunction");
7071 PG_RETURN_NULL();
7072 break;
7073 }
7074
7075 /* loop over pixels */
7076 /* if any expression present, run */
7077 if ((
7078 (calltype == TEXTOID) && (
7079 (spi_empty != spi_count) || hasnodatanodataval
7080 )
7081 ) || (
7082 (calltype == REGPROCEDUREOID) && (ufc_noid != InvalidOid)
7083 )) {
7084 for (x = 0; x < dim[0]; x++) {
7085 for (y = 0; y < dim[1]; y++) {
7086
7087 /* get pixel from each raster */
7088 for (i = 0; i < set_count; i++) {
7089 _haspixel[i] = 0;
7090 _pixel[i] = 0;
7091
7092 /* row/column */
7093 _x = (int)x - (int)_rastoffset[i][0];
7094 _y = (int)y - (int)_rastoffset[i][1];
7095
7096 /* store _x and _y in 1-based */
7097 _pos[i][0] = _x + 1;
7098 _pos[i][1] = _y + 1;
7099
7100 /* get pixel value */
7101 if (_band[i] == NULL) {
7102 if (!_hasnodata[i]) {
7103 _haspixel[i] = 1;
7104 _pixel[i] = _nodataval[i];
7105 }
7106 }
7107 else if (
7108 !_isempty[i] &&
7109 (_x >= 0 && _x < _dim[i][0]) &&
7110 (_y >= 0 && _y < _dim[i][1])
7111 ) {
7112 err = rt_band_get_pixel(_band[i], _x, _y, &(_pixel[i]), &isnodata);
7113 if (err != ES_NONE) {
7114
7115 if (calltype == TEXTOID) {
7116 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7117 SPI_finish();
7118 }
7119
7120 for (k = 0; k < set_count; k++) {
7121 if (_rast[k] != NULL)
7122 rt_raster_destroy(_rast[k]);
7123 if (pgrastpos[k] != -1)
7124 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7125 }
7126 rt_raster_destroy(raster);
7127
7128 elog(ERROR, "RASTER_mapAlgebra2: Could not get pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
7129 PG_RETURN_NULL();
7130 }
7131
7132 if (!_hasnodata[i] || !isnodata)
7133 _haspixel[i] = 1;
7134 }
7135
7136 POSTGIS_RT_DEBUGF(5, "pixel r%d(%d, %d) = %d, %f",
7137 i,
7138 _x, _y,
7139 _haspixel[i],
7140 _pixel[i]
7141 );
7142 }
7143
7144 haspixel = 0;
7145
7146 switch (calltype) {
7147 case TEXTOID: {
7148 /* which prepared plan to use? */
7149 /* !pixel0 && !pixel1 */
7150 /* use nodatanodataval */
7151 if (!_haspixel[0] && !_haspixel[1])
7152 i = 3;
7153 /* pixel0 && !pixel1 */
7154 /* run spi_plan[2] (nodata2expr) */
7155 else if (_haspixel[0] && !_haspixel[1])
7156 i = 2;
7157 /* !pixel0 && pixel1 */
7158 /* run spi_plan[1] (nodata1expr) */
7159 else if (!_haspixel[0] && _haspixel[1])
7160 i = 1;
7161 /* pixel0 && pixel1 */
7162 /* run spi_plan[0] (expression) */
7163 else
7164 i = 0;
7165
7166 /* process values */
7167 if (i == 3) {
7168 if (hasnodatanodataval) {
7169 haspixel = 1;
7170 pixel = nodatanodataval;
7171 }
7172 }
7173 /* has an evaluated value */
7174 else if (hasargval[i]) {
7175 haspixel = 1;
7176 pixel = argval[i];
7177 }
7178 /* prepared plan exists */
7179 else if (spi_plan[i] != NULL) {
7180 POSTGIS_RT_DEBUGF(4, "Using prepared plan: %d", i);
7181
7182 /* reset values to (Datum) NULL */
7183 memset(values, (Datum) NULL, sizeof(Datum) * ARGKWCOUNT);
7184 /* reset nulls to FALSE */
7185 memset(nulls, FALSE, sizeof(char) * ARGKWCOUNT);
7186
7187 /* expression has argument(s) */
7188 if (spi_argcount[i]) {
7189 /* set values and nulls */
7190 for (j = 0; j < ARGKWCOUNT; j++) {
7191 idx = argpos[i][j];
7192 if (idx < 1) continue;
7193 idx--; /* 1-based becomes 0-based */
7194
7195 if (strstr(argkw[j], "[rast1.x]") != NULL) {
7196 values[idx] = _pos[0][0];
7197 }
7198 else if (strstr(argkw[j], "[rast1.y]") != NULL) {
7199 values[idx] = _pos[0][1];
7200 }
7201 else if (
7202 (strstr(argkw[j], "[rast1.val]") != NULL) ||
7203 (strstr(argkw[j], "[rast1]") != NULL)
7204 ) {
7205 if (_isempty[0] || !_haspixel[0])
7206 nulls[idx] = TRUE;
7207 else
7208 values[idx] = Float8GetDatum(_pixel[0]);
7209 }
7210 else if (strstr(argkw[j], "[rast2.x]") != NULL) {
7211 values[idx] = _pos[1][0];
7212 }
7213 else if (strstr(argkw[j], "[rast2.y]") != NULL) {
7214 values[idx] = _pos[1][1];
7215 }
7216 else if (
7217 (strstr(argkw[j], "[rast2.val]") != NULL) ||
7218 (strstr(argkw[j], "[rast2]") != NULL)
7219 ) {
7220 if (_isempty[1] || !_haspixel[1])
7221 nulls[idx] = TRUE;
7222 else
7223 values[idx] = Float8GetDatum(_pixel[1]);
7224 }
7225 }
7226 }
7227
7228 /* run prepared plan */
7229 err = SPI_execute_plan(spi_plan[i], values, nulls, TRUE, 1);
7230 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
7231
7232 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7233 SPI_finish();
7234
7235 for (k = 0; k < set_count; k++) {
7236 if (_rast[k] != NULL)
7237 rt_raster_destroy(_rast[k]);
7238 if (pgrastpos[k] != -1)
7239 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7240 }
7241 rt_raster_destroy(raster);
7242
7243 elog(ERROR, "RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
7244 PG_RETURN_NULL();
7245 }
7246
7247 /* get output of prepared plan */
7248 tupdesc = SPI_tuptable->tupdesc;
7249 tuptable = SPI_tuptable;
7250 tuple = tuptable->vals[0];
7251
7252 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
7253 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
7254
7255 if (SPI_tuptable) SPI_freetuptable(tuptable);
7256 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7257 SPI_finish();
7258
7259 for (k = 0; k < set_count; k++) {
7260 if (_rast[k] != NULL)
7261 rt_raster_destroy(_rast[k]);
7262 if (pgrastpos[k] != -1)
7263 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7264 }
7265 rt_raster_destroy(raster);
7266
7267 elog(ERROR, "RASTER_mapAlgebra2: Could not get result of prepared statement %d", i);
7268 PG_RETURN_NULL();
7269 }
7270
7271 if (!isnull) {
7272 haspixel = 1;
7273 pixel = DatumGetFloat8(datum);
7274 }
7275
7276 if (SPI_tuptable) SPI_freetuptable(tuptable);
7277 }
7278 } break;
7279 case REGPROCEDUREOID: {
7280 Datum d[4];
7281 ArrayType *a;
7282
7283 /* build fcnarg */
7284 for (i = 0; i < set_count; i++) {
7285 ufc_info->args[i].value = Float8GetDatum(_pixel[i]);
7286 if (_haspixel[i]) {
7287 ufc_info->args[i].isnull = FALSE;
7288 ufc_nullcount--;
7289 }
7290 else {
7291 ufc_info->args[i].isnull = TRUE;
7292 ufc_nullcount++;
7293 }
7294 }
7295
7296 /* function is strict and null parameter is passed */
7297 /* http://archives.postgresql.org/pgsql-general/2011-11/msg00424.php */
7298 if (ufl_info.fn_strict && ufc_nullcount)
7299 break;
7300
7301 /* 4 parameters, add position */
7302 if (ufl_info.fn_nargs == 4) {
7303 /* Datum of 4 element array */
7304 /* array is (x1, y1, x2, y2) */
7305 for (i = 0; i < set_count; i++) {
7306 if (i < 1) {
7307 d[0] = Int32GetDatum(_pos[i][0]);
7308 d[1] = Int32GetDatum(_pos[i][1]);
7309 }
7310 else {
7311 d[2] = Int32GetDatum(_pos[i][0]);
7312 d[3] = Int32GetDatum(_pos[i][1]);
7313 }
7314 }
7315
7316 a = construct_array(d, 4, INT4OID, sizeof(int32), true, 'i');
7317 ufc_info->args[2].value = PointerGetDatum(a);
7318 ufc_info->args[2].isnull = FALSE;
7319 }
7320
7321 datum = FunctionCallInvoke(ufc_info);
7322
7323 /* result is not null*/
7324 if (!ufc_info->isnull)
7325 {
7326 haspixel = 1;
7327 pixel = DatumGetFloat8(datum);
7328 }
7329 } break;
7330 }
7331
7332 /* burn pixel if haspixel != 0 */
7333 if (haspixel) {
7334 if (rt_band_set_pixel(band, x, y, pixel, NULL) != ES_NONE) {
7335
7336 if (calltype == TEXTOID) {
7337 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7338 SPI_finish();
7339 }
7340
7341 for (k = 0; k < set_count; k++) {
7342 if (_rast[k] != NULL)
7343 rt_raster_destroy(_rast[k]);
7344 if (pgrastpos[k] != -1)
7345 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7346 }
7347 rt_raster_destroy(raster);
7348
7349 elog(ERROR, "RASTER_mapAlgebra2: Could not set pixel value of output raster");
7350 PG_RETURN_NULL();
7351 }
7352 }
7353
7354 POSTGIS_RT_DEBUGF(5, "(x, y, val) = (%d, %d, %f)", x, y, haspixel ? pixel : nodataval);
7355
7356 } /* y: height */
7357 } /* x: width */
7358 }
7359
7360 /* CLEANUP */
7361 if (calltype == TEXTOID) {
7362 for (i = 0; i < spi_count; i++) {
7363 if (spi_plan[i] != NULL) SPI_freeplan(spi_plan[i]);
7364 }
7365 SPI_finish();
7366 }
7367
7368 for (k = 0; k < set_count; k++) {
7369 if (_rast[k] != NULL)
7370 rt_raster_destroy(_rast[k]);
7371 if (pgrastpos[k] != -1)
7372 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7373 }
7374
7375 pgrtn = rt_raster_serialize(raster);
7376 rt_raster_destroy(raster);
7377 if (!pgrtn) PG_RETURN_NULL();
7378
7379 POSTGIS_RT_DEBUG(3, "Finished RASTER_mapAlgebra2");
7380
7381 SET_VARSIZE(pgrtn, pgrtn->size);
7382 PG_RETURN_POINTER(pgrtn);
7383}
#define TRUE
Definition dbfopen.c:73
#define FALSE
Definition dbfopen.c:72
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition rt_raster.c:360
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
Definition rt_raster.c:185
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
Definition rt_raster.c:217
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
Definition rt_raster.c:489
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition rt_raster.c:609
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
Definition rt_raster.c:141
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:833
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition rt_pixel.c:82
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition rt_band.c:1551
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:86
rt_pixtype
Definition librtcore.h:188
@ PT_END
Definition librtcore.h:201
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition rt_raster.c:52
rt_extenttype rt_util_extent_type(const char *name)
Definition rt_util.c:301
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition rt_pixel.c:156
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Definition rt_raster.c:1253
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
Definition rt_raster.c:154
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:114
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition rt_band.c:1140
@ ES_NONE
Definition librtcore.h:182
uint16_t rt_raster_get_height(rt_raster raster)
Definition rt_raster.c:133
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition rt_raster.c:367
rt_extenttype
Definition librtcore.h:204
@ ET_CUSTOM
Definition librtcore.h:210
@ ET_LAST
Definition librtcore.h:209
@ ET_INTERSECTION
Definition librtcore.h:205
@ ET_UNION
Definition librtcore.h:206
@ ET_SECOND
Definition librtcore.h:208
@ ET_FIRST
Definition librtcore.h:207
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:2067
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition rt_band.c:790
uint16_t rt_raster_get_width(rt_raster raster)
Definition rt_raster.c:125
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
rt_errorstate rt_raster_from_two_rasters(rt_raster rast1, rt_raster rast2, rt_extenttype extenttype, rt_raster *rtnraster, double *offset)
Definition rt_raster.c:3348
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
Definition rt_raster.c:163
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
Definition rt_raster.c:194
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition rt_raster.c:588
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
Definition rt_raster.c:226
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
pixel
Definition pixval.py:94
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition rtrowdump.py:125
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
char * rtpg_trim(const char *input)
char * rtpg_strtoupper(char *str)
#define ARGKWCOUNT
#define POSTGIS_RT_DEBUG(level, msg)
Definition rtpostgis.h:65
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition rtpostgis.h:69
unsigned int int32
Definition shpopen.c:54
Struct definitions.
Definition librtcore.h:2452

References ARGKWCOUNT, ES_NONE, ET_CUSTOM, ET_FIRST, ET_INTERSECTION, ET_LAST, ET_SECOND, ET_UNION, FALSE, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, rt_band_get_hasnodata_flag(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_pixtype(), rt_band_set_pixel(), rt_pixtype_get_min_value(), rt_pixtype_index_from_name(), rt_pixtype_name(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_from_two_rasters(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_get_height(), rt_raster_get_srid(), rt_raster_get_width(), rt_raster_get_x_offset(), rt_raster_get_x_scale(), rt_raster_get_x_skew(), rt_raster_get_y_offset(), rt_raster_get_y_scale(), rt_raster_get_y_skew(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_new(), rt_raster_same_alignment(), rt_raster_serialize(), rt_raster_set_geotransform_matrix(), rt_raster_set_scale(), rt_raster_set_srid(), rt_util_extent_type(), rtpg_strreplace(), rtpg_strtoupper(), rtpg_trim(), rt_raster_serialized_t::size, and TRUE.

Here is the call graph for this function: