Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Little improvement for label preview (box), better handling of situat…
…ions where rotation is not possible

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14877 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Dec 9, 2010
1 parent 643608c commit 9ef391f
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 82 deletions.
63 changes: 63 additions & 0 deletions src/app/qgsmaptoollabel.cpp
Expand Up @@ -345,3 +345,66 @@ bool QgsMapToolLabel::rotationPoint( QgsPoint& pos )
}
return true;
}

bool QgsMapToolLabel::dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const
{
xSuccess = false;
ySuccess = false;

if ( !vlayer )
{
return false;
}

if ( !layerIsMoveable( vlayer, xCol, yCol ) )
{
return false;
}

QgsFeature f;
if ( !vlayer->featureAtId( featureId, f, false, true ) )
{
return false;
}

QgsAttributeMap attributes = f.attributeMap();
x = attributes[xCol].toDouble( &xSuccess );
y = attributes[yCol].toDouble( &ySuccess );

return true;
}

bool QgsMapToolLabel::layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
{
const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
if ( !vlayer || !vlayer->isEditable() )
{
return false;
}

bool xColOk, yColOk;

QVariant xColumn = ml->customProperty( "labeling/dataDefinedProperty9" );
if ( !xColumn.isValid() )
{
return false;
}
xCol = xColumn.toInt( &xColOk );
if ( !xColOk )
{
return false;
}

QVariant yColumn = ml->customProperty( "labeling/dataDefinedProperty10" );
if ( !yColumn.isValid() )
{
return false;
}
yCol = yColumn.toInt( &yColOk );
if ( !yColOk )
{
return false;
}

return true;
}
17 changes: 17 additions & 0 deletions src/app/qgsmaptoollabel.h
Expand Up @@ -31,6 +31,12 @@ class QgsMapToolLabel: public QgsMapTool
QgsMapToolLabel( QgsMapCanvas* canvas );
~QgsMapToolLabel();

/**Returns true if layer move can be applied to a layer
@param xCol out: index of the attribute for data defined x coordinate
@param yCol out: index of the attribute for data defined y coordinate
@return true if labels of layer can be moved*/
bool layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;

protected:
QgsRubberBand* mLabelRubberBand;
QgsRubberBand* mFeatureRubberBand;
Expand Down Expand Up @@ -73,6 +79,17 @@ class QgsMapToolLabel: public QgsMapTool
/**Returns the font for the current feature (considering default font and data defined properties*/
QFont labelFontCurrentFeature();

/**Get data defined position of a feature
@param layerId layer identification string
@param x out: data defined x-coordinate
@param xSuccess out: false if attribute value is NULL
@param y out: data defined y-coordinate
@param ySuccess out: false if attribute value is NULL
@param xCol out: index of the x position column
@param yCol out: index of the y position column
@return false if layer does not have data defined label position enabled*/
bool dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const;

private:
QgsPalLayerSettings mInvalidLabelSettings;
};
Expand Down
65 changes: 0 additions & 65 deletions src/app/qgsmaptoolmovelabel.cpp
Expand Up @@ -116,8 +116,6 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QMouseEvent * e )
{
xPosNew = releaseCoords.x() - mClickOffsetX;
yPosNew = releaseCoords.y() - mClickOffsetY;

//todo: consider hali/vali if there
}
else
{
Expand All @@ -133,68 +131,5 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QMouseEvent * e )
mCanvas->refresh();
}

bool QgsMapToolMoveLabel::dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const
{
xSuccess = false;
ySuccess = false;

if ( !vlayer )
{
return false;
}

if ( !layerIsMoveable( vlayer, xCol, yCol ) )
{
return false;
}

QgsFeature f;
if ( !vlayer->featureAtId( featureId, f, false, true ) )
{
return false;
}

QgsAttributeMap attributes = f.attributeMap();
x = attributes[xCol].toDouble( &xSuccess );
y = attributes[yCol].toDouble( &ySuccess );

return true;
}

bool QgsMapToolMoveLabel::layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
{
const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
if ( !vlayer || !vlayer->isEditable() )
{
return false;
}

bool xColOk, yColOk;

QVariant xColumn = ml->customProperty( "labeling/dataDefinedProperty9" );
if ( !xColumn.isValid() )
{
return false;
}
xCol = xColumn.toInt( &xColOk );
if ( !xColOk )
{
return false;
}

QVariant yColumn = ml->customProperty( "labeling/dataDefinedProperty10" );
if ( !yColumn.isValid() )
{
return false;
}
yCol = yColumn.toInt( &yColOk );
if ( !yColOk )
{
return false;
}

return true;
}



16 changes: 0 additions & 16 deletions src/app/qgsmaptoolmovelabel.h
Expand Up @@ -35,23 +35,7 @@ class QgsMapToolMoveLabel: public QgsMapToolLabel

virtual void canvasReleaseEvent( QMouseEvent * e );

/**Returns true if layer move can be applied to a layer
@param xCol out: index of the attribute for data defined x coordinate
@param yCol out: index of the attribute for data defined y coordinate
@return true if labels of layer can be moved*/
bool layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;

protected:
/**Get data defined position of a feature
@param layerId layer identification string
@param x out: data defined x-coordinate
@param xSuccess out: false if attribute value is NULL
@param y out: data defined y-coordinate
@param ySuccess out: false if attribute value is NULL
@param xCol out: index of the x position column
@param yCol out: index of the y position column
@return false if layer does not have data defined label position enabled*/
bool dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const;

