PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ RASTER_GDALWarp()

Datum RASTER_GDALWarp ( PG_FUNCTION_ARGS  )

Definition at line 454 of file rtpg_gdal.c.

References clamp_srid(), FALSE, FLT_NEQ, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rtpixdump::rast, rtrowdump::raster, rt_raster_deserialize(), rt_raster_destroy(), rt_raster_gdal_warp(), rt_raster_get_srid(), rt_raster_serialize(), rt_raster_set_srid(), rt_util_gdal_resample_alg(), rtpg_getSR(), rtpg_strtoupper(), rtpg_trim(), rt_raster_serialized_t::size, SRID_UNKNOWN, and text_to_cstring().

Referenced by RASTER_getGDALDrivers().

455 {
456  rt_pgraster *pgraster = NULL;
457  rt_pgraster *pgrast = NULL;
458  rt_raster raster = NULL;
459  rt_raster rast = NULL;
460 
461  text *algtext = NULL;
462  char *algchar = NULL;
463  GDALResampleAlg alg = GRA_NearestNeighbour;
464  double max_err = 0.125;
465 
466  int src_srid = SRID_UNKNOWN;
467  char *src_srs = NULL;
468  int dst_srid = SRID_UNKNOWN;
469  char *dst_srs = NULL;
470  int no_srid = 0;
471 
472  double scale[2] = {0};
473  double *scale_x = NULL;
474  double *scale_y = NULL;
475 
476  double gridw[2] = {0};
477  double *grid_xw = NULL;
478  double *grid_yw = NULL;
479 
480  double skew[2] = {0};
481  double *skew_x = NULL;
482  double *skew_y = NULL;
483 
484  int dim[2] = {0};
485  int *dim_x = NULL;
486  int *dim_y = NULL;
487 
488  POSTGIS_RT_DEBUG(3, "RASTER_GDALWarp: Starting");
489 
490  /* pgraster is null, return null */
491  if (PG_ARGISNULL(0))
492  PG_RETURN_NULL();
493  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
494 
495  /* raster */
496  raster = rt_raster_deserialize(pgraster, FALSE);
497  if (!raster) {
498  PG_FREE_IF_COPY(pgraster, 0);
499  elog(ERROR, "RASTER_GDALWarp: Could not deserialize raster");
500  PG_RETURN_NULL();
501  }
502 
503  /* resampling algorithm */
504  if (!PG_ARGISNULL(1)) {
505  algtext = PG_GETARG_TEXT_P(1);
506  algchar = rtpg_trim(rtpg_strtoupper(text_to_cstring(algtext)));
507  alg = rt_util_gdal_resample_alg(algchar);
508  }
509  POSTGIS_RT_DEBUGF(4, "Resampling algorithm: %d", alg);
510 
511  /* max error */
512  if (!PG_ARGISNULL(2)) {
513  max_err = PG_GETARG_FLOAT8(2);
514  if (max_err < 0.) max_err = 0.;
515  }
516  POSTGIS_RT_DEBUGF(4, "max_err: %f", max_err);
517 
518  /* source SRID */
519  src_srid = clamp_srid(rt_raster_get_srid(raster));
520  POSTGIS_RT_DEBUGF(4, "source SRID: %d", src_srid);
521 
522  /* target SRID */
523  if (!PG_ARGISNULL(3)) {
524  dst_srid = clamp_srid(PG_GETARG_INT32(3));
525  if (dst_srid == SRID_UNKNOWN) {
526  rt_raster_destroy(raster);
527  PG_FREE_IF_COPY(pgraster, 0);
528  elog(ERROR, "RASTER_GDALWarp: %d is an invalid target SRID", dst_srid);
529  PG_RETURN_NULL();
530  }
531  }
532  else
533  dst_srid = src_srid;
534  POSTGIS_RT_DEBUGF(4, "destination SRID: %d", dst_srid);
535 
536  /* target SRID != src SRID, error */
537  if (src_srid == SRID_UNKNOWN && dst_srid != src_srid) {
538  rt_raster_destroy(raster);
539  PG_FREE_IF_COPY(pgraster, 0);
540  elog(ERROR, "RASTER_GDALWarp: Input raster has unknown (%d) SRID", src_srid);
541  PG_RETURN_NULL();
542  }
543  /* target SRID == src SRID, no reprojection */
544  else if (dst_srid == src_srid) {
545  no_srid = 1;
546  }
547 
548  /* scale x */
549  if (!PG_ARGISNULL(4)) {
550  scale[0] = PG_GETARG_FLOAT8(4);
551  if (FLT_NEQ(scale[0], 0)) scale_x = &scale[0];
552  }
553 
554  /* scale y */
555  if (!PG_ARGISNULL(5)) {
556  scale[1] = PG_GETARG_FLOAT8(5);
557  if (FLT_NEQ(scale[1], 0)) scale_y = &scale[1];
558  }
559 
560  /* grid alignment x */
561  if (!PG_ARGISNULL(6)) {
562  gridw[0] = PG_GETARG_FLOAT8(6);
563  grid_xw = &gridw[0];
564  }
565 
566  /* grid alignment y */
567  if (!PG_ARGISNULL(7)) {
568  gridw[1] = PG_GETARG_FLOAT8(7);
569  grid_yw = &gridw[1];
570  }
571 
572  /* skew x */
573  if (!PG_ARGISNULL(8)) {
574  skew[0] = PG_GETARG_FLOAT8(8);
575  if (FLT_NEQ(skew[0], 0)) skew_x = &skew[0];
576  }
577 
578  /* skew y */
579  if (!PG_ARGISNULL(9)) {
580  skew[1] = PG_GETARG_FLOAT8(9);
581  if (FLT_NEQ(skew[1], 0)) skew_y = &skew[1];
582  }
583 
584  /* width */
585  if (!PG_ARGISNULL(10)) {
586  dim[0] = PG_GETARG_INT32(10);
587  if (dim[0] < 0) dim[0] = 0;
588  if (dim[0] > 0) dim_x = &dim[0];
589  }
590 
591  /* height */
592  if (!PG_ARGISNULL(11)) {
593  dim[1] = PG_GETARG_INT32(11);
594  if (dim[1] < 0) dim[1] = 0;
595  if (dim[1] > 0) dim_y = &dim[1];
596  }
597 
598  /* check that at least something is to be done */
599  if (
600  (dst_srid == SRID_UNKNOWN) &&
601  (scale_x == NULL) && (scale_y == NULL) &&
602  (grid_xw == NULL) && (grid_yw == NULL) &&
603  (skew_x == NULL) && (skew_y == NULL) &&
604  (dim_x == NULL) && (dim_y == NULL)
605  ) {
606  elog(NOTICE, "No resampling parameters provided. Returning original raster");
607  rt_raster_destroy(raster);
608  PG_RETURN_POINTER(pgraster);
609  }
610  /* both values of alignment must be provided if any one is provided */
611  else if (
612  (grid_xw != NULL && grid_yw == NULL) ||
613  (grid_xw == NULL && grid_yw != NULL)
614  ) {
615  elog(NOTICE, "Values must be provided for both X and Y when specifying the alignment. Returning original raster");
616  rt_raster_destroy(raster);
617  PG_RETURN_POINTER(pgraster);
618  }
619  /* both values of scale must be provided if any one is provided */
620  else if (
621  (scale_x != NULL && scale_y == NULL) ||
622  (scale_x == NULL && scale_y != NULL)
623  ) {
624  elog(NOTICE, "Values must be provided for both X and Y when specifying the scale. Returning original raster");
625  rt_raster_destroy(raster);
626  PG_RETURN_POINTER(pgraster);
627  }
628  /* scale and width/height provided */
629  else if (
630  (scale_x != NULL || scale_y != NULL) &&
631  (dim_x != NULL || dim_y != NULL)
632  ) {
633  elog(NOTICE, "Scale X/Y and width/height are mutually exclusive. Only provide one. Returning original raster");
634  rt_raster_destroy(raster);
635  PG_RETURN_POINTER(pgraster);
636  }
637 
638  /* get srses from srids */
639  if (!no_srid) {
640  /* source srs */
641  src_srs = rtpg_getSR(src_srid);
642  if (NULL == src_srs) {
643  rt_raster_destroy(raster);
644  PG_FREE_IF_COPY(pgraster, 0);
645  elog(ERROR, "RASTER_GDALWarp: Input raster has unknown SRID (%d)", src_srid);
646  PG_RETURN_NULL();
647  }
648  POSTGIS_RT_DEBUGF(4, "src srs: %s", src_srs);
649 
650  dst_srs = rtpg_getSR(dst_srid);
651  if (NULL == dst_srs) {
652  if (!no_srid) pfree(src_srs);
653  rt_raster_destroy(raster);
654  PG_FREE_IF_COPY(pgraster, 0);
655  elog(ERROR, "RASTER_GDALWarp: Target SRID (%d) is unknown", dst_srid);
656  PG_RETURN_NULL();
657  }
658  POSTGIS_RT_DEBUGF(4, "dst srs: %s", dst_srs);
659  }
660 
661  rast = rt_raster_gdal_warp(
662  raster,
663  src_srs, dst_srs,
664  scale_x, scale_y,
665  dim_x, dim_y,
666  NULL, NULL,
667  grid_xw, grid_yw,
668  skew_x, skew_y,
669  alg, max_err);
670  rt_raster_destroy(raster);
671  PG_FREE_IF_COPY(pgraster, 0);
672  if (!no_srid) {
673  pfree(src_srs);
674  pfree(dst_srs);
675  }
676  if (!rast) {
677  elog(ERROR, "RASTER_band: Could not create transformed raster");
678  PG_RETURN_NULL();
679  }
680 
681  /* add target SRID */
682  rt_raster_set_srid(rast, dst_srid);
683 
684  pgrast = rt_raster_serialize(rast);
685  rt_raster_destroy(rast);
686 
687  if (NULL == pgrast) PG_RETURN_NULL();
688 
689  POSTGIS_RT_DEBUG(3, "RASTER_GDALWarp: done");
690 
691  SET_VARSIZE(pgrast, pgrast->size);
692  PG_RETURN_POINTER(pgrast);
693 }
char * text_to_cstring(const text *textptr)
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:347
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
raster
Be careful!! Zeros function&#39;s input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
rt_raster rt_raster_gdal_warp(rt_raster raster, const char *src_srs, const char *dst_srs, double *scale_x, double *scale_y, int *width, int *height, double *ul_xw, double *ul_yw, double *grid_xw, double *grid_yw, double *skew_x, double *skew_y, GDALResampleAlg resample_alg, double max_err)
Return a warped raster using GDAL Warp API.
Definition: rt_warp.c:178
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
#define FLT_NEQ(x, y)
Definition: librtcore.h:2213
char * rtpg_trim(const char *input)
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
#define FALSE
Definition: dbfopen.c:168
Struct definitions.
Definition: librtcore.h:2230
char * rtpg_getSR(int srid)
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
GDALResampleAlg rt_util_gdal_resample_alg(const char *algname)
Convert cstring name to GDAL Resample Algorithm.
Definition: rt_util.c:91
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:717
char * rtpg_strtoupper(char *str)
Here is the call graph for this function:
Here is the caller graph for this function: