[QGIS Commit] r14877 - trunk/qgis/src/app

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Dec 9 11:07:27 EST 2010


Author: mhugent
Date: 2010-12-09 08:07:27 -0800 (Thu, 09 Dec 2010)
New Revision: 14877

Modified:
   trunk/qgis/src/app/qgsmaptoollabel.cpp
   trunk/qgis/src/app/qgsmaptoollabel.h
   trunk/qgis/src/app/qgsmaptoolmovelabel.cpp
   trunk/qgis/src/app/qgsmaptoolmovelabel.h
   trunk/qgis/src/app/qgsmaptoolrotatelabel.cpp
   trunk/qgis/src/app/qgsmaptoolrotatelabel.h
Log:
Little improvement for label preview (box), better handling of situations where rotation is not possible

Modified: trunk/qgis/src/app/qgsmaptoollabel.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoollabel.cpp	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoollabel.cpp	2010-12-09 16:07:27 UTC (rev 14877)
@@ -345,3 +345,66 @@
   }
   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;
+}

Modified: trunk/qgis/src/app/qgsmaptoollabel.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoollabel.h	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoollabel.h	2010-12-09 16:07:27 UTC (rev 14877)
@@ -31,6 +31,12 @@
     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;
@@ -73,6 +79,17 @@
     /**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;
 };

Modified: trunk/qgis/src/app/qgsmaptoolmovelabel.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolmovelabel.cpp	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoolmovelabel.cpp	2010-12-09 16:07:27 UTC (rev 14877)
@@ -116,8 +116,6 @@
   {
     xPosNew = releaseCoords.x() - mClickOffsetX;
     yPosNew = releaseCoords.y() - mClickOffsetY;
-
-    //todo: consider hali/vali if there
   }
   else
   {
@@ -133,68 +131,5 @@
   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;
-}
-
-
-

Modified: trunk/qgis/src/app/qgsmaptoolmovelabel.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolmovelabel.h	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoolmovelabel.h	2010-12-09 16:07:27 UTC (rev 14877)
@@ -35,23 +35,7 @@
 
     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;

Modified: trunk/qgis/src/app/qgsmaptoolrotatelabel.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolrotatelabel.cpp	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoolrotatelabel.cpp	2010-12-09 16:07:27 UTC (rev 14877)
@@ -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 )
@@ -68,8 +69,11 @@
       {
         mCurrentRotation = 0;
       }
+      mStartRotation = mCurrentRotation;
       createRubberBands();
 
+      mRotationPreviewBox = createRotationPreviewBox();
+
       mRotationItem = new QgsPointRotationItem( mCanvas );
       mRotationItem->setOrientation( QgsPointRotationItem::Counterclockwise );
       mRotationItem->setSymbol( QgisApp::instance()->getThemePixmap( "mActionRotatePointSymbols.png" ).toImage() );
@@ -110,6 +114,7 @@
     if ( mRotationItem )
     {
       mRotationItem->setSymbolRotation( displayValue );
+      setRotationPreviewBox( displayValue - mStartRotation );
       mRotationItem->update();
     }
   }
@@ -117,9 +122,16 @@
 
 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 )
@@ -140,6 +152,10 @@
   }
 
   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 );
@@ -191,6 +207,16 @@
   }
 
   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;
 }
@@ -205,3 +231,53 @@
 {
   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 );
+}

Modified: trunk/qgis/src/app/qgsmaptoolrotatelabel.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolrotatelabel.h	2010-12-09 15:31:53 UTC (rev 14876)
+++ trunk/qgis/src/app/qgsmaptoolrotatelabel.h	2010-12-09 16:07:27 UTC (rev 14877)
@@ -49,11 +49,18 @@
     /**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;



More information about the QGIS-commit mailing list