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

◆ RASTER_addBandOutDB()

Datum RASTER_addBandOutDB ( PG_FUNCTION_ARGS  )

Definition at line 557 of file rtpg_create.c.

558{
559 rt_pgraster *pgraster = NULL;
560 rt_pgraster *pgrtn = NULL;
561
562 rt_raster raster = NULL;
563 rt_band band = NULL;
564 int numbands = 0;
565 int dstnband = 1; /* 1-based */
566 int appendband = FALSE;
567 char *outdbfile = NULL;
568 int *srcnband = NULL; /* 1-based */
569 int numsrcnband = 0;
570 int allbands = FALSE;
571 int hasnodata = FALSE;
572 double nodataval = 0.;
573 uint16_t width = 0;
574 uint16_t height = 0;
575 char *authname = NULL;
576 char *authcode = NULL;
577
578 int i = 0;
579 int j = 0;
580
581 GDALDatasetH hdsOut;
582
583 double ogt[6] = {0.};
584 rt_raster _rast = NULL;
585 int aligned = 0;
586 int err = 0;
587
588 /* destination raster */
589 if (!PG_ARGISNULL(0)) {
590 pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
591
592 /* raster */
594 if (!raster) {
595 PG_FREE_IF_COPY(pgraster, 0);
596 elog(ERROR, "RASTER_addBandOutDB: Cannot deserialize destination raster");
597 PG_RETURN_NULL();
598 }
599
600 POSTGIS_RT_DEBUG(4, "destination raster isn't NULL");
601 }
602
603 /* destination band index (1) */
604 if (!PG_ARGISNULL(1))
605 dstnband = PG_GETARG_INT32(1);
606 else
607 appendband = TRUE;
608
609 /* outdb file (2) */
610 if (PG_ARGISNULL(2)) {
611 elog(NOTICE, "Out-db raster file not provided. Returning original raster");
612 if (pgraster != NULL) {
613 rt_raster_destroy(raster);
614 PG_RETURN_POINTER(pgraster);
615 }
616 else
617 PG_RETURN_NULL();
618 }
619 else {
620 outdbfile = text_to_cstring(PG_GETARG_TEXT_P(2));
621 if (!strlen(outdbfile)) {
622 elog(NOTICE, "Out-db raster file not provided. Returning original raster");
623 if (pgraster != NULL) {
624 rt_raster_destroy(raster);
625 PG_RETURN_POINTER(pgraster);
626 }
627 else
628 PG_RETURN_NULL();
629 }
630 }
631
632 /* outdb band index (3) */
633 if (!PG_ARGISNULL(3)) {
634 ArrayType *array;
635 Oid etype;
636 Datum *e;
637 bool *nulls;
638
639 int16 typlen;
640 bool typbyval;
641 char typalign;
642
643 allbands = FALSE;
644
645 array = PG_GETARG_ARRAYTYPE_P(3);
646 etype = ARR_ELEMTYPE(array);
647 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
648
649 switch (etype) {
650 case INT2OID:
651 case INT4OID:
652 break;
653 default:
654 if (pgraster != NULL) {
655 rt_raster_destroy(raster);
656 PG_FREE_IF_COPY(pgraster, 0);
657 }
658 elog(ERROR, "RASTER_addBandOutDB: Invalid data type for band indexes");
659 PG_RETURN_NULL();
660 break;
661 }
662
663 deconstruct_array(array, etype, typlen, typbyval, typalign, &e, &nulls, &numsrcnband);
664
665 srcnband = palloc(sizeof(int) * numsrcnband);
666 if (srcnband == NULL) {
667 if (pgraster != NULL) {
668 rt_raster_destroy(raster);
669 PG_FREE_IF_COPY(pgraster, 0);
670 }
671 elog(ERROR, "RASTER_addBandOutDB: Cannot allocate memory for band indexes");
672 PG_RETURN_NULL();
673 }
674
675 for (i = 0, j = 0; i < numsrcnband; i++) {
676 if (nulls[i]) continue;
677
678 switch (etype) {
679 case INT2OID:
680 srcnband[j] = DatumGetInt16(e[i]);
681 break;
682 case INT4OID:
683 srcnband[j] = DatumGetInt32(e[i]);
684 break;
685 }
686 j++;
687 }
688
689 if (j < numsrcnband) {
690 srcnband = repalloc(srcnband, sizeof(int) * j);
691 if (srcnband == NULL) {
692 if (pgraster != NULL) {
693 rt_raster_destroy(raster);
694 PG_FREE_IF_COPY(pgraster, 0);
695 }
696 elog(ERROR, "RASTER_addBandOutDB: Cannot reallocate memory for band indexes");
697 PG_RETURN_NULL();
698 }
699
700 numsrcnband = j;
701 }
702 }
703 else
704 allbands = TRUE;
705
706 /* nodataval (4) */
707 if (!PG_ARGISNULL(4)) {
708 hasnodata = TRUE;
709 nodataval = PG_GETARG_FLOAT8(4);
710 }
711 else
712 hasnodata = FALSE;
713
714 /* validate input */
715
716 /* make sure dstnband is valid */
717 if (raster != NULL) {
718 numbands = rt_raster_get_num_bands(raster);
719 if (!appendband) {
720 if (dstnband < 1) {
721 elog(NOTICE, "Invalid band index %d for adding bands. Using band index 1", dstnband);
722 dstnband = 1;
723 }
724 else if (numbands > 0 && dstnband > numbands) {
725 elog(NOTICE, "Invalid band index %d for adding bands. Using band index %d", dstnband, numbands);
726 dstnband = numbands + 1;
727 }
728 }
729 else
730 dstnband = numbands + 1;
731 }
732
733 /* open outdb raster file */
735 hdsOut = rt_util_gdal_open(outdbfile, GA_ReadOnly, 1);
736 if (hdsOut == NULL) {
737 if (pgraster != NULL) {
738 rt_raster_destroy(raster);
739 PG_FREE_IF_COPY(pgraster, 0);
740 }
741 elog(ERROR, "RASTER_addBandOutDB: Cannot open out-db file with GDAL");
742 PG_RETURN_NULL();
743 }
744
745 /* get offline raster's geotransform */
746 if (GDALGetGeoTransform(hdsOut, ogt) != CE_None) {
747 ogt[0] = 0;
748 ogt[1] = 1;
749 ogt[2] = 0;
750 ogt[3] = 0;
751 ogt[4] = 0;
752 ogt[5] = -1;
753 }
754
755 /* raster doesn't exist, create it now */
756 if (raster == NULL) {
757 raster = rt_raster_new(GDALGetRasterXSize(hdsOut), GDALGetRasterYSize(hdsOut));
758 if (rt_raster_is_empty(raster)) {
759 elog(ERROR, "RASTER_addBandOutDB: Cannot create new raster");
760 PG_RETURN_NULL();
761 }
763
764 if (rt_util_gdal_sr_auth_info(hdsOut, &authname, &authcode) == ES_NONE) {
765 if (
766 authname != NULL &&
767 strcmp(authname, "EPSG") == 0 &&
768 authcode != NULL
769 ) {
770 rt_raster_set_srid(raster, atoi(authcode));
771 }
772 else
773 elog(INFO, "Unknown SRS auth name and code from out-db file. Defaulting SRID of new raster to %d", SRID_UNKNOWN);
774 }
775 else
776 elog(INFO, "Cannot get SRS auth name and code from out-db file. Defaulting SRID of new raster to %d", SRID_UNKNOWN);
777 }
778
779 /* some raster info */
780 width = rt_raster_get_width(raster);
781 height = rt_raster_get_height(raster);
782
783 /* are rasters aligned? */
784 _rast = rt_raster_new(1, 1);
787 err = rt_raster_same_alignment(raster, _rast, &aligned, NULL);
788 rt_raster_destroy(_rast);
789
790 if (err != ES_NONE) {
791 GDALClose(hdsOut);
792 if (raster != NULL)
793 rt_raster_destroy(raster);
794 if (pgraster != NULL)
795 PG_FREE_IF_COPY(pgraster, 0);
796 elog(ERROR, "RASTER_addBandOutDB: Cannot test alignment of out-db file");
797 return ES_ERROR;
798 }
799 else if (!aligned)
800 elog(WARNING, "The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
801
802 /* build up srcnband */
803 if (allbands) {
804 numsrcnband = GDALGetRasterCount(hdsOut);
805 GDALClose(hdsOut);
806
807 srcnband = palloc(sizeof(int) * numsrcnband);
808 if (srcnband == NULL) {
809 if (raster != NULL)
810 rt_raster_destroy(raster);
811 if (pgraster != NULL)
812 PG_FREE_IF_COPY(pgraster, 0);
813 elog(ERROR, "RASTER_addBandOutDB: Cannot allocate memory for band indexes");
814 PG_RETURN_NULL();
815 }
816
817 for (i = 0, j = 1; i < numsrcnband; i++, j++)
818 srcnband[i] = j;
819 }
820 else
821 GDALClose(hdsOut);
822
823 /* add band */
824 for (i = 0, j = dstnband - 1; i < numsrcnband; i++, j++) {
825
826 /* create band with path */
828 width, height,
829 hasnodata, nodataval,
830 srcnband[i], outdbfile,
831 FALSE
832 );
833 if (band == NULL) {
834 if (raster != NULL)
835 rt_raster_destroy(raster);
836 if (pgraster != NULL)
837 PG_FREE_IF_COPY(pgraster, 0);
838 elog(ERROR, "RASTER_addBandOutDB: Cannot create new out-db band");
839 PG_RETURN_NULL();
840 }
841
842 /* add band */
843 if (rt_raster_add_band(raster, band, j) < 0) {
844 if (raster != NULL)
845 rt_raster_destroy(raster);
846 if (pgraster != NULL)
847 PG_FREE_IF_COPY(pgraster, 0);
848 elog(ERROR, "RASTER_addBandOutDB: Cannot add new out-db band to raster");
849 PG_RETURN_NULL();
850 }
851 }
852
853 pgrtn = rt_raster_serialize(raster);
854 rt_raster_destroy(raster);
855 if (pgraster != NULL)
856 PG_FREE_IF_COPY(pgraster, 0);
857 if (!pgrtn)
858 PG_RETURN_NULL();
859
860 SET_VARSIZE(pgrtn, pgrtn->size);
861 PG_RETURN_POINTER(pgrtn);
862}
#define TRUE
Definition dbfopen.c:73
#define FALSE
Definition dbfopen.c:72
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition rt_raster.c:360
int rt_util_gdal_register_all(int force_register_all)
Definition rt_util.c:444
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition rt_raster.c:609
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
Definition rt_raster.c:409
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:86
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition rt_raster.c:52
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
Definition rt_util.c:491
@ 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
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_band rt_band_new_offline_from_path(uint16_t width, uint16_t height, int hasnodata, double nodataval, uint8_t bandNum, const char *path, int force)
Create an out-db rt_band from path.
Definition rt_band.c:358
uint16_t rt_raster_get_width(rt_raster raster)
Definition rt_raster.c:125
rt_errorstate rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode)
Get auth name and code.
Definition rt_util.c:380
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition rt_raster.c:1240
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition rtrowdump.py:125
#define POSTGIS_RT_DEBUG(level, msg)
Definition rtpostgis.h:65
Struct definitions.
Definition librtcore.h:2452

References ES_ERROR, ES_NONE, FALSE, POSTGIS_RT_DEBUG, rt_band_new_offline_from_path(), rt_raster_add_band(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_get_height(), rt_raster_get_num_bands(), rt_raster_get_srid(), rt_raster_get_width(), rt_raster_is_empty(), rt_raster_new(), rt_raster_same_alignment(), rt_raster_serialize(), rt_raster_set_geotransform_matrix(), rt_raster_set_srid(), rt_util_gdal_open(), rt_util_gdal_register_all(), rt_util_gdal_sr_auth_info(), rt_raster_serialized_t::size, SRID_UNKNOWN, and TRUE.

Here is the call graph for this function: