PostGIS  2.1.10dev-r@@SVN_REVISION@@
rt_errorstate rt_band_load_offline_data ( rt_band  band)

Load offline band's data.

Loaded data is internally owned and should not be released by the caller. Data will be released when band is destroyed with rt_band_destroy().

Parameters
band: the band who's data to get
Returns
ES_NONE if success, ES_ERROR if failure

Definition at line 1739 of file rt_api.c.

References rt_band_t::data, rt_context_t::err, ES_ERROR, ES_NONE, window::gt, rt_band_t::hasnodata, rt_band_t::height, rt_band_t::mem, pixval::nband, rt_band_t::nodataval, rt_band_t::offline, rt_band_t::pixtype, rt_band_t::raster, RASTER_DEBUG, RASTER_DEBUGF, rt_raster_destroy(), rt_raster_from_gdal_dataset(), rt_raster_geopoint_to_cell(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_new(), rt_raster_same_alignment(), rt_raster_set_geotransform_matrix(), rt_raster_set_srid(), rt_util_gdal_open(), rt_util_gdal_register_all(), rt_util_pixtype_to_gdal_datatype(), rtdealloc(), rterror(), rtwarn(), rt_raster_t::srid, and rt_band_t::width.

Referenced by rt_band_get_data(), and test_band_metadata().

1739  {
1740  GDALDatasetH hdsSrc = NULL;
1741  int nband = 0;
1742  VRTDatasetH hdsDst = NULL;
1743  VRTSourcedRasterBandH hbandDst = NULL;
1744  double gt[6] = {0.};
1745  double ogt[6] = {0};
1746  double offset[2] = {0};
1747 
1748  rt_raster _rast = NULL;
1749  rt_band _band = NULL;
1750  int aligned = 0;
1751  int err = ES_NONE;
1752 
1753  assert(band != NULL);
1754  assert(band->raster != NULL);
1755 
1756  if (!band->offline) {
1757  rterror("rt_band_load_offline_data: Band is not offline");
1758  return ES_ERROR;
1759  }
1760  else if (!strlen(band->data.offline.path)) {
1761  rterror("rt_band_load_offline_data: Offline band does not a have a specified file");
1762  return ES_ERROR;
1763  }
1764 
1765  /* out-db is disabled */
1766  if (!enable_outdb_rasters) {
1767  rterror("rt_raster_load_offline_data: Access to offline bands disabled");
1768  return ES_ERROR;
1769  }
1770 
1772  /*
1773  hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 1);
1774  */
1775  hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 0);
1776  if (hdsSrc == NULL) {
1777  rterror("rt_band_load_offline_data: Cannot open offline raster: %s", band->data.offline.path);
1778  return ES_ERROR;
1779  }
1780 
1781  /* # of bands */
1782  nband = GDALGetRasterCount(hdsSrc);
1783  if (!nband) {
1784  rterror("rt_band_load_offline_data: No bands found in offline raster: %s", band->data.offline.path);
1785  GDALClose(hdsSrc);
1786  return ES_ERROR;
1787  }
1788  /* bandNum is 0-based */
1789  else if (band->data.offline.bandNum + 1 > nband) {
1790  rterror("rt_band_load_offline_data: Specified band %d not found in offline raster: %s", band->data.offline.bandNum, band->data.offline.path);
1791  GDALClose(hdsSrc);
1792  return ES_ERROR;
1793  }
1794 
1795  /* get raster's geotransform */
1797  RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)",
1798  gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]);
1799 
1800  /* get offline raster's geotransform */
1801  if (GDALGetGeoTransform(hdsSrc, ogt) != CE_None) {
1802  RASTER_DEBUG(4, "Using default geotransform matrix (0, 1, 0, 0, 0, -1)");
1803  ogt[0] = 0;
1804  ogt[1] = 1;
1805  ogt[2] = 0;
1806  ogt[3] = 0;
1807  ogt[4] = 0;
1808  ogt[5] = -1;
1809  }
1810  RASTER_DEBUGF(3, "Offline geotransform (%f, %f, %f, %f, %f, %f)",
1811  ogt[0], ogt[1], ogt[2], ogt[3], ogt[4], ogt[5]);
1812 
1813  /* are rasters aligned? */
1814  _rast = rt_raster_new(1, 1);
1816  rt_raster_set_srid(_rast, band->raster->srid);
1817  err = rt_raster_same_alignment(band->raster, _rast, &aligned, NULL);
1818  rt_raster_destroy(_rast);
1819 
1820  if (err != ES_NONE) {
1821  rterror("rt_band_load_offline_data: Could not test alignment of in-db representation of out-db raster");
1822  GDALClose(hdsSrc);
1823  return ES_ERROR;
1824  }
1825  else if (!aligned) {
1826  rtwarn("The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
1827  }
1828 
1829  /* get offsets */
1831  band->raster,
1832  ogt[0], ogt[3],
1833  &(offset[0]), &(offset[1]),
1834  NULL
1835  );
1836 
1837  RASTER_DEBUGF(4, "offsets: (%f, %f)", offset[0], offset[1]);
1838 
1839  /* create VRT dataset */
1840  hdsDst = VRTCreate(band->width, band->height);
1841  GDALSetGeoTransform(hdsDst, gt);
1842  /*
1843  GDALSetDescription(hdsDst, "/tmp/offline.vrt");
1844  */
1845 
1846  /* add band as simple sources */
1847  GDALAddBand(hdsDst, rt_util_pixtype_to_gdal_datatype(band->pixtype), NULL);
1848  hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, 1);
1849 
1850  if (band->hasnodata)
1851  GDALSetRasterNoDataValue(hbandDst, band->nodataval);
1852 
1853  VRTAddSimpleSource(
1854  hbandDst, GDALGetRasterBand(hdsSrc, band->data.offline.bandNum + 1),
1855  fabs(offset[0]), fabs(offset[1]),
1856  band->width, band->height,
1857  0, 0,
1858  band->width, band->height,
1859  "near", VRT_NODATA_UNSET
1860  );
1861 
1862  /* make sure VRT reflects all changes */
1863  VRTFlushCache(hdsDst);
1864 
1865  /* convert VRT dataset to rt_raster */
1866  _rast = rt_raster_from_gdal_dataset(hdsDst);
1867 
1868  GDALClose(hdsDst);
1869  /* XXX: need to find a way to clean up the GDALOpenShared datasets at end of transaction */
1870  /* GDALClose(hdsSrc); */
1871  GDALClose(hdsSrc);
1872 
1873  if (_rast == NULL) {
1874  rterror("rt_band_load_offline_data: Cannot load data from offline raster: %s", band->data.offline.path);
1875  return ES_ERROR;
1876  }
1877 
1878  _band = rt_raster_get_band(_rast, 0);
1879  if (_band == NULL) {
1880  rterror("rt_band_load_offline_data: Cannot load data from offline raster: %s", band->data.offline.path);
1881  rt_raster_destroy(_rast);
1882  return ES_ERROR;
1883  }
1884 
1885  /* band->data.offline.mem not NULL, free first */
1886  if (band->data.offline.mem != NULL) {
1887  rtdealloc(band->data.offline.mem);
1888  band->data.offline.mem = NULL;
1889  }
1890 
1891  band->data.offline.mem = _band->data.mem;
1892 
1893  rtdealloc(_band); /* cannot use rt_band_destroy */
1894  rt_raster_destroy(_rast);
1895 
1896  return ES_NONE;
1897 }
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
Definition: rt_api.c:9339
int rt_util_gdal_register_all(int force_register_all)
Definition: rt_api.c:445
int32_t srid
Definition: rt_api.h:2225
void rtdealloc(void *mem)
Definition: rt_api.c:882
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
rt_raster raster
Definition: rt_api.h:2249
rt_pixtype pixtype
Definition: rt_api.h:2239
tuple gt
Definition: window.py:79
uint16_t height
Definition: rt_api.h:2242
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_api.c:5668
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
Definition: rt_api.c:487
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_api.c:6005
#define RASTER_DEBUG(level, msg)
Definition: rt_api.h:281
void rtwarn(const char *fmt,...)
Definition: rt_api.c:920
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
tuple nband
Definition: pixval.py:52
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition: rt_api.c:6026
double nodataval
Definition: rt_api.h:2246
uint16_t width
Definition: rt_api.h:2241
union rt_band_t::@14 data
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
int32_t offline
Definition: rt_api.h:2240
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_api.c:5686
void * mem
Definition: rt_api.h:2252
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw,yw map point to a xr,yr raster point.
Definition: rt_api.c:6105
int32_t hasnodata
Definition: rt_api.h:2243
char enable_outdb_rasters
Definition: rt_api.c:1727
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_api.c:5353
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
Definition: rt_api.c:12774
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
Definition: rt_api.c:229

Here is the call graph for this function:

Here is the caller graph for this function: