Skip to content

Commit

Permalink
Show point symbol in rotation preview and a little arrow. Also fixed …
Browse files Browse the repository at this point in the history
…a bug in QgsSingleSymbolRenderer::clone

git-svn-id: http://svn.osgeo.org/qgis/trunk@11700 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Sep 22, 2009
1 parent 209488e commit 071ac3b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 28 deletions.
74 changes: 55 additions & 19 deletions src/app/qgsmaptoolrotatepointsymbols.cpp
Expand Up @@ -26,7 +26,7 @@

QgsMapToolRotatePointSymbols::QgsMapToolRotatePointSymbols( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), \
mActiveLayer( 0 ), mFeatureNumber( 0 ), mCurrentMouseAzimut( 0.0 ), mCurrentRotationFeature( 0.0 ), \
mRotating( false ), mRotationItem( 0 ), mCtrlPressed(false)
mRotating( false ), mRotationItem( 0 ), mCtrlPressed( false )
{

}
Expand Down Expand Up @@ -123,13 +123,13 @@ void QgsMapToolRotatePointSymbols::canvasPressEvent( QMouseEvent * e )
}

mCurrentRotationFeature = attIt.value().toDouble();
createPixmapItem();
createPixmapItem( pointFeature );
if ( mRotationItem )
{
mRotationItem->setPointLocation( snapResults.at( 0 ).snappedVertex );
}
mCurrentMouseAzimut = calculateAzimut( e->pos() );
setPixmapItemRotation( (int)(mCurrentMouseAzimut) );
setPixmapItemRotation(( int )( mCurrentMouseAzimut ) );
mRotating = true;
}

Expand Down Expand Up @@ -165,17 +165,17 @@ void QgsMapToolRotatePointSymbols::canvasMoveEvent( QMouseEvent * e )

//if shift-modifier is pressed, round to 15 degrees
int displayValue;
if(e->modifiers() & Qt::ControlModifier)
if ( e->modifiers() & Qt::ControlModifier )
{
displayValue = roundTo15Degrees(mCurrentRotationFeature);
displayValue = roundTo15Degrees( mCurrentRotationFeature );
mCtrlPressed = true;
}
else
{
displayValue = (int)(mCurrentRotationFeature);
displayValue = ( int )( mCurrentRotationFeature );
mCtrlPressed = false;
}
setPixmapItemRotation(displayValue);
setPixmapItemRotation( displayValue );
}

void QgsMapToolRotatePointSymbols::canvasReleaseEvent( QMouseEvent * e )
Expand All @@ -187,13 +187,13 @@ void QgsMapToolRotatePointSymbols::canvasReleaseEvent( QMouseEvent * e )

//write mCurrentRotationFeature to all rotation attributes of feature (mFeatureNumber)
int rotation;
if(mCtrlPressed) //round to 15 degrees
if ( mCtrlPressed ) //round to 15 degrees
{
rotation = roundTo15Degrees(mCurrentRotationFeature);
rotation = roundTo15Degrees( mCurrentRotationFeature );
}
else
{
rotation = (int)mCurrentRotationFeature;
rotation = ( int )mCurrentRotationFeature;
}

QList<int>::const_iterator it = mCurrentRotationAttributes.constBegin();
Expand Down Expand Up @@ -255,15 +255,51 @@ double QgsMapToolRotatePointSymbols::calculateAzimut( const QPoint& mousePos )
{
int dx = mousePos.x() - mSnappedPoint.x();
int dy = mousePos.y() - mSnappedPoint.y();
return 180 - atan2( (double) dx, (double) dy ) * 180.0 / M_PI;
return 180 - atan2(( double ) dx, ( double ) dy ) * 180.0 / M_PI;
}

void QgsMapToolRotatePointSymbols::createPixmapItem()
void QgsMapToolRotatePointSymbols::createPixmapItem( QgsFeature& f )
{
delete mRotationItem;
mRotationItem = new QgsPointRotationItem( mCanvas );
mRotationItem->setSymbol( QgsApplication::defaultThemePath() + "mActionArrowUp.png" );
mCanvas->scene()->addItem( mRotationItem );
if ( !mCanvas )
{
return;
}

if ( mActiveLayer && mActiveLayer->renderer() )
{
//get the image that is used for that symbol, but without point rotation
QImage pointImage;
//copy renderer
QgsRenderer* r = mActiveLayer->renderer()->clone();

//set all symbol fields of the cloned renderer to -1. Very ugly but necessary
QList<QgsSymbol*> symbolList( r->symbols() );
QList<QgsSymbol*>::iterator it = symbolList.begin();
for ( ; it != symbolList.end(); ++it )
{
( *it )->setRotationClassificationField( -1 );
}


//get reference to current render context
QgsMapRenderer* mapRenderer = mCanvas->mapRenderer();
if ( !mapRenderer )
{
delete r;
return;
}
QgsRenderContext* renderContext = mCanvas->mapRenderer()->rendererContext(); //todo: check if pointers are not 0
if ( !renderContext )
{
delete r;
return;
}

r->renderFeature( *renderContext, f, &pointImage, false );
mRotationItem = new QgsPointRotationItem( mCanvas );
mRotationItem->setSymbol( pointImage );
delete r;
}
}

void QgsMapToolRotatePointSymbols::setPixmapItemRotation( double rotation )
Expand All @@ -272,9 +308,9 @@ void QgsMapToolRotatePointSymbols::setPixmapItemRotation( double rotation )
mRotationItem->update();
}