/**Start point of the move in map coordinates*/
QgsPoint mStartPointMapCoords;
Expand Down
78 changes: 77 additions & 1 deletion src/app/qgsmaptoolrotatelabel.cpp
Expand Up @@ -26,13 +26,14 @@

#include "qgisapp.h"

QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas* canvas ): QgsMapToolLabel( canvas ), mRotationItem( 0 )
QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas* canvas ): QgsMapToolLabel( canvas ), mRotationItem( 0 ), mRotationPreviewBox( 0 )
{
}

QgsMapToolRotateLabel::~QgsMapToolRotateLabel()
{
delete mRotationItem;
delete mRotationPreviewBox;
}

void QgsMapToolRotateLabel::canvasPressEvent( QMouseEvent * e )
Expand Down Expand Up @@ -68,8 +69,11 @@ void QgsMapToolRotateLabel::canvasPressEvent( QMouseEvent * e )
{
mCurrentRotation = 0;
}
mStartRotation = mCurrentRotation;
createRubberBands();

mRotationPreviewBox = createRotationPreviewBox();

mRotationItem = new QgsPointRotationItem( mCanvas );
mRotationItem->setOrientation( QgsPointRotationItem::Counterclockwise );
mRotationItem->setSymbol( QgisApp::instance()->getThemePixmap( "mActionRotatePointSymbols.png" ).toImage() );
Expand Down Expand Up @@ -110,16 +114,24 @@ void QgsMapToolRotateLabel::canvasMoveEvent( QMouseEvent * e )
if ( mRotationItem )
{
mRotationItem->setSymbolRotation( displayValue );
setRotationPreviewBox( displayValue - mStartRotation );
mRotationItem->update();
}
}
}

void QgsMapToolRotateLabel::canvasReleaseEvent( QMouseEvent * e )
{
if ( !mLabelRubberBand ) //no rubber band created (most likely because the current label cannot be rotated )
{
return;
}

deleteRubberBands();
delete mRotationItem;
mRotationItem = 0;
delete mRotationPreviewBox;
mRotationPreviewBox = 0;

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

double rotation = mCtrlPressed ? roundTo15Degrees( mCurrentRotation ) : mCurrentRotation;
if ( rotation == mStartRotation ) //mouse button pressed / released, but no rotation
{
return;
}

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

QgsAttributeMap attributes = f.attributeMap();

//test, if data defined x- and y- values are not null. Otherwise, the position is determined by PAL and the rotation cannot be fixed
int xCol, yCol;
double x, y;
bool xSuccess, ySuccess;
if ( !dataDefinedPosition( vlayer, featureId, x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess )
{
return false;
}

rotation = attributes[rotationCol].toDouble( &rotationSuccess );
return true;
}
Expand All @@ -205,3 +231,53 @@ double QgsMapToolRotateLabel::azimuthToCCW( double a )
{
return ( a > 0 ? 360 - a : -a );
}

QgsRubberBand* QgsMapToolRotateLabel::createRotationPreviewBox()
{
delete mRotationPreviewBox;
QVector< QgsPoint > boxPoints = mCurrentLabelPos.cornerPoints;
if ( boxPoints.size() < 1 )
{
return 0;
}

mRotationPreviewBox = new QgsRubberBand( mCanvas, false );
mRotationPreviewBox->setColor( Qt::blue );
mRotationPreviewBox->setWidth( 3 );
setRotationPreviewBox( mCurrentRotation - mStartRotation );
return mRotationPreviewBox;
}

void QgsMapToolRotateLabel::setRotationPreviewBox( double rotation )
{
if ( !mRotationPreviewBox )
{
return;
}

mRotationPreviewBox->reset();
QVector< QgsPoint > boxPoints = mCurrentLabelPos.cornerPoints;
if ( boxPoints.size() < 1 )
{
return;
}

for ( int i = 0; i < boxPoints.size(); ++i )
{
mRotationPreviewBox->addPoint( rotatePointCounterClockwise( boxPoints.at( i ), mRotationPoint, rotation ) );
}
mRotationPreviewBox->addPoint( rotatePointCounterClockwise( boxPoints.at( 0 ), mRotationPoint, rotation ) );
mRotationPreviewBox->show();
}

QgsPoint QgsMapToolRotateLabel::rotatePointCounterClockwise( const QgsPoint& input, const QgsPoint& centerPoint, double degrees )
{
double rad = degrees / 180 * M_PI;
double v1x = input.x() - centerPoint.x();
double v1y = input.y() - centerPoint.y();

double v2x = cos( rad ) * v1x - sin( rad ) * v1y;
double v2y = sin( rad ) * v1x + cos( rad ) * v1y;

return QgsPoint( centerPoint.x() + v2x, centerPoint.y() + v2y );
}
7 changes: 7 additions & 0 deletions src/app/qgsmaptoolrotatelabel.h
Expand Up @@ -49,11 +49,18 @@ class QgsMapToolRotateLabel: public QgsMapToolLabel
/**Converts azimuth value to counterclockwise 0 - 360*/
static double azimuthToCCW( double a );

QgsRubberBand* createRotationPreviewBox();
void setRotationPreviewBox( double rotation );

/**Rotates input point counterclockwise around centerPoint*/
QgsPoint rotatePointCounterClockwise( const QgsPoint& input, const QgsPoint& centerPoint, double degrees );

double mStartRotation; //rotation value prior to start rotating
double mCurrentRotation;
double mCurrentMouseAzimuth;
QgsPoint mRotationPoint;
QgsPointRotationItem* mRotationItem;
QgsRubberBand* mRotationPreviewBox;

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

0 comments on commit 9ef391f

Please sign in to comment.