Skip to content

Commit 693bd14

Browse files
author
ersts
committed
-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
1 parent ae55c00 commit 693bd14

6 files changed

+292
-116
lines changed

src/app/qgsrasterlayerproperties.cpp

+164-9
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QWidget *p
134134

135135
//setup custom colormap tab
136136
cboxColorInterpolation->addItem( tr( "Discrete" ) );
137-
cboxColorInterpolation->addItem( tr( "Linearly" ) );
137+
cboxColorInterpolation->addItem( tr( "Linear" ) );
138+
cboxColorInterpolation->addItem( tr( "Exact") );
138139
cboxClassificationMode->addItem( tr( "Equal interval" ) );
139-
cboxClassificationMode->addItem( tr( "Quantiles" ) );
140+
//cboxClassificationMode->addItem( tr( "Quantiles" ) );
140141

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

295+
pbtnExportColorMapToFile->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );
296+
pbtnLoadColorMapFromFile->setIcon( QgisApp::getThemeIcon( "/mActionFileOpen.png" ) );
297+
294298
// Only do pyramids if dealing directly with GDAL.
295299
if ( mRasterLayerIsGdal )
296300
{
@@ -886,13 +890,17 @@ void QgsRasterLayerProperties::syncColormapTab()
886890
sboxNumberOfEntries->setValue( myColorRampList.size() );
887891

888892
//restor state of 'color interpolation' combo box
889-
if ( QgsColorRampShader::DISCRETE == myRasterShaderFunction->getColorRampType() )
893+
if ( QgsColorRampShader::INTERPOLATED == myRasterShaderFunction->getColorRampType() )
894+
{
895+
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linear" ) ) );
896+
}
897+
else if ( QgsColorRampShader::DISCRETE == myRasterShaderFunction->getColorRampType() )
890898
{
891899
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Discrete" ) ) );
892900
}
893901
else
894902
{
895-
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linearly" ) ) );
903+
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Exact" ) ) );
896904
}
897905

898906
}
@@ -1397,13 +1405,17 @@ void QgsRasterLayerProperties::apply()
13971405
}
13981406
myRasterShaderFunction->setColorRampItemList( mColorRampItems );
13991407

1400-
if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
1408+
if ( cboxColorInterpolation->currentText() == tr( "Linear" ) )
1409+
{
1410+
myRasterShaderFunction->setColorRampType( QgsColorRampShader::INTERPOLATED );
1411+
}
1412+
else if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
14011413
{
14021414
myRasterShaderFunction->setColorRampType( QgsColorRampShader::DISCRETE );
14031415
}
14041416
else
14051417
{
1406-
myRasterShaderFunction->setColorRampType( QgsColorRampShader::INTERPOLATED );
1418+
myRasterShaderFunction->setColorRampType( QgsColorRampShader::EXACT );
14071419
}
14081420
}
14091421
else
@@ -2575,10 +2587,10 @@ void QgsRasterLayerProperties::on_mClassifyButton_clicked()
25752587
currentValue += intervalDiff;
25762588
}
25772589
}
2578-
else if ( cboxClassificationMode->currentText() == tr( "Quantiles" ) )
2579-
{
2590+
//else if ( cboxClassificationMode->currentText() == tr( "Quantiles" ) )
2591+
//{
25802592
//todo
2581-
}
2593+
//}
25822594

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

