Skip to content

Commit a62efcd

Browse files
author
mhugent
committedDec 9, 2010
Little improvement for label preview (box), better handling of situations where rotation is not possible
git-svn-id: http://svn.osgeo.org/qgis/trunk@14877 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent ad407f5 commit a62efcd

File tree

6 files changed

+164
-82
lines changed

6 files changed

+164
-82
lines changed
 

‎src/app/qgsmaptoollabel.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,66 @@ bool QgsMapToolLabel::rotationPoint( QgsPoint& pos )
345345
}
346346
return true;
347347
}
348+
349+
bool QgsMapToolLabel::dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const
350+
{
351+
xSuccess = false;
352+
ySuccess = false;
353+
354+
if ( !vlayer )
355+
{
356+
return false;
357+
}
358+
359+
if ( !layerIsMoveable( vlayer, xCol, yCol ) )
360+
{
361+
return false;
362+
}
363+
364+
QgsFeature f;
365+
if ( !vlayer->featureAtId( featureId, f, false, true ) )
366+
{
367+
return false;
368+
}
369+
370+
QgsAttributeMap attributes = f.attributeMap();
371+
x = attributes[xCol].toDouble( &xSuccess );
372+
y = attributes[yCol].toDouble( &ySuccess );
373+
374+
return true;
375+
}
376+
377+
bool QgsMapToolLabel::layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
378+
{
379+
const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
380+
if ( !vlayer || !vlayer->isEditable() )
381+
{
382+
return false;
383+
}
384+
385+
bool xColOk, yColOk;
386+
387+
QVariant xColumn = ml->customProperty( "labeling/dataDefinedProperty9" );
388+
if ( !xColumn.isValid() )
389+
{
390+
return false;
391+
}
392+
xCol = xColumn.toInt( &xColOk );
393+
if ( !xColOk )
394+
{
395+
return false;
396+
}
397+
398+
QVariant yColumn = ml->customProperty( "labeling/dataDefinedProperty10" );
399+
if ( !yColumn.isValid() )
400+
{
401+
return false;
402+
}
403+
yCol = yColumn.toInt( &yColOk );
404+
if ( !yColOk )
405+
{
406+
return false;
407+
}
408+
409+
return true;
410+
}

‎src/app/qgsmaptoollabel.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ class QgsMapToolLabel: public QgsMapTool
3131
QgsMapToolLabel( QgsMapCanvas* canvas );
3232
~QgsMapToolLabel();
3333

34+
/**Returns true if layer move can be applied to a layer
35+
@param xCol out: index of the attribute for data defined x coordinate
36+
@param yCol out: index of the attribute for data defined y coordinate
37+
@return true if labels of layer can be moved*/
38+
bool layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;
39+
3440
protected:
3541
QgsRubberBand* mLabelRubberBand;
3642
QgsRubberBand* mFeatureRubberBand;
@@ -73,6 +79,17 @@ class QgsMapToolLabel: public QgsMapTool
7379
/**Returns the font for the current feature (considering default font and data defined properties*/
7480
QFont labelFontCurrentFeature();
7581

82+
/**Get data defined position of a feature
83+
@param layerId layer identification string
84+
@param x out: data defined x-coordinate
85+
@param xSuccess out: false if attribute value is NULL
86+
@param y out: data defined y-coordinate
87+
@param ySuccess out: false if attribute value is NULL
88+
@param xCol out: index of the x position column
89+
@param yCol out: index of the y position column
90+
@return false if layer does not have data defined label position enabled*/
91+
bool dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const;
92+
7693
private:
7794
QgsPalLayerSettings mInvalidLabelSettings;
7895
};

‎src/app/qgsmaptoolmovelabel.cpp

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QMouseEvent * e )
116116
{
117117
xPosNew = releaseCoords.x() - mClickOffsetX;
118118
yPosNew = releaseCoords.y() - mClickOffsetY;
119-
120-
//todo: consider hali/vali if there
121119
}
122120
else
123121
{
@@ -133,68 +131,5 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QMouseEvent * e )
133131
mCanvas->refresh();
134132
}
135133