int QgsMapToolRotatePointSymbols::roundTo15Degrees(double n)
int QgsMapToolRotatePointSymbols::roundTo15Degrees( double n )
{
int m = (int)(n / 15.0 + 0.5);
return (m * 15);
int m = ( int )( n / 15.0 + 0.5 );
return ( m * 15 );
}

7 changes: 4 additions & 3 deletions src/app/qgsmaptoolrotatepointsymbols.h
Expand Up @@ -17,6 +17,7 @@
#define QGSMAPTOOLROTATEPOINTSYMBOLS_H

#include "qgsmaptooledit.h"
#include "qgsfeature.h"

class QgsPointRotationItem;

Expand Down Expand Up @@ -61,12 +62,12 @@ class QgsMapToolRotatePointSymbols: public QgsMapToolEdit
void drawArrow( double azimut ) const;
/**Calculates the azimut between mousePos and mSnappedPoint*/
double calculateAzimut( const QPoint& mousePos );
/**Create item that shows rotation to the user*/
void createPixmapItem();
/**Create item with the point symbol for a specific feature. This will be used to show the rotation to the user*/
void createPixmapItem( QgsFeature& f );
/**Sets the rotation of the pixmap item*/
void setPixmapItemRotation( double rotation );
/**Rounds value to 15 degree integer (used if ctrl pressed)*/
static int roundTo15Degrees(double n);
static int roundTo15Degrees( double n );
};

#endif // QGSMAPTOOLROTATEPOINTSYMBOLS_H
22 changes: 18 additions & 4 deletions src/app/qgspointrotationitem.cpp
Expand Up @@ -53,7 +53,7 @@ void QgsPointRotationItem::paint( QPainter * painter )
double h, dAngel;
if ( mPixmap.width() > 0 && mPixmap.height() > 0 )
{
h = sqrt( (double) mPixmap.width() * mPixmap.width() + mPixmap.height() * mPixmap.height() ) / 2; //the half of the item diagonal
h = sqrt(( double ) mPixmap.width() * mPixmap.width() + mPixmap.height() * mPixmap.height() ) / 2; //the half of the item diagonal
dAngel = acos( mPixmap.width() / ( h * 2 ) ) * 180 / M_PI; //the diagonal angel of the original rect
x = h * cos(( mRotation - dAngel ) * M_PI / 180 );
y = h * sin(( mRotation - dAngel ) * M_PI / 180 );
Expand All @@ -69,7 +69,7 @@ void QgsPointRotationItem::paint( QPainter * painter )
QFontMetricsF fm( mFont );
painter->fillRect( mPixmap.width(), 0, mItemSize.width() - mPixmap.width(), mItemSize.height(), QColor( Qt::white ) );
painter->setFont( mFont );
painter->drawText( mPixmap.width(), mPixmap.height() / 2.0 + fm.height() / 2.0, QString::number( mRotation) );
painter->drawText( mPixmap.width(), mPixmap.height() / 2.0 + fm.height() / 2.0, QString::number( mRotation ) );
}

void QgsPointRotationItem::setPointLocation( const QgsPoint& p )
Expand All @@ -78,10 +78,24 @@ void QgsPointRotationItem::setPointLocation( const QgsPoint& p )
setPos( transformedPoint.x() - mPixmap.width() / 2.0, transformedPoint.y() - mPixmap.height() / 2.0 );
}

void QgsPointRotationItem::setSymbol( const QString& symbolPath )
void QgsPointRotationItem::setSymbol( const QImage& symbolImage )
{
mPixmap = QPixmap( symbolPath );
mPixmap = QPixmap::fromImage( symbolImage );
QFontMetricsF fm( mFont );

//draw arrow
QPainter p( &mPixmap );
QPen pen;
pen.setWidth( 1 );
pen.setColor( QColor( Qt::red ) );
p.setPen( pen );
int halfItemWidth = mPixmap.width() / 2;
int quarterItemHeight = mPixmap.height() / 4;
p.drawLine( halfItemWidth, mPixmap.height(), halfItemWidth, 0 );
p.drawLine( halfItemWidth, 0, mPixmap.width() / 4, quarterItemHeight );
p.drawLine( halfItemWidth, 0, mPixmap.width() * 0.75, quarterItemHeight );

//set item size
mItemSize.setWidth( mPixmap.width() + fm.width( "360" ) );
double pixmapHeight = mPixmap.height();
double fontHeight = fm.height();
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgspointrotationitem.h
Expand Up @@ -36,8 +36,8 @@ class QgsPointRotationItem: public QgsMapCanvasItem
Units are degrees, starting from north direction, clockwise direction*/
void setSymbolRotation( int r ) {mRotation = r;}

/**Sets a symbol from image file*/
void setSymbol( const QString& symbolPath );
/**Sets rotation symbol from image (takes ownership)*/
void setSymbol( const QImage& symbolImage );

private:
QgsPointRotationItem();
Expand Down
9 changes: 9 additions & 0 deletions src/core/renderer/qgssinglesymbolrenderer.cpp
Expand Up @@ -72,6 +72,15 @@ QgsSingleSymbolRenderer& QgsSingleSymbolRenderer::operator=( const QgsSingleSymb

for ( QMap<QString, QgsSymbol *>::const_iterator it = other.mSymbols.begin(); it != other.mSymbols.end(); it++ )
mSymbols[ it.key()] = new QgsSymbol( *it.value() );

if ( mSymbols.size() > 0 )
{
mSymbol0 = mSymbols[0];
}
else
{
mSymbol0 = 0;
}
}
updateSymbolAttributes();
return *this;
Expand Down

0 comments on commit 071ac3b

Please sign in to comment.