Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
-Added ability to export and load color map to/from a simple text file
-Closes ticket #805
-Updaded color interpretation option Linearly to Linear 
-Fix problem displaying (pseudo and color map) paletted images

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@9170 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
ersts committed Aug 25, 2008
1 parent ae55c00 commit 693bd14
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 116 deletions.
173 changes: 164 additions & 9 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -134,9 +134,10 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QWidget *p

//setup custom colormap tab
cboxColorInterpolation->addItem( tr( "Discrete" ) );
cboxColorInterpolation->addItem( tr( "Linearly" ) );
cboxColorInterpolation->addItem( tr( "Linear" ) );
cboxColorInterpolation->addItem( tr( "Exact") );
cboxClassificationMode->addItem( tr( "Equal interval" ) );
cboxClassificationMode->addItem( tr( "Quantiles" ) );
//cboxClassificationMode->addItem( tr( "Quantiles" ) );

QStringList headerLabels;
headerLabels << "Value";
Expand Down Expand Up @@ -291,6 +292,9 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QWidget *p
pbtnMakeBandCombinationDefault->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );
pbtnMakeContrastEnhancementAlgorithmDefault->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );

pbtnExportColorMapToFile->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );
pbtnLoadColorMapFromFile->setIcon( QgisApp::getThemeIcon( "/mActionFileOpen.png" ) );

// Only do pyramids if dealing directly with GDAL.
if ( mRasterLayerIsGdal )
{
Expand Down Expand Up @@ -886,13 +890,17 @@ void QgsRasterLayerProperties::syncColormapTab()
sboxNumberOfEntries->setValue( myColorRampList.size() );

//restor state of 'color interpolation' combo box
if ( QgsColorRampShader::DISCRETE == myRasterShaderFunction->getColorRampType() )
if ( QgsColorRampShader::INTERPOLATED == myRasterShaderFunction->getColorRampType() )
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linear" ) ) );
}
else if ( QgsColorRampShader::DISCRETE == myRasterShaderFunction->getColorRampType() )
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Discrete" ) ) );
}
else
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linearly" ) ) );
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Exact" ) ) );
}

}
Expand Down Expand Up @@ -1397,13 +1405,17 @@ void QgsRasterLayerProperties::apply()
}
myRasterShaderFunction->setColorRampItemList( mColorRampItems );

if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
if ( cboxColorInterpolation->currentText() == tr( "Linear" ) )
{
myRasterShaderFunction->setColorRampType( QgsColorRampShader::INTERPOLATED );
}
else if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
{
myRasterShaderFunction->setColorRampType( QgsColorRampShader::DISCRETE );
}
else
{
myRasterShaderFunction->setColorRampType( QgsColorRampShader::INTERPOLATED );
myRasterShaderFunction->setColorRampType( QgsColorRampShader::EXACT );
}
}
else
Expand Down Expand Up @@ -2575,10 +2587,10 @@ void QgsRasterLayerProperties::on_mClassifyButton_clicked()
currentValue += intervalDiff;
}
}
else if ( cboxClassificationMode->currentText() == tr( "Quantiles" ) )
{
//else if ( cboxClassificationMode->currentText() == tr( "Quantiles" ) )
//{
//todo
}
//}

//hard code color range from blue -> red for now. Allow choice of ramps in future
int colorDiff = 0;
Expand Down Expand Up @@ -2637,6 +2649,149 @@ void QgsRasterLayerProperties::handleColormapTreeWidgetDoubleClick( QTreeWidgetI
}
}

