26 template<
typename ValueT,
typename IndexT>
struct SortPair
30 bool operator<(
const SortPair &other )
const {
return val < other.val; }
33 template<
typename ValueT,
typename IndexT> std::vector<IndexT> createSortedIndices(
const QgsRasterBlock *block,
qgssize totalCells )
35 const ValueT *rawData =
reinterpret_cast<const ValueT *
>( block->
constBits() );
36 const bool hasNoData = block->
hasNoData();
38 const ValueT noDataVal =
static_cast<ValueT
>( block->
noDataValue() );
40 std::vector<SortPair<ValueT, IndexT>> pairs;
44 pairs.resize( totalCells );
45 std::for_each( pairs.begin(), pairs.end(), [rawData, &pairs]( SortPair<ValueT, IndexT> &pair ) {
46 const IndexT idx = static_cast<IndexT>( &pair - pairs.data() );
47 pair = SortPair<ValueT, IndexT> { rawData[idx], idx };
53 pairs.reserve( totalCells );
54 for (
qgssize i = 0; i < totalCells; ++i )
58 const ValueT v = rawData[i];
59 if ( std::isnan(
static_cast<double>( v ) ) || v == noDataVal )
61 pairs.push_back( SortPair<ValueT, IndexT> { v,
static_cast<IndexT
>( i ) } );
65 pairs.push_back( SortPair<ValueT, IndexT> { rawData[i],
static_cast<IndexT
>( i ) } );
70 std::sort( pairs.begin(), pairs.end() );
73 std::vector<IndexT> sortedIndices( pairs.size() );
74 std::transform( pairs.begin(), pairs.end(), sortedIndices.begin(), [](
const SortPair<ValueT, IndexT> &p ) { return p.idx; } );
79 template<
typename IndexT> std::vector<IndexT> createSortedIndices(
const QgsRasterBlock *block,
qgssize totalCells )
84 return createSortedIndices<quint8, IndexT>( block, totalCells );
86 return createSortedIndices<qint8, IndexT>( block, totalCells );
88 return createSortedIndices<quint16, IndexT>( block, totalCells );
90 return createSortedIndices<qint16, IndexT>( block, totalCells );
92 return createSortedIndices<quint32, IndexT>( block, totalCells );
94 return createSortedIndices<qint32, IndexT>( block, totalCells );
96 return createSortedIndices<float, IndexT>( block, totalCells );
98 return createSortedIndices<double, IndexT>( block, totalCells );
106 return std::vector<IndexT>();
119 mCols =
block->width();
120 mRows =
block->height();
122 if ( totalCells <=
static_cast<qgssize>( std::numeric_limits<uint32_t>::max() ) )
124 mSortedIndices = createSortedIndices<uint32_t>( mBlock, totalCells );
128 mSortedIndices = createSortedIndices<qgssize>( mBlock, totalCells );
134 return std::visit( [](
const auto &vec ) ->
qgssize {
return vec.size(); }, mSortedIndices );
140 [rank, order](
const auto &vec ) ->
qgssize {
141 const std::size_t mappedRank = ( order == Qt::AscendingOrder ) ? rank : ( vec.size() - 1 - rank );
142 return static_cast<qgssize>( vec[mappedRank] );
150 return mBlock->value(
sortedIndex( rank, order ) );
155 indexToColumnAndRow(
sortedIndex( rank, order ), column, row );
@ Float32
Thirty two bit floating point (float).
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16).
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30).
@ UInt16
Sixteen bit unsigned integer (quint16).
@ Byte
Eight bit unsigned integer (quint8).
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32).
@ Float64
Sixty four bit floating point (double).
@ CFloat32
Complex Float32.
@ UInt32
Thirty two bit unsigned integer (quint32).
bool hasNoData() const
Returns true if the block may contain no data.
double noDataValue() const
Returns no data value.
const char * constBits(qgssize index) const
Returns a const pointer to block data.
bool isNoData(int row, int column) const
Checks if value at position is no data.
Qgis::DataType dataType() const
Returns data type.
bool hasNoDataValue() const
true if the block has no data value.
const QgsRasterBlock * block() const
Returns a pointer to source QgsRasterBlock.
double sortedValue(qgssize rank, Qt::SortOrder order=Qt::AscendingOrder) const
Returns the raster block value corresponding to the specified sorted rank.
qgssize sortedCount() const
Returns the number of valid (non-NoData) sorted cells.
qgssize sortedIndex(qgssize rank, Qt::SortOrder order=Qt::AscendingOrder) const
Returns the source raster block index corresponding to the specified sorted rank.
QgsSortedRasterBlockIndex(const QgsRasterBlock *block)
Constructor for QgsSortedRasterBlockIndex, indexing the specified raster block.
void sortedColumnRow(qgssize rank, int &column, int &row, Qt::SortOrder order=Qt::AscendingOrder) const
Retrieves the source raster block column and row corresponding to the specified sorted rank.
#define BUILTIN_UNREACHABLE
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
bool operator<(const QVariant &v1, const QVariant &v2)
Compares two QVariant values and returns whether the first is less than the second.