Skip to content

Commit 933069d

Browse files
committed
Improve point rotation tool support for renderers to allow use
with rule based renderer fixes #12917, #12123 and refs #5001
1 parent 9c3d65e commit 933069d

File tree

2 files changed

+58
-70
lines changed

2 files changed

+58
-70
lines changed

src/app/qgsmaptoolrotatepointsymbols.cpp

+56-64
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,8 @@ bool QgsMapToolRotatePointSymbols::layerIsRotatable( QgsMapLayer* ml )
5757
return false;
5858
}
5959

60-
//does it have a least one rotation attribute?
61-
QList<int> rotationAttributes;
62-
layerRotationAttributes( vLayer, rotationAttributes );
63-
if ( rotationAttributes.size() < 1 )
64-
{
65-
return false;
66-
}
60+
//we consider all point layers as rotatable, as data defined rotation can be set on a per
61+
//symbol/feature basis
6762
return true;
6863
}
6964

@@ -101,35 +96,71 @@ void QgsMapToolRotatePointSymbols::canvasPressEvent( QMouseEvent *e )
10196
}
10297

10398
mFeatureNumber = m.featureId();
99+
mCurrentRotationAttributes.clear();
100+
mSnappedPoint = toCanvasCoordinates( m.point() );
104101

105-
//get list with renderer rotation attributes
106-
if ( layerRotationAttributes( mActiveLayer, mCurrentRotationAttributes ) != 0 )
102+
QgsFeature pointFeature;
103+
if ( !mActiveLayer->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setFilterFid( mFeatureNumber ) ).nextFeature( pointFeature ) )
107104
{
108105
return;
109106
}
110107

111-
if ( mCurrentRotationAttributes.size() < 1 )
112-
{
113-
emit messageEmitted( tr( "The active point layer does not have a rotation attribute." ), QgsMessageBar::CRITICAL );
108+
//check whether selected feature has a rotatable symbol
109+
QgsFeatureRendererV2* renderer = mActiveLayer->rendererV2();
110+
if ( !renderer )
114111
return;
115-
}
112+
QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() );
113+
renderer->startRender( context, mActiveLayer->fields() );
116114

117-
mSnappedPoint = toCanvasCoordinates( m.point() );
115+
//find all rotation fields used by renderer for feature
116+
QgsMarkerSymbolV2* markerSymbol = 0;
117+
if ( renderer->capabilities() & QgsFeatureRendererV2::MoreSymbolsPerFeature )
118+
{
119+
//could be multiple symbols for this feature, so check them all
120+
foreach ( QgsSymbolV2* s, renderer->originalSymbolsForFeature( pointFeature ) )
121+
{
122+
if ( s && s->type() == QgsSymbolV2::Marker )
123+
{
124+
markerSymbol = static_cast< QgsMarkerSymbolV2* >( s );
125+
QString rotationField = ( markerSymbol->dataDefinedAngle().isActive() && !markerSymbol->dataDefinedAngle().useExpression() ) ?
126+
markerSymbol->dataDefinedAngle().field() : QString();
127+
if ( !rotationField.isEmpty() )
128+
{
129+
int fieldIndex = mActiveLayer->fields().indexFromName( rotationField );
130+
if ( !mCurrentRotationAttributes.contains( fieldIndex ) )
131+
mCurrentRotationAttributes << fieldIndex;
132+
}
133+
}
134+
}
135+
}
136+
else
137+
{
138+
QgsSymbolV2* s = renderer->originalSymbolForFeature( pointFeature );
139+
if ( s && s->type() == QgsSymbolV2::Marker )
140+
{
141+
markerSymbol = static_cast< QgsMarkerSymbolV2* >( s );
142+
QString rotationField = ( markerSymbol->dataDefinedAngle().isActive() && !markerSymbol->dataDefinedAngle().useExpression() ) ?
143+
markerSymbol->dataDefinedAngle().field() : QString();
144+
if ( !rotationField.isEmpty() )
145+
mCurrentRotationAttributes << mActiveLayer->fields().indexFromName( rotationField );
146+
}
147+
}
118148

119-
//find out initial arrow direction
120-
QgsFeature pointFeature;
121-
if ( !mActiveLayer->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setFilterFid( mFeatureNumber ) ).nextFeature( pointFeature ) )
149+
if ( mCurrentRotationAttributes.isEmpty() )
122150
{
151+
emit messageEmitted( tr( "The selected point does not have a rotation attribute." ), QgsMessageBar::CRITICAL );
123152
return;
124153
}
154+
155+
//find out initial arrow direction
125156
QVariant attrVal = pointFeature.attribute( mCurrentRotationAttributes.at( 0 ) );
126157
if ( !attrVal.isValid() )
127158
{
128159
return;
129160
}
130161

