PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ rt_raster_to_gdal_mem()

GDALDatasetH rt_raster_to_gdal_mem ( rt_raster  raster,
const char *  srs,
uint32_t bandNums,
int *  excludeNodataValues,
int  count,
GDALDriverH *  rtn_drv,
int *  destroy_rtn_drv 
)

Return GDAL dataset using GDAL MEM driver from raster.

Parameters
raster: raster to convert to GDAL MEM
srs: the raster's coordinate system in OGC WKT
bandNums: array of band numbers to extract from raster and include in the GDAL dataset (0 based)
excludeNodataValues: array of zero, nonzero where if non-zero, ignore nodata values for the band to check for pixels with value
count: number of elements in bandNums and exclude_nodata_values
rtn_drv: is set to the GDAL driver object
destroy_rtn_drv: if non-zero, caller must destroy the MEM driver
Returns
GDAL dataset using GDAL MEM driver
Parameters
raster: raster to convert to GDAL MEM
srs: the raster's coordinate system in OGC WKT
bandNums: array of band numbers to extract from raster and include in the GDAL dataset (0 based)
excludeNodataValues: array of zero, nonzero where if non-zero, ignore nodata values for the band
count: number of elements in bandNums
rtn_drv: is set to the GDAL driver object
destroy_rtn_drv: if non-zero, caller must destroy the MEM driver
Returns
GDAL dataset using GDAL MEM driver

Definition at line 1826 of file rt_raster.c.

1833  {
1834  GDALDriverH drv = NULL;
1835  GDALDatasetH ds = NULL;
1836  double gt[6] = {0.0};
1837  CPLErr cplerr;
1838  GDALDataType gdal_pt = GDT_Unknown;
1839  GDALRasterBandH band;
1840  void *pVoid;
1841  char *pszDataPointer;
1842  char szGDALOption[50];
1843  char *apszOptions[4];
1844  double nodata = 0.0;
1845  int allocBandNums = 0;
1846  int allocNodataValues = 0;
1847 
1848  int i;
1849  uint32_t numBands;
1850  uint32_t width = 0;
1851  uint32_t height = 0;
1852  rt_band rtband = NULL;
1853  rt_pixtype pt = PT_END;
1854 
1855  assert(NULL != raster);
1856  assert(NULL != rtn_drv);
1857  assert(NULL != destroy_rtn_drv);
1858 
1859  *destroy_rtn_drv = 0;
1860 
1861  /* store raster in GDAL MEM raster */
1862  if (!rt_util_gdal_driver_registered("MEM")) {
1863  RASTER_DEBUG(4, "Registering MEM driver");
1864  GDALRegister_MEM();
1865  *destroy_rtn_drv = 1;
1866  }
1867  drv = GDALGetDriverByName("MEM");
1868  if (NULL == drv) {
1869  rterror("rt_raster_to_gdal_mem: Could not load the MEM GDAL driver");
1870  return 0;
1871  }
1872  *rtn_drv = drv;
1873 
1874  /* unload driver from GDAL driver manager */
1875  if (*destroy_rtn_drv) {
1876  RASTER_DEBUG(4, "Deregistering MEM driver");
1877  GDALDeregisterDriver(drv);
1878  }
1879 
1880  width = rt_raster_get_width(raster);
1881  height = rt_raster_get_height(raster);
1882  ds = GDALCreate(
1883  drv, "",
1884  width, height,
1885  0, GDT_Byte, NULL
1886  );
1887  if (NULL == ds) {
1888  rterror("rt_raster_to_gdal_mem: Could not create a GDALDataset to convert into");
1889  return 0;
1890  }
1891 
1892  /* add geotransform */
1894  cplerr = GDALSetGeoTransform(ds, gt);
1895  if (cplerr != CE_None) {
1896  rterror("rt_raster_to_gdal_mem: Could not set geotransformation");
1897  GDALClose(ds);
1898  return 0;
1899  }
1900 
1901  /* set spatial reference */
1902  if (NULL != srs && strlen(srs)) {
1903  char *_srs = rt_util_gdal_convert_sr(srs, 0);
1904  if (_srs == NULL) {
1905  rterror("rt_raster_to_gdal_mem: Could not convert srs to GDAL accepted format");
1906  GDALClose(ds);
1907  return 0;
1908  }
1909 
1910  cplerr = GDALSetProjection(ds, _srs);
1911  CPLFree(_srs);
1912  if (cplerr != CE_None) {
1913  rterror("rt_raster_to_gdal_mem: Could not set projection");
1914  GDALClose(ds);
1915  return 0;
1916  }
1917  RASTER_DEBUGF(3, "Projection set to: %s", GDALGetProjectionRef(ds));
1918  }
1919 
1920  /* process bandNums */
1921  numBands = rt_raster_get_num_bands(raster);
1922  if (NULL != bandNums && count > 0) {
1923  for (i = 0; i < count; i++) {
1924  if (bandNums[i] >= numBands) {
1925  rterror("rt_raster_to_gdal_mem: The band index %d is invalid", bandNums[i]);
1926  GDALClose(ds);
1927  return 0;
1928  }
1929  }
1930  }
1931  else {
1932  count = numBands;
1933  bandNums = (uint32_t *) rtalloc(sizeof(uint32_t) * count);
1934  if (NULL == bandNums) {
1935  rterror("rt_raster_to_gdal_mem: Could not allocate memory for band indices");
1936  GDALClose(ds);
1937  return 0;
1938  }
1939  allocBandNums = 1;
1940  for (i = 0; i < count; i++) bandNums[i] = i;
1941  }
1942 
1943  /* process exclude_nodata_values */
1944  if (NULL == excludeNodataValues) {
1945  excludeNodataValues = (int *) rtalloc(sizeof(int) * count);
1946  if (NULL == excludeNodataValues) {
1947  rterror("rt_raster_to_gdal_mem: Could not allocate memory for NODATA flags");
1948  GDALClose(ds);
1949  return 0;
1950  }
1951  allocNodataValues = 1;
1952  for (i = 0; i < count; i++) excludeNodataValues[i] = 1;
1953  }
1954 
1955  /* add band(s) */
1956  for (i = 0; i < count; i++) {
1957  rtband = rt_raster_get_band(raster, bandNums[i]);
1958  if (NULL == rtband) {
1959  rterror("rt_raster_to_gdal_mem: Could not get requested band index %d", bandNums[i]);
1960  if (allocBandNums) rtdealloc(bandNums);
1961  if (allocNodataValues) rtdealloc(excludeNodataValues);
1962  GDALClose(ds);
1963  return 0;
1964  }
1965 
1966  pt = rt_band_get_pixtype(rtband);
1967  gdal_pt = rt_util_pixtype_to_gdal_datatype(pt);
1968  if (gdal_pt == GDT_Unknown)
1969  rtwarn("rt_raster_to_gdal_mem: Unknown pixel type for band");
1970 
1971  /*
1972  For all pixel types other than PT_8BSI, set pointer to start of data
1973  */
1974  if (pt != PT_8BSI) {
1975  pVoid = rt_band_get_data(rtband);
1976  RASTER_DEBUGF(4, "Band data is at pos %p", pVoid);
1977 
1978  pszDataPointer = (char *) rtalloc(20 * sizeof (char));
1979  sprintf(pszDataPointer, "%p", pVoid);
1980  RASTER_DEBUGF(4, "rt_raster_to_gdal_mem: szDatapointer is %p",
1981  pszDataPointer);
1982 
1983  if (strncasecmp(pszDataPointer, "0x", 2) == 0)
1984  sprintf(szGDALOption, "DATAPOINTER=%s", pszDataPointer);
1985  else
1986  sprintf(szGDALOption, "DATAPOINTER=0x%s", pszDataPointer);
1987 
1988  RASTER_DEBUG(3, "Storing info for GDAL MEM raster band");
1989 
1990  apszOptions[0] = szGDALOption;
1991  apszOptions[1] = NULL; /* pixel offset, not needed */
1992  apszOptions[2] = NULL; /* line offset, not needed */
1993  apszOptions[3] = NULL;
1994 
1995  /* free */
1996  rtdealloc(pszDataPointer);
1997 
1998  /* add band */
1999  if (GDALAddBand(ds, gdal_pt, apszOptions) == CE_Failure) {
2000  rterror("rt_raster_to_gdal_mem: Could not add GDAL raster band");
2001  if (allocBandNums) rtdealloc(bandNums);
2002  GDALClose(ds);
2003  return 0;
2004  }
2005  }
2006  /*
2007  PT_8BSI is special as GDAL has no equivalent pixel type.
2008  Must convert 8BSI to 16BSI so create basic band
2009  */
2010  else {
2011  /* add band */
2012  if (GDALAddBand(ds, gdal_pt, NULL) == CE_Failure) {
2013  rterror("rt_raster_to_gdal_mem: Could not add GDAL raster band");
2014  if (allocBandNums) rtdealloc(bandNums);
2015  if (allocNodataValues) rtdealloc(excludeNodataValues);
2016  GDALClose(ds);
2017  return 0;
2018  }
2019  }
2020 
2021  /* check band count */
2022  if (GDALGetRasterCount(ds) != i + 1) {
2023  rterror("rt_raster_to_gdal_mem: Error creating GDAL MEM raster band");
2024  if (allocBandNums) rtdealloc(bandNums);
2025  if (allocNodataValues) rtdealloc(excludeNodataValues);
2026  GDALClose(ds);
2027  return 0;
2028  }
2029 
2030  /* get new band */
2031  band = NULL;
2032  band = GDALGetRasterBand(ds, i + 1);
2033  if (NULL == band) {
2034  rterror("rt_raster_to_gdal_mem: Could not get GDAL band for additional processing");
2035  if (allocBandNums) rtdealloc(bandNums);
2036  if (allocNodataValues) rtdealloc(excludeNodataValues);
2037  GDALClose(ds);
2038  return 0;
2039  }
2040 
2041  /* PT_8BSI requires manual setting of pixels */
2042  if (pt == PT_8BSI) {
2043  uint32_t nXBlocks, nYBlocks;
2044  int nXBlockSize, nYBlockSize;
2045  uint32_t iXBlock, iYBlock;
2046  int nXValid, nYValid;
2047  int iX, iY;
2048  int iXMax, iYMax;
2049 
2050  int x, y, z;
2051  uint32_t valueslen = 0;
2052  int16_t *values = NULL;
2053  double value = 0.;
2054 
2055  /* this makes use of GDAL's "natural" blocks */
2056  GDALGetBlockSize(band, &nXBlockSize, &nYBlockSize);
2057  nXBlocks = (width + nXBlockSize - 1) / nXBlockSize;
2058  nYBlocks = (height + nYBlockSize - 1) / nYBlockSize;
2059  RASTER_DEBUGF(4, "(nXBlockSize, nYBlockSize) = (%d, %d)", nXBlockSize, nYBlockSize);
2060  RASTER_DEBUGF(4, "(nXBlocks, nYBlocks) = (%d, %d)", nXBlocks, nYBlocks);
2061 
2062  /* length is for the desired pixel type */
2063  valueslen = rt_pixtype_size(PT_16BSI) * nXBlockSize * nYBlockSize;
2064  values = rtalloc(valueslen);
2065  if (NULL == values) {
2066  rterror("rt_raster_to_gdal_mem: Could not allocate memory for GDAL band pixel values");
2067  if (allocBandNums) rtdealloc(bandNums);
2068  if (allocNodataValues) rtdealloc(excludeNodataValues);
2069  GDALClose(ds);
2070  return 0;
2071  }
2072 
2073  for (iYBlock = 0; iYBlock < nYBlocks; iYBlock++) {
2074  for (iXBlock = 0; iXBlock < nXBlocks; iXBlock++) {
2075  memset(values, 0, valueslen);
2076 
2077  x = iXBlock * nXBlockSize;
2078  y = iYBlock * nYBlockSize;
2079  RASTER_DEBUGF(4, "(iXBlock, iYBlock) = (%d, %d)", iXBlock, iYBlock);
2080  RASTER_DEBUGF(4, "(x, y) = (%d, %d)", x, y);
2081 
2082  /* valid block width */
2083  if ((iXBlock + 1) * nXBlockSize > width)
2084  nXValid = width - (iXBlock * nXBlockSize);
2085  else
2086  nXValid = nXBlockSize;
2087 
2088  /* valid block height */
2089  if ((iYBlock + 1) * nYBlockSize > height)
2090  nYValid = height - (iYBlock * nYBlockSize);
2091  else
2092  nYValid = nYBlockSize;
2093 
2094  RASTER_DEBUGF(4, "(nXValid, nYValid) = (%d, %d)", nXValid, nYValid);
2095 
2096  /* convert 8BSI values to 16BSI */
2097  z = 0;
2098  iYMax = y + nYValid;
2099  iXMax = x + nXValid;
2100  for (iY = y; iY < iYMax; iY++) {
2101  for (iX = x; iX < iXMax; iX++) {
2102  if (rt_band_get_pixel(rtband, iX, iY, &value, NULL) != ES_NONE) {
2103  rterror("rt_raster_to_gdal_mem: Could not get pixel value to convert from 8BSI to 16BSI");
2104  rtdealloc(values);
2105  if (allocBandNums) rtdealloc(bandNums);
2106  if (allocNodataValues) rtdealloc(excludeNodataValues);
2107  GDALClose(ds);
2108  return 0;
2109  }
2110 
2111  values[z++] = rt_util_clamp_to_16BSI(value);
2112  }
2113  }
2114 
2115  /* burn values */
2116  if (GDALRasterIO(
2117  band, GF_Write,
2118  x, y,
2119  nXValid, nYValid,
2120  values, nXValid, nYValid,
2121  gdal_pt,
2122  0, 0
2123  ) != CE_None) {
2124  rterror("rt_raster_to_gdal_mem: Could not write converted 8BSI to 16BSI values to GDAL band");
2125  rtdealloc(values);
2126  if (allocBandNums) rtdealloc(bandNums);
2127  if (allocNodataValues) rtdealloc(excludeNodataValues);
2128  GDALClose(ds);
2129  return 0;
2130  }
2131  }
2132  }
2133 
2134  rtdealloc(values);
2135  }
2136 
2137  /* Add nodata value for band */
2138  if (rt_band_get_hasnodata_flag(rtband) != FALSE && excludeNodataValues[i]) {
2139  rt_band_get_nodata(rtband, &nodata);
2140  if (GDALSetRasterNoDataValue(band, nodata) != CE_None)
2141  rtwarn("rt_raster_to_gdal_mem: Could not set nodata value for band");
2142  RASTER_DEBUGF(3, "nodata value set to %f", GDALGetRasterNoDataValue(band, NULL));
2143  }
2144 
2145 #if POSTGIS_DEBUG_LEVEL > 3
2146  {
2147  GDALRasterBandH _grb = NULL;
2148  double _min;
2149  double _max;
2150  double _mean;
2151  double _stddev;
2152 
2153  _grb = GDALGetRasterBand(ds, i + 1);
2154  GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL);
2155  RASTER_DEBUGF(4, "GDAL Band %d stats: %f, %f, %f, %f", i + 1, _min, _max, _mean, _stddev);
2156  }
2157 #endif
2158 
2159  }
2160 
2161  /* necessary??? */
2162  GDALFlushCache(ds);
2163 
2164  if (allocBandNums) rtdealloc(bandNums);
2165  if (allocNodataValues) rtdealloc(excludeNodataValues);
2166 
2167  return ds;
2168 }
#define FALSE
Definition: dbfopen.c:168
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:199
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:171
#define RASTER_DEBUG(level, msg)
Definition: librtcore.h:295
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
char * rt_util_gdal_convert_sr(const char *srs, int proj4)
Definition: rt_util.c:212
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:674
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1221
rt_pixtype
Definition: librtcore.h:185
@ PT_END
Definition: librtcore.h:197
@ PT_8BSI
Definition: librtcore.h:189
@ PT_16BSI
Definition: librtcore.h:191
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
Definition: rt_util.c:118
void rtwarn(const char *fmt,...)
Definition: rt_context.c:224
@ ES_NONE
Definition: librtcore.h:180
int16_t rt_util_clamp_to_16BSI(double value)
Definition: rt_util.c:59
int rt_util_gdal_driver_registered(const char *drv)
Definition: rt_util.c:355
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1730
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:631
void rtdealloc(void *mem)
Definition: rt_context.c:186
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
Definition: rt_band.c:400
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
int value
Definition: genraster.py:61
int count
Definition: genraster.py:56
band
Definition: ovdump.py:57
ds
Definition: pixval.py:66
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
gt
Definition: window.py:77
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
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:121
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:706
unsigned int uint32_t
Definition: uthash.h:78

References ovdump::band, genraster::count, pixval::ds, ES_NONE, FALSE, window::gt, PT_16BSI, PT_8BSI, PT_END, rtrowdump::raster, RASTER_DEBUG, RASTER_DEBUGF, rt_band_get_data(), rt_band_get_hasnodata_flag(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_pixtype(), rt_pixtype_size(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_get_height(), rt_raster_get_num_bands(), rt_raster_get_width(), rt_util_clamp_to_16BSI(), rt_util_gdal_convert_sr(), rt_util_gdal_driver_registered(), rt_util_pixtype_to_gdal_datatype(), rtalloc(), rtdealloc(), rterror(), rtwarn(), genraster::value, pixval::x, and pixval::y.

Referenced by rt_raster_gdal_polygonize(), rt_raster_gdal_warp(), rt_raster_to_gdal(), and test_gdal_to_raster().

Here is the call graph for this function:
Here is the caller graph for this function: