Advertisement
Guest User

Untitled

a guest
Jul 29th, 2016
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.62 KB | None | 0 0
  1. // Include processing functions
  2.  
  3. /**
  4. * brief Definition of a raster processing function.
  5. *
  6. * A GALGRasterProcessFn accepts an array of data as input, applies custom logic and writes the output to padfOutArray.
  7. * Such a function can be passed to GALGRunRasterProcess to apply custom processing to a GDALDataset in chunks and create
  8. * a new GDALDataset.
  9. *
  10. * @param padfInArray The input array of data.
  11. *
  12. * @param padfOutArray The output array of data. On first call (via GDALRunRasterProcess) this will be an empty, initialised array,
  13. * which should be populated with the result of calculations on padfInArray. In subsequent calls it will contain the result of the
  14. * previous window.
  15. *
  16. * @param nWindowXSize the actual x size (width) of the read window.
  17. *
  18. * @param nWindowYSize the actual y size (height) of the read window. The length of padfInArray == padfOutArray == nWindowXSize * nWindowYSize
  19. *
  20. * @param pData Process-specific data. This data is passed straight through to the GDALRasterProcessFn and may contain e.g user defined parameters.
  21. * The GDALRasterProcessFn definition would define the structure/type of such data.
  22. *
  23. * @param pdfNoDataValue The no data value of the dataset
  24. */
  25.  
  26. typedef GALGError (*rasterProcessFn)(double *padfInArray, double *padfOutArray,
  27. int nWindowXSize, int nWindowYSize, void *pData,
  28. double *pdfInNoDataValue, double *pdfOutNoDataValue);
  29.  
  30.  
  31. class GALG_EXPORT RasterProcess {
  32.  
  33. public:
  34. RasterProcess();
  35.  
  36.  
  37. /**
  38. * brief Apply a raster processing function to each sub-window of a raster.
  39. *
  40. * The input raster dataset is read in chunks of nWindowXSize * nWindowYSize and each chunk is passed to the processing
  41. * function. The output array from the function is written to the destination dataset.
  42. * An optional 'pixel buffer' can be specified to allow overlaps between successive windows. This is useful for
  43. * some algorithms, e.g. blob extraction, watershed/stream flow analysis, convolution etc.
  44. * Process specific data can be passed (e.g. configuration parameters). This data is simply passed straight through to the processing
  45. * function on each call.
  46. *
  47. * @param processFn A GALGRasterProcessFn to apply to each sub window of the raster.
  48. *
  49. * @param inputPathStr Path to the source raster dataset from which pixel values are read
  50. *
  51. * @param outputPathStr Path to the desired output GeoTiff dataset
  52. *
  53. * @param dataObject Process-specific data. This is passed straight through to the GDALRasterProcessFn on each call.
  54. *
  55. * @param windowXSize The desired width of each read window. If NULL it defaults to the 'natural' block size of the raster
  56. *
  57. * @param windowYSize The desired height of each read window. If NULL it defaults to the 'natural' block size.
  58. *
  59. * @param nPixelBuffer A pixel buffer to apply to the read window. The read window is expanded by pnPixelBuffer pixels in all directions such that
  60. * each window overlaps by pnPixelBuffer pixels.
  61. *
  62. * @param skipHoles If true, will skip processing blocks which contain only no data values and create a sparse geotiff. Only available for geotiff inputs
  63. *
  64. * @return a GALGError struct indicating whether the process succeeded.
  65. */
  66. GALGError map(rasterProcessFn processFn, const char *inputPathStr,
  67. const char *outputPathStr, void *dataObject, int *windowXSize,
  68. int *windowYSize, int *nPixelBuffer, bool skipHoles);
  69.  
  70. /**
  71. * brief Apply multiple raster processing functions to each sub-window of a raster
  72. *
  73. * For each window, the functions defined by the paProcessFn array are called in turn, with the array output of the previous function forming the input
  74. * to the next function. This allows processing 'toolchains' to be built without having to create intermediate datasets, which can be less efficient in time and space.
  75. *
  76. *
  77. * @param processFnArray An array of GDALRasterProcessFn to apply to each sub window of the raster
  78. *
  79. * @param nProcesses The size of paProcessFn
  80. *
  81. * @param inputPathStr The path to the source raster dataset from which pixel values are read
  82. *
  83. * @param outputPathStr The path to the destination raster dataset to which pixel values are written. Must support RasterIO in write mode.
  84. *
  85. * @param dataObjectArray an array of process-specific data objects of size nProcesses. Each data object will be passed to the corresponding GDALRasterProcessFn
  86. *
  87. * @param windowXSize The desired width of each read window. If NULL it defaults to the 'natural' block size of the raster
  88. *
  89. * @param windowYSize The desired height of each read window. If NULL it defaults to the 'natural' block size.
  90. *
  91. * @param nPixelBuffer A pixel buffer to apply to the read window. The read window is expanded by pnPixelBuffer pixels in all directions such that
  92. * each window overlaps by pnPixelBuffer pixels.
  93. *
  94. * @param skipHoles If true, will skip processing blocks which contain only no data values and create a sparse geotiff. Only available for geotiff inputs
  95. *
  96. * @return a GALGError struct indicating whether the process succeeded.
  97. */
  98. GALGError mapMany(rasterProcessFn **processFnArray, int nProcesses,
  99. const char *inputPathStr, const char *outputPathStr, void **dataObjectArray,
  100. int *windowXSize, int *windowYSize, int *nPixelBuffer, bool skipHoles);
  101.  
  102.  
  103. /**
  104. * brief Apply a raster processing 'reduction' function to each sub-window of multiple raster datasets.
  105. *
  106. * TODO: Complete
  107. */
  108. GALGError reduce(rasterProcessFn processFn, const char **inputPathStrArray,
  109. const char *outputPathStr, void *dataObject, int *windowXSize,
  110. int *windowYSize, int *nPixelBuffer, bool skipHoles);
  111.  
  112.  
  113. };
  114.  
  115. GALGError createOutputDataset(GDALDataset *srcDataset, const char *outputPathStr, GDALDataset *dstDataset, bool skipHoles) {
  116. GALGError errResult = { 0, NULL };
  117.  
  118. const char *formatStr = "GTiff";
  119. GDALDriver *gdalDriver;
  120. gdalDriver = GetGDALDriverManager()->GetDriverByName(formatStr);
  121.  
  122. RETURNIF(gdalDriver == NULL, 1, "Could not initialise Geotiff driver")
  123.  
  124. char **optionStrArray;
  125. optionStrArray = CSLSetNameValue(optionStrArray, "TILED", "YES");
  126. optionStrArray = CSLSetNameValue(optionStrArray, "COMPRESS", "LZW");
  127. if (skipHoles) {
  128. optionStrArray = CSLSetNameValue(optionStrArray, "SPARSE_OK", "TRUE");
  129. }
  130.  
  131. dstDataset = gdalDriver->Create(outputPathStr, srcDataset->GetRasterXSize(), srcDataset->GetRasterYSize(),
  132. srcDataset->GetRasterCount(), srcDataset->GetRasterBand(1)->GetRasterDataType(),
  133. optionStrArray);
  134.  
  135. RETURNIF(dstDataset == NULL, 1, "Could not create output dataset");
  136.  
  137. double geotransform[6];
  138. srcDataset->GetGeoTransform(geotransform);
  139. dstDataset->SetGeoTransform(geotransform);
  140. dstDataset->SetProjection(srcDataset->GetProjectionRef());
  141.  
  142. GDALRasterBand *srcBand, *dstBand;
  143. for (int ixBand = 0; ixBand < srcDataset->GetRasterCount(); ++ixBand) {
  144. srcBand = srcDataset->GetRasterBand(ixBand + 1);
  145. dstBand = dstDataset->GetRasterBand(ixBand + 1);
  146. dstBand->SetNoDataValue(srcBand->GetNoDataValue());
  147. }
  148. return errResult;
  149. }
  150.  
  151. RasterProcess::RasterProcess(){
  152.  
  153. }
  154.  
  155. GALGError RasterProcess::map(rasterProcessFn processFn, const char *inputPathStr,
  156. const char *outputPathStr, void *dataObject, int *windowXSize,
  157. int *windowYSize, int *nPixelBuffer, bool skipHoles) {
  158.  
  159. GALGError result = { 0, NULL };
  160. GDALDataset *srcDataset = NULL, *dstDataset = NULL;
  161.  
  162. // Open the input dataset and verify
  163. srcDataset = (GDALDataset *)GDALOpenEx(inputPathStr, NULL, NULL, NULL, NULL);
  164. RETURNIF(srcDataset == NULL, 1, "Could not open source dataset");
  165.  
  166. // Create output dataset and verify
  167. result = createOutputDataset(srcDataset, outputPathStr, dstDataset, skipHoles);
  168. RETURNIF(result.errnum != 0, result.errnum, result.msg);
  169.  
  170. // Setup the iterator. If pixelBuffer was passed, we created a buffered iterator,
  171. // otherwise use a standard BlockIterator
  172. BlockIterator *iterator = NULL;
  173. if (nPixelBuffer != NULL) {
  174. iterator = new BufferedIterator(dstDataset, *nPixelBuffer);
  175. } else {
  176. iterator = new BlockIterator(dstDataset);
  177. }
  178. RETURNIF(iterator == NULL, 1, "Unable to allocate memory for BlockIterator");
  179. iterator->setBlockSize(*windowXSize, *windowYSize);
  180.  
  181. // Prepare the data buffers
  182. double *bufInputData = NULL, *bufOutputData = NULL;
  183. bufInputData = (double *) VSIMalloc2((size_t) * windowXSize,
  184. (size_t) * windowYSize);
  185. bufOutputData = (double *) VSIMalloc2((size_t) * windowXSize,
  186. (size_t) * windowYSize);
  187. RETURNIF(bufInputData == NULL || bufOutputData == NULL, 1, "Unable to allocate data arrays");
  188.  
  189. int nBands = srcDataset->GetRasterCount();
  190. int xOff, yOff, xSize, ySize;
  191. GDALRasterBand *srcBand, *dstBand;
  192. double inNoDataValue, outNoDataValue;
  193. int bSuccess;
  194.  
  195. // Apply the process function to each sub window of each band
  196. // in the dataset
  197. for (int iBand = 0; iBand < nBands; ++iBand) {
  198.  
  199. srcBand = srcDataset->GetRasterBand(iBand);
  200. dstBand = dstDataset->GetRasterBand(iBand);
  201. inNoDataValue = srcBand->GetNoDataValue(&bSuccess);
  202. outNoDataValue = dstBand->GetNoDataValue(&bSuccess);
  203.  
  204. while (iterator->next(&xSize, &ySize, &xOff, &yOff)) {
  205.  
  206. // Read input data. TODO:: Verify function ran
  207. srcBand->RasterIO(GF_Read, xOff, yOff, xSize, ySize,
  208. bufInputData, xSize, ySize, GDT_Float64, 0, 0);
  209.  
  210. // Call the process function. TODO: Verify output
  211. processFn(bufInputData, bufOutputData, xSize, ySize, dataObject,
  212. &inNoDataValue, &outNoDataValue);
  213.  
  214. // Write out the result. TODO: Verify function ran
  215. dstBand->RasterIO(GF_Write, xOff, yOff, xSize, ySize,
  216. bufOutputData, xSize, ySize, GDT_Float64, 0, 0);
  217. }
  218. }
  219.  
  220. return result;
  221. }
  222.  
  223. GALGError RasterProcess::mapMany(rasterProcessFn **processFnArray, int nProcesses,
  224. const char *inputPathStr, const char *outputPathStr, void **dataObjectArray,
  225. int *windowXSize, int *windowYSize, int *nPixelBuffer, bool skipHoles) {
  226.  
  227. GALGError result = { 1, "Not Implemented" };
  228.  
  229. // TODO
  230.  
  231. return result;
  232. }
  233.  
  234. GALGError RasterProcess::reduce(rasterProcessFn processFn, const char **inputPathStrArray,
  235. const char *outputPathStr, void *dataObject, int *windowXSize,
  236. int *windowYSize, int *nPixelBuffer, bool skipHoles){
  237. GALGError result = { 1, "Not Implemented" };
  238.  
  239. // TODO
  240.  
  241. return result;
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement