27 #include <QFileDialog>
28 #include <QMessageBox>
30 #include <QTextStream>
34 , mMinMaxWidget( NULL )
41 mColormapTreeWidget->setColumnWidth( 1, 50 );
43 QString defaultPalette = settings.value(
"/Raster/defaultPalette",
"Spectral" ).toString();
47 QgsDebugMsg(
"defaultPalette = " + defaultPalette );
48 mColorRampComboBox->setCurrentIndex( mColorRampComboBox->findText( defaultPalette ) );
62 mMinLineEdit->setValidator(
new QDoubleValidator( mMinLineEdit ) );
63 mMaxLineEdit->setValidator(
new QDoubleValidator( mMaxLineEdit ) );
67 QHBoxLayout *layout =
new QHBoxLayout();
68 layout->setContentsMargins( 0, 0, 0, 0 );
69 mMinMaxContainerWidget->setLayout( layout );
70 layout->addWidget( mMinMaxWidget );
71 connect( mMinMaxWidget, SIGNAL( load(
int,
double,
double,
int ) ),
72 this, SLOT(
loadMinMax(
int,
double,
double,
int ) ) );
77 for (
int i = 1; i <= nBands; ++i )
82 mColorInterpolationComboBox->addItem(
tr(
"Discrete" ), 0 );
83 mColorInterpolationComboBox->addItem(
tr(
"Linear" ), 1 );
84 mColorInterpolationComboBox->addItem(
tr(
"Exact" ), 2 );
85 mColorInterpolationComboBox->setCurrentIndex( 1 );
86 mClassificationModeComboBox->addItem(
tr(
"Continuous" ),
Continuous );
87 mClassificationModeComboBox->addItem(
tr(
"Equal interval" ),
EqualInterval );
90 mNumberOfEntriesSpinBox->setValue( 5 );
95 if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() )
97 mMinMaxWidget->
load();
100 on_mClassificationModeComboBox_currentIndexChanged( 0 );
102 resetClassifyButton();
113 colorRampShader->
setClip( mClipCheckBox->isChecked() );
116 QList<QgsColorRampShader::ColorRampItem> colorRampItems;
117 int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
118 QTreeWidgetItem* currentItem;
119 for (
int i = 0; i < topLevelItemCount; ++i )
121 currentItem = mColormapTreeWidget->topLevelItem( i );
127 newColorRampItem.
value = currentItem->text( 0 ).toDouble();
128 newColorRampItem.
color = currentItem->background( 1 ).color();
129 newColorRampItem.
label = currentItem->text( 2 );
130 colorRampItems.append( newColorRampItem );
133 qSort( colorRampItems );
136 if ( mColorInterpolationComboBox->currentText() ==
tr(
"Linear" ) )
140 else if ( mColorInterpolationComboBox->currentText() ==
tr(
"Discrete" ) )
150 int bandNumber = mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt();
159 void QgsSingleBandPseudoColorRendererWidget::on_mAddEntryButton_clicked()
161 QTreeWidgetItem* newItem =
new QTreeWidgetItem( mColormapTreeWidget );
162 newItem->setText( 0,
"0.0" );
163 newItem->setBackground( 1, QBrush( QColor( Qt::magenta ) ) );
164 newItem->setText( 2,
tr(
"Custom color map entry" ) );
167 void QgsSingleBandPseudoColorRendererWidget::on_mDeleteEntryButton_clicked()
169 QTreeWidgetItem* currentItem = mColormapTreeWidget->currentItem();
176 void QgsSingleBandPseudoColorRendererWidget::on_mSortButton_clicked()
178 bool inserted =
false;
179 int myCurrentIndex = 0;
180 int myTopLevelItemCount = mColormapTreeWidget->topLevelItemCount();
181 QTreeWidgetItem* myCurrentItem;
182 QList<QgsColorRampShader::ColorRampItem> myColorRampItems;
183 for (
int i = 0; i < myTopLevelItemCount; ++i )
185 myCurrentItem = mColormapTreeWidget->topLevelItem( i );
187 if ( !myCurrentItem || myCurrentItem->text( 0 ) ==
"" )
194 myNewColorRampItem.
value = myCurrentItem->text( 0 ).toDouble();
195 myNewColorRampItem.
color = myCurrentItem->background( 1 ).color();
196 myNewColorRampItem.
label = myCurrentItem->text( 2 );
203 if ( 0 == myColorRampItems.size() || myCurrentIndex == myColorRampItems.size() )
205 myColorRampItems.push_back( myNewColorRampItem );
208 else if ( myColorRampItems[myCurrentIndex].value > myNewColorRampItem.
value )
210 myColorRampItems.insert( myCurrentIndex, myNewColorRampItem );
213 else if ( myColorRampItems[myCurrentIndex].value <= myNewColorRampItem.
value && myCurrentIndex == myColorRampItems.size() - 1 )
215 myColorRampItems.push_back( myNewColorRampItem );
218 else if ( myColorRampItems[myCurrentIndex].value <= myNewColorRampItem.
value && myColorRampItems[myCurrentIndex+1].value > myNewColorRampItem.
value )
220 myColorRampItems.insert( myCurrentIndex + 1, myNewColorRampItem );
226 populateColormapTreeWidget( myColorRampItems );
229 void QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
231 int bandComboIndex = mBandComboBox->currentIndex();
239 int numberOfEntries = 0;
241 QList<double> entryValues;
242 QList<QColor> entryColors;
244 double min = lineEditValue( mMinLineEdit );
245 double max = lineEditValue( mMaxLineEdit );
249 if ( mClassificationModeComboBox->itemData( mClassificationModeComboBox->currentIndex() ).toInt() ==
Continuous )
253 numberOfEntries = colorRamp->
count();
254 for (
int i = 0; i < colorRamp->
count(); ++i )
256 double value = colorRamp->
value( i );
257 entryValues.push_back( min + value * ( max - min ) );
263 numberOfEntries = mNumberOfEntriesSpinBox->value();
265 double currentValue =
min;
267 if ( numberOfEntries > 1 )
272 intervalDiff = ( max -
min ) / ( numberOfEntries - 1 );
277 intervalDiff = max -
min;
280 for (
int i = 0; i < numberOfEntries; ++i )
282 entryValues.push_back( currentValue );
283 currentValue += intervalDiff;
290 if ( numberOfEntries != 0 )
292 colorDiff = ( int )( 255 / numberOfEntries );
294 for (
int i = 0; i < numberOfEntries; ++i )
297 currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
298 entryColors.push_back( currentColor );
306 if ( numberOfEntries != 0 )
308 colorDiff = ( int )( 255 / numberOfEntries );
311 for (
int i = 0; i < numberOfEntries; ++i )
314 int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
315 currentColor.setRgb( colorDiff*idx, 0, 255 - colorDiff * idx );
316 entryColors.push_back( currentColor );
321 for (
int i = 0; i < numberOfEntries; ++i )
323 int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
324 entryColors.push_back( colorRamp->
color(((
double ) idx ) / ( numberOfEntries - 1 ) ) );
328 mColormapTreeWidget->clear();
330 QList<double>::const_iterator value_it = entryValues.begin();
331 QList<QColor>::const_iterator color_it = entryColors.begin();
333 for ( ; value_it != entryValues.end(); ++value_it, ++color_it )
335 QTreeWidgetItem* newItem =
new QTreeWidgetItem( mColormapTreeWidget );
336 newItem->setText( 0, QString::number( *value_it,
'f' ) );
337 newItem->setBackground( 1, QBrush( *color_it ) );
338 newItem->setText( 2, QString::number( *value_it,
'f' ) );
339 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
343 void QgsSingleBandPseudoColorRendererWidget::on_mClassificationModeComboBox_currentIndexChanged(
int index )
345 mNumberOfEntriesSpinBox->setEnabled( mClassificationModeComboBox->itemData( index ).toInt() ==
EqualInterval );
348 void QgsSingleBandPseudoColorRendererWidget::on_mColorRampComboBox_currentIndexChanged(
int index )
352 settings.setValue(
"/Raster/defaultPalette", mColorRampComboBox->currentText() );
355 void QgsSingleBandPseudoColorRendererWidget::populateColormapTreeWidget(
const QList<QgsColorRampShader::ColorRampItem>& colorRampItems )
357 mColormapTreeWidget->clear();
358 QList<QgsColorRampShader::ColorRampItem>::const_iterator it = colorRampItems.constBegin();
359 for ( ; it != colorRampItems.constEnd(); ++it )
361 QTreeWidgetItem* newItem =
new QTreeWidgetItem( mColormapTreeWidget );
362 newItem->setText( 0, QString::number( it->value,
'f' ) );
363 newItem->setBackground( 1, QBrush( it->color ) );
364 newItem->setText( 2, it->label );
368 void QgsSingleBandPseudoColorRendererWidget::on_mLoadFromBandButton_clicked()
375 int bandIndex = mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt();
379 if ( colorRampList.size() > 0 )
381 populateColormapTreeWidget( colorRampList );
382 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Linear" ) ) );
386 QMessageBox::warning(
this,
tr(
"Load Color Map" ),
tr(
"The color map for band %1 has no entries" ).arg( bandIndex ) );
390 void QgsSingleBandPseudoColorRendererWidget::on_mLoadFromFileButton_clicked()
393 bool importError =
false;
396 QString lastDir = settings.value(
"lastRasterFileFilterDir",
"" ).toString();
397 QString fileName = QFileDialog::getOpenFileName(
this,
tr(
"Open file" ), lastDir,
tr(
"Textfile (*.txt)" ) );
398 QFile inputFile( fileName );
399 if ( inputFile.open( QFile::ReadOnly ) )
402 mColormapTreeWidget->clear();
404 QTextStream inputStream( &inputFile );
406 QStringList inputStringComponents;
407 QList<QgsColorRampShader::ColorRampItem> colorRampItems;
410 while ( !inputStream.atEnd() )
413 inputLine = inputStream.readLine();
414 if ( !inputLine.isEmpty() )
416 if ( !inputLine.simplified().startsWith(
"#" ) )
418 if ( inputLine.contains(
"INTERPOLATION", Qt::CaseInsensitive ) )
420 inputStringComponents = inputLine.split(
":" );
421 if ( inputStringComponents.size() == 2 )
423 if ( inputStringComponents[1].trimmed().toUpper().compare(
"INTERPOLATED", Qt::CaseInsensitive ) == 0 )
425 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Linear" ) ) );
427 else if ( inputStringComponents[1].trimmed().toUpper().compare(
"DISCRETE", Qt::CaseInsensitive ) == 0 )
429 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Discrete" ) ) );
433 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Exact" ) ) );
439 badLines = badLines + QString::number( lineCounter ) +
":\t[" + inputLine +
"]\n";
444 inputStringComponents = inputLine.split(
"," );
445 if ( inputStringComponents.size() == 6 )
448 QColor::fromRgb( inputStringComponents[1].toInt(), inputStringComponents[2].toInt(),
449 inputStringComponents[3].toInt(), inputStringComponents[4].toInt() ),
450 inputStringComponents[5] );
451 colorRampItems.push_back( currentItem );
456 badLines = badLines + QString::number( lineCounter ) +
":\t[" + inputLine +
"]\n";
463 populateColormapTreeWidget( colorRampItems );
467 QMessageBox::warning(
this,
tr(
"Import Error" ),
tr(
"The following lines contained errors\n\n" ) + badLines );
470 else if ( !fileName.isEmpty() )
472 QMessageBox::warning(
this,
tr(
"Read access denied" ),
tr(
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
476 void QgsSingleBandPseudoColorRendererWidget::on_mExportToFileButton_clicked()
479 QString lastDir = settings.value(
"lastRasterFileFilterDir",
"" ).toString();
480 QString fileName = QFileDialog::getSaveFileName(
this,
tr(
"Save file" ), lastDir,
tr(
"Textfile (*.txt)" ) );
481 if ( !fileName.isEmpty() )
483 if ( !fileName.endsWith(
".txt", Qt::CaseInsensitive ) )
485 fileName = fileName +
".txt";
488 QFile outputFile( fileName );
489 if ( outputFile.open( QFile::WriteOnly ) )
491 QTextStream outputStream( &outputFile );
492 outputStream <<
"# " <<
tr(
"QGIS Generated Color Map Export File" ) <<
"\n";
493 outputStream <<
"INTERPOLATION:";
494 if ( mColorInterpolationComboBox->currentText() ==
tr(
"Linear" ) )
496 outputStream <<
"INTERPOLATED\n";
498 else if ( mColorInterpolationComboBox->currentText() ==
tr(
"Discrete" ) )
500 outputStream <<
"DISCRETE\n";
504 outputStream <<
"EXACT\n";
507 int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
508 QTreeWidgetItem* currentItem;
510 for (
int i = 0; i < topLevelItemCount; ++i )
512 currentItem = mColormapTreeWidget->topLevelItem( i );
517 color = currentItem->background( 1 ).color();
518 outputStream << currentItem->text( 0 ).toDouble() <<
",";
519 outputStream << color.red() <<
"," << color.green() <<
"," << color.blue() <<
"," << color.alpha() <<
",";
520 if ( currentItem->text( 2 ) ==
"" )
522 outputStream <<
"Color entry " << i + 1 <<
"\n";
526 outputStream << currentItem->text( 2 ) <<
"\n";
529 outputStream.flush();
534 QMessageBox::warning(
this,
tr(
"Write access denied" ),
tr(
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
539 void QgsSingleBandPseudoColorRendererWidget::on_mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem* item,
int column )
548 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
550 if ( newColor.isValid() )
552 item->setBackground( 1, QBrush( newColor ) );
557 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
566 mBandComboBox->setCurrentIndex( mBandComboBox->findData( pr->
band() ) );
572 if ( colorRampShader )
576 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Linear" ) ) );
580 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Discrete" ) ) );
584 mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findText(
tr(
"Exact" ) ) );
587 const QList<QgsColorRampShader::ColorRampItem> colorRampItemList = colorRampShader->
colorRampItemList();
588 QList<QgsColorRampShader::ColorRampItem>::const_iterator it = colorRampItemList.constBegin();
589 for ( ; it != colorRampItemList.end(); ++it )
591 QTreeWidgetItem* newItem =
new QTreeWidgetItem( mColormapTreeWidget );
592 newItem->setText( 0, QString::number( it->value,
'f' ) );
593 newItem->setBackground( 1, QBrush( it->color ) );
594 newItem->setText( 2, it->label );
596 mClipCheckBox->setChecked( colorRampShader->
clip() );
606 void QgsSingleBandPseudoColorRendererWidget::on_mBandComboBox_currentIndexChanged(
int index )
609 myBands.append( mBandComboBox->itemData( index ).toInt() );
615 Q_UNUSED( theBandNo );
616 QgsDebugMsg( QString(
"theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
618 if ( qIsNaN( theMin ) )
620 mMinLineEdit->clear();
624 mMinLineEdit->setText( QString::number( theMin ) );
627 if ( qIsNaN( theMax ) )
629 mMaxLineEdit->clear();
633 mMaxLineEdit->setText( QString::number( theMax ) );
636 mMinMaxOrigin = theOrigin;
640 void QgsSingleBandPseudoColorRendererWidget::showMinMaxOrigin()
645 void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit * theLineEdit,
double theValue )
648 if ( !qIsNaN( theValue ) )
650 s = QString::number( theValue );
652 theLineEdit->setText( s );
655 double QgsSingleBandPseudoColorRendererWidget::lineEditValue(
const QLineEdit * theLineEdit )
const
657 if ( theLineEdit->text().isEmpty() )
659 return std::numeric_limits<double>::quiet_NaN();
662 return theLineEdit->text().toDouble();
665 void QgsSingleBandPseudoColorRendererWidget::resetClassifyButton()
667 mClassifyButton->setEnabled(
true );
668 double min = lineEditValue( mMinLineEdit );
669 double max = lineEditValue( mMaxLineEdit );
670 if ( qIsNaN( min ) || qIsNaN( max ) || min >= max )
672 mClassifyButton->setEnabled(
false );