Skip to content

Commit c230c23

Browse files
committedApr 29, 2016
Fix calculation of point symbol bounds using data defined rotation or offset
(cherry-picked from a67853f)
1 parent 80102b1 commit c230c23

File tree

11 files changed

+76
-11
lines changed

11 files changed

+76
-11
lines changed
 

‎python/core/symbology-ng/qgssymbolv2.sip

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,16 @@ class QgsMarkerSymbolV2 : QgsSymbolV2
476476
void renderPoint( QPointF point, const QgsFeature* f, QgsRenderContext& context, int layer = -1, bool selected = false );
477477

478478
/** Returns the approximate bounding box of the marker symbol, which includes the bounding box
479-
* of all symbol layers for the symbol.
479+
* of all symbol layers for the symbol. It is recommended to use this method only between startRender()
480+
* and stopRender() calls, or data defined rotation and offset will not be correctly calculated.
481+
* @param point location of rendered point in painter units
482+
* @param context render context
483+
* @param feature feature being rendered at point (optional). If not specified, the bounds calculation will not
484+
* include data defined parameters such as offset and rotation
480485
* @returns approximate symbol bounds, in painter units
481486
* @note added in QGIS 2.14
482-
*/
483-
QRectF bounds( QPointF point, QgsRenderContext& context ) const;
487+
*/
488+
QRectF bounds(QPointF point, QgsRenderContext& context, const QgsFeature &feature = QgsFeature() ) const;
484489

485490
virtual QgsMarkerSymbolV2* clone() const /Factory/;
486491
};

‎src/core/qgsvectorlayerlabelprovider.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,9 @@ QgsGeometry* QgsVectorLayerLabelProvider::getPointObstacleGeometry( QgsFeature&
353353
if ( symbol->type() == QgsSymbolV2::Marker )
354354
{
355355
if ( bounds.isValid() )
356-
bounds = bounds.united( static_cast< QgsMarkerSymbolV2* >( symbol )->bounds( pt, context ) );
356+
bounds = bounds.united( static_cast< QgsMarkerSymbolV2* >( symbol )->bounds( pt, context, fet ) );
357357
else
358-
bounds = static_cast< QgsMarkerSymbolV2* >( symbol )->bounds( pt, context );
358+
bounds = static_cast< QgsMarkerSymbolV2* >( symbol )->bounds( pt, context, fet );
359359
}
360360
}
361361

‎src/core/symbology-ng/qgssymbolv2.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
758758
//draw debugging rect
759759
context.painter()->setPen( Qt::red );
760760
context.painter()->setBrush( QColor( 255, 0, 0, 100 ) );
761-
context.painter()->drawRect( static_cast<QgsMarkerSymbolV2*>( this )->bounds( pt, context ) );
761+
context.painter()->drawRect( static_cast<QgsMarkerSymbolV2*>( this )->bounds( pt, context, feature ) );
762762
}
763763
}
764764
break;
@@ -1422,9 +1422,9 @@ void QgsMarkerSymbolV2::renderPoint( QPointF point, const QgsFeature* f, QgsRend
14221422
}
14231423
}
14241424

1425-
QRectF QgsMarkerSymbolV2::bounds( QPointF point, QgsRenderContext& context ) const
1425+
QRectF QgsMarkerSymbolV2::bounds( QPointF point, QgsRenderContext& context, const QgsFeature& feature ) const
14261426
{
1427-
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, nullptr, nullptr, mapUnitScale() );
1427+
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, &feature, feature.fields(), mapUnitScale() );
14281428

14291429
QRectF bound;
14301430
Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )

‎src/core/symbology-ng/qgssymbolv2.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,16 @@ class CORE_EXPORT QgsMarkerSymbolV2 : public QgsSymbolV2
545545
void renderPoint( QPointF point, const QgsFeature* f, QgsRenderContext& context, int layer = -1, bool selected = false );
546546

