35 #define BICUBIC_MODULE( x ) ( ( x < 0 ) ? ( -1 * x ) : x )
36 #define BICUBIC_K1( x , a ) ( ( ( a + 2 ) * x * x * x ) - \
37 ( ( a + 3 ) * x * x ) + 1 )
38 #define BICUBIC_K2( x , a ) ( ( a * x * x * x ) - ( 5 * a * x * x ) + \
39 ( 8 * a * x ) - ( 4 * a ) )
40 #define BICUBIC_RANGES(x,a) \
41 ( ( ( 0 <= x ) && ( x <= 1 ) ) ? \
43 : ( ( ( 1 < x ) && ( x <= 2 ) ) ? \
46 #define BICUBIC_KERNEL( x , a ) BICUBIC_RANGES( BICUBIC_MODULE(x) , a )
67 for(
unsigned int bandIdx = 0 ; bandIdx < r->
getNumberOfBands() ; ++bandIdx )
99 std::complex<double> v;
101 for(std::size_t b = 0; b < m_raster->getNumberOfBands(); b++)
103 getValue(c, r, v, b);
111 if( ( c > (-0.5) ) && ( r > (-0.5) ) && ( c < m_nnLastCol ) && ( r < m_nnLastRow ) )
116 m_raster->getValue(m_nnCR, m_nnRR, v, b);
120 v = std::complex<double>( m_noDataValues[ b ], m_noDataValues[ b ] );
126 if( (r < 0.0) || (c < 0.0) || (r > m_bilLastRow) || (c > m_bilLastCol) )
128 nearestNeighborGetValue(c, r, v, b);
132 m_bilRowMin = std::floor(r);
133 m_bilRowMax = (m_bilRowMin == r)? m_bilRowMin: (m_bilRowMin + 1.0);
135 m_bilColMin = std::floor(c);
136 m_bilColMax = (m_bilColMin == c)? m_bilColMin: (m_bilColMin + 1.0);
138 m_bilRowDifMin = r - m_bilRowMin;
139 m_bilRowDifMax = m_bilRowMax - r;
141 m_bilColDifMin = c - m_bilColMin;
142 m_bilColDifMax = m_bilColMax - c;
144 m_bilDistances[0] = std::sqrt((m_bilRowDifMin * m_bilRowDifMin) + (m_bilColDifMin * m_bilColDifMin));
145 m_bilDistances[1] = std::sqrt((m_bilRowDifMin * m_bilRowDifMin) + (m_bilColDifMax * m_bilColDifMax));
146 m_bilDistances[2] = std::sqrt((m_bilRowDifMax * m_bilRowDifMax) + (m_bilColDifMin * m_bilColDifMin));
147 m_bilDistances[3] = std::sqrt((m_bilRowDifMax * m_bilRowDifMax) + (m_bilColDifMin * m_bilColDifMax));
149 m_bilWeights[0] = (m_bilDistances[0] == 0)? 1.0: (1 / m_bilDistances[0]);
150 m_bilWeights[1] = (m_bilDistances[1] == 0)? 1.0: (1 / m_bilDistances[1]);
151 m_bilWeights[2] = (m_bilDistances[2] == 0)? 1.0: (1 / m_bilDistances[2]);
152 m_bilWeights[3] = (m_bilDistances[3] == 0)? 1.0: (1 / m_bilDistances[3]);
154 m_raster->getValue((
unsigned) m_bilColMin, (
unsigned) m_bilRowMin, m_bilValues[0], b);
155 m_raster->getValue((
unsigned) m_bilColMax, (
unsigned) m_bilRowMin, m_bilValues[1], b);
156 m_raster->getValue((
unsigned) m_bilColMin, (
unsigned) m_bilRowMax, m_bilValues[2], b);
157 m_raster->getValue((
unsigned) m_bilColMax, (
unsigned) m_bilRowMax, m_bilValues[3], b);
159 double vr = ( (m_bilValues[0].real() * m_bilWeights[0]) +
160 (m_bilValues[1].real() * m_bilWeights[1]) +
161 (m_bilValues[2].real() * m_bilWeights[2]) +
162 (m_bilValues[3].real() * m_bilWeights[3]) ) /
163 (m_bilWeights[0] + m_bilWeights[1] + m_bilWeights[2] + m_bilWeights[3]);
164 double vi = ( (m_bilValues[0].imag() * m_bilWeights[0]) +
165 (m_bilValues[1].imag() * m_bilWeights[1]) +
166 (m_bilValues[2].imag() * m_bilWeights[2]) +
167 (m_bilValues[3].imag() * m_bilWeights[3]) ) /
168 (m_bilWeights[0] + m_bilWeights[1] + m_bilWeights[2] + m_bilWeights[3]);
169 v = std::complex<double>(vr,vi);
172 if( (v.real() == m_raster->getBand(b)->getProperty()->m_noDataValue) ||
173 (v.imag() == m_raster->getBand(b)->getProperty()->m_noDataValue) )
174 nearestNeighborGetValue(c, r, v, b);
179 if( (r <= 1.0) || (c <= 1.0) || (r >= m_bicRowBound) || (c >= m_bicColBound) )
181 nearestNeighborGetValue(c, r, v, b);
185 m_bicGridRow = ((unsigned) std::floor(r)) - 1;
186 m_bicGridCol = ((unsigned) std::floor(c)) - 1;
189 for(m_bicBufRow = 0; m_bicBufRow < 4; ++m_bicBufRow)
191 for(m_bicBufCol = 0; m_bicBufCol < 4 ; ++m_bicBufCol)
193 m_raster->getValue(m_bicGridCol + m_bicBufCol, m_bicGridRow + m_bicBufRow,
194 m_bicBbufferReal[m_bicBufRow][m_bicBufCol], b);
195 m_raster->getIValue(m_bicGridCol + m_bicBufCol, m_bicGridRow + m_bicBufRow,
196 m_bicBbufferImag[m_bicBufRow][m_bicBufCol], b);
201 m_bicOffsetX = c - (double)(m_bicGridCol + 1);
202 m_bicOffsetY = r - (double)(m_bicGridRow + 1);
204 m_bicHWeights[0] =
BICUBIC_KERNEL(1.0 + m_bicOffsetX, m_bicKernel);
206 m_bicHWeights[2] =
BICUBIC_KERNEL(1.0 - m_bicOffsetX, m_bicKernel);
207 m_bicHWeights[3] =
BICUBIC_KERNEL(2.0 - m_bicOffsetX, m_bicKernel);
209 m_bicVWeights[0] =
BICUBIC_KERNEL(1.0 + m_bicOffsetY, m_bicKernel);
211 m_bicVWeights[2] =
BICUBIC_KERNEL(1.0 - m_bicOffsetY, m_bicKernel);
212 m_bicVWeights[3] =
BICUBIC_KERNEL(2.0 - m_bicOffsetY, m_bicKernel);
214 m_bicHSum = m_bicHWeights[0] + m_bicHWeights[1] + m_bicHWeights[2] + m_bicHWeights[3];
215 m_bicVSum = m_bicVWeights[0] + m_bicVWeights[1] + m_bicVWeights[2] + m_bicVWeights[3];
218 for(m_bicBufRow = 0 ; m_bicBufRow < 4 ; ++m_bicBufRow)
220 m_bicRowAccumReal = 0.0;
221 m_bicRowAccumImag = 0.0;
222 for(m_bicBufCol = 0; m_bicBufCol < 4; ++m_bicBufCol)
224 m_bicRowAccumReal += m_bicBbufferReal[m_bicBufRow][m_bicBufCol] *
225 m_bicHWeights[m_bicBufCol];
226 m_bicRowAccumImag += m_bicBbufferImag[m_bicBufRow][m_bicBufCol] *
227 m_bicHWeights[m_bicBufCol];
230 m_bicRowsValuesReal[m_bicBufRow] = m_bicRowAccumReal / m_bicHSum;
231 m_bicRowsValuesImag[m_bicBufRow] = m_bicRowAccumImag / m_bicHSum;
233 double vr = ( m_bicRowsValuesReal[0] * m_bicVWeights[0] +
234 m_bicRowsValuesReal[1] * m_bicVWeights[1] +
235 m_bicRowsValuesReal[2] * m_bicVWeights[2] +
236 m_bicRowsValuesReal[3] * m_bicVWeights[3] ) / m_bicVSum;
238 double vi = ( m_bicRowsValuesImag[0] * m_bicVWeights[0] +
239 m_bicRowsValuesImag[1] * m_bicVWeights[1] +
240 m_bicRowsValuesImag[2] * m_bicVWeights[2] +
241 m_bicRowsValuesImag[3] * m_bicVWeights[3] ) / m_bicVSum;
242 v = std::complex<double>(vr,vi);
245 if( (v.real() == m_raster->getBand(b)->getProperty()->m_noDataValue) ||
246 (v.imag() == m_raster->getBand(b)->getProperty()->m_noDataValue) )
247 nearestNeighborGetValue(c, r, v, b);
It gives access to values in one band (dimension) of a raster.
Interpolator(Raster const *r, int m)
Constructor.
TERASTEREXPORT int Round(double val)
Round a double value to a integer value.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
It describes one band (or dimension) of a raster.
#define BICUBIC_KERNEL(x, a)
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
void bilinearGetValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Bilinear interpolation method.
int m_method
The interpolation method.
virtual ~Interpolator()
Destructor.
double m_bilLastRow
Last row available for bilinear interpolation.
Bilinear interpolation method.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Bicubic interpolation method.
double m_bicColBound
Last column available for bicubic interpolation.
double m_bilLastCol
Last column available for bilinear interpolation.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
std::vector< std::complex< double > > m_bilValues
Bilinear values;.
InterpolationFunction m_function
The current interpolation function pointer.
double m_nnLastRow
Last row available for nearest Neighbor interpolation.
void getValues(const double &c, const double &r, std::vector< std::complex< double > > &values)
Get the interpolated value for all bands.
It interpolates one pixel based on a selected algorithm.
An abstract class for raster data strucutures.
BandProperty * getProperty()
Returns the band property.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
void nearestNeighborGetValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Nearest neighbor interpolation method.
void bicubicGetValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Bicubic interpolation method.
double m_nnLastCol
Last column available for nearest Neighbor interpolation.
std::vector< double > m_noDataValues
Raster no-data values (for each band);.
double m_bicRowBound
Last row available for bicubic interpolation.
Near neighborhood interpolation method.
Utility functions for the raster module.
Raster const * m_raster
My input raster.