2 changes: 1 addition & 1 deletion python/plugins/sextante/gui/AutofillDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ def okPressed(self):
self.close()

def cancelPressed(self):
self.mode == None
self.mode = None
self.param = None
self.close()
17 changes: 15 additions & 2 deletions python/plugins/sextante/modeler/ModelerDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* *
***************************************************************************
"""
import sys

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand Down Expand Up @@ -179,8 +180,20 @@ def saveModel(self, saveAs):
self.alg.descriptionFile = filename
if filename:
text = self.alg.serialize()
fout = codecs.open(filename, "w", encoding='utf-8')
#fout = open(filename, "w")
try:
fout = codecs.open(filename, "w", encoding='utf-8')
except:
if saveAs:
QMessageBox.warning(self,
self.tr("I/O error"),
self.tr("Unable to save edits. Reason:\n %1").arg(unicode(sys.exc_info()[1]))
)
else:
QMessageBox.warning(self,
self.tr("Can't save model"),
self.tr("This model can't be saved in its original location\n(probably you do not have permission to do it).\nPlease, use the 'Save as...' option.")
)
return
fout.write(text)
fout.close()
self.update = True
Expand Down
23 changes: 23 additions & 0 deletions src/app/composer/qgscomposermapwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ void QgsComposerMapWidget::updateGuiElements()
//overview frame
int overviewMapFrameId = mComposerMap->overviewFrameMapId();
mOverviewFrameMapComboBox->setCurrentIndex( mOverviewFrameMapComboBox->findData( overviewMapFrameId ) );
//overview frame blending mode
mOverviewBlendModeComboBox->setBlendMode( mComposerMap->overviewBlendMode() );
//overview inverted
mOverviewInvertCheckbox->setChecked( mComposerMap->overviewInverted() );

//grid
if ( mComposerMap->gridEnabled() )
Expand Down Expand Up @@ -437,6 +441,8 @@ void QgsComposerMapWidget::blockAllSignals( bool b )
mFrameWidthSpinBox->blockSignals( b );
mOverviewFrameMapComboBox->blockSignals( b );
mOverviewFrameStyleButton->blockSignals( b );
mOverviewBlendModeComboBox->blockSignals( b );
mOverviewInvertCheckbox->blockSignals( b );
}

void QgsComposerMapWidget::on_mUpdatePreviewButton_clicked()
Expand Down Expand Up @@ -559,6 +565,23 @@ void QgsComposerMapWidget::on_mOverviewFrameStyleButton_clicked()
}
}

void QgsComposerMapWidget::on_mOverviewBlendModeComboBox_currentIndexChanged( int index )
{
Q_UNUSED( index );
if ( mComposerMap )
{
mComposerMap->setOverviewBlendMode( mOverviewBlendModeComboBox->blendMode() );
}

}
void QgsComposerMapWidget::on_mOverviewInvertCheckbox_toggled( bool state )
{
if ( mComposerMap )
{
mComposerMap->setOverviewInverted( state );
}
}

void QgsComposerMapWidget::on_mGridCheckBox_toggled( bool state )
{
if ( !mComposerMap )
Expand Down
2 changes: 2 additions & 0 deletions src/app/composer/qgscomposermapwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
void on_mDrawCanvasItemsCheckBox_stateChanged( int state );
void on_mOverviewFrameMapComboBox_currentIndexChanged( const QString& text );
void on_mOverviewFrameStyleButton_clicked();
void on_mOverviewBlendModeComboBox_currentIndexChanged( int index );
void on_mOverviewInvertCheckbox_toggled( bool state );

void on_mXMinLineEdit_editingFinished();
void on_mXMaxLineEdit_editingFinished();
Expand Down
8 changes: 4 additions & 4 deletions src/app/legend/qgslegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,7 +2716,7 @@ void QgsLegend::legendLayerZoomNative()
QgsRasterLayer *layer = qobject_cast<QgsRasterLayer *>( currentLayer->layer() );
if ( layer )
{
QgsDebugMsg( "Raster units per pixel : " + QString::number( layer->rasterUnitsPerPixel() ) );
QgsDebugMsg( "Raster units per pixel : " + QString::number( layer->rasterUnitsPerPixelX() ) );
QgsDebugMsg( "MapUnitsPerPixel before : " + QString::number( mMapCanvas->mapUnitsPerPixel() ) );

layer->setCacheImage( NULL );
Expand All @@ -2732,11 +2732,11 @@ void QgsLegend::legendLayerZoomNative()
p2 = ct.transform( p2 );
double width = sqrt( p1.sqrDist( p2 ) ); // width of reprojected pixel
// This is not perfect of course, we use the resolution in just one direction
mMapCanvas->zoomByFactor( qAbs( layer->rasterUnitsPerPixel() / width ) );
mMapCanvas->zoomByFactor( qAbs( layer->rasterUnitsPerPixelX() / width ) );
}
else
{
mMapCanvas->zoomByFactor( qAbs( layer->rasterUnitsPerPixel() / mMapCanvas->mapUnitsPerPixel() ) );
mMapCanvas->zoomByFactor( qAbs( layer->rasterUnitsPerPixelX() / mMapCanvas->mapUnitsPerPixel() ) );
}
mMapCanvas->refresh();
QgsDebugMsg( "MapUnitsPerPixel after : " + QString::number( mMapCanvas->mapUnitsPerPixel() ) );
Expand All @@ -2757,7 +2757,7 @@ void QgsLegend::legendLayerStretchUsingCurrentExtent()

QgsRectangle myRectangle;
myRectangle = mMapCanvas->mapRenderer()->outputExtentToLayerExtent( layer, mMapCanvas->extent() );
layer->setContrastEnhancementAlgorithm( contrastEnhancementAlgorithm, QgsRaster::ContrastEnhancementMinMax, myRectangle );
layer->setContrastEnhancement( contrastEnhancementAlgorithm, QgsRaster::ContrastEnhancementMinMax, myRectangle );

layer->setCacheImage( NULL );
refreshLayerSymbology( layer->id() );
Expand Down
7 changes: 5 additions & 2 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4295,7 +4295,10 @@ void QgisApp::saveAsRasterFile()
}

QgsRasterNuller *nuller = new QgsRasterNuller();
nuller->setNoData( d.noData() );
for ( int band = 1; band <= rasterLayer->dataProvider()->bandCount(); band ++ )
{
nuller->setNoData( band, d.noData() );
}
if ( !pipe->insert( 1, nuller ) )
{
QgsDebugMsg( "Cannot set pipe nuller" );
Expand Down Expand Up @@ -6488,7 +6491,7 @@ void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRaster::ContrastEnhance
QgsRectangle myRectangle;
if ( visibleAreaOnly ) myRectangle = mMapCanvas->mapRenderer()->outputExtentToLayerExtent( myRasterLayer, mMapCanvas->extent() );

myRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );
myRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );

myRasterLayer->setCacheImage( NULL );
mMapCanvas->refresh();
Expand Down
34 changes: 26 additions & 8 deletions src/app/qgsdiagramproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,21 +325,29 @@ void QgsDiagramProperties::on_mDiagramTypeComboBox_currentIndexChanged( int inde
mBarWidthLabel->show();
mBarWidthSpinBox->show();
mOrientationFrame->show();
mFixedSizeCheckBox->setChecked( false );
mFixedSizeCheckBox->setVisible( false );
mDiagramSizeSpinBox->setVisible( false );
mLinearlyScalingLabel->setText( tr( "Bar length: Scale linearly, such as the following value matches the specified size." ) );
}
else
{
mBarWidthLabel->hide();
mBarWidthSpinBox->hide();
mOrientationFrame->hide();
mLinearlyScalingLabel->setText( tr( "Scale linearly between 0 and the following attribute value / diagram size:" ) );
mAttributeBasedScalingOptions->show();
mFixedSizeCheckBox->setVisible( true );
mDiagramSizeSpinBox->setVisible( true );
}

if ( DIAGRAM_NAME_HISTOGRAM == diagramType || DIAGRAM_NAME_TEXT == diagramType )
{
mDiagramPropertiesToolBox->setItemEnabled( 3, true );
mDiagramPropertiesTabWidget->setTabEnabled( 3, true );
}
else
{
mDiagramPropertiesToolBox->setItemEnabled( 3, false );
mDiagramPropertiesTabWidget->setTabEnabled( 3, false );
}

if ( DIAGRAM_NAME_TEXT == diagramType || DIAGRAM_NAME_PIE == diagramType )
Expand Down Expand Up @@ -465,23 +473,33 @@ void QgsDiagramProperties::apply()
}
else
{
QgsDiagram* diagram = 0;
int index = mDiagramTypeComboBox->currentIndex();
QString diagramType = mDiagramTypeComboBox->itemData( index ).toString();

if ( 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
{
QMessageBox::warning( this, tr( "No attributes added." ),
tr( "You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ), QMessageBox::Ok );
}

bool scaleAttributeValueIsNumeric;
mValueLineEdit->text().toDouble( &scaleAttributeValueIsNumeric );
if ( !mFixedSizeCheckBox->isChecked() && !scaleAttributeValueIsNumeric )
bool scaleAttributeValueOk = false;
if ( diagramType == DIAGRAM_NAME_HISTOGRAM )
{
// We don't need a scale attribute, the field is used as a multiplicator
scaleAttributeValueOk = true;
}
else
{
// Check if a (usable) scale attribute value is inserted
mValueLineEdit->text().toDouble( &scaleAttributeValueOk );
}
if ( !mFixedSizeCheckBox->isChecked() && !scaleAttributeValueOk )
{
QMessageBox::warning( this, tr( "No attribute value specified" ),
tr( "You did not specify a maximum value for the diagram size. Please specify the attribute and a reference value as a base for scaling in the Tab Diagram / Size." ), QMessageBox::Ok );
}

QgsDiagram* diagram = 0;
int index = mDiagramTypeComboBox->currentIndex();
QString diagramType = mDiagramTypeComboBox->itemData( index ).toString();
if ( diagramType == DIAGRAM_NAME_TEXT )
{
diagram = new QgsTextDiagram();
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsmaptoolmovefeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
mMovedFeatures.clear();
mMovedFeatures << cf.id(); //todo: take the closest feature, not the first one...

mRubberBand = createRubberBand();
mRubberBand = createRubberBand( vlayer->geometryType() );
mRubberBand->setToGeometry( cf.geometry(), vlayer );
}
else
{
mMovedFeatures = vlayer->selectedFeaturesIds();

mRubberBand = createRubberBand();
mRubberBand = createRubberBand( vlayer->geometryType() );
for ( int i = 0; i < vlayer->selectedFeatureCount(); i++ )
{
mRubberBand->addGeometry( vlayer->selectedFeatures()[i].geometry(), vlayer );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsmaptoolrotatefeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ void QgsMapToolRotateFeature::canvasPressEvent( QMouseEvent * e )
mRotatedFeatures.clear();
mRotatedFeatures << cf.id(); //todo: take the closest feature, not the first one...

mRubberBand = createRubberBand();
mRubberBand = createRubberBand( vlayer->geometryType() );
mRubberBand->setToGeometry( cf.geometry(), vlayer );
}
else
{
mRotatedFeatures = vlayer->selectedFeaturesIds();

mRubberBand = createRubberBand();
mRubberBand = createRubberBand( vlayer->geometryType() );
for ( int i = 0; i < vlayer->selectedFeatureCount(); i++ )
{
mRubberBand->addGeometry( vlayer->selectedFeatures()[i].geometry(), vlayer );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsrasterlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ void QgsRasterLayerProperties::sync()
mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
lblSrcNoDataValue->setEnabled( enableSrcNoData );

QgsRasterRangeList noDataRangeList = mRasterLayer->dataProvider()->userNoDataValue( 1 );
QgsRasterRangeList noDataRangeList = mRasterLayer->dataProvider()->userNoDataValues( 1 );
QgsDebugMsg( QString( "noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
if ( noDataRangeList.size() > 0 )
{
Expand Down
70 changes: 63 additions & 7 deletions src/core/composer/qgscomposermap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height )
: QgsComposerItem( x, y, width, height, composition ), mKeepLayerSet( false ),
mOverviewFrameMapId( -1 ), mGridEnabled( false ), mGridStyle( Solid ),
mOverviewFrameMapId( -1 ), mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mGridEnabled( false ), mGridStyle( Solid ),
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ),
mLeftGridAnnotationPosition( OutsideMapFrame ), mRightGridAnnotationPosition( OutsideMapFrame ), mTopGridAnnotationPosition( OutsideMapFrame ),
mBottomGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ),
Expand Down Expand Up @@ -82,7 +82,8 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
}

QgsComposerMap::QgsComposerMap( QgsComposition *composition )
: QgsComposerItem( 0, 0, 10, 10, composition ), mKeepLayerSet( false ), mOverviewFrameMapId( -1 ), mGridEnabled( false ), mGridStyle( Solid ),
: QgsComposerItem( 0, 0, 10, 10, composition ), mKeepLayerSet( false ), mOverviewFrameMapId( -1 ),
mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mGridEnabled( false ), mGridStyle( Solid ),
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ),
mLeftGridAnnotationPosition( OutsideMapFrame ), mRightGridAnnotationPosition( OutsideMapFrame ), mTopGridAnnotationPosition( OutsideMapFrame ),
mBottomGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ),
Expand Down Expand Up @@ -283,7 +284,7 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
//Qt 4.4.0 and 4.4.1 have problems with recursive paintings
//QgsComposerMap::cache() and QgsComposerMap::update() need to be called by
//client functions

//Background color is already included in cached image, so no need to draw

QgsRectangle requestRectangle;
Expand Down Expand Up @@ -682,10 +683,20 @@ bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
//overview map frame
QDomElement overviewFrameElem = doc.createElement( "overviewFrame" );
overviewFrameElem.setAttribute( "overviewFrameMap", mOverviewFrameMapId );
overviewFrameElem.setAttribute( "overviewBlendMode", QgsMapRenderer::getBlendModeEnum( mOverviewBlendMode ) );
if ( mOverviewInverted )
{
overviewFrameElem.setAttribute( "overviewInverted", "true" );
}
else
{
overviewFrameElem.setAttribute( "overviewInverted", "false" );
}
QDomElement overviewFrameStyleElem = QgsSymbolLayerV2Utils::saveSymbol( QString(), mOverviewFrameMapSymbol, doc );
overviewFrameElem.appendChild( overviewFrameStyleElem );
composerMapElem.appendChild( overviewFrameElem );


//extent
QDomElement extentElem = doc.createElement( "Extent" );
extentElem.setAttribute( "xmin", QString::number( mExtent.xMinimum() ) );
Expand Down Expand Up @@ -779,6 +790,18 @@ bool QgsComposerMap::readXML( const QDomElement& itemElem, const QDomDocument& d
if ( !overviewFrameElem.isNull() )
{
setOverviewFrameMap( overviewFrameElem.attribute( "overviewFrameMap", "-1" ).toInt() );
setOverviewBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) overviewFrameElem.attribute( "overviewBlendMode", "0" ).toUInt() ) );

QString overviewInvertedFlag = overviewFrameElem.attribute( "overviewInverted" );
if ( overviewInvertedFlag.compare( "true", Qt::CaseInsensitive ) == 0 )
{
setOverviewInverted( true );
}
else
{
setOverviewInverted( false );
}

QDomElement overviewFrameSymbolElem = overviewFrameElem.firstChildElement( "symbol" );
if ( !overviewFrameSymbolElem.isNull() )
{
Expand Down Expand Up @@ -1699,6 +1722,18 @@ void QgsComposerMap::setOverviewFrameMapSymbol( QgsFillSymbolV2* symbol )
mOverviewFrameMapSymbol = symbol;
}

void QgsComposerMap::setOverviewBlendMode( QPainter::CompositionMode blendMode )
{
mOverviewBlendMode = blendMode;
update();
}

void QgsComposerMap::setOverviewInverted( bool inverted )
{
mOverviewInverted = inverted;
update();
}

void QgsComposerMap::setGridLineSymbol( QgsLineSymbolV2* symbol )
{
delete mGridLineSymbol;
Expand Down Expand Up @@ -2043,17 +2078,38 @@ void QgsComposerMap::drawOverviewMapExtent( QPainter* p )
context.setRasterScaleFactor( mComposition->printResolution() / 25.4 );
}

QPolygonF polygon;
p->save();
p->setCompositionMode( mOverviewBlendMode );
mOverviewFrameMapSymbol->startRender( context );

//construct a polygon corresponding to the intersecting map extent
QPolygonF intersectPolygon;
double x = ( intersectRect.xMinimum() - thisExtent.xMinimum() ) / thisExtent.width() * rect().width();
double y = ( thisExtent.yMaximum() - intersectRect.yMaximum() ) / thisExtent.height() * rect().height();
double width = intersectRect.width() / thisExtent.width() * rect().width();
double height = intersectRect.height() / thisExtent.height() * rect().height();
polygon << QPointF( x, y ) << QPointF( x + width, y ) << QPointF( x + width, y + height ) << QPointF( x, y + height ) << QPointF( x, y );
intersectPolygon << QPointF( x, y ) << QPointF( x + width, y ) << QPointF( x + width, y + height ) << QPointF( x, y + height ) << QPointF( x, y );

QList<QPolygonF> rings; //empty list
mOverviewFrameMapSymbol->startRender( context );
mOverviewFrameMapSymbol->renderPolygon( polygon, &rings, 0, context );
if ( !mOverviewInverted )
{
//Render the intersecting map extent
mOverviewFrameMapSymbol->renderPolygon( intersectPolygon, &rings, 0, context );;
}
else
{
//We are inverting the overview frame (ie, shading outside the intersecting extent)
//Construct a polygon corresponding to the overview map extent
QPolygonF outerPolygon;
outerPolygon << QPointF( 0, 0 ) << QPointF( rect().width(), 0 ) << QPointF( rect().width(), rect().height() ) << QPointF( 0, rect().height() ) << QPointF( 0, 0 );

//Intersecting extent is an inner ring for the shaded area
rings.append( intersectPolygon );
mOverviewFrameMapSymbol->renderPolygon( outerPolygon, &rings, 0, context );
}

mOverviewFrameMapSymbol->stopRender( context );
p->restore();
}

void QgsComposerMap::createDefaultOverviewFrameSymbol()
Expand Down
13 changes: 13 additions & 0 deletions src/core/composer/qgscomposermap.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,16 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
void setOverviewFrameMapSymbol( QgsFillSymbolV2* symbol );
QgsFillSymbolV2* overviewFrameMapSymbol() { return mOverviewFrameMapSymbol; }

/** Returns the overview's blending mode */
QPainter::CompositionMode overviewBlendMode() const {return mOverviewBlendMode;}
/** Sets the overview's blending mode*/
void setOverviewBlendMode( QPainter::CompositionMode blendMode );

/** Returns true if the overview frame is inverted */
bool overviewInverted() const {return mOverviewInverted;}
/** Sets the overview's inversion mode*/
void setOverviewInverted( bool inverted );

void setGridLineSymbol( QgsLineSymbolV2* symbol );
QgsLineSymbolV2* gridLineSymbol() { return mGridLineSymbol; }

Expand Down Expand Up @@ -380,6 +390,9 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/**Drawing style for overview farme*/
QgsFillSymbolV2* mOverviewFrameMapSymbol;
QgsLineSymbolV2* mGridLineSymbol;
/**Blend mode for overview*/
QPainter::CompositionMode mOverviewBlendMode;
bool mOverviewInverted;

/**Establishes signal/slot connection for update in case of layer change*/
void connectUpdateSlot();
Expand Down
2 changes: 1 addition & 1 deletion src/core/diagram/qgshistogramdiagram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ QSizeF QgsHistogramDiagram::diagramSize( const QgsAttributes& attributes, const
{
case QgsDiagramSettings::Up:
case QgsDiagramSettings::Down:
mScaleFactor = (( is.upperSize.width() - is.lowerSize.height() ) / ( is.upperValue - is.lowerValue ) );
mScaleFactor = ( ( is.upperSize.width() - is.lowerSize.height() ) / ( is.upperValue - is.lowerValue ) );
size.scale( s.barWidth * attributes.size(), maxValue * mScaleFactor, Qt::IgnoreAspectRatio );
break;

Expand Down
5 changes: 4 additions & 1 deletion src/core/qgsfeaturestore.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ class CORE_EXPORT QgsFeatureStore
/** Get features list reference */
QgsFeatureList& features() { return mFeatures; }

/** Set map of optional parameters */
void setParams( const QMap<QString, QVariant> &theParams ) { mParams = theParams; }

/** Get map of optional parameters */
QMap<QString, QVariant>& params() { return mParams; }
QMap<QString, QVariant> params() const { return mParams; }

private:
QgsFields mFields;
Expand Down
29 changes: 23 additions & 6 deletions src/core/qgsmaprenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -877,8 +877,7 @@ QgsPoint QgsMapRenderer::layerToMapCoordinates( QgsMapLayer* theLayer, QgsPoint
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse );
QgsDebugMsg( QString( "Transform error caught: %1" ).arg( cse.what() ) );
QgsMessageLog::logMessage( QString( "Transform error caught: %1" ).arg( cse.what() ) );
}
}
else
Expand All @@ -888,6 +887,26 @@ QgsPoint QgsMapRenderer::layerToMapCoordinates( QgsMapLayer* theLayer, QgsPoint
return point;
}

QgsRectangle QgsMapRenderer::layerToMapCoordinates( QgsMapLayer* theLayer, QgsRectangle rect )
{
if ( hasCrsTransformEnabled() )
{
try
{
rect = tr( theLayer )->transform( rect, QgsCoordinateTransform::ForwardTransform );
}
catch ( QgsCsException &cse )
{
QgsMessageLog::logMessage( QString( "Transform error caught: %1" ).arg( cse.what() ) );
}
}
else
{
// leave point without transformation
}
return rect;
}

QgsPoint QgsMapRenderer::mapToLayerCoordinates( QgsMapLayer* theLayer, QgsPoint point )
{
if ( hasCrsTransformEnabled() )
Expand All @@ -898,8 +917,7 @@ QgsPoint QgsMapRenderer::mapToLayerCoordinates( QgsMapLayer* theLayer, QgsPoint
}
catch ( QgsCsException &cse )
{
QgsDebugMsg( QString( "Transform error caught: %1" ).arg( cse.what() ) );
throw cse; //let client classes know there was a transformation error
QgsMessageLog::logMessage( QString( "Transform error caught: %1" ).arg( cse.what() ) );
}
}
else
Expand All @@ -919,8 +937,7 @@ QgsRectangle QgsMapRenderer::mapToLayerCoordinates( QgsMapLayer* theLayer, QgsRe
}
catch ( QgsCsException &cse )
{
QgsDebugMsg( QString( "Transform error caught: %1" ).arg( cse.what() ) );
throw cse; //let client classes know there was a transformation error
QgsMessageLog::logMessage( QString( "Transform error caught: %1" ).arg( cse.what() ) );
}
}
return rect;
Expand Down
35 changes: 30 additions & 5 deletions src/core/qgsmaprenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,19 +190,44 @@ class CORE_EXPORT QgsMapRenderer : public QObject
QSize outputSize();
QSizeF outputSizeF();

//! transform extent in layer's CRS to extent in output CRS
/**
* @brief transform bounding box from layer's CRS to output CRS
* @see layerToMapCoordinates( QgsMapLayer* theLayer, QgsRectangle rect ) if you want to transform a rectangle
* @return a bounding box (aligned rectangle) containing the transformed extent
*/
QgsRectangle layerExtentToOutputExtent( QgsMapLayer* theLayer, QgsRectangle extent );

//! transform extent in output CRS to extent in layer's CRS
/**
* @brief transform bounding box from output CRS to layer's CRS
* @see mapToLayerCoordinates( QgsMapLayer* theLayer,QgsRectangle rect ) if you want to transform a rectangle
* @return a bounding box (aligned rectangle) containing the transformed extent
*/
QgsRectangle outputExtentToLayerExtent( QgsMapLayer* theLayer, QgsRectangle extent );

//! transform coordinates from layer's CRS to output CRS
/**
* @brief transform point coordinates from layer's CRS to output CRS
* @return the transformed point
*/
QgsPoint layerToMapCoordinates( QgsMapLayer* theLayer, QgsPoint point );

//! transform coordinates from output CRS to layer's CRS
/**
* @brief transform rectangle from layer's CRS to output CRS
* @see layerExtentToOutputExtent() if you want to transform a bounding box
* @return the transformed rectangle
*/
QgsRectangle layerToMapCoordinates( QgsMapLayer* theLayer, QgsRectangle rect );

/**
* @brief transform point coordinates from output CRS to layer's CRS
* @return the transformed point
*/
QgsPoint mapToLayerCoordinates( QgsMapLayer* theLayer, QgsPoint point );

//! transform rect's coordinates from output CRS to layer's CRS
/**
* @brief transform rectangle from output CRS to layer's CRS
* @see outputExtentToLayerExtent() if you want to transform a bounding box
* @return the transformed rectangle
*/
QgsRectangle mapToLayerCoordinates( QgsMapLayer* theLayer, QgsRectangle rect );

//! sets whether to use projections for this layer set
Expand Down
43 changes: 0 additions & 43 deletions src/core/qgsvectordataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,43 +175,6 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
@note: added in version 1.2*/
virtual void enumValues( int index, QStringList& enumList ) { Q_UNUSED( index ); enumList.clear(); }

/**
* Start editing transaction. This method must be called before edit methods.
* File based providers usually reopen files in update mode.
* Database based providers usually start new transaction.
* It is not possible to start more editing transactions, if a transaction
* was already started, this method fails and returns false.
* @return true in case of success and false in case of failure
*/
virtual bool startEditing() { return false; }

/**
* Stop editing transaction and discard the edits.
* Roll back is not supported by all providers. For example file based
* providers are usually writing changes immediately to files and in that case
* there is no way to do roll back on provider level. If roll back is required,
* QgsVectorLayer may be used, which keeps all changes in buffer until commitChanges()
* and fully supports rool back. If a provider does not support roll back,
* editing is canceled but false is returned.
* @return true in case of success and false in case of failure
*/
virtual bool rollBack() { return false; }

/**
* Commit changes and stop editing transaction.
* File based providers usually reopen files in read only mode.
* Database based providers usually commit transaction.
* @return true in case of success and false in case of failure
*/
virtual bool commitChanges() { return false; }

/**
* Returns editing status. True after successfull startEditing()
* before rollBack() or commitChanges().
* @return true if editing transaction is opened
*/
virtual bool isEdited() { return false; }

/**
* Adds a list of features
* @return true in case of success and false in case of failure
Expand Down Expand Up @@ -365,12 +328,6 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
*/
QStringList errors();

signals:
/** Is emitted, when editing has started */
void editingStarted();

/** Is emitted, when editing stopped */
void editingStopped();

protected:
QVariant convertValue( QVariant::Type type, QString value );
Expand Down
19 changes: 18 additions & 1 deletion src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
{
if ( layOptions.join( "" ).toUpper().indexOf( "ENCODING=" ) == -1 )
{
layOptions.append( "ENCODING=" + fileEncoding );
layOptions.append( "ENCODING=" + convertCodecNameForEncodingOption( fileEncoding ) );
}

CPLSetConfigOption( "SHAPE_ENCODING", "" );
Expand Down Expand Up @@ -1023,6 +1023,23 @@ QString QgsVectorFileWriter::filterForDriver( const QString& driverName )
return trLongName + " [OGR] (" + glob.toLower() + " " + glob.toUpper() + ")";
}

QString QgsVectorFileWriter::convertCodecNameForEncodingOption( const QString &codecName )
{
if ( codecName == "System" )
return QString( "LDID/0" );

QRegExp re = QRegExp( QString( "(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
if ( re.exactMatch( codecName ) )
{
QString c = re.cap( 2 ).replace( "-" , "" );
bool isNumber;
c.toInt( &isNumber );
if ( isNumber )
return c;
}
return codecName;
}

bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName, QString &trLongName, QString &glob, QString &ext )
{
if ( driverName.startsWith( "AVCE00" ) )
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorfilewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class CORE_EXPORT QgsVectorFileWriter
/**Creates a filter for an OGR driver key*/
static QString filterForDriver( const QString& driverName );

/**Converts codec name to string passed to ENCODING layer creation option of OGR Shapefile*/
static QString convertCodecNameForEncodingOption( const QString &codecName );

/** checks whether there were any errors in constructor */
WriterError hasError();

Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgshuesaturationfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void QgsHueSaturationFilter::processSaturation( int &r, int &g, int &b, int &h,
{
// Raising the saturation. Use a saturation curve to prevent
// clipping at maximum saturation with ugly results.
s = qMin(( int )( 255. * ( 1 - pow( 1 - ( s / 255. ) , mSaturationScale * 2 ) ) ), 255 );
s = qMin(( int )( 255. * ( 1 - pow( 1 - ( s / 255. ) , pow( mSaturationScale, 2 ) ) ) ), 255 );
}

// Saturation changed, so update rgb values
Expand Down
14 changes: 4 additions & 10 deletions src/core/raster/qgsrasterbandstats.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class CORE_EXPORT QgsRasterBandStats

QgsRasterBandStats()
{
bandName = "";
statsGathered = None;
minimumValue = std::numeric_limits<double>::max();
maximumValue = std::numeric_limits<double>::min();
Expand All @@ -73,19 +72,14 @@ class CORE_EXPORT QgsRasterBandStats
}

/** \brief The name of the band that these stats belong to. */
QString bandName;
//QString bandName;

/** \brief The gdal band number (starts at 1)*/
int bandNumber;

/** Color table
* @note not available in python bindings
*/
QList<QgsColorRampShader::ColorRampItem> colorTable;

/** \brief The number of cells in the band. Equivalent to height x width.
* TODO: check if NO_DATA are excluded!*/
int elementCount;
/** \brief The number of not no data cells in the band. */
// TODO: check if no data are excluded in stats calculation
size_t elementCount;

/** \brief The maximum cell value in the raster band. NO_DATA values
* are ignored. This does not use the gdal GetMaximmum function. */
Expand Down
5 changes: 3 additions & 2 deletions src/core/raster/qgsrasterblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ bool QgsRasterBlock::hasNoData() const

bool QgsRasterBlock::isNoDataValue( double value, double noDataValue )
{
// TODO: optimize no data value test by memcmp()
// More precise would be qIsNaN(value) && qIsNaN(noDataValue(bandNo)), but probably
// not important and slower
if ( qIsNaN( value ) ||
Expand Down Expand Up @@ -360,7 +361,7 @@ bool QgsRasterBlock::setValue( int row, int column, double value )

bool QgsRasterBlock::setColor( int row, int column, QRgb color )
{
return setColor(( size_t )row*column, color );
return setColor(( size_t )row*mWidth + column, color );
}

bool QgsRasterBlock::setColor( size_t index, QRgb color )
Expand All @@ -385,7 +386,7 @@ bool QgsRasterBlock::setColor( size_t index, QRgb color )

bool QgsRasterBlock::setIsNoData( int row, int column )
{
return setIsNoData(( size_t )row*column );
return setIsNoData(( size_t )row*mWidth + column );
}

bool QgsRasterBlock::setIsNoData( size_t index )
Expand Down
4 changes: 2 additions & 2 deletions src/core/raster/qgsrasterdataprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons
}

// apply user no data values
block->applyNoDataValues( userNoDataValue( theBandNo ) );
block->applyNoDataValues( userNoDataValues( theBandNo ) );
return block;
}

Expand Down Expand Up @@ -501,7 +501,7 @@ QgsRasterInterface::Capability QgsRasterDataProvider::identifyFormatToCapability
}
}

bool QgsRasterDataProvider::userNoDataValueContains( int bandNo, double value ) const
bool QgsRasterDataProvider::userNoDataValuesContains( int bandNo, double value ) const
{
QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
return QgsRasterRange::contains( value, rangeList );
Expand Down
7 changes: 4 additions & 3 deletions src/core/raster/qgsrasterdataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
virtual void setUserNoDataValue( int bandNo, QgsRasterRangeList noData );

/** Get list of user no data value ranges */
virtual QgsRasterRangeList userNoDataValue( int bandNo ) const { return mUserNoDataValue.value( bandNo -1 ); }
virtual QgsRasterRangeList userNoDataValues( int bandNo ) const { return mUserNoDataValue.value( bandNo -1 ); }

virtual QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo ) const
{ Q_UNUSED( bandNo ); return QList<QgsColorRampShader::ColorRampItem>(); }
Expand Down Expand Up @@ -313,7 +313,8 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
virtual bool setNoDataValue( int bandNo, double noDataValue ) { Q_UNUSED( bandNo ); Q_UNUSED( noDataValue ); return false; }

/** Returns the formats supported by create() */
virtual QStringList createFormats() const { return QStringList(); }
// TODO: this should be static and call C functions in provider library
//static QStringList createFormats();

/** Remove dataset*/
virtual bool remove() { return false; }
Expand Down Expand Up @@ -357,7 +358,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
{ Q_UNUSED( bandNo ); Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); }

/** Returns true if user no data contains value */
bool userNoDataValueContains( int bandNo, double value ) const;
bool userNoDataValuesContains( int bandNo, double value ) const;

static QStringList cStringList2Q_( char ** stringList );

Expand Down
13 changes: 2 additions & 11 deletions src/core/raster/qgsrasterdrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,17 @@ void QgsRasterDrawer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsM

// last pipe filter has only 1 band
int bandNumber = 1;
mIterator->startRasterRead( bandNumber, viewPort->drawableAreaXDim, viewPort->drawableAreaYDim, viewPort->mDrawnExtent );
mIterator->startRasterRead( bandNumber, viewPort->mWidth, viewPort->mHeight, viewPort->mDrawnExtent );

//number of cols/rows in output pixels
int nCols = 0;
int nRows = 0;
//number of raster cols/rows with oversampling
//int nRasterCols = 0;
//int nRasterRows = 0;
//shift to top left point for the raster part
int topLeftCol = 0;
int topLeftRow = 0;

// We know that the output data type of last pipe filter is QImage data
//QgsRasterDataProvider::DataType rasterType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mGrayBand );

//void* rasterData;
QgsRasterBlock *block;

// readNextRasterPart calcs and resets nCols, nRows, topLeftCol, topLeftRow
Expand All @@ -68,11 +63,7 @@ void QgsRasterDrawer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsM
QgsDebugMsg( "Cannot get block" );
continue;
}
//create image
//QImage img( nRasterCols, nRasterRows, QImage::Format_ARGB32_Premultiplied );

// TODO: the exact format should be read from input
//QImage img(( uchar * ) rasterData, nCols, nRows, QImage::Format_ARGB32_Premultiplied );
QImage img = block->image();

drawImage( p, viewPort, img, topLeftCol, topLeftRow );
Expand All @@ -89,7 +80,7 @@ void QgsRasterDrawer::drawImage( QPainter* p, QgsRasterViewPort* viewPort, const
}

//top left position in device coords
QPoint tlPoint = QPoint( viewPort->topLeftPoint.x() + topLeftCol, viewPort->topLeftPoint.y() + topLeftRow );
QPoint tlPoint = QPoint( viewPort->mTopLeftPoint.x() + topLeftCol, viewPort->mTopLeftPoint.y() + topLeftRow );
p->save();
p->setRenderHint( QPainter::Antialiasing, false );
p->drawImage( tlPoint, img );
Expand Down
48 changes: 5 additions & 43 deletions src/core/raster/qgsrasterfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ QgsRasterFileWriter::~QgsRasterFileWriter()

}

//QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeRaster( QgsRasterIterator* iter, int nCols, int nRows, QgsRectangle outputExtent,
QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeRaster( const QgsRasterPipe* pipe, int nCols, int nRows, QgsRectangle outputExtent,
const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog )
{
QgsDebugMsg( "Entered" );

//if ( !iter )
if ( !pipe )
{
return SourceProviderError;
Expand Down Expand Up @@ -127,15 +125,12 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster( const Qgs
return SourceProviderError;
}

//const QgsRasterInterface* iface = iter->input();
const QgsRasterInterface* iface = pipe->last();
if ( !iface )
{
return SourceProviderError;
}

//const QgsRasterDataProvider* srcProvider = dynamic_cast<const QgsRasterDataProvider*>( iface->srcInput() );
//QgsRasterDataProvider* srcProvider = dynamic_cast<QgsRasterDataProvider*>( iface->srcInput() );
QgsRasterDataProvider* srcProvider = const_cast<QgsRasterDataProvider*>( dynamic_cast<const QgsRasterDataProvider*>( iface->srcInput() ) );
if ( !srcProvider )
{
Expand Down Expand Up @@ -179,7 +174,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster( const Qgs
bool destHasNoDataValue = false;
double destNoDataValue = std::numeric_limits<double>::quiet_NaN();
QGis::DataType destDataType = srcProvider->srcDataType( bandNo );
//QGis::DataType destDataType = srcProvider->dataType( bandNo );
// TODO: verify what happens/should happen if srcNoDataValue is disabled by setUseSrcNoDataValue
QgsDebugMsg( QString( "srcHasNoDataValue = %1 srcNoDataValue = %2" ).arg( srcHasNoDataValue ).arg( srcProvider->srcNoDataValue( bandNo ) ) );
if ( srcHasNoDataValue )
Expand All @@ -189,10 +183,10 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster( const Qgs
destNoDataValue = srcProvider->srcNoDataValue( bandNo );
destHasNoDataValue = true;
}
else if ( nuller && nuller->noData().size() > 0 )
else if ( nuller && nuller->noData( bandNo ).size() > 0 )
{
// Use one user defined no data value
destNoDataValue = nuller->noData().value( 0 ).min;
destNoDataValue = nuller->noData( bandNo ).value( 0 ).min();
destHasNoDataValue = true;
}
else
Expand Down Expand Up @@ -232,7 +226,9 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster( const Qgs
}

if ( nuller && destHasNoDataValue )
nuller->setOutputNoData( destNoDataValue );
{
nuller->setOutputNoDataValue( bandNo, destNoDataValue );
}

QgsDebugMsg( QString( "bandNo = %1 destDataType = %2 destHasNoDataValue = %3 destNoDataValue = %4" ).arg( bandNo ).arg( destDataType ).arg( destHasNoDataValue ).arg( destNoDataValue ) );
destDataTypeList.append( destDataType );
Expand Down Expand Up @@ -328,8 +324,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster(
for ( int i = 1; i <= nBands; ++i )
{
iter->startRasterRead( i, nCols, nRows, outputExtent );
// TODO: no need to alloc memory, change to readBlock() returning the allocated block
//blockList.push_back( qgsMalloc( dataTypeSize * mMaxTileWidth * mMaxTileHeight ) );
blockList.push_back( 0 );
if ( destProvider ) // no tiles
{
Expand Down Expand Up @@ -358,7 +352,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster(
if ( !iter->readNextRasterPart( i, iterCols, iterRows, &( blockList[i - 1] ), iterLeft, iterTop ) )
{
// No more parts, create VRT and return
//delete destProvider;
if ( mTiledMode )
{
QString vrtFilePath( mOutputUrl + "/" + vrtFileName() );
Expand Down Expand Up @@ -416,7 +409,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster(

if ( mTiledMode ) //write to file
{
//delete destProvider;
QgsRasterDataProvider* partDestProvider = createPartProvider( outputExtent,
nCols, iterCols, iterRows,
iterLeft, iterTop, mOutputUrl,
Expand Down Expand Up @@ -471,7 +463,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste
iter->setMaximumTileWidth( mMaxTileWidth );
iter->setMaximumTileHeight( mMaxTileHeight );

//void* data = qgsMalloc( QgsRasterBlock::typeSize( inputDataType ) * mMaxTileWidth * mMaxTileHeight );
void* redData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
void* greenData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
void* blueData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
Expand All @@ -488,7 +479,6 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste

destProvider = initOutput( nCols, nRows, crs, geoTransform, 4, QGis::Byte );

//iter->select( outputExtent, outputMapUnitsPerPixel );
iter->startRasterRead( 1, nCols, nRows, outputExtent );

int nParts = 0;
Expand Down Expand Up @@ -699,7 +689,6 @@ void QgsRasterFileWriter::buildPyramids( const QString& filename )
{
QgsDebugMsg( "filename = " + filename );
// open new dataProvider so we can build pyramids with it
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, filename );
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, filename );
if ( !destProvider )
{
Expand Down Expand Up @@ -883,14 +872,6 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );

QString outputFile = outputUrl + "/" + partFileName( fileIndex );
#if 0
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, outputFile );
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, outputFile );
if ( !destProvider )
{
return 0;
}
#endif

//geotransform
double geoTransform[6];
Expand All @@ -902,14 +883,6 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
geoTransform[5] = -mup;

// perhaps we need a separate createOptions for tiles ?
#if 0
if ( !destProvider->create( mOutputFormat, nBands, type, iterCols, iterRows, geoTransform,
crs ) )
{
delete destProvider;
return 0;
}
#endif

QgsRasterDataProvider* destProvider = QgsRasterDataProvider::create( mOutputProviderKey, outputFile, mOutputFormat, nBands, type, iterCols, iterRows, geoTransform, crs, mCreateOptions ) ;

Expand All @@ -935,24 +908,13 @@ QgsRasterDataProvider* QgsRasterFileWriter::initOutput( int nCols, int nRows, co
mCreateOptions << "COPY_SRC_OVERVIEWS=YES";
#endif

//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, mOutputUrl );
//QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, mOutputUrl );
QgsRasterDataProvider* destProvider = QgsRasterDataProvider::create( mOutputProviderKey, mOutputUrl, mOutputFormat, nBands, type, nCols, nRows, geoTransform, crs, mCreateOptions ) ;

if ( !destProvider )
{
QgsDebugMsg( "No provider created" );
}

#if 0
if ( !destProvider->create( mOutputFormat, nBands, type, nCols, nRows, geoTransform,
crs, mCreateOptions ) )
{
delete destProvider;
return 0;
}
#endif

return destProvider;
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/core/raster/qgsrasterfilewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ class CORE_EXPORT QgsRasterFileWriter

private:
QgsRasterFileWriter(); //forbidden
//WriterError writeDataRaster( QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent,
WriterError writeDataRaster( const QgsRasterPipe* pipe, QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent,
const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog = 0 );

Expand All @@ -115,23 +114,27 @@ class CORE_EXPORT QgsRasterFileWriter
WriterError writeImageRaster( QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent,
const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog = 0 );

//initialize vrt member variables
/** \brief Initialize vrt member variables
* @param destHasNoDataValueList true if destination has no data value, indexed from 0
* @param destNoDataValueList no data value, indexed from 0
*/
void createVRT( int xSize, int ySize, const QgsCoordinateReferenceSystem& crs, double* geoTransform, QGis::DataType type, QList<bool> destHasNoDataValueList, QList<double> destNoDataValueList );
//write vrt document to disk
bool writeVRT( const QString& file );
//add file entry to vrt
void addToVRT( const QString& filename, int band, int xSize, int ySize, int xOffset, int yOffset );
void buildPyramids( const QString& filename );

//static int pyramidsProgress( double dfComplete, const char *pszMessage, void* pData );

/**Create provider and datasource for a part image (vrt mode)*/
QgsRasterDataProvider* createPartProvider( const QgsRectangle& extent, int nCols, int iterCols, int iterRows,
int iterLeft, int iterTop,
const QString& outputUrl, int fileIndex, int nBands, QGis::DataType type,
const QgsCoordinateReferenceSystem& crs );

/**Init VRT (for tiled mode) or create global output provider (single-file mode)*/
/** \brie Init VRT (for tiled mode) or create global output provider (single-file mode)
* @param destHasNoDataValueList true if destination has no data value, indexed from 0
* @param destNoDataValueList no data value, indexed from 0
*/
QgsRasterDataProvider* initOutput( int nCols, int nRows,
const QgsCoordinateReferenceSystem& crs, double* geoTransform, int nBands,
QGis::DataType type,
Expand Down
1 change: 0 additions & 1 deletion src/core/raster/qgsrasterinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ void QgsRasterInterface::initStatistics( QgsRasterBandStats &theStatistics,
{
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );

theStatistics.bandName = generateBandName( theBandNo );
theStatistics.bandNumber = theBandNo;
theStatistics.statsGathered = theStats;

Expand Down
10 changes: 1 addition & 9 deletions src/core/raster/qgsrasteriterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,12 @@ void QgsRasterIterator::startRasterRead( int bandNumber, int nCols, int nRows, c
pInfo.nRows = nRows;
pInfo.currentCol = 0;
pInfo.currentRow = 0;
pInfo.block = 0;
pInfo.prj = 0;
mRasterPartInfos.insert( bandNumber, pInfo );
}

bool QgsRasterIterator::readNextRasterPart( int bandNumber,
int& nCols, int& nRows,
//void** rasterData,
QgsRasterBlock **block,
int& topLeftCol, int& topLeftRow )
{
Expand All @@ -73,9 +71,6 @@ bool QgsRasterIterator::readNextRasterPart( int bandNumber,
}

//remove last data block
// TODO: block is released somewhere else (check)
//delete pInfo.block;
pInfo.block = 0;
delete pInfo.prj;
pInfo.prj = 0;

Expand All @@ -98,9 +93,7 @@ bool QgsRasterIterator::readNextRasterPart( int bandNumber,
double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / ( double )pInfo.nRows * viewPortExtent.height();
QgsRectangle blockRect( xmin, ymin, xmax, ymax );

pInfo.block = mInput->block( bandNumber, blockRect, nCols, nRows );

*block = pInfo.block;
*block = mInput->block( bandNumber, blockRect, nCols, nRows );
topLeftCol = pInfo.currentCol;
topLeftRow = pInfo.currentRow;

Expand Down Expand Up @@ -129,7 +122,6 @@ void QgsRasterIterator::removePartInfo( int bandNumber )
if ( partIt != mRasterPartInfos.end() )
{
RasterPartInfo& pInfo = partIt.value();
delete pInfo.block;
delete pInfo.prj;
mRasterPartInfos.remove( bandNumber );
}
Expand Down
23 changes: 12 additions & 11 deletions src/core/raster/qgsrasteriterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ struct QgsRasterViewPort;
class CORE_EXPORT QgsRasterIterator
{
public:
//Stores information about reading of a raster band. Columns and rows are in unsampled coordinates
struct RasterPartInfo
{
int currentCol;
int currentRow;
int nCols;
int nRows;
QgsRasterBlock *block;
QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done)
};

QgsRasterIterator( QgsRasterInterface* input );
~QgsRasterIterator();
Expand All @@ -52,7 +42,8 @@ class CORE_EXPORT QgsRasterIterator
*/
void startRasterRead( int bandNumber, int nCols, int nRows, const QgsRectangle& extent );

/**Fetches next part of raster data
/**Fetches next part of raster data, caller takes ownership of the block and
caller should delete the block.
@param bandNumber band to read
@param nCols number of columns on output device
@param nRows number of rows on output device
Expand All @@ -76,6 +67,16 @@ class CORE_EXPORT QgsRasterIterator
int maximumTileHeight() const { return mMaximumTileHeight; }

private:
//Stores information about reading of a raster band. Columns and rows are in unsampled coordinates
struct RasterPartInfo
{
int currentCol;
int currentRow;
int nCols;
int nRows;
QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done)
};

QgsRasterInterface* mInput;
QMap<int, RasterPartInfo> mRasterPartInfos;
QgsRectangle mExtent;
Expand Down
72 changes: 39 additions & 33 deletions src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
}

// clip raster extent to view extent
//QgsRectangle myRasterExtent = theViewExtent.intersect( &mLayerExtent );
QgsRectangle myRasterExtent = myProjectedViewExtent.intersect( &myProjectedLayerExtent );
if ( myRasterExtent.isEmpty() )
{
Expand Down Expand Up @@ -367,8 +366,8 @@ bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
}

// get dimensions of clipped raster image in device coordinate space (this is the size of the viewport)
myRasterViewPort->topLeftPoint = theQgsMapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() );
myRasterViewPort->bottomRightPoint = theQgsMapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() );
myRasterViewPort->mTopLeftPoint = theQgsMapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() );
myRasterViewPort->mBottomRightPoint = theQgsMapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() );

// align to output device grid, i.e. floor/ceil to integers
// TODO: this should only be done if paint device is raster - screen, image
Expand All @@ -378,22 +377,22 @@ bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
// the provider anyway
if ( true )
{
myRasterViewPort->topLeftPoint.setX( floor( myRasterViewPort->topLeftPoint.x() ) );
myRasterViewPort->topLeftPoint.setY( floor( myRasterViewPort->topLeftPoint.y() ) );
myRasterViewPort->bottomRightPoint.setX( ceil( myRasterViewPort->bottomRightPoint.x() ) );
myRasterViewPort->bottomRightPoint.setY( ceil( myRasterViewPort->bottomRightPoint.y() ) );
myRasterViewPort->mTopLeftPoint.setX( floor( myRasterViewPort->mTopLeftPoint.x() ) );
myRasterViewPort->mTopLeftPoint.setY( floor( myRasterViewPort->mTopLeftPoint.y() ) );
myRasterViewPort->mBottomRightPoint.setX( ceil( myRasterViewPort->mBottomRightPoint.x() ) );
myRasterViewPort->mBottomRightPoint.setY( ceil( myRasterViewPort->mBottomRightPoint.y() ) );
// recalc myRasterExtent to aligned values
myRasterExtent.set(
theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->topLeftPoint.x(),
myRasterViewPort->bottomRightPoint.y() ),
theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->bottomRightPoint.x(),
myRasterViewPort->topLeftPoint.y() )
theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->mTopLeftPoint.x(),
myRasterViewPort->mBottomRightPoint.y() ),
theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->mBottomRightPoint.x(),
myRasterViewPort->mTopLeftPoint.y() )
);

}

myRasterViewPort->drawableAreaXDim = static_cast<int>( qAbs(( myRasterExtent.width() / theQgsMapToPixel.mapUnitsPerPixel() ) ) );
myRasterViewPort->drawableAreaYDim = static_cast<int>( qAbs(( myRasterExtent.height() / theQgsMapToPixel.mapUnitsPerPixel() ) ) );
myRasterViewPort->mWidth = static_cast<int>( qAbs(( myRasterExtent.width() / theQgsMapToPixel.mapUnitsPerPixel() ) ) );
myRasterViewPort->mHeight = static_cast<int>( qAbs(( myRasterExtent.height() / theQgsMapToPixel.mapUnitsPerPixel() ) ) );

//the drawable area can start to get very very large when you get down displaying 2x2 or smaller, this is becasue
//theQgsMapToPixel.mapUnitsPerPixel() is less then 1,
Expand All @@ -407,20 +406,19 @@ bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
QgsDebugMsgLevel( QString( "myRasterExtent.yMinimum() = %1" ).arg( myRasterExtent.yMinimum() ), 3 );
QgsDebugMsgLevel( QString( "myRasterExtent.yMaximum() = %1" ).arg( myRasterExtent.yMaximum() ), 3 );

QgsDebugMsgLevel( QString( "topLeftPoint.x() = %1" ).arg( myRasterViewPort->topLeftPoint.x() ), 3 );
QgsDebugMsgLevel( QString( "bottomRightPoint.x() = %1" ).arg( myRasterViewPort->bottomRightPoint.x() ), 3 );
QgsDebugMsgLevel( QString( "topLeftPoint.y() = %1" ).arg( myRasterViewPort->topLeftPoint.y() ), 3 );
QgsDebugMsgLevel( QString( "bottomRightPoint.y() = %1" ).arg( myRasterViewPort->bottomRightPoint.y() ), 3 );
QgsDebugMsgLevel( QString( "mTopLeftPoint.x() = %1" ).arg( myRasterViewPort->mTopLeftPoint.x() ), 3 );
QgsDebugMsgLevel( QString( "mBottomRightPoint.x() = %1" ).arg( myRasterViewPort->mBottomRightPoint.x() ), 3 );
QgsDebugMsgLevel( QString( "mTopLeftPoint.y() = %1" ).arg( myRasterViewPort->mTopLeftPoint.y() ), 3 );
QgsDebugMsgLevel( QString( "mBottomRightPoint.y() = %1" ).arg( myRasterViewPort->mBottomRightPoint.y() ), 3 );

QgsDebugMsgLevel( QString( "drawableAreaXDim = %1" ).arg( myRasterViewPort->drawableAreaXDim ), 3 );
QgsDebugMsgLevel( QString( "drawableAreaYDim = %1" ).arg( myRasterViewPort->drawableAreaYDim ), 3 );
QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( myRasterViewPort->mWidth ), 3 );
QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( myRasterViewPort->mHeight ), 3 );

// /\/\/\ - added to handle zoomed-in rasters

mLastViewPort = *myRasterViewPort;

// Provider mode: See if a provider key is specified, and if so use the provider instead

// TODO: is it necessary? Probably WMS only?
mDataProvider->setDpi( rendererContext.rasterScaleFactor() * 25.4 * rendererContext.scaleFactor() );

draw( theQPainter, myRasterViewPort, &theQgsMapToPixel );
Expand Down Expand Up @@ -762,31 +760,39 @@ QString QgsRasterLayer::providerType() const
/**
* @return the horizontal units per pixel as reported in the GDAL geotramsform[1]
*/
double QgsRasterLayer::rasterUnitsPerPixel()
double QgsRasterLayer::rasterUnitsPerPixelX()
{
// We return one raster pixel per map unit pixel
// One raster pixel can have several raster units...

// We can only use one of the mGeoTransform[], so go with the
// horisontal one.

//return qAbs( mGeoTransform[1] );
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size && mDataProvider->xSize() > 0 )
{
return mDataProvider->extent().width() / mDataProvider->xSize();
}
return 1;
}

double QgsRasterLayer::rasterUnitsPerPixelY()
{
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size && mDataProvider->xSize() > 0 )
{
return mDataProvider->extent().height() / mDataProvider->ySize();
}
return 1;
}

void QgsRasterLayer::init()
{
mRasterType = QgsRasterLayer::GrayOrUndefined;

setDrawingStyle( QgsRasterLayer::UndefinedDrawingStyle );

//Initialize the last view port structure, should really be a class
mLastViewPort.drawableAreaXDim = 0;
mLastViewPort.drawableAreaYDim = 0;
mLastViewPort.mWidth = 0;
mLastViewPort.mHeight = 0;
}

void QgsRasterLayer::setDataProvider( QString const & provider )
Expand Down Expand Up @@ -1002,7 +1008,7 @@ void QgsRasterLayer::closeDataProvider()
mDataProvider = 0;
}

void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRaster::ContrastEnhancementLimits theLimits, QgsRectangle theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRaster::ContrastEnhancementLimits theLimits, QgsRectangle theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
{
QgsDebugMsg( QString( "theAlgorithm = %1 theLimits = %2 theExtent.isEmpty() = %3" ).arg( theAlgorithm ).arg( theLimits ).arg( theExtent.isEmpty() ) );
if ( !mPipe.renderer() || !mDataProvider )
Expand Down Expand Up @@ -1131,7 +1137,7 @@ void QgsRasterLayer::setDefaultContrastEnhancement()
QString myLimitsString = mySettings.value( "/Raster/defaultContrastEnhancementLimits", "CumulativeCut" ).toString();
QgsRaster::ContrastEnhancementLimits myLimits = QgsRaster::contrastEnhancementLimitsFromString( myLimitsString );

setContrastEnhancementAlgorithm( myAlgorithm, myLimits );
setContrastEnhancement( myAlgorithm, myLimits );
}

/**
Expand Down Expand Up @@ -1266,10 +1272,10 @@ QPixmap QgsRasterLayer::previewAsPixmap( QSize size, QColor bgColor )
double myPixelWidth = myExtent.width() / myMapUnitsPerPixel;
double myPixelHeight = myExtent.height() / myMapUnitsPerPixel;

myRasterViewPort->topLeftPoint = QgsPoint( myX, myY );
myRasterViewPort->bottomRightPoint = QgsPoint( myPixelWidth, myPixelHeight );
myRasterViewPort->drawableAreaXDim = myQPixmap.width();
myRasterViewPort->drawableAreaYDim = myQPixmap.height();
myRasterViewPort->mTopLeftPoint = QgsPoint( myX, myY );
myRasterViewPort->mBottomRightPoint = QgsPoint( myPixelWidth, myPixelHeight );
myRasterViewPort->mWidth = myQPixmap.width();
myRasterViewPort->mHeight = myQPixmap.height();

myRasterViewPort->mDrawnExtent = myExtent;
myRasterViewPort->mSrcCRS = QgsCoordinateReferenceSystem(); // will be invalid
Expand Down Expand Up @@ -1619,13 +1625,13 @@ bool QgsRasterLayer::writeXml( QDomNode & layer_node,

for ( int bandNo = 1; bandNo <= mDataProvider->bandCount(); bandNo++ )
{
if ( mDataProvider->userNoDataValue( bandNo ).isEmpty() ) continue;
if ( mDataProvider->userNoDataValues( bandNo ).isEmpty() ) continue;

QDomElement noDataRangeList = document.createElement( "noDataList" );
noDataRangeList.setAttribute( "bandNo", bandNo );
noDataRangeList.setAttribute( "useSrcNoData", mDataProvider->useSrcNoDataValue( bandNo ) );

foreach ( QgsRasterRange range, mDataProvider->userNoDataValue( bandNo ) )
foreach ( QgsRasterRange range, mDataProvider->userNoDataValues( bandNo ) )
{
QDomElement noDataRange = document.createElement( "noDataRange" );

Expand Down
13 changes: 7 additions & 6 deletions src/core/raster/qgsrasterlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
QString providerType() const;

/** \brief Returns the number of raster units per each raster pixel. In a world file, this is normally the first row (without the sign) */
double rasterUnitsPerPixel();
double rasterUnitsPerPixelX();
double rasterUnitsPerPixelY();

/** \brief Set contrast enhancement algorithm
* @param theAlgorithm Contrast enhancement algorithm
Expand All @@ -346,11 +347,11 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
* @param theGenerateLookupTableFlag Generate llokup table. */


void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
QgsRaster::ContrastEnhancementLimits theLimits = QgsRaster::ContrastEnhancementMinMax,
QgsRectangle theExtent = QgsRectangle(),
int theSampleSize = SAMPLE_SIZE,
bool theGenerateLookupTableFlag = true );
void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
QgsRaster::ContrastEnhancementLimits theLimits = QgsRaster::ContrastEnhancementMinMax,
QgsRectangle theExtent = QgsRectangle(),
int theSampleSize = SAMPLE_SIZE,
bool theGenerateLookupTableFlag = true );

/** \brief Set default contrast enhancement */
void setDefaultContrastEnhancement();
Expand Down
69 changes: 54 additions & 15 deletions src/core/raster/qgsrasternuller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,31 @@ QgsRasterInterface * QgsRasterNuller::clone() const
QgsDebugMsg( "Entered" );
QgsRasterNuller * nuller = new QgsRasterNuller( 0 );
nuller->mNoData = mNoData;
nuller->mOutputNoData = mOutputNoData;
nuller->mHasOutputNoData = mHasOutputNoData;
return nuller;
}

void QgsRasterNuller::setOutputNoDataValue( int bandNo, double noData )
{
if ( bandNo > mOutputNoData.size() )
{
mOutputNoData.resize( bandNo );
mHasOutputNoData.resize( bandNo );
}
mOutputNoData[bandNo-1] = noData;
mHasOutputNoData[bandNo-1] = true;
}

void QgsRasterNuller::setNoData( int bandNo, QgsRasterRangeList noData )
{
if ( bandNo > mNoData.size() )
{
mNoData.resize( bandNo );
}
mNoData[bandNo-1] = noData;
}

int QgsRasterNuller::bandCount() const
{
if ( mInput ) return mInput->bandCount();
Expand All @@ -56,34 +78,51 @@ QgsRasterBlock * QgsRasterNuller::block( int bandNo, QgsRectangle const & exten
return outputBlock;
}

//void * rasterData = mInput->block( bandNo, extent, width, height );
QgsRasterBlock *inputBlock = mInput->block( bandNo, extent, width, height );
QgsRasterBlock *outputBlock = 0;

// Input may be without no data value
//double noDataValue = mInput->noDataValue( bandNo );
double noDataValue = mOutputNoData;
if ( mHasOutputNoData.value( bandNo - 1 ) || inputBlock->hasNoDataValue() )
{
double noDataValue;
if ( mHasOutputNoData.value( bandNo - 1 ) )
{
noDataValue = mOutputNoData.value( bandNo - 1 );
}
else
{
noDataValue = inputBlock->noDataValue();
}
outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height, noDataValue );
}
else
{
outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height );
}

for ( int i = 0; i < height; i++ )
{
for ( int j = 0; j < width; j++ )
{
//int index = i * width + j;

//double value = readValue( rasterData, dataType, index );
double value = inputBlock->value( i, j );

foreach ( NoData noData, mNoData )
bool isNoData = inputBlock->isNoData( i, j );
if ( QgsRasterRange::contains( value, mNoData.value( bandNo - 1 ) ) )
{
isNoData = true;
}
outputBlock->setValue( i, j, inputBlock->value( i, j ) );
if ( isNoData )
{
outputBlock->setIsNoData( i, j );
}
else
{
if (( value >= noData.min && value <= noData.max ) ||
qgsDoubleNear( value, noData.min ) ||
qgsDoubleNear( value, noData.max ) )
{
inputBlock->setValue( i, j, noDataValue );
}
outputBlock->setValue( i, j, value );
}
}
}
delete inputBlock;

return inputBlock;
return outputBlock;
}

15 changes: 9 additions & 6 deletions src/core/raster/qgsrasternuller.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define QGSRASTERNULLER_H

#include "qgsrasterdataprovider.h"
#include "qgsrasterrange.h"
#include "qgsrasterinterface.h"

#include <QList>
Expand Down Expand Up @@ -46,17 +47,19 @@ class CORE_EXPORT QgsRasterNuller : public QgsRasterInterface

QgsRasterBlock* block( int bandNo, const QgsRectangle &extent, int width, int height );

void setNoData( QList<QgsRasterNuller::NoData> noData ) { mNoData = noData; }
void setNoData( int bandNo, QgsRasterRangeList noData );

QList<QgsRasterNuller::NoData> noData() const { return mNoData; }
QgsRasterRangeList noData( int bandNo ) const { return mNoData.value( bandNo -1 ); }

/** \brief Set output no data value. */
void setOutputNoData( double noData ) { mOutputNoData = noData; }
void setOutputNoDataValue( int bandNo, double noData );

private:
QList<QgsRasterNuller::NoData> mNoData;
// no data to be set in output
double mOutputNoData;
// no data indext from 0
QVector< QgsRasterRangeList > mNoData;
// no data to be set in output, indexed form 0
QVector<double> mOutputNoData;
QVector<bool> mHasOutputNoData;
};

#endif // QGSRASTERNULLER_H
13 changes: 7 additions & 6 deletions src/core/raster/qgsrasterprojector.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
***************************************************************************/

/* This code takes ideas from WarpBuilder in Geotools.
* Thank you to Ing. Andrea Aime, Ing. Simone Giannecchini and GeoSolutions S.A.S.
* Thank to Ing. Andrea Aime, Ing. Simone Giannecchini and GeoSolutions S.A.S.
* See : http://geo-solutions.blogspot.com/2011/01/developers-corner-improving.html
*/

Expand Down Expand Up @@ -57,7 +57,9 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
QgsRectangle theExtent
);
QgsRasterProjector();
// * copy constructor to avoid synthesized which fails on copy of QgsCoordinateTransform (QObject child) in Python bindings
/** \brief Copy constructor */
// To avoid synthesized which fails on copy of QgsCoordinateTransform
// (QObject child) in Python bindings
QgsRasterProjector( const QgsRasterProjector &projector );

/** \brief The destructor */
Expand Down Expand Up @@ -86,6 +88,9 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
mMaxSrcXRes = theMaxSrcXRes; mMaxSrcYRes = theMaxSrcYRes;
}

QgsRasterBlock *block( int bandNo, const QgsRectangle & extent, int width, int height );

private:
/** get source extent */
QgsRectangle srcExtent() { return mSrcExtent; }

Expand All @@ -101,10 +106,6 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
int dstRows() const { return mDestRows; }
int dstCols() const { return mDestCols; }

QgsRasterBlock *block( int bandNo, const QgsRectangle & extent, int width, int height );


private:
/** \brief get destination point for _current_ destination position */
void destPointOnCPMatrix( int theRow, int theCol, double *theX, double *theY );

Expand Down
35 changes: 17 additions & 18 deletions src/core/raster/qgsrasterviewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,27 @@

struct QgsRasterViewPort
{
// NOT IN MAP SPACE BUT DEVICE SPACE
/** \brief Coordinate (in geographic coordinate system) of top left corner of the part of the raster that
* is to be rendered.*/
QgsPoint topLeftPoint;
/** \brief Coordinate (in geographic coordinate system) of bottom right corner of the part of the raster that
* is to be rendered.*/
QgsPoint bottomRightPoint;
/** \brief Distance in map units from left edge to right edge for the part of the raster that
* is to be rendered.*/

int drawableAreaXDim;
/** \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
/** \brief Coordinate (in output device coordinate system) of top left corner
* of the part of the raster that is to be rendered.*/
QgsPoint mTopLeftPoint;
/** \brief Coordinate (in output device coordinate system) of bottom right corner
* of the part of the raster that is to be rendered.*/
QgsPoint mBottomRightPoint;

/** \brief Width, number of columns to be rendered */
int mWidth;
/** \brief Distance in map units from bottom edge to top edge for the part of
* the raster that is to be rendered.*/
/** \brief Height, number of rows to be rendered */
int mHeight;

/** \brief Intersection of current map extent and layer extent */
QgsRectangle mDrawnExtent;

// Source coordinate system
/** \brief Source coordinate system */
QgsCoordinateReferenceSystem mSrcCRS;

// Target coordinate system
/** \brief Target coordinate system */
QgsCoordinateReferenceSystem mDestCRS;
};

Expand Down
9 changes: 4 additions & 5 deletions src/gui/qgsrasterlayersaveasdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,18 +797,17 @@ void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
lineEdit->setFixedWidth( width );
}

QList<QgsRasterNuller::NoData> QgsRasterLayerSaveAsDialog::noData() const
QgsRasterRangeList QgsRasterLayerSaveAsDialog::noData() const
{
QList<QgsRasterNuller::NoData> noDataList;
QgsRasterRangeList noDataList;
if ( ! mNoDataGroupBox->isChecked() )
return noDataList;

for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
{
QgsRasterNuller::NoData noData;
noData.min = noDataCellValue( r, 0 );
noData.max = noDataCellValue( r, 1 );
QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
noDataList.append( noData );

}
return noDataList;
}
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsrasterlayersaveasdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "ui_qgsrasterlayersaveasdialogbase.h"
#include "qgsrectangle.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrasternuller.h"
#include "qgsrasterrange.h"

class QgsRasterLayer;
class QgsRasterDataProvider;
Expand Down Expand Up @@ -70,7 +70,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
QgsCoordinateReferenceSystem outputCrs();
QStringList createOptions() const;
QgsRectangle outputRectangle() const;
QList<QgsRasterNuller::NoData> noData() const;
QgsRasterRangeList noData() const;

QList< int > pyramidsList() const;
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const;
Expand Down
9 changes: 5 additions & 4 deletions src/gui/qgsrubberband.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,17 @@ void QgsRubberBand::updateRect()
{
return;
}
QgsRectangle r( it->x() + mTranslationOffsetX, it->y() + mTranslationOffsetY,
it->x() + mTranslationOffsetX, it->y() + mTranslationOffsetY );
qreal s = ( mIconSize - 1 ) / 2;
qreal p = mWidth;

QgsRectangle r ( it->x() + mTranslationOffsetX - s - p, it->y() + mTranslationOffsetY - s - p,
it->x() + mTranslationOffsetX + s + p, it->y() + mTranslationOffsetY + s + p );

for ( int i = 0; i < mPoints.size(); ++i )
{
QList<QgsPoint>::const_iterator it = mPoints.at( i ).constBegin();
for ( ; it != mPoints.at( i ).constEnd(); ++it )
{
qreal s = ( mIconSize - 1 ) / 2;
qreal p = mWidth;
QgsRectangle rect = QgsRectangle( it->x() + mTranslationOffsetX - s - p, it->y() + mTranslationOffsetY - s - p,
it->x() + mTranslationOffsetX + s + p, it->y() + mTranslationOffsetY + s + p );
r.combineExtentWith( &rect );
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/georeferencer/qgsgcpcanvasitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ double QgsGCPCanvasItem::residualToScreenFactor() const
QgsRasterLayer* rasterLayer = dynamic_cast<QgsRasterLayer*>( mapLayer );
if ( rasterLayer )
{
mapUnitsPerRasterPixel = rasterLayer->rasterUnitsPerPixel();
mapUnitsPerRasterPixel = rasterLayer->rasterUnitsPerPixelX();
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/georeferencer/qgsgeorefplugingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ void QgsGeorefPluginGui::showGeorefConfigDialog()
// Histogram stretch slots
void QgsGeorefPluginGui::fullHistogramStretch()
{
mLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum );
mLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum );
mLayer->setCacheImage( NULL );
mCanvas->refresh();
}
Expand All @@ -641,7 +641,7 @@ void QgsGeorefPluginGui::localHistogramStretch()
{
QgsRectangle rectangle = mIface->mapCanvas()->mapRenderer()->outputExtentToLayerExtent( mLayer, mIface->mapCanvas()->extent() );

mLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax, rectangle );
mLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax, rectangle );
mLayer->setCacheImage( NULL );
mCanvas->refresh();
}
Expand Down
19 changes: 6 additions & 13 deletions src/providers/gdal/qgsgdalprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ QgsRasterBlock* QgsGdalProvider::block( int theBandNo, const QgsRectangle &theEx
block->setIsNoDataExcept( subRect );
}
readBlock( theBandNo, theExtent, theWidth, theHeight, block->bits() );
block->applyNoDataValues( userNoDataValue( theBandNo ) );
block->applyNoDataValues( userNoDataValues( theBandNo ) );
return block;
}

Expand Down Expand Up @@ -963,7 +963,7 @@ QgsRasterIdentifyResult QgsGdalProvider::identify( const QgsPoint & thePoint, Qg

if (( srcHasNoDataValue( i ) && useSrcNoDataValue( i ) &&
( qIsNaN( value ) || qgsDoubleNear( value, srcNoDataValue( i ) ) ) ) ||
( QgsRasterRange::contains( value, userNoDataValue( i ) ) ) )
( QgsRasterRange::contains( value, userNoDataValues( i ) ) ) )
{
results.insert( i, QVariant() ); // null QVariant represents no data
}
Expand Down Expand Up @@ -1152,7 +1152,7 @@ bool QgsGdalProvider::hasHistogram( int theBandNo,
}

if (( srcHasNoDataValue( theBandNo ) && !useSrcNoDataValue( theBandNo ) ) ||
userNoDataValue( theBandNo ).size() > 0 )
userNoDataValues( theBandNo ).size() > 0 )
{
QgsDebugMsg( "Custom no data values -> GDAL histogram not sufficient." );
return false;
Expand Down Expand Up @@ -1234,7 +1234,7 @@ QgsRasterHistogram QgsGdalProvider::histogram( int theBandNo,
}

if (( srcHasNoDataValue( theBandNo ) && !useSrcNoDataValue( theBandNo ) ) ||
userNoDataValue( theBandNo ).size() > 0 )
userNoDataValues( theBandNo ).size() > 0 )
{
QgsDebugMsg( "Custom no data values, using generic histogram." );
return QgsRasterDataProvider::histogram( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
Expand Down Expand Up @@ -2068,7 +2068,7 @@ bool QgsGdalProvider::hasStatistics( int theBandNo,
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );

if (( srcHasNoDataValue( theBandNo ) && !useSrcNoDataValue( theBandNo ) ) ||
userNoDataValue( theBandNo ).size() > 0 )
userNoDataValues( theBandNo ).size() > 0 )
{
QgsDebugMsg( "Custom no data values -> GDAL statistics not sufficient." );
return false;
Expand Down Expand Up @@ -2162,7 +2162,7 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, int theStats,
// We cannot use GDAL stats if user disabled src no data value or set
// custom no data values
if (( srcHasNoDataValue( theBandNo ) && !useSrcNoDataValue( theBandNo ) ) ||
userNoDataValue( theBandNo ).size() > 0 )
userNoDataValues( theBandNo ).size() > 0 )
{
QgsDebugMsg( "Custom no data values, using generic statistics." );
return QgsRasterDataProvider::bandStatistics( theBandNo, theStats, theExtent, theSampleSize );
Expand Down Expand Up @@ -2233,8 +2233,6 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, int theStats,
// if stats are found populate the QgsRasterBandStats object
if ( CE_None == myerval )
{

myRasterBandStats.bandName = generateBandName( theBandNo );
myRasterBandStats.bandNumber = theBandNo;
myRasterBandStats.range = pdfMax - pdfMin;
myRasterBandStats.minimumValue = pdfMin;
Expand Down Expand Up @@ -2555,11 +2553,6 @@ bool QgsGdalProvider::setNoDataValue( int bandNo, double noDataValue )
return true;
}

QStringList QgsGdalProvider::createFormats() const
{
return QStringList();
}

bool QgsGdalProvider::remove()
{
if ( mGdalDataset )
Expand Down
13 changes: 0 additions & 13 deletions src/providers/gdal/qgsgdalprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,24 +228,11 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase

static QMap<QString, QString> supportedMimes();

/** Creates a new dataset with mDataSourceURI
@return true in case of success*/
/*
bool create( const QString& format, int nBands,
QGis::DataType type,
int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions = QStringList() );
*/

/**Writes into the provider datasource*/
bool write( void* data, int band, int width, int height, int xOffset, int yOffset );

bool setNoDataValue( int bandNo, double noDataValue );

/**Returns the formats supported by create()*/
QStringList createFormats() const;

/**Remove dataset*/
bool remove();

Expand Down
2 changes: 1 addition & 1 deletion src/providers/grass/qgsgrassrasterprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ QgsRasterIdentifyResult QgsGrassRasterProvider::identify( const QgsPoint & thePo
}

// Apply user no data
QgsRasterRangeList myNoDataRangeList = userNoDataValue( 1 );
QgsRasterRangeList myNoDataRangeList = userNoDataValues( 1 );
if ( QgsRasterRange::contains( value, myNoDataRangeList ) )
{
return noDataResult;
Expand Down
2 changes: 1 addition & 1 deletion src/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,7 +1850,7 @@ QGISEXTERN bool createEmptyDataSource( const QString &uri,
char **papszOptions = NULL;
if ( driverName == "ESRI Shapefile" )
{
papszOptions = CSLSetNameValue( papszOptions, "ENCODING", encoding.toLocal8Bit().data() );
papszOptions = CSLSetNameValue( papszOptions, "ENCODING", QgsVectorFileWriter::convertCodecNameForEncodingOption( encoding ).toLocal8Bit().data() );
// OGR Shapefile fails to create fields if given encoding is not supported by its side
// so disable encoding conversion of OGR Shapefile layer
CPLSetConfigOption( "SHAPE_ENCODING", "" );
Expand Down
2 changes: 1 addition & 1 deletion src/providers/wcs/qgswcsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ QgsRasterIdentifyResult QgsWcsProvider::identify( const QgsPoint & thePoint, Qgs
// Apply no data and user no data
if (( srcHasNoDataValue( i ) && useSrcNoDataValue( i ) &&
( qIsNaN( value ) || qgsDoubleNear( value, srcNoDataValue( i ) ) ) ) ||
( QgsRasterRange::contains( value, userNoDataValue( i ) ) ) )
( QgsRasterRange::contains( value, userNoDataValues( i ) ) ) )
{
results.insert( i, QVariant() );
}
Expand Down
8 changes: 5 additions & 3 deletions src/providers/wms/qgswmsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4270,9 +4270,11 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
QMap<QgsFeatureId, QgsFeature* > features = gml.featuresMap();
QgsDebugMsg( QString( "%1 features read" ).arg( features.size() ) );
QgsFeatureStore featureStore( fields, crs() );
featureStore.params().insert( "sublayer", *layers );
featureStore.params().insert( "featureType", featureTypeName );
featureStore.params().insert( "getFeatureInfoUrl", requestUrl.toString() );
QMap<QString, QVariant> params;
params.insert( "sublayer", *layers );
params.insert( "featureType", featureTypeName );
params.insert( "getFeatureInfoUrl", requestUrl.toString() );
featureStore.setParams( params );
foreach ( QgsFeatureId id, features.keys() )
{
QgsFeature * feature = features.value( id );
Expand Down
22 changes: 22 additions & 0 deletions src/ui/qgscomposermapwidgetbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,23 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mOverviewBlendModeLabel">
<property name="text">
<string>Overview blending mode</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsBlendModeComboBox" name="mOverviewBlendModeComboBox"/>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="mOverviewInvertCheckbox">
<property name="text">
<string>Invert overview</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand All @@ -680,6 +697,11 @@
<header location="global">qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsBlendModeComboBox</class>
<extends>QComboBox</extends>
<header>qgsblendmodecombobox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
Expand Down
135 changes: 59 additions & 76 deletions src/ui/qgsdiagrampropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>752</width>
<height>613</height>
<width>743</width>
<height>644</height>
</rect>
</property>
<layout class="QVBoxLayout" name="scrollAreaLayout">
Expand Down Expand Up @@ -118,17 +118,12 @@
<layout class="QHBoxLayout" name="appearanceLayout"/>
</item>
<item>
<widget class="QToolBox" name="mDiagramPropertiesToolBox">
<widget class="QWidget" name="mDiagramPropertiesToolBoxPage1">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>713</width>
<height>394</height>
</rect>
</property>
<attribute name="label">
<widget class="QTabWidget" name="mDiagramPropertiesTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="mDiagramPropertiesTabWidgetPage1">
<attribute name="title">
<string>Appearance</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
Expand Down Expand Up @@ -315,16 +310,8 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mDiagramPropertiesToolBoxPage2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>715</width>
<height>278</height>
</rect>
</property>
<attribute name="label">
<widget class="QWidget" name="mDiagramPropertiesTabWidgetPage2">
<attribute name="title">
<string>Size</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
Expand Down Expand Up @@ -393,6 +380,9 @@
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="mLinearlyScalingLabel">
<property name="text">
Expand All @@ -406,32 +396,41 @@
<item>
<layout class="QHBoxLayout" name="mLinearlyScalingLayout">
<item>
<widget class="QLabel" name="mSizeAttributeLabel">
<property name="text">
<string>Attribute</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mSizeAttributeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mFindMaximumValueButton">
<property name="text">
<string>Find maximum value</string>
</property>
<widget class="QWidget" name="mAttributeBasedScalingOptions" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="mSizeAttributeLabel">
<property name="text">
<string>Attribute</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mSizeAttributeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mFindMaximumValueButton">
<property name="text">
<string>Find maximum value</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mValueLineEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mValueLineEdit"/>
</item>
<item>
<widget class="QLabel" name="mSizeLabel">
<property name="text">
Expand All @@ -445,7 +444,7 @@
<number>10000000</number>
</property>
<property name="value">
<number>100</number>
<number>50</number>
</property>
</widget>
</item>
Expand Down Expand Up @@ -504,16 +503,8 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mDiagramPropertiesToolBoxPage3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>713</width>
<height>271</height>
</rect>
</property>
<attribute name="label">
<widget class="QWidget" name="mDiagramPropertiesTabWidgetPage3">
<attribute name="title">
<string>Position</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
Expand Down Expand Up @@ -666,16 +657,8 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mDiagramPropertiesToolBoxPage4">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>728</width>
<height>166</height>
</rect>
</property>
<attribute name="label">
<widget class="QWidget" name="mDiagramPropertiesTabOptions">
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
Expand Down Expand Up @@ -980,12 +963,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>75</x>
<y>118</y>
<x>48</x>
<y>122</y>
</hint>
<hint type="destinationlabel">
<x>158</x>
<y>118</y>
<x>78</x>
<y>122</y>
</hint>
</hints>
</connection>
Expand All @@ -996,12 +979,12 @@
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>75</x>
<y>118</y>
<x>48</x>
<y>122</y>
</hint>
<hint type="destinationlabel">
<x>390</x>
<y>222</y>
<x>77</x>
<y>132</y>
</hint>
</hints>
</connection>
Expand Down
5 changes: 4 additions & 1 deletion src/ui/qgsoptionsbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,10 @@
<item>
<widget class="QCheckBox" name="cbxIgnoreShapeEncoding">
<property name="text">
<string>Ignore shapefile encoding</string>
<string>Ignore shapefile encoding declaration</string>
</property>
<property name="toolTip">
<string>Disable OGR on-the-fly conversion from declared encoding to UTF-8</string>
</property>
</widget>
</item>
Expand Down
2 changes: 2 additions & 0 deletions tests/src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ ADD_QGIS_TEST(contrastenhancementtest testcontrastenhancements.cpp)
ADD_QGIS_TEST(maplayertest testqgsmaplayer.cpp)
ADD_QGIS_TEST(rendererstest testqgsrenderers.cpp)
ADD_QGIS_TEST(maprenderertest testqgsmaprenderer.cpp)
ADD_QGIS_TEST(blendmodestest testqgsblendmodes.cpp)
ADD_QGIS_TEST(geometrytest testqgsgeometry.cpp)
ADD_QGIS_TEST(coordinatereferencesystemtest testqgscoordinatereferencesystem.cpp)
ADD_DEPENDENCIES(qgis_coordinatereferencesystemtest synccrsdb)
Expand All @@ -101,6 +102,7 @@ ADD_QGIS_TEST(rulebasedrenderertest testqgsrulebasedrenderer.cpp)
ADD_QGIS_TEST(ziplayertest testziplayer.cpp)
ADD_QGIS_TEST(dataitemtest testqgsdataitem.cpp)
ADD_QGIS_TEST(composermaptest testqgscomposermap.cpp)
ADD_QGIS_TEST(composereffectstest testqgscomposereffects.cpp)
ADD_QGIS_TEST(atlascompositiontest testqgsatlascomposition.cpp)
ADD_QGIS_TEST(composerlabeltest testqgscomposerlabel.cpp)
ADD_QGIS_TEST(stylev2test testqgsstylev2.cpp)
Expand Down
154 changes: 154 additions & 0 deletions tests/src/core/testqgsblendmodes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/***************************************************************************
testqgsblendmodes.cpp
--------------------------------------
Date : May 2013
Copyright : (C) 2013 by Nyall Dawson, Tim Sutton
Email : nyall dot dawson at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QtTest>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QApplication>
#include <QDir>
#include <QPainter>

//qgis includes...
#include <qgsmaprenderer.h>
#include <qgsmaplayer.h>
#include <qgsvectorlayer.h>
#include <qgsapplication.h>
#include <qgsproviderregistry.h>
#include <qgsmaplayerregistry.h>
#include <qgsmultibandcolorrenderer.h>
#include <qgsrasterlayer.h>
//qgis test includes
#include "qgsrenderchecker.h"

/** \ingroup UnitTests
* This is a unit test for layer blend modes
*/
class TestQgsBlendModes: public QObject
{
Q_OBJECT;
private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init() {};// will be called before each testfunction is executed.
void cleanup() {};// will be called after every testfunction.

void vectorBlending();
void rasterBlending();
private:
bool imageCheck( QString theType ); //as above
QgsMapRenderer * mpMapRenderer;
QgsMapLayer * mpPointsLayer;
QgsMapLayer * mpPolysLayer;
QgsRasterLayer* mRasterLayer1;
QgsRasterLayer* mRasterLayer2;
QString mTestDataDir;
};


void TestQgsBlendModes::initTestCase()
{

// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();
QgsApplication::showSettings();

//create some objects that will be used in tests

//create a point layer
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
mTestDataDir = myDataDir + QDir::separator();
QString myPointsFileName = mTestDataDir + "points.shp";
QFileInfo myPointFileInfo( myPointsFileName );
mpPointsLayer = new QgsVectorLayer( myPointFileInfo.filePath(),
myPointFileInfo.completeBaseName(), "ogr" );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpPointsLayer );

//create a poly layer that will be used in tests
QString myPolysFileName = mTestDataDir + "polys.shp";
QFileInfo myPolyFileInfo( myPolysFileName );
mpPolysLayer = new QgsVectorLayer( myPolyFileInfo.filePath(),
myPolyFileInfo.completeBaseName(), "ogr" );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpPolysLayer );

//create two raster layers
QFileInfo rasterFileInfo( mTestDataDir + "landsat.tif" );
mRasterLayer1 = new QgsRasterLayer( rasterFileInfo.filePath(),
rasterFileInfo.completeBaseName() );
mRasterLayer2 = new QgsRasterLayer( rasterFileInfo.filePath(),
rasterFileInfo.completeBaseName() );
QgsMultiBandColorRenderer* rasterRenderer = new QgsMultiBandColorRenderer( mRasterLayer1->dataProvider(), 2, 3, 4 );
mRasterLayer1->setRenderer( rasterRenderer );
mRasterLayer2->setRenderer( rasterRenderer );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mRasterLayer1 );
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mRasterLayer2);

mpMapRenderer = new QgsMapRenderer();
}
void TestQgsBlendModes::cleanupTestCase()
{

}

void TestQgsBlendModes::vectorBlending()
{
//Add two vector layers
QStringList myLayers;
myLayers << mpPointsLayer->id();
myLayers << mpPolysLayer->id();
mpMapRenderer->setLayerSet( myLayers );

//Set blending modes for both layers
mpPointsLayer->setBlendMode( QPainter::CompositionMode_Overlay );
mpPolysLayer->setBlendMode( QPainter::CompositionMode_Multiply );
mpMapRenderer->setExtent( mpPointsLayer->extent() );
QVERIFY( imageCheck( "vector_blendmodes" ) );
}

void TestQgsBlendModes::rasterBlending()
{
//Add two raster layers to map renderer
QStringList myLayers;
myLayers << mRasterLayer1->id();
myLayers << mRasterLayer2->id();
mpMapRenderer->setLayerSet( myLayers );
mpMapRenderer->setExtent( mRasterLayer1->extent() );

// set blending mode for top layer
mRasterLayer1->setBlendMode( QPainter::CompositionMode_Plus );
QVERIFY( imageCheck( "raster_blendmodes" ) );
}

//
// Private helper functions not called directly by CTest
//

bool TestQgsBlendModes::imageCheck( QString theTestType )
{
//use the QgsRenderChecker test utility class to
//ensure the rendered output matches our control image
QgsRenderChecker myChecker;
myChecker.setControlName( "expected_" + theTestType );
myChecker.setMapRenderer( mpMapRenderer );
bool myResultFlag = myChecker.runTest( theTestType );
return myResultFlag;
}

QTEST_MAIN( TestQgsBlendModes )
#include "moc_testqgsblendmodes.cxx"
103 changes: 103 additions & 0 deletions tests/src/core/testqgscomposereffects.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/***************************************************************************
testqgscomposereffects.cpp
----------------------
begin : April 2013
copyright : (C) 2013 by Marco Hugentobler, Nyall Dawson
email : nyall dot dawson at gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsapplication.h"
#include "qgscomposition.h"
#include "qgscompositionchecker.h"
#include "qgscomposershape.h"
#include "qgsmaprenderer.h"
#include <QObject>
#include <QtTest>
#include <QColor>
#include <QPainter>

class TestQgsComposerEffects: public QObject
{
Q_OBJECT;
private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init();// will be called before each testfunction is executed.
void cleanup();// will be called after every testfunction.
void blend_modes(); //test if composer item blending is functioning
void transparency(); //test if composer transparency is functioning

private:
QgsComposition* mComposition;
QgsComposerShape* mComposerRect1;
QgsComposerShape* mComposerRect2;
QgsMapRenderer* mMapRenderer;
};

void TestQgsComposerEffects::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();

//create composition with two rectangles
mMapRenderer = new QgsMapRenderer();

mComposition = new QgsComposition( mMapRenderer );
mComposition->setPaperSize( 297, 210 ); //A4 landscape
mComposerRect1 = new QgsComposerShape( 20, 20, 150, 100, mComposition );
mComposerRect1->setShapeType( QgsComposerShape::Rectangle );
mComposerRect1->setBackgroundColor( QColor::fromRgb( 255, 150, 0 ) );
mComposition->addComposerShape( mComposerRect1 );
mComposerRect2 = new QgsComposerShape( 50, 50, 150, 100, mComposition );
mComposerRect2->setBackgroundColor( QColor::fromRgb( 0, 100, 150 ) );
mComposerRect2->setShapeType( QgsComposerShape::Rectangle );
mComposition->addComposerShape( mComposerRect2 );

}

void TestQgsComposerEffects::cleanupTestCase()
{
delete mComposition;
}

void TestQgsComposerEffects::init()
{

}

void TestQgsComposerEffects::cleanup()
{

}

void TestQgsComposerEffects::blend_modes()
{
mComposerRect2->setBlendMode( QPainter::CompositionMode_Multiply );

QgsCompositionChecker checker( "Composer effects blending", mComposition, QString( QString( TEST_DATA_DIR ) + QDir::separator() +
"control_images" + QDir::separator() + "expected_composereffects" + QDir::separator() + "composereffect_blend.png" ) );
QVERIFY( checker.testComposition() );
// reset blending
mComposerRect2->setBlendMode( QPainter::CompositionMode_SourceOver );
}

void TestQgsComposerEffects::transparency()
{
mComposerRect2->setTransparency( 50 );

QgsCompositionChecker checker( "Composer item transparency", mComposition, QString( QString( TEST_DATA_DIR ) + QDir::separator() +
"control_images" + QDir::separator() + "expected_composereffects" + QDir::separator() + "composereffect_transparency.png" ) );
QVERIFY( checker.testComposition() );
}

QTEST_MAIN( TestQgsComposerEffects )
#include "moc_testqgscomposereffects.cxx"
36 changes: 36 additions & 0 deletions tests/src/core/testqgscomposermap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class TestQgsComposerMap: public QObject
void render(); //test if rendering of the composition with composr map is correct
void grid(); //test if grid and grid annotation works
void overviewMap(); //test if overview map frame works
void overviewMapBlending(); //test if blend modes with overview map frame works
void overviewMapInvert(); //test if invert of overview map frame works
void uniqueId(); //test if map id is adapted when doing copy paste
void zebraStyle(); //test zebra map border style

Expand Down Expand Up @@ -135,6 +137,40 @@ void TestQgsComposerMap::overviewMap()
QVERIFY( testResult );
}

void TestQgsComposerMap::overviewMapBlending()
{
QgsComposerMap* overviewMapBlend = new QgsComposerMap( mComposition, 20, 130, 70, 70 );
overviewMapBlend->setFrameEnabled( true );
mComposition->addComposerMap( overviewMapBlend );
mComposerMap->setNewExtent( QgsRectangle( 785462.375, 3341423.125, 789262.375, 3343323.125 ) ); //zoom in
overviewMapBlend->setNewExtent( QgsRectangle( 781662.375, 3339523.125, 793062.375, 3350923.125 ) );
overviewMapBlend->setOverviewFrameMap( mComposerMap->id() );
overviewMapBlend->setOverviewBlendMode( QPainter::CompositionMode_Multiply );

QgsCompositionChecker checker( "Composer map overview blending", mComposition, QString( QString( TEST_DATA_DIR ) + QDir::separator() +
"control_images" + QDir::separator() + "expected_composermap" + QDir::separator() + "composermap_landsat_overview_blend.png" ) );
bool testResult = checker.testComposition();
mComposition->removeComposerItem( overviewMapBlend );
QVERIFY( testResult );
}

void TestQgsComposerMap::overviewMapInvert()
{
QgsComposerMap* overviewMapInvert = new QgsComposerMap( mComposition, 20, 130, 70, 70 );
overviewMapInvert->setFrameEnabled( true );
mComposition->addComposerMap( overviewMapInvert );
mComposerMap->setNewExtent( QgsRectangle( 785462.375, 3341423.125, 789262.375, 3343323.125 ) ); //zoom in
overviewMapInvert->setNewExtent( QgsRectangle( 781662.375, 3339523.125, 793062.375, 3350923.125 ) );
overviewMapInvert->setOverviewFrameMap( mComposerMap->id() );
overviewMapInvert->setOverviewInverted( true );

QgsCompositionChecker checker( "Composer map overview invert", mComposition, QString( QString( TEST_DATA_DIR ) + QDir::separator() +
"control_images" + QDir::separator() + "expected_composermap" + QDir::separator() + "composermap_landsat_overview_invert.png" ) );
bool testResult = checker.testComposition();
mComposition->removeComposerItem( overviewMapInvert );
QVERIFY( testResult );
}

void TestQgsComposerMap::uniqueId()
{
QDomDocument doc;
Expand Down
5 changes: 4 additions & 1 deletion tests/src/core/testqgsrasterfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName )

// Nuller currently is not really used
QgsRasterNuller *nuller = new QgsRasterNuller();
//nuller->setNoData( ... );
for ( int band = 1; band <= provider->bandCount(); band++ )
{
//nuller->setNoData( ... );
}
if ( !pipe->insert( 1, nuller ) )
{
logError( "Cannot set pipe nuller" );
Expand Down
Loading