PostGIS  3.2.2dev-r@@SVN_REVISION@@

◆ RASTER_GDALWarp()

Datum RASTER_GDALWarp ( PG_FUNCTION_ARGS  )

Definition at line 834 of file rtpg_gdal.c.

835 {
836  rt_pgraster *pgraster = NULL;
837  rt_pgraster *pgrast = NULL;
838  rt_raster raster = NULL;
839  rt_raster rast = NULL;
840 
841  text *algtext = NULL;
842  char *algchar = NULL;
843  GDALResampleAlg alg = GRA_NearestNeighbour;
844  double max_err = 0.125;
845 
846  int src_srid = SRID_UNKNOWN;
847  char *src_srs = NULL;
848  int dst_srid = SRID_UNKNOWN;
849  char *dst_srs = NULL;
850  int no_srid = 0;
851 
852  double scale[2] = {0};
853  double *scale_x = NULL;
854  double *scale_y = NULL;
855 
856  double gridw[2] = {0};
857  double *grid_xw = NULL;
858  double *grid_yw = NULL;
859 
860  double skew[2] = {0};
861  double *skew_x = NULL;
862  double *skew_y = NULL;
863 
864  int dim[2] = {0};
865  int *dim_x = NULL;
866  int *dim_y = NULL;
867 
868  POSTGIS_RT_DEBUG(3, "RASTER_GDALWarp: Starting");
869 
870  /* pgraster is null, return null */
871  if (PG_ARGISNULL(0))
872  PG_RETURN_NULL();
873  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
874 
875  /* raster */
876  raster = rt_raster_deserialize(pgraster, FALSE);
877  if (!raster) {
878  PG_FREE_IF_COPY(pgraster, 0);
879  elog(ERROR, "RASTER_GDALWarp: Could not deserialize raster");
880  PG_RETURN_NULL();
881  }
882 
883  /* resampling algorithm */
884  if (!PG_ARGISNULL(1)) {
885  algtext = PG_GETARG_TEXT_P(1);
886  algchar = rtpg_trim(rtpg_strtoupper(text_to_cstring(algtext)));
887  alg = rt_util_gdal_resample_alg(algchar);
888  }
889  POSTGIS_RT_DEBUGF(4, "Resampling algorithm: %d", alg);
890 
891  /* max error */
892  if (!PG_ARGISNULL(2)) {
893  max_err = PG_GETARG_FLOAT8(2);
894  if (max_err < 0.) max_err = 0.;
895  }
896  POSTGIS_RT_DEBUGF(4, "max_err: %f", max_err);
897 
898  /* source SRID */
899  src_srid = clamp_srid(rt_raster_get_srid(raster));
900  POSTGIS_RT_DEBUGF(4, "source SRID: %d", src_srid);
901 
902  /* target SRID */
903  if (!PG_ARGISNULL(3)) {
904  dst_srid = clamp_srid(PG_GETARG_INT32(3));
905  if (dst_srid == SRID_UNKNOWN) {
907  PG_FREE_IF_COPY(pgraster, 0);
908  elog(ERROR, "RASTER_GDALWarp: %d is an invalid target SRID", dst_srid);
909  PG_RETURN_NULL();
910  }
911  }
912  else
913  dst_srid = src_srid;
914  POSTGIS_RT_DEBUGF(4, "destination SRID: %d", dst_srid);
915 
916  /* target SRID != src SRID, error */
917  if (src_srid == SRID_UNKNOWN && dst_srid != src_srid) {
919  PG_FREE_IF_COPY(pgraster, 0);
920  elog(ERROR, "RASTER_GDALWarp: Input raster has unknown (%d) SRID", src_srid);
921  PG_RETURN_NULL();
922  }
923  /* target SRID == src SRID, no reprojection */
924  else if (dst_srid == src_srid) {
925  no_srid = 1;
926  }
927 
928  /* scale x */
929  if (!PG_ARGISNULL(4)) {
930  scale[0] = PG_GETARG_FLOAT8(4);
931  if (FLT_NEQ(scale[0], 0.0))
932  scale_x = &scale[0];
933  }
934 
935  /* scale y */
936  if (!PG_ARGISNULL(5)) {
937  scale[1] = PG_GETARG_FLOAT8(5);
938  if (FLT_NEQ(scale[1], 0.0))
939  scale_y = &scale[1];
940  }
941 
942  /* grid alignment x */
943  if (!PG_ARGISNULL(6)) {
944  gridw[0] = PG_GETARG_FLOAT8(6);
945  grid_xw = &gridw[0];
946  }
947 
948  /* grid alignment y */
949  if (!PG_ARGISNULL(7)) {
950  gridw[1] = PG_GETARG_FLOAT8(7);
951  grid_yw = &gridw[1];
952  }
953 
954  /* skew x */
955  if (!PG_ARGISNULL(8)) {
956  skew[0] = PG_GETARG_FLOAT8(8);
957  if (FLT_NEQ(skew[0], 0.0))
958  skew_x = &skew[0];
959  }
960 
961  /* skew y */
962  if (!PG_ARGISNULL(9)) {
963  skew[1] = PG_GETARG_FLOAT8(9);
964  if (FLT_NEQ(skew[1], 0.0))
965  skew_y = &skew[1];
966  }
967 
968  /* width */
969  if (!PG_ARGISNULL(10)) {
970  dim[0] = PG_GETARG_INT32(10);
971  if (dim[0] < 0) dim[0] = 0;
972  if (dim[0] > 0) dim_x = &dim[0];
973  }
974 
975  /* height */
976  if (!PG_ARGISNULL(11)) {
977  dim[1] = PG_GETARG_INT32(11);
978  if (dim[1] < 0) dim[1] = 0;
979  if (dim[1] > 0) dim_y = &dim[1];
980  }
981 
982  /* check that at least something is to be done */
983  if (
984  (dst_srid == SRID_UNKNOWN) &&
985  (scale_x == NULL) && (scale_y == NULL) &&
986  (grid_xw == NULL) && (grid_yw == NULL) &&
987  (skew_x == NULL) && (skew_y == NULL) &&
988  (dim_x == NULL) && (dim_y == NULL)
989  ) {
990  elog(NOTICE, "No resampling parameters provided. Returning original raster");
992  PG_RETURN_POINTER(pgraster);
993  }
994  /* both values of alignment must be provided if any one is provided */
995  else if (
996  (grid_xw != NULL && grid_yw == NULL) ||
997  (grid_xw == NULL && grid_yw != NULL)
998  ) {
999  elog(NOTICE, "Values must be provided for both X and Y when specifying the alignment. Returning original raster");
1001  PG_RETURN_POINTER(pgraster);
1002  }
1003  /* both values of scale must be provided if any one is provided */
1004  else if (
1005  (scale_x != NULL && scale_y == NULL) ||
1006  (scale_x == NULL && scale_y != NULL)
1007  ) {
1008  elog(NOTICE, "Values must be provided for both X and Y when specifying the scale. Returning original raster");
1010  PG_RETURN_POINTER(pgraster);
1011  }
1012  /* scale and width/height provided */
1013  else if (
1014  (scale_x != NULL || scale_y != NULL) &&
1015  (dim_x != NULL || dim_y != NULL)
1016  ) {
1017  elog(NOTICE, "Scale X/Y and width/height are mutually exclusive. Only provide one. Returning original raster");
1019  PG_RETURN_POINTER(pgraster);
1020  }
1021 
1022  /* get srses from srids */
1023  if (!no_srid) {
1024  /* source srs */
1025  src_srs = rtpg_getSR(src_srid);
1026  if (NULL == src_srs) {
1028  PG_FREE_IF_COPY(pgraster, 0);
1029  elog(ERROR, "RASTER_GDALWarp: Input raster has unknown SRID (%d)", src_srid);
1030  PG_RETURN_NULL();
1031  }
1032  POSTGIS_RT_DEBUGF(4, "src srs: %s", src_srs);
1033 
1034  dst_srs = rtpg_getSR(dst_srid);
1035  if (NULL == dst_srs) {
1036  pfree(src_srs);
1038  PG_FREE_IF_COPY(pgraster, 0);
1039  elog(ERROR, "RASTER_GDALWarp: Target SRID (%d) is unknown", dst_srid);
1040  PG_RETURN_NULL();
1041  }
1042  POSTGIS_RT_DEBUGF(4, "dst srs: %s", dst_srs);
1043  }
1044 
1046  raster,
1047  src_srs, dst_srs,
1048  scale_x, scale_y,
1049  dim_x, dim_y,
1050  NULL, NULL,
1051  grid_xw, grid_yw,
1052  skew_x, skew_y,
1053  alg, max_err);
1055  PG_FREE_IF_COPY(pgraster, 0);
1056  if (!no_srid) {
1057  pfree(src_srs);
1058  pfree(dst_srs);
1059  }
1060  if (!rast) {
1061  elog(ERROR, "RASTER_band: Could not create transformed raster");
1062  PG_RETURN_NULL();
1063  }
1064 
1065  /* add target SRID */
1066  rt_raster_set_srid(rast, dst_srid);
1067 
1068  pgrast = rt_raster_serialize(rast);
1070 
1071  if (NULL == pgrast) PG_RETURN_NULL();
1072 
1073  POSTGIS_RT_DEBUG(3, "RASTER_GDALWarp: done");
1074 
1075  SET_VARSIZE(pgrast, pgrast->size);
1076  PG_RETURN_POINTER(pgrast);
1077 }
#define FALSE
Definition: dbfopen.c:72
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:229
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:333
#define FLT_NEQ(x, y)
Definition: librtcore.h:2379
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:360
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:86
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
GDALResampleAlg rt_util_gdal_resample_alg(const char *algname)
Convert cstring name to GDAL Resample Algorithm.
Definition: rt_util.c:94
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:367
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
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
char * rtpg_getSR(int32_t srid)
char * rtpg_strtoupper(char *str)
char * rtpg_trim(const char *input)
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
Struct definitions.
Definition: librtcore.h:2396

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, and SRID_UNKNOWN.

Here is the call graph for this function: