[QGIS Commit] r14511 - in branches/raster-providers/src: core
core/raster providers/grass
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Fri Nov 5 03:28:20 EDT 2010
Author: rblazek
Date: 2010-11-05 00:28:20 -0700 (Fri, 05 Nov 2010)
New Revision: 14511
Modified:
branches/raster-providers/src/core/qgsrasterdataprovider.cpp
branches/raster-providers/src/core/qgsrasterdataprovider.h
branches/raster-providers/src/core/raster/qgsrasterlayer.cpp
branches/raster-providers/src/core/raster/qgsrasterlayer.h
branches/raster-providers/src/core/raster/qgsrasterviewport.h
branches/raster-providers/src/providers/grass/qgis.d.rast.c
branches/raster-providers/src/providers/grass/qgsgrass.cpp
branches/raster-providers/src/providers/grass/qgsgrass.h
branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp
branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h
Log:
raster providers initial work, basic support for passing data for rendering from providers to raster layer
Modified: branches/raster-providers/src/core/qgsrasterdataprovider.cpp
===================================================================
--- branches/raster-providers/src/core/qgsrasterdataprovider.cpp 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/core/qgsrasterdataprovider.cpp 2010-11-05 07:28:20 UTC (rev 14511)
@@ -39,10 +39,21 @@
if ( abilities & QgsRasterDataProvider::Identify )
{
- abilitiesList += "Identify";
- QgsDebugMsg( "Identify" );
+ abilitiesList += tr( "Identify" );
}
+ if ( abilities & QgsRasterDataProvider::Draw )
+ {
+ abilitiesList += tr( "Draw" );
+ }
+
+ if ( abilities & QgsRasterDataProvider::Data )
+ {
+ abilitiesList += tr( "Data" );
+ }
+
+ QgsDebugMsg( "Capability: " + abilitiesList.join( ", " ) );
+
return abilitiesList.join( ", " );
}
Modified: branches/raster-providers/src/core/qgsrasterdataprovider.h
===================================================================
--- branches/raster-providers/src/core/qgsrasterdataprovider.h 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/core/qgsrasterdataprovider.h 2010-11-05 07:28:20 UTC (rev 14511)
@@ -21,7 +21,7 @@
#ifndef QGSRASTERDATAPROVIDER_H
#define QGSRASTERDATAPROVIDER_H
-
+#include "qgslogger.h"
#include "qgsdataprovider.h"
class QImage;
@@ -46,11 +46,55 @@
enum Capability
{
NoCapabilities = 0,
- Identify = 1
-// Capability2 = 1 << 1, etc
+ Identify = 1,
+ // Draw: the provider is capable to render data on QImage, e.g. WMS, GRASS
+ Draw = 1 << 1,
+ // Data: the provider is capable to return data values, so that
+ // QgsRasterLayer can render them using selected rendering mode, e.g. GDAL, GRASS
+ Data = 1 << 2
};
+ // This is modified copy of GDALDataType
+ enum DataType
+ {
+ /*! Unknown or unspecified type */ UnknownDataType = 0,
+ /*! Eight bit unsigned integer */ Byte = 1,
+ /*! Sixteen bit unsigned integer */ UInt16 = 2,
+ /*! Sixteen bit signed integer */ Int16 = 3,
+ /*! Thirty two bit unsigned integer */ UInt32 = 4,
+ /*! Thirty two bit signed integer */ Int32 = 5,
+ /*! Thirty two bit floating point */ Float32 = 6,
+ /*! Sixty four bit floating point */ Float64 = 7,
+ /*! Complex Int16 */ CInt16 = 8,
+ /*! Complex Int32 */ CInt32 = 9,
+ /*! Complex Float32 */ CFloat32 = 10,
+ /*! Complex Float64 */ CFloat64 = 11,
+ TypeCount = 12 /* maximum type # + 1 */
+ };
+ // This is modified copy of GDALColorInterp
+ enum ColorInterpretation
+ {
+ UndefinedColorInterpretation=0,
+ /*! Greyscale */ GrayIndex=1,
+ /*! Paletted (see associated color table) */ PaletteIndex=2,
+ /*! Red band of RGBA image */ RedBand=3,
+ /*! Green band of RGBA image */ GreenBand=4,
+ /*! Blue band of RGBA image */ BlueBand=5,
+ /*! Alpha (0=transparent, 255=opaque) */ AlphaBand=6,
+ /*! Hue band of HLS image */ HueBand=7,
+ /*! Saturation band of HLS image */ SaturationBand=8,
+ /*! Lightness band of HLS image */ LightnessBand=9,
+ /*! Cyan band of CMYK image */ CyanBand=10,
+ /*! Magenta band of CMYK image */ MagentaBand=11,
+ /*! Yellow band of CMYK image */ YellowBand=12,
+ /*! Black band of CMLY image */ BlackBand=13,
+ /*! Y Luminance */ YCbCr_YBand=14,
+ /*! Cb Chroma */ YCbCr_CbBand=15,
+ /*! Cr Chroma */ YCbCr_CrBand=16,
+ /*! Max current value */ ColorInterpretationMax=16
+ };
+
QgsRasterDataProvider();
QgsRasterDataProvider( QString const & uri );
@@ -108,7 +152,73 @@
// TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box
+ /** Returns data type for the band specified by number */
+ virtual int dataType ( int bandNo ) const
+ {
+ return QgsRasterDataProvider::UnknownDataType;
+ }
+ int dataTypeSize ( int dataType ) const
+ {
+ // modified copy from GDAL
+ switch( dataType )
+ {
+ case Byte:
+ return 8;
+
+ case UInt16:
+ case Int16:
+ return 16;
+
+ case UInt32:
+ case Int32:
+ case Float32:
+ case CInt16:
+ return 32;
+
+ case Float64:
+ case CInt32:
+ case CFloat32:
+ return 64;
+
+ case CFloat64:
+ return 128;
+
+ default:
+ return 0;
+ }
+ }
+
+ /** Get numbur of bands */
+ virtual int bandCount() const {
+ return 0;
+ }
+
+ /** Returns data type for the band specified by number */
+ virtual int colorInterpretation ( int bandNo ) const {
+ return QgsRasterDataProvider::UndefinedColorInterpretation;
+ }
+
+ /** Get block size */
+ virtual int xBlockSize() const { return 0; }
+ virtual int yBlockSize() const { return 0; }
+
+ /** Get raster size */
+ virtual int xSize() const { return 0; }
+ virtual int ySize() const { return 0; }
+
+ /** read block of data */
+ virtual void readBlock( int bandNo, int xBlock, int yBlock, void *data ){}
+
+ /** read block of data using give extent and size */
+ virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data ) {};
+
+ /** value representing null data */
+ virtual double noDataValue() const { return 0; }
+
+ virtual double minimumValue(int bandNo)const { return 0; }
+ virtual double maximumValue(int bandNo)const { return 0; }
+
/**
* Get metadata in a format suitable for feeding directly
* into a subset of the GUI raster properties "Metadata" tab.
Modified: branches/raster-providers/src/core/raster/qgsrasterlayer.cpp
===================================================================
--- branches/raster-providers/src/core/raster/qgsrasterlayer.cpp 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/core/raster/qgsrasterlayer.cpp 2010-11-05 07:28:20 UTC (rev 14511)
@@ -682,8 +682,11 @@
*/
const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
{
+ QgsDebugMsg( "theBandNo = " + QString::number(theBandNo) );
+ QgsDebugMsg( "mRasterType = " + QString::number(mRasterType) );
// check if we have received a valid band number
- if (( GDALGetRasterCount( mGdalDataset ) < theBandNo ) && mRasterType != Palette )
+ //if (( GDALGetRasterCount( mGdalDataset ) < theBandNo ) && mRasterType != Palette )
+ if (( mDataProvider->bandCount() < theBandNo ) && mRasterType != Palette )
{
// invalid band id, return nothing
QgsRasterBandStats myNullReturnStats;
@@ -716,11 +719,11 @@
emit statusChanged( tr( "Retrieving stats for %1" ).arg( name() ) );
qApp->processEvents();
QgsDebugMsg( "stats for band " + QString::number( theBandNo ) );
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ // Not used
+ //QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
- QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
-
// XXX this sets the element count to a sensible value; but then you ADD to
// XXX it later while iterating through all the pixels?
//myRasterBandStats.elementCount = mWidth * mHeight;
@@ -734,21 +737,29 @@
// let the user know we're going to possibly be taking a while
//QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType ( theBandNo );
int myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
- GDALGetBlockSize( myGdalBand, &myXBlockSize, &myYBlockSize );
+ //GDALGetBlockSize( myGdalBand, &myXBlockSize, &myYBlockSize );
+ myXBlockSize = mDataProvider->xBlockSize();
+ myYBlockSize = mDataProvider->yBlockSize();
- myNXBlocks = ( GDALGetRasterXSize( myGdalBand ) + myXBlockSize - 1 ) / myXBlockSize;
- myNYBlocks = ( GDALGetRasterYSize( myGdalBand ) + myYBlockSize - 1 ) / myYBlockSize;
+ //myNXBlocks = ( GDALGetRasterXSize( myGdalBand ) + myXBlockSize - 1 ) / myXBlockSize;
+ //myNYBlocks = ( GDALGetRasterYSize( myGdalBand ) + myYBlockSize - 1 ) / myYBlockSize;
- void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( GDALGetDataTypeSize( myDataType ) / 8 ) );
+ myNXBlocks = ( mDataProvider->xSize() + myXBlockSize - 1 ) / myXBlockSize;
+ myNYBlocks = ( mDataProvider->ySize() + myYBlockSize - 1 ) / myYBlockSize;
+ //void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( GDALGetDataTypeSize( myDataType ) / 8 ) );
+ void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( mDataProvider->dataTypeSize( myDataType ) / 8 ) );
+
// unfortunately we need to make two passes through the data to calculate stddev
bool myFirstIterationFlag = true;
//ifdefs below to remove compiler warning about unused vars
#ifdef QGISDEBUG
+/*
int success;
double GDALminimum = GDALGetRasterMinimum( myGdalBand, &success );
@@ -787,10 +798,13 @@
QgsLogger::debug( "exactly computed GDALmaximum:", GDALrange[1] );
QgsDebugMsg( "starting manual stat computation" );
+*/
#endif
- int myGdalBandXSize = GDALGetRasterXSize( myGdalBand );
- int myGdalBandYSize = GDALGetRasterYSize( myGdalBand );
+ //int myGdalBandXSize = GDALGetRasterXSize( myGdalBand );
+ //int myGdalBandYSize = GDALGetRasterYSize( myGdalBand );
+ int myGdalBandXSize = mDataProvider->xSize();
+ int myGdalBandYSize = mDataProvider->ySize();
for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
{
emit drawingProgress( iYBlock, myNYBlocks * 2 );
@@ -798,7 +812,8 @@
for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
{
int nXValid, nYValid;
- GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
+ //GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
+ mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
// Compute the portion of the block that is valid
// for partial edge blocks.
@@ -866,7 +881,8 @@
{
int nXValid, nYValid;
- GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
+ //GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
+ mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
// Compute the portion of the block that is valid
// for partial edge blocks.
@@ -886,6 +902,7 @@
for ( int iX = 0; iX < nXValid; iX++ )
{
double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
+ //QgsDebugMsg ( "myValue = " + QString::number(myValue) );
if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
{
@@ -1259,7 +1276,9 @@
if ( 0 == theMinMax ) { return; }
GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBand );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBand );
+ // TODO
void* myGdalScanData = readData( myGdalBand, &mLastViewPort );
/* Check for out of memory error */
@@ -1439,6 +1458,7 @@
//the contents of the rasterViewPort will change
QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
+ myRasterViewPort->mDrawnExtent = myRasterExtent;
// calculate raster pixel offsets from origin to clipped rect
// we're only interested in positive offsets where the origin of the raster
@@ -1565,7 +1585,8 @@
QgsDebugMsg( "Checking for provider key." );
- if ( !mProviderKey.isEmpty() )
+ //if ( !mProviderKey.isEmpty() )
+ if ( mDataProvider->capabilities() & QgsRasterDataProvider::Draw )
{
QgsDebugMsg( "Wanting a '" + mProviderKey + "' provider to draw this." );
@@ -1659,10 +1680,11 @@
}
}
}
- else
+ else if ( mDataProvider->capabilities() & QgsRasterDataProvider::Data )
{
- // Otherwise use the old-fashioned GDAL direct-drawing style
- // TODO: Move into its own GDAL provider.
+ // (Otherwise use the old-fashioned GDAL direct-drawing style
+ // TODO: Move into its own GDAL provider.)
+ // the driver can pass the data values ( capability QgsRasterDataProvider::Data )
// \/\/\/ - commented-out to handle zoomed-in rasters
// draw(theQPainter,myRasterViewPort);
@@ -1691,6 +1713,10 @@
// procedure to use :
//
+ // debug
+ QgsDebugMsg( "mDrawingStyle = " + QString::number(mDrawingStyle) );
+ //drawSingleBandGray( theQPainter, theRasterViewPort, theQgsMapToPixel, 1 );
+ //return;
switch ( mDrawingStyle )
{
// a "Gray" or "Undefined" layer drawn as a range of gray colors
@@ -3159,12 +3185,17 @@
{
mNoDataValue = std::numeric_limits<int>::max();
mValidNoDataValue = false;
- if ( mGdalDataset != NULL && GDALGetRasterCount( mGdalDataset ) > 0 )
+ //if ( mGdalDataset != NULL && GDALGetRasterCount( mGdalDataset ) > 0 )
+ if ( mDataProvider != NULL && mDataProvider->bandCount() > 0 )
{
int myRequestValid;
- double myValue = GDALGetRasterNoDataValue(
- GDALGetRasterBand( mGdalDataset, 1 ), &myRequestValid );
+ //double myValue = GDALGetRasterNoDataValue(
+ // GDALGetRasterBand( mGdalDataset, 1 ), &myRequestValid );
+ // TODO: add 'has null value' to capabilities
+ myRequestValid = 1;
+ double myValue = mDataProvider->noDataValue();
+
if ( 0 != myRequestValid )
{
setNoDataValue( myValue );
@@ -3258,6 +3289,8 @@
mDataProvider->setImageEncoding( format );
mDataProvider->setImageCrs( crs );
+ setNoDataValue( mDataProvider->noDataValue() );
+
// get the extent
QgsRectangle mbr = mDataProvider->extent();
@@ -3286,6 +3319,27 @@
{
*mCRS = QgsCoordinateReferenceSystem( mDataProvider->crs() );
}
+ //mBandCount = GDALGetRasterCount( mGdalDataset );
+ mBandCount = mDataProvider->bandCount( );
+ for ( int i = 1; i <= mBandCount; i++ )
+ {
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
+ QgsRasterBandStats myRasterBandStats;
+ myRasterBandStats.bandName = generateBandName( i );
+ myRasterBandStats.bandNumber = i;
+ myRasterBandStats.statsGathered = false;
+ myRasterBandStats.histogramVector = new QgsRasterBandStats::HistogramVector();
+ //Store the default color table
+ // TODO
+ //readColorTable( i, &myRasterBandStats.colorTable );
+
+ mRasterStatsList.push_back( myRasterBandStats );
+
+ //Build a new contrast enhancement for the band and store in list
+ //QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )GDALGetRasterDataType( myGdalBand ) );
+ QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )mDataProvider->dataType( i ) );
+ mContrastEnhancementList.append( myContrastEnhancement );
+ }
}
}
else
@@ -3417,6 +3471,7 @@
*/
void QgsRasterLayer::setDrawingStyle( QString const & theDrawingStyleQString )
{
+ QgsDebugMsg( "DrawingStyle = " + theDrawingStyleQString );
if ( theDrawingStyleQString == "SingleBandGray" )//no need to tr() this its not shown in ui
{
mDrawingStyle = SingleBandGray;
@@ -3483,6 +3538,7 @@
void QgsRasterLayer::setMaximumValue( unsigned int theBand, double theValue, bool theGenerateLookupTableFlag )
{
+ QgsDebugMsg( "setMaximumValue theValue = " + QString::number(theValue) );
if ( 0 < theBand && theBand <= bandCount() )
{
mContrastEnhancementList[theBand - 1].setMaximumValue( theValue, theGenerateLookupTableFlag );
@@ -3528,6 +3584,7 @@
void QgsRasterLayer::setMinimumValue( unsigned int theBand, double theValue, bool theGenerateLookupTableFlag )
{
+ QgsDebugMsg( "setMinimumValue theValue = " + QString::number(theValue) );
if ( 0 < theBand && theBand <= bandCount() )
{
mContrastEnhancementList[theBand - 1].setMinimumValue( theValue, theGenerateLookupTableFlag );
@@ -3824,7 +3881,9 @@
*/
snode = mnl.namedItem( "mNoDataValue" );
myElement = snode.toElement();
+ QgsDebugMsg( "ReadXml: mNoDataValue = " + myElement.text() );
setNoDataValue( myElement.text().toDouble() );
+ QgsDebugMsg( "ReadXml: mNoDataValue = " + QString::number( mNoDataValue ) );
if ( myElement.attribute( "mValidNoDataValue", "false" ).compare( "true" ) )
{
// If flag element is not true, set to false.
@@ -4495,12 +4554,15 @@
QgsContrastEnhancement* myGreenContrastEnhancement = contrastEnhancement( myGreenBandNo );
QgsContrastEnhancement* myBlueContrastEnhancement = contrastEnhancement( myBlueBandNo );
- QgsRasterImageBuffer redImageBuffer( myGdalRedBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer redImageBuffer( myGdalRedBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer redImageBuffer( mDataProvider, myRedBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
redImageBuffer.reset();
- QgsRasterImageBuffer greenImageBuffer( myGdalGreenBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer greenImageBuffer( myGdalGreenBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer greenImageBuffer( mDataProvider, myGreenBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
greenImageBuffer.setWritingEnabled( false ); //only draw to redImageBuffer
greenImageBuffer.reset();
- QgsRasterImageBuffer blueImageBuffer( myGdalBlueBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer blueImageBuffer( myGdalBlueBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer blueImageBuffer( mDataProvider, myBlueBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
blueImageBuffer.setWritingEnabled( false ); //only draw to redImageBuffer
blueImageBuffer.reset();
@@ -4593,10 +4655,12 @@
return;
}
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBandNo );
- QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
imageBuffer.reset();
QRgb* imageScanLine = 0;
@@ -4673,10 +4737,12 @@
return;
}
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBandNo );
- QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
imageBuffer.reset();
QRgb* imageScanLine = 0;
@@ -4753,10 +4819,12 @@
}
QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBandNo );
- QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
imageBuffer.reset();
QRgb* imageScanLine = 0;
@@ -4851,9 +4919,12 @@
return;
}
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
- QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBandNo );
+ QgsDebugMsg( "myDataType = " + QString::number( myDataType) );
+ //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
imageBuffer.reset();
QRgb* imageScanLine = 0;
@@ -4866,8 +4937,10 @@
QgsContrastEnhancement* myContrastEnhancement = contrastEnhancement( theBandNo );
QgsRasterBandStats myGrayBandStats;
+ //myGrayBandStats = bandStatistics( theBandNo ); // debug
if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedGrayMinimumMaximum && mStandardDeviations > 0 )
{
+ QgsDebugMsg( "XXX calc stats" );
mGrayMinimumMaximumEstimated = false;
myGrayBandStats = bandStatistics( theBandNo );
setMaximumValue( theBandNo, myGrayBandStats.mean + ( mStandardDeviations * myGrayBandStats.stdDev ) );
@@ -4875,21 +4948,28 @@
}
else if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedGrayMinimumMaximum )
{
+ QgsDebugMsg( "XXX use provider minmax" );
//This case will be true the first time the image is loaded, so just approimate the min max to keep
//from calling generate raster band stats
double GDALrange[2];
- GDALComputeRasterMinMax( myGdalBand, 1, GDALrange ); //Approximate
+ //GDALComputeRasterMinMax( myGdalBand, 1, GDALrange ); //Approximate
mGrayMinimumMaximumEstimated = true;
- setMaximumValue( theBandNo, GDALrange[1] );
- setMinimumValue( theBandNo, GDALrange[0] );
+ //setMaximumValue( theBandNo, GDALrange[1] );
+ //setMinimumValue( theBandNo, GDALrange[0] );
+ setMaximumValue( theBandNo, mDataProvider->maximumValue ( theBandNo ) );
+ setMinimumValue( theBandNo, mDataProvider->minimumValue ( theBandNo ) );
}
+ QgsDebugMsg( " -> imageBuffer.nextScanLine");
while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
{
for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
{
myGrayValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i );
+ if ( myGrayValue != -2147483647 ) {
+ //QgsDebugMsg( "myGrayValue = " + QString::number( myGrayValue ) );
+ }
if ( mValidNoDataValue && ( fabs( myGrayValue - mNoDataValue ) <= TINY_VALUE || myGrayValue != myGrayValue ) )
{
@@ -4918,6 +4998,7 @@
myGrayVal = 255 - myGrayVal;
}
+ //QgsDebugMsg( QString( "i = %1 myGrayValue = %2").arg(i).arg( myGrayValue ) );
imageScanLine[ i ] = qRgba( myGrayVal, myGrayVal, myGrayVal, myAlphaValue );
}
}
@@ -4936,10 +5017,12 @@
}
QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
- GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+ //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
+ int myDataType = mDataProvider->dataType( theBandNo );
- QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
+ QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
imageBuffer.reset();
QRgb* imageScanLine = 0;
@@ -5419,24 +5502,25 @@
mRasterTransparency.initializeTransparentPixelList( mNoDataValue );
}
- mBandCount = GDALGetRasterCount( mGdalDataset );
- for ( int i = 1; i <= mBandCount; i++ )
- {
- GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
- QgsRasterBandStats myRasterBandStats;
- myRasterBandStats.bandName = generateBandName( i );
- myRasterBandStats.bandNumber = i;
- myRasterBandStats.statsGathered = false;
- myRasterBandStats.histogramVector = new QgsRasterBandStats::HistogramVector();
- //Store the default color table
- readColorTable( i, &myRasterBandStats.colorTable );
+ // Moved to setDataProvider, later maybe to constructor
+ //mBandCount = GDALGetRasterCount( mGdalDataset );
+ //for ( int i = 1; i <= mBandCount; i++ )
+ //{
+ //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
+ //QgsRasterBandStats myRasterBandStats;
+ //myRasterBandStats.bandName = generateBandName( i );
+ //myRasterBandStats.bandNumber = i;
+ //myRasterBandStats.statsGathered = false;
+ //myRasterBandStats.histogramVector = new QgsRasterBandStats::HistogramVector();
+ ////Store the default color table
+ //readColorTable( i, &myRasterBandStats.colorTable );
- mRasterStatsList.push_back( myRasterBandStats );
+ //mRasterStatsList.push_back( myRasterBandStats );
- //Build a new contrast enhancement for the band and store in list
- QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )GDALGetRasterDataType( myGdalBand ) );
- mContrastEnhancementList.append( myContrastEnhancement );
- }
+ ////Build a new contrast enhancement for the band and store in list
+ //QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )GDALGetRasterDataType( myGdalBand ) );
+ //mContrastEnhancementList.append( myContrastEnhancement );
+ //}
//defaults - Needs to be set after the Contrast list has been build
//Try to read the default contrast enhancement from the config file
@@ -5537,32 +5621,32 @@
/*
* @param index index in memory block
*/
-double QgsRasterLayer::readValue( void *data, GDALDataType type, int index )
+double QgsRasterLayer::readValue( void *data, int type, int index )
{
if ( !data )
return mValidNoDataValue ? mNoDataValue : 0.0;
switch ( type )
{
- case GDT_Byte:
+ case QgsRasterDataProvider::Byte:
return ( double )(( GByte * )data )[index];
break;
- case GDT_UInt16:
+ case QgsRasterDataProvider::UInt16:
return ( double )(( GUInt16 * )data )[index];
break;
- case GDT_Int16:
+ case QgsRasterDataProvider::Int16:
return ( double )(( GInt16 * )data )[index];
break;
- case GDT_UInt32:
+ case QgsRasterDataProvider::UInt32:
return ( double )(( GUInt32 * )data )[index];
break;
- case GDT_Int32:
+ case QgsRasterDataProvider::Int32:
return ( double )(( GInt32 * )data )[index];
break;
- case GDT_Float32:
+ case QgsRasterDataProvider::Float32:
return ( double )(( float * )data )[index];
break;
- case GDT_Float64:
+ case QgsRasterDataProvider::Float64:
return ( double )(( double * )data )[index];
break;
default:
@@ -5661,8 +5745,9 @@
return TRSTRING_NOT_SET;
}
-QgsRasterImageBuffer::QgsRasterImageBuffer( GDALRasterBandH rasterBand, QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* geoTransform ):
- mRasterBand( rasterBand ), mPainter( p ), mViewPort( viewPort ), mMapToPixel( mapToPixel ), mGeoTransform( geoTransform ), mValid( false ), mWritingEnabled( true ), mDrawPixelRect( false ), mCurrentImage( 0 ), mCurrentGDALData( 0 )
+//QgsRasterImageBuffer::QgsRasterImageBuffer( GDALRasterBandH rasterBand, QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* geoTransform ):
+QgsRasterImageBuffer::QgsRasterImageBuffer( QgsRasterDataProvider *dataProvider, int bandNo, QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* geoTransform ):
+ mDataProvider( dataProvider ), mBandNo(bandNo), mPainter( p ), mViewPort( viewPort ), mMapToPixel( mapToPixel ), mGeoTransform( geoTransform ), mValid( false ), mWritingEnabled( true ), mDrawPixelRect( false ), mCurrentImage( 0 ), mCurrentGDALData( 0 )
{
}
@@ -5675,7 +5760,9 @@
void QgsRasterImageBuffer::reset( int maxPixelsInVirtualMemory )
{
- if ( !mRasterBand || !mPainter || !mViewPort )
+ QgsDebugMsg( "Start" );
+ //if ( !mRasterBand || !mPainter || !mViewPort )
+ if ( !mDataProvider || mBandNo <= 0 || !mPainter || !mViewPort )
{
mValid = false;
return;
@@ -5705,6 +5792,7 @@
bool QgsRasterImageBuffer::nextScanLine( QRgb** imageScanLine, void** rasterScanLine )
{
+ //QgsDebugMsg( "Entered" );
if ( !mValid )
return false;
@@ -5729,8 +5817,9 @@
{
*imageScanLine = 0;
}
- GDALDataType type = GDALGetRasterDataType( mRasterBand );
- int size = GDALGetDataTypeSize( type ) / 8;
+ //GDALDataType type = GDALGetRasterDataType( mRasterBand );
+ //int size = GDALGetDataTypeSize( type ) / 8;
+ int size = mDataProvider->dataTypeSize(mDataProvider->dataType(mBandNo))/8;
*rasterScanLine = ( unsigned char * )mCurrentGDALData + mCurrentPartImageRow * mViewPort->drawableAreaXDim * size;
++mCurrentPartImageRow;
@@ -5740,6 +5829,7 @@
bool QgsRasterImageBuffer::createNextPartImage()
{
+ QgsDebugMsg( "Entered" );
//draw the last image if mCurrentImage exists
if ( mCurrentImage )
{
@@ -5803,11 +5893,13 @@
mCurrentPartImageRow = 0;
//read GDAL image data
- GDALDataType type = GDALGetRasterDataType( mRasterBand );
- int size = GDALGetDataTypeSize( type ) / 8;
+ //GDALDataType type = GDALGetRasterDataType( mRasterBand );
+ //int size = GDALGetDataTypeSize( type ) / 8;
+ int size = mDataProvider->dataTypeSize ( mDataProvider->dataType(mBandNo) ) / 8 ;
int xSize = mViewPort->drawableAreaXDim;
int ySize = mViewPort->drawableAreaYDim;
+ //TODO: clean up - most should be thrown out
//make the raster tiles overlap at least 2 pixels to avoid white stripes
int overlapRows = 0;
if ( mMapToPixel )
@@ -5838,16 +5930,25 @@
}
mNumCurrentImageRows = ySize;
mCurrentGDALData = VSIMalloc( size * xSize * ySize );
- CPLErr myErr = GDALRasterIO( mRasterBand, GF_Read, mViewPort->rectXOffset,
- mViewPort->rectYOffset + mCurrentRow, mViewPort->clippedWidth, rasterYSize,
- mCurrentGDALData, xSize, ySize, type, 0, 0 );
+ //CPLErr myErr = GDALRasterIO( mRasterBand, GF_Read, mViewPort->rectXOffset,
+ // mViewPort->rectYOffset + mCurrentRow, mViewPort->clippedWidth, rasterYSize,
+ // mCurrentGDALData, xSize, ySize, type, 0, 0 );
- if ( myErr != CPLE_None )
- {
- CPLFree( mCurrentGDALData );
- mCurrentGDALData = 0;
- return false;
- }
+ // TODO: check this, it is probably not precise
+ double yMax = mViewPort->mDrawnExtent.yMaximum() - mCurrentRow * mMapToPixel->mapUnitsPerPixel();
+ double yMin = yMax - ySize * mMapToPixel->mapUnitsPerPixel();
+
+ QgsRectangle partExtent ( mViewPort->mDrawnExtent.xMinimum(), yMin,
+ mViewPort->mDrawnExtent.xMaximum(), yMax );
+ mDataProvider->readBlock ( mBandNo, partExtent, xSize, ySize, mCurrentGDALData );
+
+ // TODO - error check - throw exception
+ //if ( myErr != CPLE_None )
+ //{
+ // CPLFree( mCurrentGDALData );
+ // mCurrentGDALData = 0;
+ // return false;
+ //}
//create the QImage
if ( mWritingEnabled )
Modified: branches/raster-providers/src/core/raster/qgsrasterlayer.h
===================================================================
--- branches/raster-providers/src/core/raster/qgsrasterlayer.h 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/core/raster/qgsrasterlayer.h 2010-11-05 07:28:20 UTC (rev 14511)
@@ -778,7 +778,8 @@
bool readFile( const QString & fileName );
/** \brief Read a raster value given position from memory block created by readData() */
- inline double readValue( void *data, GDALDataType type, int index );
+ //inline double readValue( void *data, GDALDataType type, int index );
+ inline double readValue( void *data, int type, int index );
/** \brief Update the layer if it is outdated */
bool update();
@@ -922,8 +923,9 @@
class CORE_EXPORT QgsRasterImageBuffer
{
public:
- QgsRasterImageBuffer( GDALRasterBandH rasterBand, QPainter* p,
- QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* mGeoTransform );
+ //QgsRasterImageBuffer( GDALRasterBandH rasterBand, QPainter* p,
+ QgsRasterImageBuffer( QgsRasterDataProvider *dataProvider, int bandNo, QPainter* p,
+ QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* mGeoTransform );
~QgsRasterImageBuffer();
void reset( int maxPixelsInVirtualMemory = 5000000 );
/**Returns a pointer to the next scan line (or 0 if end)*/
@@ -939,7 +941,9 @@
/**Peter's fix for zoomed in rasters*/
void drawPixelRectangle();
- GDALRasterBandH mRasterBand; //raster band
+ //GDALRasterBandH mRasterBand; //raster band
+ QgsRasterDataProvider* mDataProvider;
+ int mBandNo;
QPainter* mPainter;
QgsRasterViewPort* mViewPort;
const QgsMapToPixel* mMapToPixel;
@@ -957,6 +961,7 @@
int mCurrentPartRasterMax; //maximum (raster source) row of current image
int mCurrentPartImageRow; //current image row
int mNumCurrentImageRows; //number of image rows for the current part
+ //QgsRectangle mCurrentPartExtent; // extent of current part in map units
//current memory image and gdal scan data
QImage* mCurrentImage;
Modified: branches/raster-providers/src/core/raster/qgsrasterviewport.h
===================================================================
--- branches/raster-providers/src/core/raster/qgsrasterviewport.h 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/core/raster/qgsrasterviewport.h 2010-11-05 07:28:20 UTC (rev 14511)
@@ -74,6 +74,9 @@
/** \brief Distance in map units from bottom edge to top edge for the part of the raster that
* is to be rendered.*/
int drawableAreaYDim;
+
+ // intersection of current map extent and layer extent
+ QgsRectangle mDrawnExtent;
};
#endif //QGSRASTERVIEWPORT_H
Modified: branches/raster-providers/src/providers/grass/qgis.d.rast.c
===================================================================
--- branches/raster-providers/src/providers/grass/qgis.d.rast.c 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/providers/grass/qgis.d.rast.c 2010-11-05 07:28:20 UTC (rev 14511)
@@ -21,7 +21,7 @@
#include <grass/raster.h>
#include <grass/display.h>
-int display( char *name, char *mapset, RASTER_MAP_TYPE data_type );
+int display( char *name, char *mapset, RASTER_MAP_TYPE data_type, char *format );
int main( int argc, char **argv )
{
@@ -31,6 +31,7 @@
struct GModule *module;
struct Option *map;
struct Option *win;
+ struct Option *format;
struct Cell_head window;
/* Initialize the GIS calls */
@@ -43,6 +44,12 @@
map = G_define_standard_option( G_OPT_R_MAP );
map->description = ( "Raster map to be displayed" );
+ format = G_define_option();
+ format->key = "format";
+ format->type = TYPE_STRING;
+ format->description = "format";
+ format->options = "color,value";
+
win = G_define_option();
win->key = "window";
win->type = TYPE_DOUBLE;
@@ -76,18 +83,19 @@
/* use DCELL even if the map is FCELL */
if ( fp )
- display( name, mapset, DCELL_TYPE );
+ display( name, mapset, DCELL_TYPE, format->answer );
else
- display( name, mapset, CELL_TYPE );
+ display( name, mapset, CELL_TYPE, format->answer );
exit( EXIT_SUCCESS );
}
-static int cell_draw( char *, char *, struct Colors *, RASTER_MAP_TYPE );
+static int cell_draw( char *, char *, struct Colors *, RASTER_MAP_TYPE, char *format );
int display( char *name,
char *mapset,
- RASTER_MAP_TYPE data_type )
+ RASTER_MAP_TYPE data_type,
+ char *format )
{
struct Colors colors;
@@ -97,7 +105,7 @@
//G_set_null_value_color(r, g, b, &colors);
/* Go draw the raster map */
- cell_draw( name, mapset, &colors, data_type );
+ cell_draw( name, mapset, &colors, data_type, format );
/* release the colors now */
G_free_colors( &colors );
@@ -108,7 +116,8 @@
static int cell_draw( char *name,
char *mapset,
struct Colors *colors,
- RASTER_MAP_TYPE data_type )
+ RASTER_MAP_TYPE data_type,
+ char *format )
{
int cellfile;
void *xarray;
@@ -120,6 +129,7 @@
int big_endian;
long one = 1;
FILE *fo;
+ int raster_size;
big_endian = !( *(( char * )( &one ) ) );
@@ -145,6 +155,7 @@
// Unfortunately this is not sufficient on Windows to switch stdout to binary mode
fo = fdopen( fileno( stdout ), "wb" );
+ raster_size = G_raster_size( data_type );
/* loop for array rows */
for ( row = 0; row < nrows; row++ )
{
@@ -157,25 +168,53 @@
for ( i = 0; i < ncols; i++ )
{
unsigned char alpha = 255;
+ //G_debug ( 0, "row = %d col = %d", row, i );
if ( G_is_null_value( ptr, data_type ) )
{
alpha = 0;
}
- ptr = G_incr_void_ptr( ptr, G_raster_size( data_type ) );
+ ptr = G_incr_void_ptr( ptr, raster_size );
-
- // We need data suitable for QImage 32-bpp
- // the data are stored in QImage as QRgb which is unsigned int.
- // Because it depends on byte order of the platform we have to
- // consider byte order (well, middle endian ignored)
- if ( big_endian )
+ if ( strcmp(format,"color") == 0 )
{
- // I have never tested this
- fprintf( fo, "%c%c%c%c", alpha, red[i], grn[i], blu[i] );
+ // We need data suitable for QImage 32-bpp
+ // the data are stored in QImage as QRgb which is unsigned int.
+ // Because it depends on byte order of the platform we have to
+ // consider byte order (well, middle endian ignored)
+ if ( big_endian )
+ {
+ // I have never tested this
+ fprintf( fo, "%c%c%c%c", alpha, red[i], grn[i], blu[i] );
+ }
+ else
+ {
+ fprintf( fo, "%c%c%c%c", blu[i], grn[i], red[i], alpha );
+ }
}
else
{
- fprintf( fo, "%c%c%c%c", blu[i], grn[i], red[i], alpha );
+ int *val;
+ val = (int*) (ptr);
+ //G_debug ( 0, "val = %d", *val );
+ if ( data_type == CELL_TYPE) {
+ G_debug ( 0, "valx = %d", *((CELL *) ptr));
+ }
+ if ( G_is_null_value(ptr, data_type) ) {
+ if ( data_type == CELL_TYPE) {
+ int nul = -2147483647;
+ fwrite( &nul , 4, 1, fo );
+ } else if ( data_type == DCELL_TYPE) {
+ double nul = 2.2250738585072014e-308;
+ fwrite( &nul , 8, 1, fo );
+ } else if ( data_type == FCELL_TYPE) {
+ double nul = 1.17549435e-38F;
+ fwrite( &nul , 4, 1, fo );
+ }
+ }
+ else
+ {
+ fwrite( ptr, raster_size, 1, fo );
+ }
}
}
}
Modified: branches/raster-providers/src/providers/grass/qgsgrass.cpp
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrass.cpp 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/providers/grass/qgsgrass.cpp 2010-11-05 07:28:20 UTC (rev 14511)
@@ -29,6 +29,7 @@
#include <QSettings>
#include <QTextStream>
#include <QTemporaryFile>
+#include <QHash>
#include <QTextCodec>
@@ -1171,6 +1172,60 @@
return QgsRectangle( 0, 0, 0, 0 );
}
+void GRASS_EXPORT QgsGrass::size( QString gisdbase, QString location, QString mapset, QString map, int *cols, int *rows )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+
+ *cols = 0;
+ *rows = 0;
+ try
+ {
+ QString str = QgsGrass::getInfo( "size", gisdbase, location, mapset, map, QgsGrass::Raster );
+ QStringList list = str.split( "," );
+ if ( list.size() != 2 )
+ {
+ throw QgsGrass::Exception( "Cannot parse GRASS map size: " + str );
+ }
+ *cols = list[0].toInt();
+ *rows = list[1].toInt();
+ }
+ catch ( QgsGrass::Exception &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Cannot get raster extent" ) + "\n" + e.what() );
+ }
+
+ QgsDebugMsg( QString( "raster size = %1 %2" ).arg( *cols ).arg( *rows ) );
+}
+
+QHash<QString, QString> GRASS_EXPORT QgsGrass::info( QString gisdbase, QString location, QString mapset, QString map, MapType type )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+ QHash<QString, QString> inf;
+
+ try
+ {
+ QString str = QgsGrass::getInfo( "info", gisdbase, location, mapset, map, type );
+ QgsDebugMsg( str );
+ QStringList list = str.split( "\n" );
+ for ( int i = 0; i < list.size(); i++ ) {
+ QStringList keyVal = list[i].split(':');
+ if ( list[i].isEmpty() ) { continue; }
+ if ( keyVal.size() != 2 )
+ {
+ throw QgsGrass::Exception( "Cannot parse GRASS map info key value : " + list[i] + " (" + str + " ) " );
+ }
+ inf[keyVal[0]] = keyVal[1];
+ }
+ }
+ catch ( QgsGrass::Exception &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Cannot get map info" ) + "\n" + e.what() );
+ }
+ return inf;
+}
+
QMap<QString, QString> GRASS_EXPORT QgsGrass::query( QString gisdbase, QString location, QString mapset, QString map, MapType type, double x, double y )
{
QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
Modified: branches/raster-providers/src/providers/grass/qgsgrass.h
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrass.h 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/providers/grass/qgsgrass.h 2010-11-05 07:28:20 UTC (rev 14511)
@@ -27,6 +27,7 @@
#include "qgsexception.h"
#include <QString>
#include <QMap>
+#include <QHash>
class QgsCoordinateReferenceSystem;
class QgsRectangle;
@@ -188,6 +189,14 @@
static GRASS_EXPORT QgsRectangle extent( QString gisdbase, QString location,
QString mapset, QString map, MapType type = None );
+ // ! Get raster map size
+ static GRASS_EXPORT void size( QString gisdbase, QString location,
+ QString mapset, QString map, int *cols, int *rows );
+
+ // ! Get raster info
+ static GRASS_EXPORT QHash<QString, QString> info( QString gisdbase, QString location,
+ QString mapset, QString map, MapType type );
+
// ! Get map value / feautre info
static GRASS_EXPORT QMap<QString, QString> query( QString gisdbase, QString location,
QString mapset, QString map, MapType type, double x, double y );
Modified: branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp 2010-11-05 07:28:20 UTC (rev 14511)
@@ -38,6 +38,7 @@
#include <QDir>
#include <QFileInfo>
#include <QFile>
+#include <QHash>
static QString PROVIDER_KEY = "grassraster";
static QString PROVIDER_DESCRIPTION = "GRASS raster provider";
@@ -75,6 +76,15 @@
QgsDebugMsg( QString( "mapName: %1" ).arg( mMapName ) );
mCrs = QgsGrass::crs( mGisdbase, mLocation );
+
+ // the block size can change of course when the raster is overridden
+ // ibut it is only called once when statistics are calculated
+ QgsGrass::size( mGisdbase, mLocation, mMapset, mMapName, &mCols, &mRows );
+
+ mInfo = QgsGrass::info( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster );
+
+ mGrassDataType = mInfo["TYPE"].toInt();
+ QgsDebugMsg( "mGrassDataType = " + QString::number( mGrassDataType ) );
}
QgsGrassRasterProvider::~QgsGrassRasterProvider()
@@ -123,6 +133,114 @@
return image;
}
+
+void QgsGrassRasterProvider::readBlock( int bandNo, int xBlock, int yBlock, void *block )
+{
+ QgsDebugMsg( "Entered" );
+ // TODO: optimize, see extent()
+
+ QgsDebugMsg( "yBlock = " + QString::number( yBlock ) );
+
+ QStringList arguments;
+ arguments.append( "map=" + mMapName + "@" + mMapset );
+
+ QgsRectangle ext = extent();
+
+ double cellHeight = ext.height() / mRows;
+ double yMaximum = ext.yMaximum() - cellHeight * yBlock;
+ double yMinimum = yMaximum - cellHeight;
+
+ arguments.append(( QString( "window=%1,%2,%3,%4,%5,%6" )
+ .arg( ext.xMinimum() ).arg( yMinimum )
+ .arg( ext.xMaximum() ).arg( yMaximum )
+ .arg( mCols ).arg( 1 ) ) );
+
+ arguments.append( "format=value");
+ QProcess process( this );
+ QString cmd = QgsApplication::prefixPath() + "/" QGIS_LIBEXEC_SUBDIR "/grass/modules/qgis.d.rast";
+ QByteArray data;
+ try
+ {
+ data = QgsGrass::runModule( mGisdbase, mLocation, cmd, arguments );
+ }
+ catch ( QgsGrass::Exception &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot draw raster" ) + "\n"
+ + e.what() );
+
+ // We don't set mValid to false, because the raster can be recreated and work next time
+ }
+ QgsDebugMsg( QString( "%1 bytes read from modules stdout" ).arg( data.size() ) );
+ // byteCount() in Qt >= 4.6
+ //int size = image->byteCount() < data.size() ? image->byteCount() : data.size();
+ // TODO : data type size
+ int typeSize = 4;
+ int size = mCols * typeSize < data.size() ? mCols * typeSize : data.size();
+ memcpy( block, data.data(), size );
+}
+
+void QgsGrassRasterProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, int pixelWidth, int pixelHeight, void *block )
+{
+ QgsDebugMsg( "Entered" );
+ QgsDebugMsg( "pixelWidth = " + QString::number( pixelWidth ) );
+ QgsDebugMsg( "pixelHeight = " + QString::number( pixelHeight ) );
+ QgsDebugMsg( "viewExtent: " + viewExtent.toString() );
+
+ QImage *image = new QImage( pixelWidth, pixelHeight, QImage::Format_ARGB32 );
+ image->fill( QColor( Qt::gray ).rgb() );
+
+ QStringList arguments;
+ arguments.append( "map=" + mMapName + "@" + mMapset );
+
+ arguments.append(( QString( "window=%1,%2,%3,%4,%5,%6" )
+ .arg( viewExtent.xMinimum() ).arg( viewExtent.yMinimum() )
+ .arg( viewExtent.xMaximum() ).arg( viewExtent.yMaximum() )
+ .arg( pixelWidth ).arg( pixelHeight ) ) );
+ arguments.append( "format=value");
+ QProcess process( this );
+ QString cmd = QgsApplication::prefixPath() + "/" QGIS_LIBEXEC_SUBDIR "/grass/modules/qgis.d.rast";
+ QByteArray data;
+ try
+ {
+ data = QgsGrass::runModule( mGisdbase, mLocation, cmd, arguments );
+ }
+ catch ( QgsGrass::Exception &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot draw raster" ) + "\n"
+ + e.what() );
+
+ // We don't set mValid to false, because the raster can be recreated and work next time
+ return;
+ }
+ QgsDebugMsg( QString( "%1 bytes read from modules stdout" ).arg( data.size() ) );
+ // byteCount() in Qt >= 4.6
+ //int size = image->byteCount() < data.size() ? image->byteCount() : data.size();
+ // TODO : data type size
+ int typeSize = 4;
+ int size = pixelWidth * pixelHeight * typeSize < data.size() ? pixelWidth * pixelHeight * typeSize : data.size();
+ memcpy( block, data.data(), size );
+}
+
+double QgsGrassRasterProvider::noDataValue() const {
+ double nul;
+ if ( mGrassDataType == CELL_TYPE ) {
+ nul = -2147483647;
+ } else if ( mGrassDataType == DCELL_TYPE ) {
+ nul = 2.2250738585072014e-308;
+ } else if ( mGrassDataType == FCELL_TYPE ) {
+ nul = 1.17549435e-38F;
+ }
+ QgsDebugMsg( QString( "noDataValue = %1" ).arg( nul ) );
+ return nul;
+}
+
+double QgsGrassRasterProvider::minimumValue( int bandNo ) const {
+ return mInfo["MIN_VALUE"].toDouble();
+}
+double QgsGrassRasterProvider::maximumValue( int bandNo ) const {
+ return mInfo["MAX_VALUE"].toDouble();
+}
+
QgsCoordinateReferenceSystem QgsGrassRasterProvider::crs()
{
QgsDebugMsg( "Entered" );
@@ -134,11 +252,19 @@
// The extend can change of course so we get always fresh, to avoid running always the module
// we should save mExtent and mLastModified and check if the map was modified
- QgsRectangle rect;
- rect = QgsGrass::extent( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster );
- return rect;
+ mExtent = QgsGrass::extent( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster );
+ return mExtent;
}
+// this is only called once when statistics are calculated
+int QgsGrassRasterProvider::xBlockSize() const { return mCols; }
+int QgsGrassRasterProvider::yBlockSize() const { return 1; }
+
+// TODO this should be always refreshed if raster has changed ?
+// maybe also only for stats
+int QgsGrassRasterProvider::xSize() const { return mCols; }
+int QgsGrassRasterProvider::ySize() const { return mRows; }
+
bool QgsGrassRasterProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
{
QgsDebugMsg( "Entered" );
@@ -149,10 +275,28 @@
int QgsGrassRasterProvider::capabilities() const
{
- int capability = QgsRasterDataProvider::Identify;
+ int capability = QgsRasterDataProvider::Identify
+ | QgsRasterDataProvider::Data;
return capability;
}
+int QgsGrassRasterProvider::dataType( int bandNo ) const
+{
+ // TODO
+ return QgsRasterDataProvider::Int32;
+}
+
+int QgsGrassRasterProvider::bandCount() const
+{
+ // TODO
+ return 1;
+}
+
+int QgsGrassRasterProvider::colorInterpretation ( int bandNo ) const {
+ // TODO
+ return QgsRasterDataProvider::GrayIndex;
+}
+
bool QgsGrassRasterProvider::isValid()
{
return mValid;
Modified: branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h 2010-11-05 07:26:04 UTC (rev 14510)
+++ branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h 2010-11-05 07:28:20 UTC (rev 14511)
@@ -21,6 +21,11 @@
#ifndef QGSWMSPROVIDER_H
#define QGSWMSPROVIDER_H
+extern "C"
+{
+#include <grass/gis.h>
+}
+
#include "qgscoordinatereferencesystem.h"
#include "qgsrasterdataprovider.h"
#include "qgsrectangle.h"
@@ -171,6 +176,26 @@
*/
int capabilities() const;
+ int dataType ( int bandNo ) const;
+
+ int bandCount() const;
+
+ int colorInterpretation ( int bandNo ) const;
+
+ int xBlockSize() const;
+ int yBlockSize() const;
+
+ int xSize() const;
+ int ySize() const;
+
+
+ void readBlock( int bandNo, int xBlock, int yBlock, void *data );
+ void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
+
+ double noDataValue() const;
+ double minimumValue(int bandNo)const;
+ double maximumValue(int bandNo)const;
+
/**
* Get metadata in a format suitable for feeding directly
* into a subset of the GUI raster properties "Metadata" tab.
@@ -196,7 +221,16 @@
QString mMapset; // map mapset
QString mMapName; // map name
+ RASTER_MAP_TYPE mGrassDataType; // CELL_TYPE, DCELL_TYPE, FCELL_TYPE
+
+ QgsRectangle mExtent;
+ int mCols;
+ int mRows;
+
+ QHash<QString, QString> mInfo;
+
QgsCoordinateReferenceSystem mCrs;
+
};
#endif
More information about the QGIS-commit
mailing list