|
| 1 | +#include "qgsrasteriterator.h" |
| 2 | +#include "qgsrasterinterface.h" |
| 3 | +#include "qgsrasterprojector.h" |
| 4 | +#include "qgsrasterviewport.h" |
| 5 | + |
| 6 | +QgsRasterIterator::QgsRasterIterator( QgsRasterInterface* input ): mInput( input ) |
| 7 | +{ |
| 8 | +} |
| 9 | + |
| 10 | +QgsRasterIterator::~QgsRasterIterator() |
| 11 | +{ |
| 12 | +} |
| 13 | + |
| 14 | +void QgsRasterIterator::startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel ) |
| 15 | +{ |
| 16 | + if ( !viewPort || !mapToPixel || !mInput ) |
| 17 | + { |
| 18 | + return; |
| 19 | + } |
| 20 | + |
| 21 | + //remove any previous part on that band |
| 22 | + removePartInfo( bandNumber ); |
| 23 | + |
| 24 | + //split raster into small portions if necessary |
| 25 | + RasterPartInfo pInfo; |
| 26 | + pInfo.nCols = viewPort->drawableAreaXDim; |
| 27 | + pInfo.nRows = viewPort->drawableAreaYDim; |
| 28 | + |
| 29 | + //effective oversampling factors are different to global one because of rounding |
| 30 | + //oversamplingX = (( double )pInfo.nCols * oversampling ) / viewPort->drawableAreaXDim; |
| 31 | + //oversamplingY = (( double )pInfo.nRows * oversampling ) / viewPort->drawableAreaYDim; |
| 32 | + |
| 33 | + // TODO : we dont know oversampling (grid size) here - how to get totalMemoryUsage ? |
| 34 | + //int totalMemoryUsage = pInfo.nCols * oversamplingX * pInfo.nRows * oversamplingY * mInput->dataTypeSize( bandNumber ); |
| 35 | + int totalMemoryUsage = pInfo.nCols * pInfo.nRows * mInput->dataTypeSize( bandNumber ); |
| 36 | + int parts = totalMemoryUsage / 100000000 + 1; |
| 37 | + int nPartsPerDimension = sqrt( parts ); |
| 38 | + pInfo.nColsPerPart = pInfo.nCols / nPartsPerDimension; |
| 39 | + pInfo.nRowsPerPart = pInfo.nRows / nPartsPerDimension; |
| 40 | + pInfo.currentCol = 0; |
| 41 | + pInfo.currentRow = 0; |
| 42 | + pInfo.data = 0; |
| 43 | + pInfo.prj = 0; |
| 44 | + mRasterPartInfos.insert( bandNumber, pInfo ); |
| 45 | +} |
| 46 | + |
| 47 | +bool QgsRasterIterator::readNextRasterPart( int bandNumber, QgsRasterViewPort* viewPort, |
| 48 | + int& nCols, int& nRows, |
| 49 | + void** rasterData, |
| 50 | + int& topLeftCol, int& topLeftRow ) |
| 51 | +{ |
| 52 | + if ( !viewPort ) |
| 53 | + { |
| 54 | + return false; |
| 55 | + } |
| 56 | + |
| 57 | + //get partinfo |
| 58 | + QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber ); |
| 59 | + if ( partIt == mRasterPartInfos.end() ) |
| 60 | + { |
| 61 | + return false; |
| 62 | + } |
| 63 | + |
| 64 | + RasterPartInfo& pInfo = partIt.value(); |
| 65 | + |
| 66 | + //remove last data block |
| 67 | + // TODO: data are released somewhere else (check) |
| 68 | + //free( pInfo.data ); |
| 69 | + pInfo.data = 0; |
| 70 | + delete pInfo.prj; |
| 71 | + pInfo.prj = 0; |
| 72 | + |
| 73 | + //already at end |
| 74 | + if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows ) |
| 75 | + { |
| 76 | + return false; |
| 77 | + } |
| 78 | + |
| 79 | + //read data block |
| 80 | + nCols = qMin( pInfo.nColsPerPart, pInfo.nCols - pInfo.currentCol ); |
| 81 | + nRows = qMin( pInfo.nRowsPerPart, pInfo.nRows - pInfo.currentRow ); |
| 82 | + |
| 83 | + //get subrectangle |
| 84 | + QgsRectangle viewPortExtent = viewPort->mDrawnExtent; |
| 85 | + double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / ( double )pInfo.nCols * viewPortExtent.width(); |
| 86 | + double xmax = viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / ( double )pInfo.nCols * viewPortExtent.width(); |
| 87 | + double ymin = viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / ( double )pInfo.nRows * viewPortExtent.height(); |
| 88 | + double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / ( double )pInfo.nRows * viewPortExtent.height(); |
| 89 | + QgsRectangle blockRect( xmin, ymin, xmax, ymax ); |
| 90 | + |
| 91 | + pInfo.data = mInput->block( bandNumber, blockRect, nCols, nRows ); |
| 92 | + |
| 93 | + *rasterData = pInfo.data; |
| 94 | + topLeftCol = pInfo.currentCol; |
| 95 | + topLeftRow = pInfo.currentRow; |
| 96 | + |
| 97 | + pInfo.currentCol += nCols; |
| 98 | + if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster |
| 99 | + { |
| 100 | + pInfo.currentRow = pInfo.nRows; |
| 101 | + } |
| 102 | + else if ( pInfo.currentCol == pInfo.nCols ) //start new row |
| 103 | + { |
| 104 | + pInfo.currentCol = 0; |
| 105 | + pInfo.currentRow += pInfo.nRowsPerPart; |
| 106 | + } |
| 107 | + |
| 108 | + return true; |
| 109 | +} |
| 110 | + |
| 111 | +void QgsRasterIterator::stopRasterRead( int bandNumber ) |
| 112 | +{ |
| 113 | + removePartInfo( bandNumber ); |
| 114 | +} |
| 115 | + |
| 116 | +void QgsRasterIterator::removePartInfo( int bandNumber ) |
| 117 | +{ |
| 118 | + QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber ); |
| 119 | + if ( partIt != mRasterPartInfos.end() ) |
| 120 | + { |
| 121 | + RasterPartInfo& pInfo = partIt.value(); |
| 122 | + //CPLFree( pInfo.data ); |
| 123 | + free( pInfo.data ); |
| 124 | + delete pInfo.prj; |
| 125 | + mRasterPartInfos.remove( bandNumber ); |
| 126 | + } |
| 127 | +} |
0 commit comments