547547
/** Returns the approximate bounding box of the marker symbol, which includes the bounding box
548-
* of all symbol layers for the symbol.
548+
* of all symbol layers for the symbol. It is recommended to use this method only between startRender()
549+
* and stopRender() calls, or data defined rotation and offset will not be correctly calculated.
550+
* @param point location of rendered point in painter units
551+
* @param context render context
552+
* @param feature feature being rendered at point (optional). If not specified, the bounds calculation will not
553+
* include data defined parameters such as offset and rotation
549554
* @returns approximate symbol bounds, in painter units
550-
* @note added in QGIS 2.14 */
551-
QRectF bounds( QPointF point, QgsRenderContext& context ) const;
555+
* @note added in QGIS 2.14
556+
*/
557+
QRectF bounds( QPointF point, QgsRenderContext& context, const QgsFeature &feature = QgsFeature() ) const;
552558

553559
virtual QgsMarkerSymbolV2* clone() const override;
554560

‎tests/src/core/testqgssimplemarker.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class TestQgsSimpleMarkerSymbol : public QObject
6060

6161
void simpleMarkerSymbol();
6262
void bounds();
63+
void boundsWithOffset();
64+
void boundsWithRotation();
65+
void boundsWithRotationAndOffset();
6366

6467
private:
6568
bool mTestHasError;
@@ -152,6 +155,57 @@ void TestQgsSimpleMarkerSymbol::bounds()
152155
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, true );
153156
bool result = imageCheck( "simplemarker_bounds" );
154157
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, false );
158+
mSimpleMarkerLayer->removeDataDefinedProperty( "size" );
159+
QVERIFY( result );
160+
}
161+
162+
void TestQgsSimpleMarkerSymbol::boundsWithOffset()
163+
{
164+
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
165+
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
166+
mSimpleMarkerLayer->setName( "circle" );
167+
mSimpleMarkerLayer->setSize( 5 );
168+
mSimpleMarkerLayer->setDataDefinedProperty( "offset", new QgsDataDefined( true, true, "if(importance > 2, '5,10', '10, 5')" ) );
169+
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
170+
171+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, true );
172+
bool result = imageCheck( "simplemarker_boundsoffset" );
173+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, false );
174+
mSimpleMarkerLayer->removeDataDefinedProperty( "offset" );
175+
QVERIFY( result );
176+
}
177+
178+
void TestQgsSimpleMarkerSymbol::boundsWithRotation()
179+
{
180+
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
181+
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
182+
mSimpleMarkerLayer->setName( "square" );
183+
mSimpleMarkerLayer->setSize( 5 );
184+
mSimpleMarkerLayer->setDataDefinedProperty( "angle", new QgsDataDefined( true, true, "importance * 20" ) );
185+
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
186+
187+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, true );
188+
bool result = imageCheck( "simplemarker_boundsrotation" );
189+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, false );
190+
mSimpleMarkerLayer->removeDataDefinedProperty( "angle" );
191+
QVERIFY( result );
192+
}
193+
194+
void TestQgsSimpleMarkerSymbol::boundsWithRotationAndOffset()
195+
{
196+
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
197+
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
198+
mSimpleMarkerLayer->setName( "square" );
199+
mSimpleMarkerLayer->setSize( 5 );
200+
mSimpleMarkerLayer->setDataDefinedProperty( "offset", new QgsDataDefined( true, true, "if(importance > 2, '5,10', '10, 5')" ) );
201+
mSimpleMarkerLayer->setDataDefinedProperty( "angle", new QgsDataDefined( true, false, QString(), "heading" ) );
202+
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
203+
204+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, true );
205+
bool result = imageCheck( "simplemarker_boundsrotationoffset" );
206+
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, false );
207+
mSimpleMarkerLayer->removeDataDefinedProperty( "offset" );
208+
mSimpleMarkerLayer->removeDataDefinedProperty( "angle" );
155209
QVERIFY( result );
156210
}
157211

0 commit comments

Comments
 (0)
Please sign in to comment.