2652+
void QgsRasterLayerProperties::on_pbtnExportColorMapToFile_clicked()
2653+
{
2654+
QString myFileName = QFileDialog::getSaveFileName( this, tr( "Save file" ), "/", tr( "Textfile (*.txt)" ) );
2655+
if ( !myFileName.isEmpty() )
2656+
{
2657+
if ( !myFileName.endsWith( ".txt", Qt::CaseInsensitive ) )
2658+
{
2659+
myFileName = myFileName + ".txt";
2660+
}
2661+
2662+
QFile myOutputFile( myFileName );
2663+
if ( myOutputFile.open( QFile::WriteOnly ) )
2664+
{
2665+
QTextStream myOutputStream( &myOutputFile );
2666+
myOutputStream << "# " << tr( "QGIS Generated Color Map Export File" ) << "\n";
2667+
myOutputStream << "INTERPOLATION:";
2668+
if ( cboxColorInterpolation->currentText() == tr( "Linear" ) )
2669+
{
2670+
myOutputStream << "INTERPOLATED\n";
2671+
}
2672+
else if ( cboxColorInterpolation->currentText() == tr( "Discrete" ) )
2673+
{
2674+
myOutputStream << "DISCRETE\n";
2675+
}
2676+
else
2677+
{
2678+
myOutputStream << "EXACT\n";
2679+
}
2680+
2681+
int myTopLevelItemCount = mColormapTreeWidget->topLevelItemCount();
2682+
QTreeWidgetItem* myCurrentItem;
2683+
QColor myColor;
2684+
for ( int i = 0; i < myTopLevelItemCount; ++i )
2685+
{
2686+
myCurrentItem = mColormapTreeWidget->topLevelItem( i );
2687+
if ( !myCurrentItem )
2688+
{
2689+
continue;
2690+
}
2691+
myColor = myCurrentItem->background( 1 ).color();
2692+
myOutputStream << myCurrentItem->text( 0 ).toDouble() << ",";
2693+
myOutputStream << myColor.red() << "," << myColor.green() << "," << myColor.blue() << "," << myColor.alpha() << ",";
2694+
if(myCurrentItem->text(2) == "")
2695+
{
2696+
myOutputStream << "Color entry " << i+1 << "\n";
2697+
}
2698+
else
2699+
{
2700+
myOutputStream << myCurrentItem->text( 2 ) << "\n";
2701+
}
2702+
}
2703+
myOutputStream.flush();
2704+
myOutputFile.close();
2705+
}
2706+
else
2707+
{
2708+
QMessageBox::warning( this, tr( "Write access denied" ), tr( "Write access denied. Adjust the file permissions and try again.\n\n" ) );
2709+
}
2710+
}
2711+
}
2712+
2713+
void QgsRasterLayerProperties::on_pbtnLoadColorMapFromFile_clicked()
2714+
{
2715+
int myLineCounter = 0;
2716+
bool myImportError = false;
2717+
QString myBadLines;
2718+
QString myFileName = QFileDialog::getOpenFileName( this, tr( "Open file" ), "/", tr( "Textfile (*.txt)" ) );
2719+
QFile myInputFile( myFileName );
2720+
if ( myInputFile.open( QFile::ReadOnly ) )
2721+
{
2722+
//clear the current tree
2723+
mColormapTreeWidget->clear();
2724+
2725+
QTextStream myInputStream( &myInputFile );
2726+
QString myInputLine;
2727+
QStringList myInputStringComponents;
2728+
2729+
//read through the input looking for valid data
2730+
while ( !myInputStream.atEnd() )
2731+
{
2732+
myLineCounter++;
2733+
myInputLine = myInputStream.readLine();
2734+
if ( !myInputLine.isEmpty() )
2735+
{
2736+
if ( !myInputLine.simplified().startsWith( "#" ) )
2737+
{
2738+
if(myInputLine.contains("INTERPOLATION", Qt::CaseInsensitive))
2739+
{
2740+
myInputStringComponents = myInputLine.split(":");
2741+
if(myInputStringComponents.size() == 2)
2742+
{
2743+
if(myInputStringComponents[1].trimmed().toUpper().compare ("INTERPOLATED", Qt::CaseInsensitive) == 0)
2744+
{
2745+
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Linear" ) ) );
2746+
}
2747+
else if(myInputStringComponents[1].trimmed().toUpper().compare ("DISCRETE", Qt::CaseInsensitive) == 0)
2748+
{
2749+
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Discrete" ) ) );
2750+
}
2751+
else
2752+
{
2753+
cboxColorInterpolation->setCurrentIndex( cboxColorInterpolation->findText( tr( "Exact" ) ) );
2754+
}
2755+
}
2756+
else
2757+
{
2758+
myImportError = true;
2759+
myBadLines = myBadLines + QString::number( myLineCounter ) + ":\t[" + myInputLine + "]\n";
2760+
}
2761+
}
2762+
else
2763+
{
2764+
myInputStringComponents = myInputLine.split(",");
2765+
if(myInputStringComponents.size() == 6)
2766+
{
2767+
QTreeWidgetItem* newItem = new QTreeWidgetItem( mColormapTreeWidget );
2768+
newItem->setText( 0, myInputStringComponents[0] );
2769+
newItem->setBackground( 1, QBrush( QColor::fromRgb(myInputStringComponents[1].toInt(), myInputStringComponents[2].toInt(), myInputStringComponents[3].toInt(), myInputStringComponents[4].toInt()) ) );
2770+
newItem->setText( 2, myInputStringComponents[5] );
2771+
}
2772+
else
2773+
{
2774+
myImportError = true;
2775+
myBadLines = myBadLines + QString::number( myLineCounter ) + ":\t[" + myInputLine + "]\n";
2776+
}
2777+
}
2778+
}
2779+
}
2780+
myLineCounter++;
2781+
}
2782+
2783+
2784+
if ( myImportError )
2785+
{
2786+
QMessageBox::warning( this, tr( "Import Error" ), tr( "The following lines contained errors\n\n" ) + myBadLines );
2787+
}
2788+
}
2789+
else if ( !myFileName.isEmpty() )
2790+
{
2791+
QMessageBox::warning( this, tr( "Read access denied" ), tr( "Read access denied. Adjust the file permissions and try again.\n\n" ) );
2792+
}
2793+
}
2794+
26402795
void QgsRasterLayerProperties::on_pbtnLoadMinMax_clicked()
26412796
{
26422797
if ( mRasterLayerIsGdal && ( mRasterLayer->getDrawingStyle() == QgsRasterLayer::SINGLE_BAND_GRAY || mRasterLayer->getDrawingStyle() == QgsRasterLayer::MULTI_BAND_SINGLE_BAND_GRAY || mRasterLayer->getDrawingStyle() == QgsRasterLayer::MULTI_BAND_COLOR ) )

src/app/qgsrasterlayerproperties.h

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
106106
void on_mDeleteEntryButton_clicked();
107107
/**Callback for double clicks on the colormap entry widget*/
108108
void handleColormapTreeWidgetDoubleClick( QTreeWidgetItem* item, int column );
109+
/**This slots saves the current color map to a file */
110+
void on_pbtnExportColorMapToFile_clicked();
111+
/**This slots saves the current color map to a file */
112+
void on_pbtnLoadColorMapFromFile_clicked();
109113
/**This slot loads the minimum and maximum values from the raster band and updates the gui*/
110114
void on_pbtnLoadMinMax_clicked();
111115
/**This slot sets the default band combination varaible to current band combination */

src/core/raster/qgscolorrampshader.cpp

+27-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ QgsColorRampShader::QgsColorRampShader( double theMinimumValue, double theMaximu
2929

3030
bool QgsColorRampShader::generateShadedValue( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
3131
{
32-
if ( QgsColorRampShader::DISCRETE == mColorRampType )
32+
if ( QgsColorRampShader::INTERPOLATED == mColorRampType )
33+
{
34+
return getInterpolatedColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
35+
}
36+
else if ( QgsColorRampShader::DISCRETE == mColorRampType )
3337
{
3438
return getDiscreteColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
3539
}
3640

37-
return getInterpolatedColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
41+
return getExactColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
3842
}
3943

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

98+
bool QgsColorRampShader::getExactColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
99+
{
100+
if ( mColorRampItemList.count() <= 0 )
101+
{
102+
return false;
103+
}
104+
QList<QgsColorRampShader::ColorRampItem>::const_iterator it;
105+
for ( it = mColorRampItemList.begin(); it != mColorRampItemList.end(); ++it )
106+
{
107+
if ( theValue == it->value )
108+
{
109+
*theReturnRedValue = it->color.red();
110+
*theReturnGreenValue = it->color.green();
111+
*theReturnBlueValue = it->color.blue();
112+
return true;
113+
}
114+
}
115+
116+
return false; // value not found
117+
}
118+
94119
bool QgsColorRampShader::getInterpolatedColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
95120
{
96121
if ( mColorRampItemList.count() <= 0 )

src/core/raster/qgscolorrampshader.h

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction
7373
private:
7474
/**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.*/
7575
bool getDiscreteColor( double, int*, int*, int* );
76+
/**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 */
77+
bool getExactColor( double, int*, int*, int* );
7678
/**Gets the color for a pixel value from the classification vector mValueClassification. Interpolates the color between two class breaks linearly.*/
7779
bool getInterpolatedColor( double, int*, int*, int* );
7880

src/core/raster/qgsrasterlayer.cpp

+1-25
Original file line numberDiff line numberDiff line change
@@ -1746,32 +1746,12 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor( QPainter * theQPainter,
17461746
mRasterShader->setMinimumValue( myMinimumValue );
17471747
mRasterShader->setMaximumValue( myMaximumValue );
17481748

1749-
QgsColorTable *myColorTable = &( myRasterBandStats.colorTable );
1750-
int myRedLUTValue = 0;
1751-
int myGreenLUTValue = 0;
1752-
int myBlueLUTValue;
1753-
17541749
double myPixelValue = 0.0;
17551750
int myRedValue = 0;
17561751
int myGreenValue = 0;
17571752
int myBlueValue = 0;
17581753
int myAlphaValue = 0;
17591754

1760-
//Set a pointer to the LUT color channel
1761-
int* myGrayValue;
1762-
if ( theColorQString == mRedBandName )
1763-
{
1764-
myGrayValue = &myRedLUTValue;
1765-
}
1766-
else if ( theColorQString == mGreenBandName )
1767-
{
1768-
myGrayValue = &myGreenLUTValue;
1769-
}
1770-
else
1771-
{
1772-
myGrayValue = &myBlueLUTValue;
1773-
}
1774-
17751755
for ( int myColumn = 0; myColumn < theRasterViewPort->drawableAreaYDim; ++myColumn )
17761756
{
17771757
for ( int myRow = 0; myRow < theRasterViewPort->drawableAreaXDim; ++myRow )
@@ -1793,11 +1773,7 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor( QPainter * theQPainter,
17931773
continue;
17941774
}
17951775

1796-
bool found = myColorTable->color( myPixelValue, &myRedLUTValue, &myGreenLUTValue, &myBlueLUTValue );
1797-
if ( !found ) continue;
1798-
1799-
1800-
if ( !mRasterShader->generateShadedValue(( double )*myGrayValue, &myRedValue, &myGreenValue, &myBlueValue ) )
1776+
if ( !mRasterShader->generateShadedValue(myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
18011777
{
18021778
continue;
18031779
}

0 commit comments

Comments
 (0)