PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ RASTER_addBandOutDB()

Datum RASTER_addBandOutDB ( PG_FUNCTION_ARGS  )

Definition at line 546 of file rtpg_create.c.

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

Referenced by RASTER_addBandRasterArray().

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