136-
bool QgsMapToolMoveLabel::dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const
137-
{
138-
xSuccess = false;
139-
ySuccess = false;
140-
141-
if ( !vlayer )
142-
{
143-
return false;
144-
}
145-
146-
if ( !layerIsMoveable( vlayer, xCol, yCol ) )
147-
{
148-
return false;
149-
}
150-
151-
QgsFeature f;
152-
if ( !vlayer->featureAtId( featureId, f, false, true ) )
153-
{
154-
return false;
155-
}
156-
157-
QgsAttributeMap attributes = f.attributeMap();
158-
x = attributes[xCol].toDouble( &xSuccess );
159-
y = attributes[yCol].toDouble( &ySuccess );
160-
161-
return true;
162-
}
163-
164-
bool QgsMapToolMoveLabel::layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
165-
{
166-
const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
167-
if ( !vlayer || !vlayer->isEditable() )
168-
{
169-
return false;
170-
}
171-
172-
bool xColOk, yColOk;
173-
174-
QVariant xColumn = ml->customProperty( "labeling/dataDefinedProperty9" );
175-
if ( !xColumn.isValid() )
176-
{
177-
return false;
178-
}
179-
xCol = xColumn.toInt( &xColOk );
180-
if ( !xColOk )
181-
{
182-
return false;
183-
}
184-
185-
QVariant yColumn = ml->customProperty( "labeling/dataDefinedProperty10" );
186-
if ( !yColumn.isValid() )
187-
{
188-
return false;
189-
}
190-
yCol = yColumn.toInt( &yColOk );
191-
if ( !yColOk )
192-
{
193-
return false;
194-
}
195-
196-
return true;
197-
}
198-
199134

200135

‎src/app/qgsmaptoolmovelabel.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,7 @@ class QgsMapToolMoveLabel: public QgsMapToolLabel
3535

3636
virtual void canvasReleaseEvent( QMouseEvent * e );
3737

38-
/**Returns true if layer move can be applied to a layer
39-
@param xCol out: index of the attribute for data defined x coordinate
40-
@param yCol out: index of the attribute for data defined y coordinate
41-
@return true if labels of layer can be moved*/
42-
bool layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;
43-
4438
protected:
45-
/**Get data defined position of a feature
46-
@param layerId layer identification string
47-
@param x out: data defined x-coordinate
48-
@param xSuccess out: false if attribute value is NULL
49-
@param y out: data defined y-coordinate
50-
@param ySuccess out: false if attribute value is NULL
51-
@param xCol out: index of the x position column
52-
@param yCol out: index of the y position column
53-
@return false if layer does not have data defined label position enabled*/
54-
bool dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const;
5539

5640
/**Start point of the move in map coordinates*/
5741
QgsPoint mStartPointMapCoords;

‎src/app/qgsmaptoolrotatelabel.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@
2626

2727
#include "qgisapp.h"
2828

29-
QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas* canvas ): QgsMapToolLabel( canvas ), mRotationItem( 0 )
29+
QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas* canvas ): QgsMapToolLabel( canvas ), mRotationItem( 0 ), mRotationPreviewBox( 0 )
3030
{
3131
}
3232

3333
QgsMapToolRotateLabel::~QgsMapToolRotateLabel()
3434
{
3535
delete mRotationItem;
36+
delete mRotationPreviewBox;
3637
}
3738

3839
void QgsMapToolRotateLabel::canvasPressEvent( QMouseEvent * e )
@@ -68,8 +69,11 @@ void QgsMapToolRotateLabel::canvasPressEvent( QMouseEvent * e )
6869
{
6970
mCurrentRotation = 0;
7071
}
72+
mStartRotation = mCurrentRotation;
7173
createRubberBands();
7274

75+
mRotationPreviewBox = createRotationPreviewBox();
76+
7377
mRotationItem = new QgsPointRotationItem( mCanvas );
7478
mRotationItem->setOrientation( QgsPointRotationItem::Counterclockwise );
7579
mRotationItem->setSymbol( QgisApp::instance()->getThemePixmap( "mActionRotatePointSymbols.png" ).toImage() );
@@ -110,16 +114,24 @@ void QgsMapToolRotateLabel::canvasMoveEvent( QMouseEvent * e )
110114
if ( mRotationItem )
111115
{
112116
mRotationItem->setSymbolRotation( displayValue );
117+
setRotationPreviewBox( displayValue - mStartRotation );
113118
mRotationItem->update();
114119
}
115120
}
116121
}
117122

118123
void QgsMapToolRotateLabel::canvasReleaseEvent( QMouseEvent * e )
119124
{
125+
if ( !mLabelRubberBand ) //no rubber band created (most likely because the current label cannot be rotated )
126+
{
127+
return;
128+
}
129+
120130
deleteRubberBands();
121131
delete mRotationItem;
122132
mRotationItem = 0;
133+
delete mRotationPreviewBox;
134+
mRotationPreviewBox = 0;
123135

124136
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( mCurrentLabelPos.layerID );
125137
if ( !layer )
@@ -140,6 +152,10 @@ void QgsMapToolRotateLabel::canvasReleaseEvent( QMouseEvent * e )
140152
}
141153

142154
double rotation = mCtrlPressed ? roundTo15Degrees( mCurrentRotation ) : mCurrentRotation;
155+
if ( rotation == mStartRotation ) //mouse button pressed / released, but no rotation
156+
{
157+
return;
158+
}
143159

144160
vlayer->beginEditCommand( tr( "Label rotated" ) );
145161
vlayer->changeAttributeValue( mCurrentLabelPos.featureId, rotationCol, rotation, false );
@@ -191,6 +207,16 @@ bool QgsMapToolRotateLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int fea
191207
}
192208

193209
QgsAttributeMap attributes = f.attributeMap();
210+
211+
//test, if data defined x- and y- values are not null. Otherwise, the position is determined by PAL and the rotation cannot be fixed
212+
int xCol, yCol;
213+
double x, y;
214+
bool xSuccess, ySuccess;
215+
if ( !dataDefinedPosition( vlayer, featureId, x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess )
216+
{
217+
return false;
218+
}
219+
194220
rotation = attributes[rotationCol].toDouble( &rotationSuccess );
195221
return true;
196222
}
@@ -205,3 +231,53 @@ double QgsMapToolRotateLabel::azimuthToCCW( double a )
205231
{
206232
return ( a > 0 ? 360 - a : -a );
207233
}
234+
235+
QgsRubberBand* QgsMapToolRotateLabel::createRotationPreviewBox()
236+
{
237+
delete mRotationPreviewBox;
238+
QVector< QgsPoint > boxPoints = mCurrentLabelPos.cornerPoints;
239+
if ( boxPoints.size() < 1 )
240+
{
241+
return 0;
242+
}
243+
244+
mRotationPreviewBox = new QgsRubberBand( mCanvas, false );
245+
mRotationPreviewBox->setColor( Qt::blue );
246+
mRotationPreviewBox->setWidth( 3 );
247+
setRotationPreviewBox( mCurrentRotation - mStartRotation );
248+
return mRotationPreviewBox;
249+
}
250+
251+
void QgsMapToolRotateLabel::setRotationPreviewBox( double rotation )
252+
{
253+
if ( !mRotationPreviewBox )
254+
{
255+
return;
256+
}
257+
258+
mRotationPreviewBox->reset();
259+
QVector< QgsPoint > boxPoints = mCurrentLabelPos.cornerPoints;
260+
if ( boxPoints.size() < 1 )
261+
{
262+
return;
263+
}
264+
265+
for ( int i = 0; i < boxPoints.size(); ++i )
266+
{
267+
mRotationPreviewBox->addPoint( rotatePointCounterClockwise( boxPoints.at( i ), mRotationPoint, rotation ) );
268+
}
269+
mRotationPreviewBox->addPoint( rotatePointCounterClockwise( boxPoints.at( 0 ), mRotationPoint, rotation ) );
270+
mRotationPreviewBox->show();
271+
}
272+
273+
QgsPoint QgsMapToolRotateLabel::rotatePointCounterClockwise( const QgsPoint& input, const QgsPoint& centerPoint, double degrees )
274+
{
275+
double rad = degrees / 180 * M_PI;
276+
double v1x = input.x() - centerPoint.x();
277+
double v1y = input.y() - centerPoint.y();
278+
279+
double v2x = cos( rad ) * v1x - sin( rad ) * v1y;
280+
double v2y = sin( rad ) * v1x + cos( rad ) * v1y;
281+
282+
return QgsPoint( centerPoint.x() + v2x, centerPoint.y() + v2y );
283+
}

‎src/app/qgsmaptoolrotatelabel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,18 @@ class QgsMapToolRotateLabel: public QgsMapToolLabel
4949
/**Converts azimuth value to counterclockwise 0 - 360*/
5050
static double azimuthToCCW( double a );
5151

52+
QgsRubberBand* createRotationPreviewBox();
53+
void setRotationPreviewBox( double rotation );
5254

55+
/**Rotates input point counterclockwise around centerPoint*/
56+
QgsPoint rotatePointCounterClockwise( const QgsPoint& input, const QgsPoint& centerPoint, double degrees );
57+
58+
double mStartRotation; //rotation value prior to start rotating
5359
double mCurrentRotation;
5460
double mCurrentMouseAzimuth;
5561
QgsPoint mRotationPoint;
5662
QgsPointRotationItem* mRotationItem;
63+
QgsRubberBand* mRotationPreviewBox;
5764

5865
/**True if ctrl was pressed during the last mouse move event*/
5966
bool mCtrlPressed;

0 commit comments

Comments
 (0)
Please sign in to comment.