void QgsMapToolRotatePointSymbols::canvasPressOnFeature( QgsMapMouseEvent *e, const QgsFeature &feature, const QgsPointXY &snappedPoint )
{
  //find out initial arrow direction
  QVariant attrVal = feature.attribute( mCurrentRotationAttributes.toList().at( 0 ) );

  mCurrentRotationFeature = attrVal.toDouble();
  createPixmapItem( mMarkerSymbol.get() );
  if ( mRotationItem )
  {
    mRotationItem->setPointLocation( snappedPoint );
  }
  mCurrentMouseAzimut = calculateAzimut( e->pos() );
  setPixmapItemRotation( ( int )( mCurrentMouseAzimut ) );
  mRotating = true;
}
void QgsMapToolRotatePointSymbols::canvasMoveEvent( QgsMapMouseEvent* e )
{
  if ( !mRotating )
  {
    return;
  }

  double azimut = calculateAzimut( e->pos() );
  double azimutDiff = azimut - mCurrentMouseAzimut;

  //assign new feature rotation, making sure to respect the 0 - 360 degree range
  mCurrentRotationFeature += azimutDiff;
  if ( mCurrentRotationFeature < 0 )
  {
    mCurrentRotationFeature = 360 - mCurrentRotationFeature;
  }
  else if ( mCurrentRotationFeature >= 360 )
  {
    mCurrentRotationFeature -= 360;
  }
  mCurrentMouseAzimut = azimut;
  if ( mCurrentMouseAzimut < 0 )
  {
    mCurrentMouseAzimut = 360 - mCurrentMouseAzimut;
  }
  else if ( mCurrentMouseAzimut >= 360 )
  {
    mCurrentMouseAzimut -= 360;
  }

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

  mActiveLayer = currentVectorLayer();
  if ( !mActiveLayer )
  {
    notifyNotVectorLayer();
    return;
  }

  if ( !mActiveLayer->isEditable() )
  {
    notifyNotEditableLayer();
    return;
  }

  if ( mActiveLayer->geometryType() != QGis::Point )
  {
    return;
  }

  //find the closest feature to the pressed position
  QgsMapCanvasSnapper canvasSnapper( mCanvas );
  QList<QgsSnappingResult> snapResults;
  if ( canvasSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, -1 ) != 0 || snapResults.size() < 1 )
  {
    QMessageBox::critical( 0, tr( "No point feature" ), tr( "No point feature was detected at the clicked position. Please click closer to the feature or enhance the search tolerance under Settings->Options->Digitizing->Serch radius for vertex edits" ) );
    return; //error during snapping
  }

  mFeatureNumber = snapResults.at( 0 ).snappedAtGeometry;

  //get list with renderer rotation attributes
  if ( layerRotationAttributes( mActiveLayer, mCurrentRotationAttributes ) != 0 )
  {
    return;
  }

  if ( mCurrentRotationAttributes.size() < 1 )
  {
    QMessageBox::critical( 0, tr( "No rotation Attributes" ), tr( "The active point layer does not have a rotation attribute" ) );
    return;
  }

  mSnappedPoint = toCanvasCoordinates( snapResults.at( 0 ).snappedVertex );

  //find out initial arrow direction
  QgsFeature pointFeature;
  if ( !mActiveLayer->featureAtId( mFeatureNumber, pointFeature, false, true ) )
  {
    return;
  }
  const QgsAttributeMap pointFeatureAttributes = pointFeature.attributeMap();
  const QgsAttributeMap::const_iterator attIt = pointFeatureAttributes.find( mCurrentRotationAttributes.at( 0 ) );
  if ( attIt == pointFeatureAttributes.constEnd() )
  {
    return;
  }

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