14

I am currently working on two-scan raster algorithms (euclidean distance transformations, cost surface analysis, etc.). Those algorithms require a line-wise forward raster scan (from top left to bottom right) as well as a backward/reversed raster scan (from bottom right to top left).

I am currently using GDAL to read the raster data using the C++ code provided by the tutorial.

float *pafScanline;
int   nXSize = poBand->GetXSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, 1,
                pafScanline, nXSize, 1, GDT_Float32,
                0, 0 );

The RasterIo method reads the raster as scanlines into dynamically allocated memory (provided by CPLMalloc) and it does so from left to right. Up to now I did not find any GDAL methods to read a raster scanline from right to left (eg. backwards).

My question: Is there any better method to achieve a backwards raster scan than reading the scanline from left to right and then reorder the values (which would mean that the scanline has to be processed twice)?

7
  • I'm confused. The RasterIO call just fills the buffer pafScanline. You then need to execute your algorithm on the buffer, presumably by iterating over the contents. When you operate left to right, you iterate with your index running from 0 to nXSize. Why can't you just iterate from nXSize to 0 when you want to operate right to left?
    – Llaves
    Jan 20, 2021 at 4:55
  • I understand your confusion. I know that, under normal circumstances I could iterate beginning with the last element, counting down. In my case I am working within QgsNineCellFilter which uses OpenCL. The iteration is controlled by OpenCL and is performed from left to right. Thats why I have been looking for a solution on the GDAL side. I have not yet checked if OpenCL provides a method to scan the buffer backwards.
    – root676
    Jan 20, 2021 at 8:39
  • 2
    Thanks. I actually wondered for a moment if the issue had something to do with GPU calls.
    – Llaves
    Jan 21, 2021 at 14:37
  • 2
    Unoptimised working code is better than no working code. ;) I don't think miracles are possible and you either need to read often or cache parts.
    – Al rl
    Mar 20, 2021 at 22:49
  • 1
    I guarantee you that there is no free lunch for this one - someone has to invert it somewhere - that data comes out of the decompression (or eventually direct I/O for uncompressed files) and it comes in forward order - someone has to invert it Jan 12, 2022 at 10:24

1 Answer 1

1

RasterIO supports negative line/pixel spaces - but this comes at a cost, since you won't benefit from the CPU L1 cache Pass a pointer to the end of your buffer and set pixelSpace = -sizeof(type), lineSpace = -sizeof(type) * lineLen

In your case this would be

float *pafScanline;
int   nXSize = poBand->GetXSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, 1,
                pafScanline + (XSize-1)*sizeof(float),
                nXSize, 1, GDT_Float32,
                -sizeof(float), -sizeof(float)*XSize );

This is used both by the Python numpy implementation (numpy arrays can go backwards) and the Node.js ndarray implementation (Disclaimer: of which I am the author).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.