PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ 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 */
593  raster = rt_raster_deserialize(pgraster, FALSE);
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) {
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) {
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) {
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) {
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) {
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) {
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)
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)
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)
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)
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);
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:169
#define FALSE
Definition: dbfopen.c:168
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:229
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:356
int rt_util_gdal_register_all(int force_register_all)
Definition: rt_util.c:338
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition: rt_raster.c:727
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
Definition: rt_raster.c:405
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:48
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
Definition: rt_util.c:383
@ 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
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_raster.c:129
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:363
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:199
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:121
rt_errorstate rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode)
Get auth name and code.
Definition: rt_util.c:272
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.
Definition: rt_serialize.c:725
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1329
band
Definition: ovdump.py:58
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
char * text_to_cstring(const text *textptr)
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
Struct definitions.
Definition: librtcore.h:2251

References ovdump::band, ES_ERROR, ES_NONE, FALSE, POSTGIS_RT_DEBUG, rtrowdump::raster, 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, text_to_cstring(), and TRUE.

Here is the call graph for this function: