Skip to content

Commit

Permalink
fixed simple marker, ellipse, svg anchor with data defined size, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed May 12, 2014
1 parent 4670a16 commit 1ed94d0
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 30 deletions.
16 changes: 13 additions & 3 deletions src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,22 @@ void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Rend
QString colorString = outlineColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
mPen.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) );
}
double scaledWidth = mSymbolWidth;
double scaledHeight = mSymbolHeight;
if ( widthExpression || heightExpression || symbolNameExpression )
{
QString symbolName = mSymbolName;
if ( symbolNameExpression )
{
symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
}
preparePath( symbolName, context, context.feature() );
preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() );
}

//offset
double offsetX = 0;
double offsetY = 0;
markerOffset( context, mSymbolWidth, mSymbolHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale );
markerOffset( context, scaledWidth, scaledHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale );
QPointF off( offsetX, offsetY );

QPainter* p = context.renderContext().painter();
Expand Down Expand Up @@ -459,7 +461,7 @@ bool QgsEllipseSymbolLayerV2::hasDataDefinedProperty() const
|| dataDefinedProperty( "symbol_name" ) || dataDefinedProperty( "offset" ) );
}

void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, const QgsFeature* f )
void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, double* scaledWidth, double* scaledHeight, const QgsFeature* f )
{
mPainterPath = QPainterPath();
const QgsRenderContext& ct = context.renderContext();
Expand All @@ -479,6 +481,10 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
{
width = mSymbolWidth;
}
if ( scaledWidth )
{
*scaledWidth = width;
}
width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( ct, mSymbolWidthUnit, mSymbolHeightMapUnitScale );

double height = 0;
Expand All @@ -495,6 +501,10 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
{
height = mSymbolHeight;
}
if ( scaledHeight )
{
*scaledHeight = height;
}
height *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( ct, mSymbolHeightUnit, mSymbolHeightMapUnitScale );

if ( symbolName == "circle" )
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsellipsesymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
@param symbolName name of symbol
@param context render context
@param f feature f to render (0 if no data defined rendering)*/
void preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, const QgsFeature* f = 0 );
void preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, double* scaledWidth = 0, double* scaledHeight = 0, const QgsFeature* f = 0 );

/**True if this symbol layer uses a data defined property*/
bool hasDataDefinedProperty() const;
Expand Down
51 changes: 26 additions & 25 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,27 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
return;
}

QgsExpression *sizeExpression = expression( "size" );
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;

double scaledSize = mSize;
if ( hasDataDefinedSize )
{
if ( sizeExpression )
{
scaledSize = sizeExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}

if ( mScaleMethod == QgsSymbolV2::ScaleArea )
{
scaledSize = sqrt( scaledSize );
}
}

//offset
double offsetX = 0;
double offsetY = 0;
markerOffset( context, offsetX, offsetY );
markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
QPointF off( offsetX, offsetY );

//angle
Expand Down Expand Up @@ -522,30 +539,13 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
// move to the desired position
transform.translate( point.x() + off.x(), point.y() + off.y() );

QgsExpression *sizeExpression = expression( "size" );
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;

// resize if necessary
if ( hasDataDefinedSize )
{
double scaledSize = mSize;
if ( sizeExpression )
{
scaledSize = sizeExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}

switch ( mScaleMethod )
{
case QgsSymbolV2::ScaleArea:
scaledSize = sqrt( scaledSize );
break;
case QgsSymbolV2::ScaleDiameter:
break;
}

scaledSize *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit, mSizeMapUnitScale );
double s = scaledSize * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit, mSizeMapUnitScale );

double half = scaledSize / 2.0;
double half = s / 2.0;
transform.scale( half, half );
}

Expand Down Expand Up @@ -1140,27 +1140,28 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
if ( !p )
return;

double size = mSize;
double scaledSize = mSize;
QgsExpression* sizeExpression = expression( "size" );
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;

if ( sizeExpression )
{
size = sizeExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
scaledSize = sizeExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}

if ( hasDataDefinedSize )
{
switch ( mScaleMethod )
{
case QgsSymbolV2::ScaleArea:
size = sqrt( size );
scaledSize = sqrt( scaledSize );
break;
case QgsSymbolV2::ScaleDiameter:
break;
}
}
size *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit, mSizeMapUnitScale );

double size = scaledSize * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit, mSizeMapUnitScale );

//don't render symbols with size below one or above 10,000 pixels
if (( int )size < 1 || 10000.0 < size )
Expand All @@ -1173,7 +1174,7 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
//offset
double offsetX = 0;
double offsetY = 0;
markerOffset( context, offsetX, offsetY );
markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
QPointF outputOffset( offsetX, offsetY );

double angle = mAngle;
Expand Down
1 change: 0 additions & 1 deletion src/core/symbology-ng/qgsmarkersymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QgsMapUnitScale mapUnitScale() const;

protected:

void drawMarker( QPainter* p, QgsSymbolV2RenderContext& context );

bool prepareShape( QString name = QString() );
Expand Down
5 changes: 5 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& conte
markerOffset( context, mSize, mSize, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
}

void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double width, double height, double& offsetX, double& offsetY ) const
{
markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
}

void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double width, double height,
QgsSymbolV2::OutputUnit widthUnit, QgsSymbolV2::OutputUnit heightUnit,
double& offsetX, double& offsetY, const QgsMapUnitScale& widthMapUnitScale, const QgsMapUnitScale& heightMapUnitScale ) const
Expand Down
4 changes: 4 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,13 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
protected:
QgsMarkerSymbolLayerV2( bool locked = false );

bool hasDataDefinedSize() const;

//handles marker offset and anchor point shift together
void markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;

void markerOffset( const QgsSymbolV2RenderContext& context, double width, double height, double& offsetX, double& offsetY ) const;

//! @note available in python bindings as markerOffset2
void markerOffset( const QgsSymbolV2RenderContext& context, double width, double height,
QgsSymbolV2::OutputUnit widthUnit, QgsSymbolV2::OutputUnit heightUnit,
Expand Down

0 comments on commit 1ed94d0

Please sign in to comment.