void QgsRasterLayerProperties::on_pbtnExportColorMapToFile_clicked()
{
QString myFileName = QFileDialog::getSaveFileName( this, tr( "Save file" ), "/", tr( "Textfile (*.txt)" ) );
if ( !myFileName.isEmpty() )
{
if ( !myFileName.endsWith( ".txt", Qt::CaseInsensitive ) )
{
myFileName = myFileName + ".txt";
}

QFile myOutputFile( myFileName );
if ( myOutputFile.open( QFile::WriteOnly ) )
{
QTextStream myOutputStream( &myOutputFile );
myOutputStream << "# " << tr( "QGIS Generated Color Map Export File" ) << "\n";
myOutputStream << "INTERPOLATION:";
if ( cboxColorInterpolation->currentText() == tr( "Linear" ) )
{
myOutputStream << "INTERPOLATED\n";
}
else if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
{
myOutputStream << "DISCRETE\n";
}
else
{
myOutputStream << "EXACT\n";
}

int myTopLevelItemCount = mColormapTreeWidget->topLevelItemCount();
QTreeWidgetItem* myCurrentItem;
QColor myColor;
for ( int i = 0; i < myTopLevelItemCount; ++i )
{
myCurrentItem = mColormapTreeWidget->topLevelItem( i );
if ( !myCurrentItem )
{
continue;
}
myColor = myCurrentItem->background( 1 ).color();
myOutputStream << myCurrentItem->text( 0 ).toDouble() << ",";
myOutputStream << myColor.red() << "," << myColor.green() << "," << myColor.blue() << "," << myColor.alpha() << ",";
if(myCurrentItem->text(2) == "")
{
myOutputStream << "Color entry " << i+1 << "\n";
}
else
{
myOutputStream << myCurrentItem->text( 2 ) << "\n";
}
}
myOutputStream.flush();
myOutputFile.close();
}
else
{
QMessageBox::warning( this, tr( "Write access denied" ), tr( "Write access denied. Adjust the file permissions and try again.\n\n" ) );
}
}
}

void QgsRasterLayerProperties::on_pbtnLoadColorMapFromFile_clicked()
{
int myLineCounter = 0;
bool myImportError = false;
QString myBadLines;
QString myFileName = QFileDialog::getOpenFileName( this, tr( "Open file" ), "/", tr( "Textfile (*.txt)" ) );
QFile myInputFile( myFileName );
if ( myInputFile.open( QFile::ReadOnly ) )
{
//clear the current tree
mColormapTreeWidget->clear();

QTextStream myInputStream( &myInputFile );
QString myInputLine;
QStringList myInputStringComponents;

//read through the input looking for valid data
while ( !myInputStream.atEnd() )
{
myLineCounter++;
myInputLine = myInputStream.readLine();
if ( !myInputLine.isEmpty() )
{
if ( !myInputLine.simplified().startsWith( "#" ) )
{
if(myInputLine.contains("INTERPOLATION", Qt::CaseInsensitive))
{
myInputStringComponents = myInputLine.split(":");
if(myInputStringComponents.size() == 2)
{
if(myInputStringComponents[1].trimmed().toUpper().compare ("INTERPOLATED", Qt::CaseInsensitive) == 0)
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linear" ) ) );
}
else if(myInputStringComponents[1].trimmed().toUpper().compare ("DISCRETE", Qt::CaseInsensitive) == 0)
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Discrete" ) ) );
}
else
{
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Exact" ) ) );
}
}
else
{
myImportError = true;
myBadLines = myBadLines + QString::number( myLineCounter ) + ":\t[" + myInputLine + "]\n";
}
}
else
{
myInputStringComponents = myInputLine.split(",");
if(myInputStringComponents.size() == 6)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem( mColormapTreeWidget );
newItem->setText( 0, myInputStringComponents[0] );
newItem->setBackground( 1, QBrush( QColor::fromRgb(myInputStringComponents[1].toInt(), myInputStringComponents[2].toInt(), myInputStringComponents[3].toInt(), myInputStringComponents[4].toInt()) ) );
newItem->setText( 2, myInputStringComponents[5] );
}
else
{
myImportError = true;
myBadLines = myBadLines + QString::number( myLineCounter ) + ":\t[" + myInputLine + "]\n";
}
}
}
}
myLineCounter++;
}


if ( myImportError )
{
QMessageBox::warning( this, tr( "Import Error" ), tr( "The following lines contained errors\n\n" ) + myBadLines );
}
}
else if ( !myFileName.isEmpty() )
{
QMessageBox::warning( this, tr( "Read access denied" ), tr( "Read access denied. Adjust the file permissions and try again.\n\n" ) );
}
}

void QgsRasterLayerProperties::on_pbtnLoadMinMax_clicked()
{
if ( mRasterLayerIsGdal && ( mRasterLayer->getDrawingStyle() == QgsRasterLayer::SINGLE_BAND_GRAY || mRasterLayer->getDrawingStyle() == QgsRasterLayer::MULTI_BAND_SINGLE_BAND_GRAY || mRasterLayer->getDrawingStyle() == QgsRasterLayer::MULTI_BAND_COLOR ) )
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgsrasterlayerproperties.h
Expand Up @@ -106,6 +106,10 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
void on_mDeleteEntryButton_clicked();
/**Callback for double clicks on the colormap entry widget*/
void handleColormapTreeWidgetDoubleClick( QTreeWidgetItem* item, int column );
/**This slots saves the current color map to a file */
void on_pbtnExportColorMapToFile_clicked();
/**This slots saves the current color map to a file */
void on_pbtnLoadColorMapFromFile_clicked();
/**This slot loads the minimum and maximum values from the raster band and updates the gui*/
void on_pbtnLoadMinMax_clicked();
/**This slot sets the default band combination varaible to current band combination */
Expand Down
29 changes: 27 additions & 2 deletions src/core/raster/qgscolorrampshader.cpp
Expand Up @@ -29,12 +29,16 @@ QgsColorRampShader::QgsColorRampShader( double theMinimumValue, double theMaximu

bool QgsColorRampShader::generateShadedValue( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
{
if ( QgsColorRampShader::DISCRETE == mColorRampType )
if ( QgsColorRampShader::INTERPOLATED == mColorRampType )
{
return getInterpolatedColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
}
else if ( QgsColorRampShader::DISCRETE == mColorRampType )
{
return getDiscreteColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
}

return getInterpolatedColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
return getExactColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
}

bool QgsColorRampShader::generateShadedValue( double theRedValue, double theGreenValue, double theBlueValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
Expand Down Expand Up @@ -91,6 +95,27 @@ bool QgsColorRampShader::getDiscreteColor( double theValue, int* theReturnRedVal
return false; // value not found
}

bool QgsColorRampShader::getExactColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
{
if ( mColorRampItemList.count() <= 0 )
{
return false;
}
QList<QgsColorRampShader::ColorRampItem>::const_iterator it;
for ( it = mColorRampItemList.begin(); it != mColorRampItemList.end(); ++it )
{
if ( theValue == it->value )
{
*theReturnRedValue = it->color.red();
*theReturnGreenValue = it->color.green();
*theReturnBlueValue = it->color.blue();
return true;
}
}

return false; // value not found
}

bool QgsColorRampShader::getInterpolatedColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
{
if ( mColorRampItemList.count() <= 0 )
Expand Down
2 changes: 2 additions & 0 deletions src/core/raster/qgscolorrampshader.h
Expand Up @@ -73,6 +73,8 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction
private:
/**Gets the color for a pixel value from the classification vector mValueClassification. Assigns the color of the lower class for every pixel between two class breaks.*/
bool getDiscreteColor( double, int*, int*, int* );
/**Gets the color for a pixel value from the classification vector mValueClassification. Assigns the color of the exact matching value in the color ramp item list */
bool getExactColor( double, int*, int*, int* );
/**Gets the color for a pixel value from the classification vector mValueClassification. Interpolates the color between two class breaks linearly.*/
bool getInterpolatedColor( double, int*, int*, int* );

Expand Down
26 changes: 1 addition & 25 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -1746,32 +1746,12 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor( QPainter * theQPainter,
mRasterShader->setMinimumValue( myMinimumValue );
mRasterShader->setMaximumValue( myMaximumValue );

QgsColorTable *myColorTable = &( myRasterBandStats.colorTable );
int myRedLUTValue = 0;
int myGreenLUTValue = 0;
int myBlueLUTValue;

double myPixelValue = 0.0;
int myRedValue = 0;
int myGreenValue = 0;
int myBlueValue = 0;
int myAlphaValue = 0;

//Set a pointer to the LUT color channel
int* myGrayValue;
if ( theColorQString == mRedBandName )
{
myGrayValue = &myRedLUTValue;
}
else if ( theColorQString == mGreenBandName )
{
myGrayValue = &myGreenLUTValue;
}
else
{
myGrayValue = &myBlueLUTValue;
}

for ( int myColumn = 0; myColumn < theRasterViewPort->drawableAreaYDim; ++myColumn )
{
for ( int myRow = 0; myRow < theRasterViewPort->drawableAreaXDim; ++myRow )
Expand All @@ -1793,11 +1773,7 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor( QPainter * theQPainter,
continue;
}

bool found = myColorTable->color( myPixelValue, &myRedLUTValue, &myGreenLUTValue, &myBlueLUTValue );
if ( !found ) continue;


if ( !mRasterShader->generateShadedValue(( double )*myGrayValue, &myRedValue, &myGreenValue, &myBlueValue ) )
if ( !mRasterShader->generateShadedValue(myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
{
continue;
}
Expand Down

0 comments on commit 693bd14

Please sign in to comment.