131162
mCurrentRotationFeature = attrVal.toDouble();
132-
createPixmapItem( pointFeature );
163+
createPixmapItem( markerSymbol );
133164
if ( mRotationItem )
134165
{
135166
mRotationItem->setPointLocation( m.point() );
@@ -228,69 +259,30 @@ void QgsMapToolRotatePointSymbols::canvasReleaseEvent( QMouseEvent *e )
228259
mCanvas->refresh();
229260
}
230261

231-
int QgsMapToolRotatePointSymbols::layerRotationAttributes( QgsVectorLayer* vl, QList<int>& attList )
232-
{
233-
attList.clear();
234-
if ( !vl )
235-
{
236-
return 1;
237-
}
238-
239-
//new symbology
240-
const QgsFeatureRendererV2* symbologyNgRenderer = vl->rendererV2();
241-
if ( symbologyNgRenderer )
242-
{
243-
//TODO - replace this method with code which handles data defined rotation on the symbol level
244-
Q_NOWARN_DEPRECATED_PUSH
245-
QString rotationFieldName = symbologyNgRenderer->rotationField();
246-
Q_NOWARN_DEPRECATED_POP
247-
248-
if ( !rotationFieldName.isEmpty() )
249-
{
250-
attList.push_back( vl->fieldNameIndex( rotationFieldName ) );
251-
}
252-
return 0;
253-
}
254-
255-
//no renderer
256-
return 2;
257-
}
258-
259-
260-
261262
double QgsMapToolRotatePointSymbols::calculateAzimut( const QPoint& mousePos )
262263
{
263264
int dx = mousePos.x() - mSnappedPoint.x();
264265
int dy = mousePos.y() - mSnappedPoint.y();
265266
return 180 - atan2(( double ) dx, ( double ) dy ) * 180.0 / M_PI;
266267
}
267268

268-
void QgsMapToolRotatePointSymbols::createPixmapItem( QgsFeature& f )
269+
void QgsMapToolRotatePointSymbols::createPixmapItem( QgsMarkerSymbolV2* markerSymbol )
269270
{
270271
if ( !mCanvas )
271272
{
272273
return;
273274
}
274275

275-
QgsRenderContext renderContext( QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ) );
276-
277276
//get the image that is used for that symbol, but without point rotation
278277
QImage pointImage;
279278

280-
if ( mActiveLayer && mActiveLayer->rendererV2() ) //symbology-ng
279+
if ( markerSymbol )
281280
{
282-
QgsFeatureRendererV2* rv2 = mActiveLayer->rendererV2()->clone();
283-
rv2->startRender( renderContext, mActiveLayer->fields() );
284-
285-
QgsSymbolV2* symbolV2 = rv2->symbolForFeature( f );
286-
if ( symbolV2 && symbolV2->type() == QgsSymbolV2::Marker )
287-
{
288-
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( symbolV2 );
289-
markerSymbol->setDataDefinedAngle( QgsDataDefined() );
290-
pointImage = markerSymbol->bigSymbolPreviewImage();
291-
}
292-
rv2->stopRender( renderContext );
293-
delete rv2;
281+
QgsSymbolV2* clone = markerSymbol->clone();
282+
QgsMarkerSymbolV2* markerClone = static_cast<QgsMarkerSymbolV2*>( clone );
283+
markerClone->setDataDefinedAngle( QgsDataDefined() );
284+
pointImage = markerClone->bigSymbolPreviewImage();
285+
delete clone;
294286
}
295287

296288
mRotationItem = new QgsPointRotationItem( mCanvas );

src/app/qgsmaptoolrotatepointsymbols.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "qgsfeature.h"
2121

2222
class QgsPointRotationItem;
23+
class QgsMarkerSymbolV2;
2324

2425
/** A class that allows interactive manipulation the value of the rotation field(s) for point layers*/
2526
class APP_EXPORT QgsMapToolRotatePointSymbols: public QgsMapToolEdit
@@ -56,16 +57,11 @@ class APP_EXPORT QgsMapToolRotatePointSymbols: public QgsMapToolEdit
5657
/** True if ctrl was pressed during the last mouse move event*/
5758
bool mCtrlPressed;
5859

59-
/** Finds out the rotation attributes of mActiveLayers
60-
@param vl the point vector layer
61-
@param attList out: the list containing the rotation indices
62-
@return 0 in case of success*/
63-
static int layerRotationAttributes( QgsVectorLayer* vl, QList<int>& attList );
6460
void drawArrow( double azimut ) const;
6561
/** Calculates the azimut between mousePos and mSnappedPoint*/
6662
double calculateAzimut( const QPoint& mousePos );
6763
/** Create item with the point symbol for a specific feature. This will be used to show the rotation to the user*/
68-
void createPixmapItem( QgsFeature& f );
64+
void createPixmapItem( QgsMarkerSymbolV2 *markerSymbol );
6965
/** Sets the rotation of the pixmap item*/
7066
void setPixmapItemRotation( double rotation );
7167
/** Rounds value to 15 degree integer (used if ctrl pressed)*/

0 commit comments

Comments
 (0)