Esempio n. 1
0
bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, const QgsFeatureId &featureId, double& rotation, bool& rotationSuccess, bool ignoreXY ) const
{
  rotationSuccess = false;
  if ( !vlayer )
  {
    return false;
  }

  int rotationCol;
  if ( !layerIsRotatable( vlayer, rotationCol ) )
  {
    return false;
  }

  QgsFeature f;
  if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) )
  {
    return false;
  }

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

  rotation = f.attribute( rotationCol ).toDouble( &rotationSuccess );
  return true;
}
Esempio n. 2
0
bool QgsMapToolLabel::isPinned()
{
  bool rc = false;

  if ( ! mCurrentLabelPos.isDiagram )
  {
    rc = mCurrentLabelPos.isPinned;
  }
  else
  {
    // for diagrams, the isPinned attribute is not set. So we check directly if
    // there's data defined.
    int xCol, yCol;
    double x, y;
    bool xSuccess, ySuccess;

    if ( dataDefinedPosition( currentLayer(), mCurrentLabelPos.featureId, x,
                              xSuccess, y, ySuccess, xCol, yCol ) && xSuccess && ySuccess )
      rc = true;
  }

  return rc;
}
Esempio n. 3
0
bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess, bool ignoreXY )
{
    rotationSuccess = false;
    if ( !vlayer )
    {
        return false;
    }

    int rotationCol;
    if ( !layerIsRotatable( vlayer, rotationCol ) )
    {
        return false;
    }

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

    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
    if ( !ignoreXY )
    {
        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;
}
Esempio n. 4
0
void QgsMapToolMoveLabel::canvasReleaseEvent( QgsMapMouseEvent* e )
{
  if ( !mLabelRubberBand )
  {
    return;
  }

  deleteRubberBands();

  QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( mCurrentLabelPos.layerID );
  if ( !layer )
  {
    return;
  }

  QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
  if ( !vlayer )
  {
    return;
  }

  if ( !vlayer->isEditable() )
  {
    return;
  }

  QgsPoint releaseCoords = toMapCoordinates( e->pos() );
  double xdiff = releaseCoords.x() - mStartPointMapCoords.x();
  double ydiff = releaseCoords.y() - mStartPointMapCoords.y();

  int xCol, yCol;
  double xPosOrig, yPosOrig;
  bool xSuccess, ySuccess;

  if ( !dataDefinedPosition( vlayer, mCurrentLabelPos.featureId, xPosOrig, xSuccess, yPosOrig, ySuccess, xCol, yCol ) )
  {
    return;
  }

  double xPosNew, yPosNew;

  if ( !xSuccess || !ySuccess )
  {
    xPosNew = releaseCoords.x() - mClickOffsetX;
    yPosNew = releaseCoords.y() - mClickOffsetY;
  }
  else
  {
    //transform to map crs first, because xdiff,ydiff are in map coordinates
    const QgsMapSettings& ms = mCanvas->mapSettings();
    if ( ms.hasCrsTransformEnabled() )
    {
      QgsPoint transformedPoint = ms.layerToMapCoordinates( vlayer, QgsPoint( xPosOrig, yPosOrig ) );
      xPosOrig = transformedPoint.x();
      yPosOrig = transformedPoint.y();
    }
    xPosNew = xPosOrig + xdiff;
    yPosNew = yPosOrig + ydiff;
  }

  //transform back to layer crs
  if ( mCanvas )
  {
    const QgsMapSettings& s = mCanvas->mapSettings();
    if ( s.hasCrsTransformEnabled() )
    {
      QgsPoint transformedPoint = s.mapToLayerCoordinates( vlayer, QgsPoint( xPosNew, yPosNew ) );
      xPosNew = transformedPoint.x();
      yPosNew = transformedPoint.y();
    }
  }

  vlayer->beginEditCommand( tr( "Moved label" ) + QString( " '%1'" ).arg( currentLabelText( 24 ) ) );
  vlayer->changeAttributeValue( mCurrentLabelPos.featureId, xCol, xPosNew );
  vlayer->changeAttributeValue( mCurrentLabelPos.featureId, yCol, yPosNew );

  // set rotation to that of label, if data-defined and no rotation set yet
  // honor whether to preserve preexisting data on pin
  // must come after setting x and y positions
  int rCol;
  if ( !mCurrentLabelPos.isDiagram
       && !mCurrentLabelPos.isPinned
       && !preserveRotation()
       && layerIsRotatable( vlayer, rCol ) )
  {
    double defRot;
    bool rSuccess;
    if ( dataDefinedRotation( vlayer, mCurrentLabelPos.featureId, defRot, rSuccess ) )
    {
      double labelRot = mCurrentLabelPos.rotation * 180 / M_PI;
      vlayer->changeAttributeValue( mCurrentLabelPos.featureId, rCol, labelRot );
    }
  }
  vlayer->endEditCommand();

  if ( mCanvas )
    mCanvas->refresh();
}
Esempio n. 5
0
bool QgsMapToolPinLabels::pinUnpinLabel( QgsVectorLayer* vlayer,
    const QgsLabelPosition& labelpos,
    bool pin )
{
  // skip diagrams
  if ( labelpos.isDiagram )
  {
    QgsDebugMsg( QString( "Label is diagram, skipping" ) );
    return false;
  }

  // verify attribute table has x, y fields mapped
  int xCol, yCol;
  double xPosOrig, yPosOrig;
  bool xSuccess, ySuccess;

  if ( !dataDefinedPosition( vlayer, mCurrentLabelPos.featureId, xPosOrig, xSuccess, yPosOrig, ySuccess, xCol, yCol ) )
  {
    QgsDebugMsg( QString( "Label X or Y column not mapped, skipping" ) );
    return false;
  }

  // rotation field is optional, but will be used if available, unless data exists
  int rCol;
  bool rSuccess = false;
  double defRot;

  bool hasRCol = ( layerIsRotatable( vlayer, rCol )
                   && dataDefinedRotation( vlayer, mCurrentLabelPos.featureId, defRot, rSuccess, true ) );

  // get whether to preserve predefined rotation data during label pin/unpin operations
  bool preserveRot = preserveRotation();

  // edit attribute table
  int fid = labelpos.featureId;

  bool writeFailed = false;
  QString labelText = currentLabelText( 24 );

  if ( pin )
  {

//     QgsPoint labelpoint = labelpos.cornerPoints.at( 0 );

    QgsPoint referencePoint;
    if ( !rotationPoint( referencePoint, !preserveRot, false ) )
    {
      referencePoint.setX( mCurrentLabelPos.labelRect.xMinimum() );
      referencePoint.setY( mCurrentLabelPos.labelRect.yMinimum() );
    }

    double labelX = referencePoint.x();
    double labelY = referencePoint.y();
    double labelR = labelpos.rotation * 180 / M_PI;

    // transform back to layer crs, if on-fly on
    if ( mCanvas->mapSettings().hasCrsTransformEnabled() )
    {
      QgsPoint transformedPoint = mCanvas->mapSettings().mapToLayerCoordinates( vlayer, referencePoint );
      labelX = transformedPoint.x();
      labelY = transformedPoint.y();
    }

    vlayer->beginEditCommand( tr( "Pinned label" ) + QString( " '%1'" ).arg( labelText ) );
    writeFailed = !vlayer->changeAttributeValue( fid, xCol, labelX );
    if ( !vlayer->changeAttributeValue( fid, yCol, labelY ) )
      writeFailed = true;
    if ( hasRCol && !preserveRot )
    {
      if ( !vlayer->changeAttributeValue( fid, rCol, labelR ) )
        writeFailed = true;
    }
    vlayer->endEditCommand();
  }
  else
  {
    vlayer->beginEditCommand( tr( "Unpinned label" ) + QString( " '%1'" ).arg( labelText ) );
    writeFailed = !vlayer->changeAttributeValue( fid, xCol, QVariant( QString::null ) );
    if ( !vlayer->changeAttributeValue( fid, yCol, QVariant( QString::null ) ) )
      writeFailed = true;
    if ( hasRCol && !preserveRot )
    {
      if ( !vlayer->changeAttributeValue( fid, rCol, QVariant( QString::null ) ) )
        writeFailed = true;
    }
    vlayer->endEditCommand();
  }

  if ( writeFailed )
  {
    QgsDebugMsg( QString( "Write to attribute table failed" ) );

#if 0
    QgsDebugMsg( QString( "Undoing and removing failed command from layer's undo stack" ) );
    int lastCmdIndx = vlayer->undoStack()->count();
    const QgsUndoCommand* lastCmd = qobject_cast<const QgsUndoCommand *>( vlayer->undoStack()->command( lastCmdIndx ) );
    if ( lastCmd )
    {
      vlayer->undoEditCommand( lastCmd );
      delete vlayer->undoStack()->command( lastCmdIndx );
    }
#endif

    return false;
  }

  return true;
}