110309_qgis_diagrams.diff

Marco Hugentobler, 2011-03-09 05:39 AM

Download (81.9 KB)

View differences:

src/app/qgslabelpropertydialog.cpp (Arbeitskopie)
18 18
#include "qgslabelpropertydialog.h"
19 19
#include "qgsmaplayerregistry.h"
20 20
#include "qgsmaprenderer.h"
21
#include "qgsvectorlayer.h"
21 22
#include <QColorDialog>
22 23
#include <QFontDialog>
23 24

  
src/app/qgsmaptoollabel.cpp (Arbeitskopie)
280 280
    pos = mCurrentLabelPos.cornerPoints.at( 0 );
281 281
  }
282 282

  
283
  //alignment always center/center and rotation 0 for diagrams
284
  if( mCurrentLabelPos.isDiagram )
285
  {
286
    pos.setX( pos.x() + mCurrentLabelPos.labelRect.width() / 2.0 );
287
    pos.setY( pos.y() + mCurrentLabelPos.labelRect.height() / 2.0 );
288
    return true;
289
  }
290

  
283 291
  //adapt pos depending on data defined alignment
284 292
  QString haliString, valiString;
285 293
  currentAlignment( haliString, valiString );
......
356 364
    return false;
357 365
  }
358 366

  
359
  if ( !layerIsMoveable( vlayer, xCol, yCol ) )
367
  if( mCurrentLabelPos.isDiagram )
360 368
  {
369
    if( !diagramMoveable( vlayer, xCol, yCol ) )
370
    {
371
      return false;
372
    }
373
  }
374
  else if ( !labelMoveable( vlayer, xCol, yCol ) )
375
  {
361 376
    return false;
362 377
  }
363 378

  
......
374 389
  return true;
375 390
}
376 391

  
377
bool QgsMapToolLabel::layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
392
bool QgsMapToolLabel:: diagramMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
378 393
{
379 394
  const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
395
  if( vlayer && vlayer->diagramRenderer() )
396
  {
397
    QgsDiagramLayerSettings dls = vlayer->diagramLayerSettings();
398
    if( dls.xPosColumn >= 0 && dls.yPosColumn >= 0 )
399
    {
400
      xCol = dls.xPosColumn;
401
      yCol = dls.yPosColumn;
402
      return true;
403
    }
404
  }
405
  return false;
406
}
407

  
408
bool QgsMapToolLabel::labelMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const
409
{
410
  const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>( ml );
380 411
  if ( !vlayer || !vlayer->isEditable() )
381 412
  {
382 413
    return false;
src/app/qgsmaptoollabel.h (Arbeitskopie)
31 31
    QgsMapToolLabel( QgsMapCanvas* canvas );
32 32
    ~QgsMapToolLabel();
33 33

  
34
    /**Returns true if layer move can be applied to a layer
34
    /**Returns true if label move can be applied to a layer
35 35
        @param xCol out: index of the attribute for data defined x coordinate
36 36
        @param yCol out: index of the attribute for data defined y coordinate
37 37
        @return true if labels of layer can be moved*/
38
    bool layerIsMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;
38
    bool labelMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;
39
    /**Returns true if diagram move can be applied to a layer
40
        @param xCol out: index of the attribute for data defined x coordinate
41
        @param yCol out: index of the attribute for data defined y coordinate
42
        @return true if labels of layer can be moved*/
43
    bool diagramMoveable( const QgsMapLayer* ml, int& xCol, int& yCol ) const;
39 44

  
40 45
  protected:
41 46
    QgsRubberBand* mLabelRubberBand;
src/app/qgsvectorlayerproperties.h (Arbeitskopie)
106 106
    void on_pbnSelectEditForm_clicked();
107 107
    void on_tabWidget_currentChanged( int idx );
108 108
    void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
109
    void on_mAddCategoryPushButton_clicked();
110
    void on_mRemoveCategoryPushButton_clicked();
111
    void on_mDiagramFontButton_clicked();
112
    void on_mFixedSizeCheckBox_stateChanged( int state );
113
    void on_mFindMaximumValueButton_clicked();
114
    void on_mBackgroundColorButton_clicked();
109 115

  
110 116
    void enableLabelOptions( bool theFlag );
111 117
    void addAttribute();
......
120 126
    void on_mButtonAddJoin_clicked();
121 127
    void on_mButtonRemoveJoin_clicked();
122 128

  
129
    /**Set color for diagram category*/
130
    void handleDiagramItemDoubleClick( QTreeWidgetItem * item, int column );
131

  
123 132
  signals:
124 133

  
125 134
    /** emitted when changes to layer were saved to update legend */
......
164 173
    QMap<int, QgsVectorLayer::RangeData> mRanges;
165 174
    QMap<int, QPair<QString, QString> > mCheckedStates;
166 175

  
176
    QFont mDiagramFont;
177

  
167 178
    void updateButtons();
168 179
    void loadRows();
169 180
    void setRow( int row, int idx, const QgsField &field );
170 181

  
182
    void initDiagramTab();
183

  
171 184
    /**Requests all overlay plugis from the plugin registry. Useful for inserting their dialogs as new tabs*/
172 185
    QList<QgsVectorOverlayPlugin*> overlayPlugins() const;
173 186

  
src/app/qgsvectorlayerproperties.cpp (Arbeitskopie)
28 28
#include "qgscontexthelp.h"
29 29
#include "qgscontinuouscolordialog.h"
30 30
#include "qgscoordinatetransform.h"
31
#include "qgsdiagram.h"
32
#include "qgsdiagramrendererv2.h"
31 33
#include "qgsfieldcalculator.h"
32 34
#include "qgsgraduatedsymboldialog.h"
33 35
#include "qgslabeldialog.h"
......
53 55
#include <QFile>
54 56
#include <QFileDialog>
55 57
#include <QFileInfo>
58
#include <QFontDialog>
56 59
#include <QSettings>
57 60
#include <QComboBox>
58 61
#include <QCheckBox>
59 62
#include <QHeaderView>
63
#include <QColorDialog>
60 64

  
61 65
#include "qgsrendererv2propertiesdialog.h"
62 66
#include "qgsstylev2.h"
......
142 146
    addJoinToTreeWidget( joins[i] );
143 147
  }
144 148

  
149
  initDiagramTab();
150

  
145 151
  //for each overlay plugin create a new tab
146 152
  int position;
147 153
  QList<QgsVectorOverlayPlugin*> overlayPluginList = overlayPlugins();
......
678 684

  
679 685
  }
680 686

  
687
  //apply diagram settings
688
  if( !mDisplayDiagramsCheckBox->isChecked() )
689
  {
690
    layer->setDiagramRenderer( 0 );
691
  }
692
  else
693
  {
694
    QgsDiagram* diagram = 0;
695
    if( mDiagramTypeComboBox->currentText() == tr("Text diagram") )
696
    {
697
      diagram = new QgsTextDiagram();
698
    }
699
    else if( mDiagramTypeComboBox->currentText() == tr("Pie chart") )
700
    {
701
      diagram = new QgsPieDiagram();
702
    }
703

  
704
    QgsDiagramSettings ds;
705
    ds.font = mDiagramFont;
706
    QList<QColor> categoryColors;
707
    QList<int> categoryAttributes;
708
    for( int i = 0; i < mDiagramAttributesTreeWidget->topLevelItemCount(); ++i )
709
    {
710
      categoryColors.append( mDiagramAttributesTreeWidget->topLevelItem( i )->background( 1 ).color() );
711
      categoryAttributes.append( mDiagramAttributesTreeWidget->topLevelItem( i )->data(0, Qt::UserRole ).toInt() );
712
    }
713
    ds.categoryColors = categoryColors;
714
    ds.categoryIndices = categoryAttributes;
715
    ds.size = QSizeF( mDiagramSizeSpinBox->value(), mDiagramSizeSpinBox->value() );
716
    ds.backgroundColor = mBackgroundColorButton->color();
717

  
718
    QgsDiagramRendererV2* r = 0;
719
    if( mFixedSizeCheckBox->isChecked() )
720
    {
721
      QgsSingleCategoryDiagramRenderer* dr = new QgsSingleCategoryDiagramRenderer();
722
      dr->setDiagram( diagram );
723
      dr->setDiagramSettings( ds );
724
      layer->setDiagramRenderer( dr );
725
    }
726
    else
727
    {
728
      QgsLinearlyInterpolatedDiagramRenderer* dr = new QgsLinearlyInterpolatedDiagramRenderer();
729
      dr->setLowerValue( 0.0 );
730
      dr->setLowerSize( QSizeF( 0.0, 0.0 ) );
731
      dr->setUpperValue( mValueLineEdit->text().toDouble() );
732
      dr->setUpperSize( QSizeF( mSizeSpinBox->value(), mSizeSpinBox->value() ) );
733
      dr->setClassificationAttribute( mSizeAttributeComboBox->itemData( mSizeAttributeComboBox->currentIndex() ).toInt() );
734
      dr->setDiagram( diagram );
735
      dr->setDiagramSettings( ds );
736
      layer->setDiagramRenderer( dr );
737
    }
738

  
739
    QgsDiagramLayerSettings dls;
740
    dls.dist = mDiagramDistanceSpinBox->value();
741
    dls.priority = mPrioritySlider->value();
742
    dls.xPosColumn = mDataDefinedXComboBox->itemData( mDataDefinedXComboBox->currentIndex() ).toInt();
743
    dls.yPosColumn = mDataDefinedYComboBox->itemData( mDataDefinedYComboBox->currentIndex() ).toInt();
744
    dls.placement = (QgsDiagramLayerSettings::Placement)mPlacementComboBox->itemData( mPlacementComboBox->currentIndex() ).toInt();
745
    if( mLineOptionsComboBox->isEnabled() )
746
    {
747
      dls.placementFlags = (QgsDiagramLayerSettings::LinePlacementFlags)mLineOptionsComboBox->itemData( mLineOptionsComboBox->currentIndex() ).toInt();
748
    }
749
    layer->setDiagramLayerSettings( dls );
750
  }
751

  
752

  
681 753
  //apply overlay dialogs
682 754
  for ( QList<QgsApplyDialog*>::iterator it = mOverlayDialogs.begin(); it != mOverlayDialogs.end(); ++it )
683 755
  {
......
1243 1315
  mJoinTreeWidget->takeTopLevelItem( mJoinTreeWidget->indexOfTopLevelItem( currentJoinItem ) );
1244 1316
}
1245 1317

  
1318
void QgsVectorLayerProperties::handleDiagramItemDoubleClick( QTreeWidgetItem * item, int column )
1319
{
1320
  if ( column == 1 ) //change color
1321
  {
1322
    QColor newColor = QColorDialog::getColor();
1323
    if ( newColor.isValid() )
1324
    {
1325
      item->setBackground( 1, QBrush( newColor ) );
1326
    }
1327
  }
1328
}
1329

  
1246 1330
void QgsVectorLayerProperties::useNewSymbology()
1247 1331
{
1248 1332
  int res = QMessageBox::question( this, tr( "Symbology" ),
......
1338 1422
{
1339 1423
  labelOptionsFrame->setEnabled( theFlag );
1340 1424
}
1425

  
1426
void QgsVectorLayerProperties::on_mAddCategoryPushButton_clicked()
1427
{
1428
  QTreeWidgetItem *newItem = new QTreeWidgetItem( mDiagramAttributesTreeWidget );
1429
  newItem->setText( 0, mDiagramAttributesComboBox->currentText() );
1430
  newItem->setData( 0, Qt::UserRole, mDiagramAttributesComboBox->itemData( mDiagramAttributesComboBox->currentIndex() ) );
1431

  
1432
  //set initial color for diagram category
1433
  int red = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
1434
  int green = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
1435
  int blue = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
1436
  QColor randomColor( red, green, blue );
1437
  newItem->setBackground( 1, QBrush( randomColor ) );
1438
  mDiagramAttributesTreeWidget->addTopLevelItem( newItem );
1439
}
1440

  
1441
void QgsVectorLayerProperties::on_mRemoveCategoryPushButton_clicked()
1442
{
1443
  QTreeWidgetItem* currentItem = mDiagramAttributesTreeWidget->currentItem();
1444
  if ( currentItem )
1445
  {
1446
    delete currentItem;
1447
  }
1448
}
1449

  
1450
void QgsVectorLayerProperties::on_mDiagramFontButton_clicked()
1451
{
1452
  bool ok;
1453
  mDiagramFont = QFontDialog::getFont( &ok, mDiagramFont );
1454
}
1455

  
1456
void QgsVectorLayerProperties::on_mFixedSizeCheckBox_stateChanged( int state )
1457
{
1458
  mDiagramSizeSpinBox->setEnabled( state == Qt::Checked );
1459

  
1460
  //enable / disable all widget in the scaling layout
1461
  mLinearlyScalingLabel->setEnabled( state != Qt::Checked );
1462
  QWidget* currentWidget = 0;
1463
  for( int i = 0; i < mLinearlyScalingLayout->count(); ++i )
1464
  {
1465
    currentWidget = mLinearlyScalingLayout->itemAt( i )->widget();
1466
    if( currentWidget )
1467
    {
1468
      currentWidget->setEnabled( state != Qt::Checked );
1469
    }
1470
  }
1471
}
1472

  
1473
void QgsVectorLayerProperties::on_mFindMaximumValueButton_clicked()
1474
{
1475
  //get maximum value from provider (ignoring not-commited edits)
1476
  if ( layer )
1477
  {
1478
    QgsVectorDataProvider* provider = layer->dataProvider();
1479
    if ( provider )
1480
    {
1481
      mValueLineEdit->setText( provider->maximumValue( mSizeAttributeComboBox->itemData( mSizeAttributeComboBox->currentIndex() ).toInt() ).toString());
1482
    }
1483
  }
1484
}
1485

  
1486
void QgsVectorLayerProperties::on_mBackgroundColorButton_clicked()
1487
{
1488
  QColor newColor = QColorDialog::getColor( mBackgroundColorButton->color(), 0, tr("Background color"), QColorDialog::ShowAlphaChannel);
1489
  if( newColor.isValid() )
1490
  {
1491
    mBackgroundColorButton->setColor( newColor );
1492
  }
1493
}
1494

  
1495
void QgsVectorLayerProperties::initDiagramTab()
1496
{
1497
  if( !layer )
1498
  {
1499
    mDiagramPage->setEnabled( false );
1500
  }
1501

  
1502
  QGis::GeometryType layerType = layer->geometryType();
1503
  if( layerType == QGis::UnknownGeometry || layerType == QGis::NoGeometry )
1504
  {
1505
    mDiagramPage->setEnabled( false );
1506
  }
1507

  
1508
  //insert placement options
1509

  
1510
  if( layerType == QGis::Point || layerType == QGis::Polygon )
1511
  {
1512
    mPlacementComboBox->addItem( tr("AroundPoint"), 0 );
1513
    mPlacementComboBox->addItem( tr("OverPoint"), 1 );
1514
  }
1515

  
1516
  if( layerType == QGis::Line || layerType == QGis::Polygon )
1517
  {
1518
    mPlacementComboBox->addItem( tr("Line"), 2 );
1519
    mPlacementComboBox->addItem( tr("Horizontal"), 3 );
1520
  }
1521

  
1522
  if( layerType == QGis::Polygon )
1523
  {
1524
    mPlacementComboBox->addItem( tr("Free"), 4 );
1525
  }
1526

  
1527
  if( layerType == QGis::Line )
1528
  {
1529
    mLineOptionsComboBox->addItem( tr("On line"), 1);
1530
    mLineOptionsComboBox->addItem( tr("Above line"), 2);
1531
    mLineOptionsComboBox->addItem( tr("Below Line"), 4);
1532
    mLineOptionsComboBox->addItem( tr("Map orientation"), 8);
1533
  }
1534
  else
1535
  {
1536
    mLineOptionsComboBox->setEnabled( false );
1537
  }
1538

  
1539
  mDiagramTypeComboBox->addItem( tr("Pie chart") );
1540
  mDiagramTypeComboBox->addItem( tr("Text diagram") );
1541

  
1542
  //insert all attributes into the combo boxes
1543
  const QgsFieldMap& layerFields = layer->pendingFields();
1544
  QgsFieldMap::const_iterator fieldIt = layerFields.constBegin();
1545
  for(; fieldIt != layerFields.constEnd(); ++fieldIt )
1546
  {
1547
    mDiagramAttributesComboBox->addItem( fieldIt.value().name(), fieldIt.key() );
1548
    if( fieldIt.value().type() != QVariant::String )
1549
    {
1550
      mSizeAttributeComboBox->addItem( fieldIt.value().name(), fieldIt.key() );
1551
    }
1552
  }
1553

  
1554
  mDataDefinedXComboBox->addItem( tr("None"), -1 );
1555
  for( fieldIt = layerFields.constBegin(); fieldIt != layerFields.constEnd(); ++fieldIt )
1556
  {
1557
    mDataDefinedXComboBox->addItem( fieldIt.value().name(), fieldIt.key() );
1558
  }
1559
  mDataDefinedYComboBox->addItem( tr("None"), -1 );
1560
  for( fieldIt = layerFields.constBegin(); fieldIt != layerFields.constEnd(); ++fieldIt )
1561
  {
1562
    mDataDefinedYComboBox->addItem( fieldIt.value().name(), fieldIt.key() );
1563
  }
1564

  
1565
  const QgsDiagramRendererV2* dr = layer->diagramRenderer();
1566
  if( !dr )
1567
  {
1568
    mDisplayDiagramsCheckBox->setChecked( false );
1569
    mFixedSizeCheckBox->setChecked( true );
1570

  
1571
    //insert reasonable default for placement
1572
    switch( layerType )
1573
    {
1574
      case QGis::Point:
1575
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( 1 ));
1576
        break;
1577
      case QGis::Line:
1578
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( 3 ));
1579
        mLineOptionsComboBox->setCurrentIndex( mLineOptionsComboBox->findData( 2 ) );
1580
        break;
1581
      case QGis::Polygon:
1582
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( 1 ));
1583
        break;
1584
    }
1585
    mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) );
1586
  }
1587
  else
1588
  {
1589
    mDisplayDiagramsCheckBox->setChecked( true );
1590

  
1591
    //single category renderer or interpolated one?
1592
    mFixedSizeCheckBox->setChecked( dr->rendererName() == "SingleCategory" );
1593

  
1594
    //assume single category or linearly interpolated diagram renderer for now
1595
    QList<QgsDiagramSettings> settingList = dr->diagramSettings();
1596
    if( settingList.size() > 0 )
1597
    {
1598
      mDiagramFont = settingList.at(0).font;
1599
      QSizeF size = settingList.at(0).size;
1600
      mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor );
1601
      mDiagramSizeSpinBox->setValue( ( size.width() + size.height() ) / 2.0 );
1602

  
1603
      QList< QColor > categoryColors = settingList.at(0).categoryColors;
1604
      QList< int > categoryIndices = settingList.at(0).categoryIndices;
1605
      QList< int >::const_iterator catIt = categoryIndices.constBegin();
1606
      QList< QColor >::const_iterator coIt = categoryColors.constBegin();
1607
      for(;catIt != categoryIndices.constEnd(); ++catIt, ++coIt )
1608
      {
1609
        QTreeWidgetItem *newItem = new QTreeWidgetItem( mDiagramAttributesTreeWidget );
1610
        newItem->setText( 0, layer->pendingFields()[*catIt].name() );
1611
        newItem->setData( 0, Qt::UserRole, *catIt );
1612
        newItem->setBackground( 1, QBrush( *coIt ) );
1613
      }
1614
    }
1615

  
1616
    if( dr->rendererName() == "LinearlyInterpolated" )
1617
    {
1618
      const QgsLinearlyInterpolatedDiagramRenderer* lidr = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( dr );
1619
      if( lidr )
1620
      {
1621
        mDiagramSizeSpinBox->setEnabled( false );
1622
        mValueLineEdit->setText( QString::number( lidr->upperValue() ) );
1623
        mSizeSpinBox->setValue( ( lidr->upperSize().width() + lidr->upperSize().height() ) / 2 );
1624
        mSizeAttributeComboBox->setCurrentIndex( mSizeAttributeComboBox->findData( lidr->classificationAttribute() ) );
1625
      }
1626
    }
1627

  
1628
    QgsDiagramLayerSettings dls = layer->diagramLayerSettings();
1629
    mDiagramDistanceSpinBox->setValue( dls.dist );
1630
    mPrioritySlider->setValue( dls.priority );
1631
    mDataDefinedXComboBox->setCurrentIndex( mDataDefinedXComboBox->findData( dls.xPosColumn ) );
1632
    mDataDefinedYComboBox->setCurrentIndex( mDataDefinedYComboBox->findData( dls.yPosColumn ) );
1633
    mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( dls.placement ) );
1634
    mLineOptionsComboBox->setCurrentIndex( mLineOptionsComboBox->findData( dls.placementFlags ) );
1635

  
1636
    if( dr->diagram() )
1637
    {
1638
      QString diagramName = dr->diagram()->diagramName();
1639
      if( diagramName == "Text" )
1640
      {
1641
        mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr("Text diagram") ) );
1642
      }
1643
      else if( diagramName == "Pie" )
1644
      {
1645
        mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findText( tr("Pie chart") ) );
1646
      }
1647
    }
1648
  }
1649
  QObject::connect( mDiagramAttributesTreeWidget, SIGNAL( itemDoubleClicked ( QTreeWidgetItem*, int ) ), this, SLOT( handleDiagramItemDoubleClick(QTreeWidgetItem*,int) ) );
1650
}
src/app/qgsmaptoolmovelabel.cpp (Arbeitskopie)
40 40
  }
41 41

  
42 42
  QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( mCurrentLabelPos.layerID );
43
  if ( !layer )
43
  if ( !layer || !layer->isEditable() )
44 44
  {
45 45
    return;
46 46
  }
47 47

  
48 48
  int xCol, yCol;
49
  if ( layerIsMoveable( layer, xCol, yCol ) )
49
  if ( labelMoveable( layer, xCol, yCol ) || diagramMoveable( layer, xCol, yCol ) )
50 50
  {
51 51
    mStartPointMapCoords = toMapCoordinates( e->pos() );
52 52
    mClickOffsetX = mStartPointMapCoords.x() - mCurrentLabelPos.labelRect.xMinimum();
src/app/qgisapp.cpp (Arbeitskopie)
6241 6241
  for ( QMap<QString, QgsMapLayer*>::iterator it = layers.begin(); it != layers.end(); it++ )
6242 6242
  {
6243 6243
    QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( it.value() );
6244
    if ( !vlayer || !vlayer->isEditable() || vlayer->customProperty( "labeling" ).toString() != QString( "pal" ) )
6244
    if ( !vlayer || !vlayer->isEditable() ||
6245
         (!vlayer->diagramRenderer() && vlayer->customProperty( "labeling" ).toString() != QString( "pal" ) ) )
6245 6246
      continue;
6246 6247

  
6247 6248
    int colX, colY, colAng;
6248 6249
    enableMove =
6249 6250
      enableMove ||
6250 6251
      ( qobject_cast<QgsMapToolMoveLabel*>( mMapTools.mMoveLabel ) &&
6251
        qobject_cast<QgsMapToolMoveLabel*>( mMapTools.mMoveLabel )->layerIsMoveable( vlayer, colX, colY ) );
6252
        ( qobject_cast<QgsMapToolMoveLabel*>( mMapTools.mMoveLabel )->labelMoveable( vlayer, colX, colY )
6253
        || qobject_cast<QgsMapToolMoveLabel*>( mMapTools.mMoveLabel )->diagramMoveable( vlayer, colX, colY) )
6254
        );
6252 6255

  
6253 6256
    enableRotate =
6254 6257
      enableRotate ||
src/core/qgsdiagramrendererv2.h (Revision 0)
1
#ifndef QGSDIAGRAMRENDERERV2_H
2
#define QGSDIAGRAMRENDERERV2_H
3

  
4
#include <QColor>
5
#include <QFont>
6
#include <QList>
7
#include <QPointF>
8
#include <QSizeF>
9
#include "pal/layer.h" //pal::Layer
10
#include "qgsfeature.h"
11
#include "qgspallabeling.h"
12

  
13
class QgsDiagram;
14
class QgsDiagramRendererV2;
15
class QgsFeature;
16
class QgsRenderContext;
17
class QDomElement;
18

  
19
struct QgsDiagramLayerSettings
20
{
21
  //avoid inclusion of QgsPalLabeling
22
  enum Placement
23
  {
24
    AroundPoint, // Point / Polygon
25
    OverPoint, // Point / Polygon
26
    Line, // Line / Polygon
27
    Curved, // Line
28
    Horizontal, // Polygon
29
    Free // Polygon
30
  };
31

  
32
  enum LinePlacementFlags
33
  {
34
    OnLine    = 1,
35
    AboveLine = 2,
36
    BelowLine = 4,
37
    MapOrientation = 8
38
  };
39

  
40
  QgsDiagramLayerSettings(): placement( AroundPoint ), placementFlags( OnLine ), priority( 5 ), obstacle( false ), dist( 0.0), renderer( 0 ),
41
  palLayer( 0 ), ct( 0 ), xform( 0 ), xPosColumn( -1 ), yPosColumn( -1 )
42
  {
43
  }
44

  
45
  //pal placement properties
46
  Placement placement;
47
  LinePlacementFlags placementFlags;
48
  int priority; // 0 = low, 10 = high
49
  bool obstacle; // whether it's an obstacle
50
  double dist; // distance from the feature (in mm)
51
  QgsDiagramRendererV2* renderer;
52

  
53
  //assigned when layer gets prepared
54
  pal::Layer* palLayer;
55
  const QgsCoordinateTransform* ct;
56
  const QgsMapToPixel* xform;
57
  QList<QgsPalGeometry*> geometries;
58

  
59
  int xPosColumn; //attribute index for x coordinate (or -1 if position not data defined)
60
  int yPosColumn;//attribute index for y coordinate (or -1 if position not data defined)
61

  
62
  void readXML( const QDomElement& elem );
63
  void writeXML( QDomElement& layerElem, QDomDocument& doc ) const;
64
};
65

  
66
//diagram settings for rendering
67
struct QgsDiagramSettings
68
{
69
  QFont font;
70
  QList< QColor > categoryColors;
71
  QList< int > categoryIndices;
72
  QSizeF size; //size in mm
73
  QColor backgroundColor;
74

  
75
  void readXML( const QDomElement& elem );
76
  void writeXML( QDomElement& rendererElem, QDomDocument& doc ) const;
77
};
78

  
79
/**Returns diagram settings for a feature*/
80
class QgsDiagramRendererV2
81
{
82
  public:
83

  
84
    QgsDiagramRendererV2();
85
    virtual ~QgsDiagramRendererV2();
86

  
87
    /**Returns size of the diagram for feature f in map units. Returns an invalid QSizeF in case of error*/
88
    virtual QSizeF sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c );
89

  
90
    virtual QString rendererName() const = 0;
91

  
92
    /**Returns attribute indices needed for diagram rendering*/
93
    virtual QList<int> diagramAttributes() const = 0;
94

  
95
    void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos );
96

  
97
    void setDiagram( QgsDiagram* d );
98
    const QgsDiagram* diagram() const { return mDiagram; }
99

  
100
    /**Returns list with all diagram settings in the renderer*/
101
    virtual QList<QgsDiagramSettings> diagramSettings() const = 0;
102

  
103
    virtual void readXML( const QDomElement& elem ) = 0;
104
    virtual void writeXML( QDomElement& layerElem, QDomDocument& doc ) const = 0;
105

  
106
  protected:
107

  
108
    /**Returns diagram settings for a feature (or false if the diagram for the feature is not to be rendered). Used internally within renderDiagram()
109
      @param s out: diagram settings for the feature*/
110
    virtual bool diagramSettings( const QgsAttributeMap& att, const QgsRenderContext& c, QgsDiagramSettings& s ) = 0;
111

  
112
    /**Returns size of the diagram (in painter units) or an invalid size in case of error*/
113
    virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) = 0;
114

  
115
    /**Converts size from mm to map units*/
116
    void convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const;
117

  
118
    /**Returns the paint device dpi (or -1 in case of error*/
119
    static int dpiPaintDevice( const QPainter* );
120

  
121
    //read / write diagram
122
    void _readXML( const QDomElement& elem );
123
    void _writeXML( QDomElement& rendererElem, QDomDocument& doc ) const;
124

  
125
    /**Reference to the object that does the real diagram rendering*/
126
    QgsDiagram* mDiagram;
127
};
128

  
129
/**Renders the diagrams for all features with the same settings*/
130
class QgsSingleCategoryDiagramRenderer: public QgsDiagramRendererV2
131
{
132
  public:
133
    QgsSingleCategoryDiagramRenderer();
134
    ~QgsSingleCategoryDiagramRenderer();
135

  
136
    QString rendererName() const { return "SingleCategory"; }
137

  
138
    QList<int> diagramAttributes() const { return mSettings.categoryIndices; }
139

  
140
    void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; }
141

  
142
    QList<QgsDiagramSettings> diagramSettings() const;
143

  
144
    void readXML( const QDomElement& elem );
145
    void writeXML( QDomElement& layerElem, QDomDocument& doc ) const;
146

  
147
  protected:
148
    bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s );
149

  
150
    QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ){ return mSettings.size; }
151

  
152
  private:
153
    QgsDiagramSettings mSettings;
154
};
155

  
156
class QgsLinearlyInterpolatedDiagramRenderer: public QgsDiagramRendererV2
157
{
158
  public:
159
    QgsLinearlyInterpolatedDiagramRenderer();
160
    ~QgsLinearlyInterpolatedDiagramRenderer();
161

  
162
    /**Returns list with all diagram settings in the renderer*/
163
    QList<QgsDiagramSettings> diagramSettings() const;
164

  
165
    void setDiagramSettings( const QgsDiagramSettings& s ) { mSettings = s; }
166

  
167
    QList<int> diagramAttributes() const;
168

  
169
    QString rendererName() const { return "LinearlyInterpolated"; }
170

  
171
    void setLowerValue( double val ){ mLowerValue = val; }
172
    double lowerValue() const { return mLowerValue; }
173

  
174
    void setUpperValue( double val ){ mUpperValue = val; }
175
    double upperValue() const { return mUpperValue; }
176

  
177
    void setLowerSize( QSizeF s ){ mLowerSize = s; }
178
    QSizeF lowerSize() const { return mLowerSize; }
179

  
180
    void setUpperSize( QSizeF s ){ mUpperSize = s; }
181
    QSizeF upperSize() const { return mUpperSize; }
182

  
183
    int classificationAttribute() const { return mClassificationAttribute; }
184
    void setClassificationAttribute( int index ){ mClassificationAttribute = index; }
185

  
186
    void readXML( const QDomElement& elem );
187
    void writeXML( QDomElement& layerElem, QDomDocument& doc ) const;
188

  
189
  protected:
190
    bool diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s );
191

  
192
    QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c );
193

  
194
  private:
195
    QgsDiagramSettings mSettings;
196
    QSizeF mLowerSize;
197
    QSizeF mUpperSize;
198
    double mLowerValue;
199
    double mUpperValue;
200
    /**Index of the classification attribute*/
201
    int mClassificationAttribute;
202
};
203

  
204
#endif // QGSDIAGRAMRENDERERV2_H
src/core/qgsmaprenderer.h (Arbeitskopie)
39 39
class QgsVectorLayer;
40 40
class QgsFeature;
41 41

  
42
struct QgsDiagramLayerSettings;
43

  
42 44
struct CORE_EXPORT QgsLabelPosition
43 45
{
44
  QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, bool upside_down ):
45
      featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), upsideDown( upside_down ) {}
46
  QgsLabelPosition(): featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), upsideDown( false ) {}
46
  QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, bool upside_down, bool diagram = false ):
47
      featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), upsideDown( upside_down ), isDiagram( diagram ) {}
48
  QgsLabelPosition(): featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), upsideDown( false ), isDiagram( false ) {}
47 49
  int featureId;
48 50
  double rotation;
49 51
  QVector< QgsPoint > cornerPoints;
......
52 54
  double height;
53 55
  QString layerID;
54 56
  bool upsideDown;
57
  bool isDiagram;
55 58
};
56 59

  
57 60
/** Labeling engine interface.
......
70 73
    //! called when starting rendering of a layer
71 74
    //! @note: this method was added in version 1.6
72 75
    virtual int prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx ) = 0;
76
    //! adds a diagram layer to the labeling engine
77
    virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings& s ){};
73 78
    //! called for every feature
74 79
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
80
    //! called for every diagram feature
81
    virtual void registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ){};
75 82
    //! called when the map is drawn and labels should be placed
76 83
    virtual void drawLabeling( QgsRenderContext& context ) = 0;
77 84
    //! called when we're done with rendering
src/core/qgspallabeling.cpp (Arbeitskopie)
38 38
#include <QTime>
39 39
#include <QPainter>
40 40

  
41
#include "qgsdiagram.h"
42
#include "qgsdiagramrendererv2.h"
41 43
#include "qgslabelsearchtree.h"
42 44
#include <qgslogger.h>
43 45
#include <qgsvectorlayer.h>
......
54 56
class QgsPalGeometry : public PalGeometry
55 57
{
56 58
  public:
57
    QgsPalGeometry( int id, QString text, GEOSGeometry* g ): mG( g ), mText( text ), mId( id ), mInfo( NULL )
59
    QgsPalGeometry( int id, QString text, GEOSGeometry* g ): mG( g ), mText( text ), mId( id ), mInfo( NULL ), mIsDiagram( false )
58 60
    {
59 61
      mStrId = QByteArray::number( id );
60 62
    }
......
100 102
    const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& dataDefinedValues() const { return mDataDefinedValues; }
101 103
    void addDataDefinedValue( QgsPalLayerSettings::DataDefinedProperties p, QVariant v ) { mDataDefinedValues.insert( p, v ); }
102 104

  
105
    void setIsDiagram( bool d ) { mIsDiagram = d; }
106
    bool isDiagram() const { return mIsDiagram; }
107

  
108
    void addDiagramAttribute( int index, QVariant value ){ mDiagramAttributes.insert( index, value ); }
109
    const QgsAttributeMap& diagramAttributes(){ return mDiagramAttributes; }
110

  
103 111
  protected:
104 112
    GEOSGeometry* mG;
105 113
    QString mText;
106 114
    QByteArray mStrId;
107 115
    int mId;
108 116
    LabelInfo* mInfo;
117
    bool mIsDiagram;
109 118
    /**Stores attribute values for data defined properties*/
110 119
    QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues;
120

  
121
    /**Stores attribute values for diagram rendering*/
122
    QgsAttributeMap mDiagramAttributes;
111 123
};
112 124

  
113 125
// -------------
......
414 426
  labelY = qAbs( ptSize.y() - ptZero.y() );
415 427
}
416 428

  
417

  
418 429
void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context )
419 430
{
420 431
  QString labelText = f.attributeMap()[fieldIndex].toString();
......
743 754
  return 1; // init successful
744 755
}
745 756

  
757
int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings& s )
758
{
759
  Layer* l = mPal->addLayer( layer->id().append("d").toLocal8Bit().data(), -1, -1, pal::Arrangement(s.placement), METER, s.priority, s.obstacle, true, true );
760
  l->setArrangementFlags( s.placementFlags );
746 761

  
762
  s.palLayer = l;
763
  if ( mMapRenderer->hasCrsTransformEnabled() )
764
    s.ct = new QgsCoordinateTransform( layer->srs(), mMapRenderer->destinationSrs() );
765
  else
766
    s.ct = NULL;
767
  s.xform = mMapRenderer->coordinateTransform();
768
  mActiveDiagramLayers.insert( layer, s );
769
  return 1;
770
}
771

  
747 772
void QgsPalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
748 773
{
749 774
  QgsPalLayerSettings& lyr = mActiveLayers[layer];
750 775
  lyr.registerFeature( f, context );
751 776
}
752 777

  
778
void QgsPalLabeling::registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context )
779
{
780
  //get diagram layer settings, diagram renderer
781
  QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator layerIt = mActiveDiagramLayers.find( layer );
782
  if( layerIt == mActiveDiagramLayers.constEnd() )
783
  {
784
    return;
785
  }
753 786

  
787
  //convert geom to geos
788
  QgsGeometry* geom = feat.geometry();
789

  
790
  if ( layerIt.value().ct ) // reproject the geometry if necessary
791
  {
792
    geom->transform( *(layerIt.value().ct) );
793
  }
794

  
795
  GEOSGeometry* geos_geom = geom->asGeos();
796
  if ( geos_geom == 0 )
797
  {
798
    return; // invalid geometry
799
  }
800

  
801
  //create PALGeometry with diagram = true
802
  QgsPalGeometry* lbl = new QgsPalGeometry( feat.id(), "", GEOSGeom_clone( geos_geom ) );
803
  lbl->setIsDiagram( true );
804

  
805
  // record the created geometry - it will be deleted at the end.
806
  layerIt.value().geometries.append( lbl );
807

  
808
  double diagramWidth = 0;
809
  double diagramHeight = 0;
810
  QgsDiagramRendererV2* dr = layerIt.value().renderer;
811
  if( dr )
812
  {
813
    QSizeF diagSize = dr->sizeMapUnits( feat.attributeMap(), context );
814
    if( diagSize.isValid() )
815
    {
816
      diagramWidth = diagSize.width();
817
      diagramHeight= diagSize.height();
818
    }
819

  
820
    //append the diagram attributes to lbl
821
    QList<int> diagramAttrib = dr->diagramAttributes();
822
    QList<int>::const_iterator diagAttIt = diagramAttrib.constBegin();
823
    for(; diagAttIt != diagramAttrib.constEnd(); ++diagAttIt )
824
    {
825
      lbl->addDiagramAttribute( *diagAttIt, feat.attributeMap()[*diagAttIt] );
826
    }
827
  }
828

  
829
  // register feature to the layer
830
  int ddColX = layerIt.value().xPosColumn;
831
  int ddColY = layerIt.value().yPosColumn;
832
  double ddPosX = 0.0;
833
  double ddPosY = 0.0;
834
  bool ddPos = (ddColX >= 0 && ddColY >= 0);
835
  if( ddPos )
836
  {
837
    bool posXOk, posYOk;
838
    //data defined diagram position is always centered
839
    ddPosX = feat.attributeMap()[ddColX].toDouble( &posXOk )- diagramWidth / 2.0;
840
    ddPosY = feat.attributeMap()[ddColY].toDouble( &posYOk )- diagramHeight / 2.0;
841
    if( !posXOk || !posYOk )
842
    {
843
      ddPos = false;
844
    }
845
  }
846

  
847
  try
848
  {
849
    if ( !layerIt.value().palLayer->registerFeature( lbl->strId(), lbl, diagramWidth, diagramHeight, "", ddPosX, ddPosY, ddPos ) )
850
    {
851
      return;
852
    }
853
  }
854
  catch ( std::exception* e )
855
  {
856
    QgsDebugMsg( QString( "Ignoring feature %1 due PAL exception: " ).arg( feat.id() ) + QString::fromLatin1( e->what() ) );
857
    return;
858
  }
859

  
860
  pal::Feature* palFeat = layerIt.value().palLayer->getFeature( lbl->strId() );
861
  QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
862
  QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
863
  palFeat->setDistLabel( qAbs( ptOne.x() - ptZero.x() ) * layerIt.value().dist );
864
}
865

  
866

  
754 867
void QgsPalLabeling::init( QgsMapRenderer* mr )
755 868
{
756 869
  mMapRenderer = mr;
......
779 892
  mPal->setPolyP( mCandPolygon );
780 893

  
781 894
  mActiveLayers.clear();
895
  mActiveDiagramLayers.clear();
782 896
}
783 897

  
784 898
void QgsPalLabeling::exit()
......
867 981
  std::list<LabelPosition*>::iterator it = labels->begin();
868 982
  for ( ; it != labels->end(); ++it )
869 983
  {
984
    QgsPalGeometry* palGeometry = dynamic_cast< QgsPalGeometry* >(( *it )->getFeaturePart()->getUserGeometry() );
985
    if ( !palGeometry )
986
    {
987
      continue;
988
    }
989

  
990
    if( palGeometry->isDiagram() )
991
    {
992
      //render diagram
993
      QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator dit = mActiveDiagramLayers.begin();
994
      for ( dit = mActiveDiagramLayers.begin(); dit != mActiveDiagramLayers.end(); ++dit )
995
      {
996
        if ( dit.key() && dit.key()->id().append("d") == ( *it )->getLayerName() )
997
        {
998
          QgsPoint outPt = xform->transform( (*it)->getX(), (*it)->getY() );
999
          dit.value().renderer->renderDiagram( palGeometry->diagramAttributes(), context, QPointF( outPt.x(), outPt.y() ) );
1000
        }
1001
      }
1002

  
1003
      //insert into label search tree to manipulate position interactively
1004
      if ( mLabelSearchTree )
1005
      {
1006
        //for diagrams, remove the additional 'd' at the end of the layer id
1007
        QString layerId = (*it )->getLayerName();
1008
        layerId.chop( 1 );
1009
        mLabelSearchTree->insertLabel( *it,  QString( palGeometry->strId() ).toInt(), layerId, true );
1010
      }
1011
      continue;
1012
    }
1013

  
870 1014
    const QgsPalLayerSettings& lyr = layer(( *it )->getLayerName() );
871 1015
    QFont fontForLabel = lyr.textFont;
872 1016
    QColor fontColor = lyr.textColor;
873 1017
    double bufferSize = lyr.bufferSize;
874 1018
    QColor bufferColor = lyr.bufferColor;
875 1019

  
876
    QgsPalGeometry* palGeometry = dynamic_cast< QgsPalGeometry* >(( *it )->getFeaturePart()->getUserGeometry() );
877
    if ( !palGeometry )
878
    {
879
      continue;
880
    }
881

  
882 1020
    //apply data defined settings for the label
883 1021
    //font size
884 1022
    QVariant dataDefinedSize = palGeometry->dataDefinedValues().value( QgsPalLayerSettings::Size );
......
969 1107
      delete *git;
970 1108
    lyr.geometries.clear();
971 1109
  }
972
  // labeling is done: clear the active layers hashtable
973
// mActiveLayers.clear();
974 1110

  
1111
  //delete all allocated geometries for diagrams
1112
  QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator dIt = mActiveDiagramLayers.begin();
1113
  for(; dIt != mActiveDiagramLayers.end(); ++dIt )
1114
  {
1115
    QgsDiagramLayerSettings& dls = dIt.value();
1116
    for ( QList<QgsPalGeometry*>::iterator git = dls.geometries.begin(); git != dls.geometries.end(); ++git )
1117
    {
1118
      delete *git;
1119
    }
1120
    dls.geometries.clear();
1121
  }
975 1122
}
976 1123

  
977 1124
QList<QgsLabelPosition> QgsPalLabeling::labelsAtPosition( const QgsPoint& p )
src/core/qgsrendercontext.h (Arbeitskopie)
41 41
    //getters
42 42

  
43 43
    QPainter* painter() {return mPainter;}
44
    const QPainter* constPainter() const { return mPainter; }
44 45

  
45 46
    const QgsCoordinateTransform* coordinateTransform() const {return mCoordTransform;}
46 47

  
src/core/qgspallabeling.h (Arbeitskopie)
23 23

  
24 24
class QFontMetricsF;
25 25
class QPainter;
26
class QgsGeometry;
26 27
class QgsMapRenderer;
27 28
class QgsRectangle;
28 29
class QgsCoordinateTransform;
29 30
class QgsLabelSearchTree;
31
struct QgsDiagramLayerSettings;
30 32

  
31 33
#include <QString>
32 34
#include <QFont>
33 35
#include <QColor>
36
#include <QHash>
34 37
#include <QList>
35 38
#include <QRectF>
36 39

  
......
45 48
class QgsFeature;
46 49
#include "qgspoint.h"
47 50

  
48
#include "qgsvectorlayer.h" // definition of QgsLabelingEngineInterface
51
#include "qgsmaprenderer.h" // definition of QgsLabelingEngineInterface
49 52

  
50 53
class QgsPalGeometry;
54
class QgsVectorLayer;
51 55

  
52 56
class CORE_EXPORT QgsPalLayerSettings
53 57
{
......
195 199
    virtual bool willUseLayer( QgsVectorLayer* layer );
196 200
    //! hook called when drawing layer before issuing select()
197 201
    virtual int prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx );
202
    //! adds a diagram layer to the labeling engine
203
    virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings& s );
198 204
    //! hook called when drawing for every feature in a layer
199 205
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
206
    virtual void registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
200 207
    //! called when the map is drawn and labels should be placed
201 208
    virtual void drawLabeling( QgsRenderContext& context );
202 209
    //! called when we're done with rendering
......
220 227
  protected:
221 228
    // hashtable of layer settings, being filled during labeling
222 229
    QHash<QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers;
230
    // hashtable of active diagram layers
231
    QHash<QgsVectorLayer*, QgsDiagramLayerSettings> mActiveDiagramLayers;
223 232
    QgsPalLayerSettings mInvalidLayerSettings;
224 233

  
225 234
    QgsMapRenderer* mMapRenderer;
src/core/qgslabelsearchtree.h (Arbeitskopie)
44 44

  
45 45
    /**Inserts label position. Does not take ownership of labelPos
46 46
      @return true in case of success*/
47
    bool insertLabel( LabelPosition* labelPos, int featureId, const QString& layerName );
47
    bool insertLabel( LabelPosition* labelPos, int featureId, const QString& layerName, bool diagram = false );
48 48

  
49 49
  private:
50 50
    RTree<QgsLabelPosition*, double, 2, double> mSpatialIndex;
src/core/qgsvectorlayer.cpp (Arbeitskopie)
112 112
    mLabelOn( false ),
113 113
    mVertexMarkerOnlyForSelection( false ),
114 114
    mFetching( false ),
115
    mJoinBuffer( 0 )
115
    mJoinBuffer( 0 ),
116
    mDiagramRenderer( 0 )
116 117
{
117 118
  mActions = new QgsAttributeAction( this );
118 119

  
......
754 755
      mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker );
755 756

  
756 757
      // labeling - register feature
757
      if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
758
        rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
758
      if( mRendererV2->symbolForFeature( fet ) != NULL )
759
      {
760
        if ( labeling )
761
        {
762
          rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
763
        }
764
        if( mDiagramRenderer )
765
        {
766
          rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
767
        }
768
      }
759 769

  
760 770
      if ( mEditable )
761 771
      {
......
821 831
    }
822 832
    features[sym].append( fet );
823 833

  
824
    if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
825
      rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
834
    if( mRendererV2->symbolForFeature( fet ) != NULL )
835
    {
836
      if ( labeling )
837
      {
838
        rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
839
      }
840
      if( mDiagramRenderer )
841
      {
842
        rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
843
      }
844
    }
826 845

  
827 846
    if ( mEditable )
828 847
    {
......
949 968
    }
950 969

  
951 970
    bool labeling = false;
952
    if ( rendererContext.labelingEngine() )
953
    {
954
      QSet<int> attrIndex;
955
      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex, rendererContext ) )
956
      {
957
        QSet<int>::const_iterator attIt = attrIndex.constBegin();
958
        for ( ; attIt != attrIndex.constEnd(); ++attIt )
959
        {
960
          if ( !attributes.contains( *attIt ) )
961
          {
962
            attributes << *attIt;
963
          }
964
        }
965
        labeling = true;
966
      }
967
    }
971
    //register label and diagram layer to the labeling engine
972
    prepareLabelingAndDiagrams( rendererContext, attributes, labeling );
968 973

  
969 974
    select( attributes, rendererContext.extent() );
970 975

  
......
1011 1016
    QgsAttributeList attributes = mRenderer->classificationAttributes();
1012 1017

  
1013 1018
    bool labeling = false;
1014
    if ( rendererContext.labelingEngine() )
1015
    {
1016
      QSet<int> attrIndex;
1017
      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex, rendererContext ) )
1018
      {
1019
        QSet<int>::const_iterator attIt = attrIndex.constBegin();
1020
        for ( ; attIt != attrIndex.constEnd(); ++attIt )
1021
        {
1022
          if ( !attributes.contains( *attIt ) )
1023
          {
1024
            attributes << *attIt;
1025
          }
1026
        }
1027
        labeling = true;
1028
      }
1029
    }
1019
    prepareLabelingAndDiagrams( rendererContext, attributes, labeling );
1030 1020

  
1031 1021
    select( attributes, rendererContext.extent() );
1032 1022

  
......
1092 1082
        //double scale = rendererContext.scaleFactor() /  markerScaleFactor;
1093 1083
        drawFeature( rendererContext, fet, &marker );
1094 1084

  
1095
        if ( labeling && mRenderer->willRenderFeature( &fet ) )
1085
        if( mRenderer->willRenderFeature( &fet ) )
1096 1086
        {
1097
          rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
1087
          if ( labeling )
1088
          {
1089
            rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
1090
          }
1091
          if( mDiagramRenderer )
1092
          {
1093
            rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
1094
          }
1098 1095
        }
1099

  
1100 1096
        ++featureCount;
1101 1097
      }
1102 1098
    }
......
1303 1299
  }
1304 1300
}
1305 1301

  
1302
void QgsVectorLayer::setDiagramRenderer( QgsDiagramRendererV2* r )
1303
{
1304
  delete mDiagramRenderer;
1305
  mDiagramRenderer = r;
1306
}
1307

  
1306 1308
QGis::GeometryType QgsVectorLayer::geometryType() const
1307 1309
{
1308 1310
  if ( mDataProvider )
......
2934 2936
      QgsDebugMsg( "calling readXML" );
2935 2937
      mLabel->readXML( labelattributesnode );
2936 2938
    }
2939

  
2940
    //diagram renderer and diagram layer settings
2941
    delete mDiagramRenderer; mDiagramRenderer = 0;
2942
    QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
2943
    if( !singleCatDiagramElem.isNull() )
2944
    {
2945
      mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
2946
      mDiagramRenderer->readXML( singleCatDiagramElem );
2947
    }
2948
    QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
2949
    if( !linearDiagramElem.isNull() )
2950
    {
2951
      mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
2952
      mDiagramRenderer->readXML( linearDiagramElem );
2953
    }
2954

  
2955
    if( mDiagramRenderer )
2956
    {
2957
      QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
2958
      if( !diagramSettingsElem.isNull() )
2959
      {
2960
        mDiagramLayerSettings.readXML( diagramSettingsElem );
2961
      }
2962
    }
2937 2963
  }
2938 2964

  
2939 2965
  // process the attribute actions
......
3103 3129
    }
3104 3130

  
3105 3131
    mLabel->writeXML( node, doc );
3132

  
3133
    if( mDiagramRenderer )
3134
    {
3135
      mDiagramRenderer->writeXML( mapLayerNode, doc );
3136
      mDiagramLayerSettings.writeXML( mapLayerNode, doc );
3137
    }
3106 3138
  }
3107 3139

  
3108 3140
  //edit types
......
4956 4988
  map.insert( newIndex, it.value() );
4957 4989
  map.remove( oldIndex );
4958 4990
}
4991

  
4992
void QgsVectorLayer::prepareLabelingAndDiagrams( QgsRenderContext& rendererContext, QgsAttributeList& attributes, bool& labeling )
4993
{
4994
  if ( rendererContext.labelingEngine() )
4995
    {
4996
      QSet<int> attrIndex;
4997
      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex, rendererContext ) )
4998
      {
4999
        QSet<int>::const_iterator attIt = attrIndex.constBegin();
5000
        for ( ; attIt != attrIndex.constEnd(); ++attIt )
5001
        {
5002
          if ( !attributes.contains( *attIt ) )
5003
          {
5004
            attributes << *attIt;
5005
          }
5006
        }
5007
        labeling = true;
5008
      }
5009

  
5010
      //register diagram layers
5011
      if( mDiagramRenderer )
5012
      {
5013
        mDiagramLayerSettings.renderer = mDiagramRenderer;
5014
        rendererContext.labelingEngine()->addDiagramLayer( this, mDiagramLayerSettings );
5015
        //add attributes needed by the diagram renderer
5016
        QList<int> att = mDiagramRenderer->diagramAttributes();
5017
        QList<int>::const_iterator attIt = att.constBegin();
5018
        for(; attIt != att.constEnd(); ++attIt )
5019
        {
5020
          if( !attributes.contains( *attIt ) )
5021
          {
5022
            attributes << *attIt;
5023
          }
5024
        }
5025
        //and the ones needed for data defined diagram positions
5026
        if( mDiagramLayerSettings.xPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings.xPosColumn ) )
5027
        {
5028
          attributes << mDiagramLayerSettings.xPosColumn;
5029
        }
5030
        if( mDiagramLayerSettings.yPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings.yPosColumn ) )
5031
        {
5032
          attributes << mDiagramLayerSettings.yPosColumn;
5033
        }
5034
      }
5035
    }
5036
}
src/core/qgsdiagram.h (Revision 0)
1
#ifndef QGSDIAGRAM_H
2
#define QGSDIAGRAM_H
3

  
4
#include "qgsfeature.h"
5
#include <QPen>
6

  
7
class QPainter;
8
class QPointF;
9
struct QgsDiagramSettings;
10

  
11
class QgsRenderContext;
12

  
13
/**Base class for all diagram types*/
14
class QgsDiagram
15
{
16
  public:
17
    /**Draws the diagram at the given position (in pixel coordinates)*/
18
    virtual void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) = 0;
19
    virtual QString diagramName() const = 0;
20
};
21

  
22
class QgsTextDiagram: public QgsDiagram
23
{
24
  public:
25
    enum Shape
26
    {
27
      Circle = 0,
28
      Rectangle,
29
      Triangle
30
    };
31

  
32
    enum Orientation
33
    {
34
      Horizontal = 0,
35
      Vertical
36
    };
37

  
38
    QgsTextDiagram();
39
    ~QgsTextDiagram();
40
    void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
41

  
42
    QString diagramName() const { return "Text"; }
43

  
44
  private:
45
    Orientation mOrientation;
46
    Shape mShape;
47
    QBrush mBrush; //transparent brush
48
    QPen mPen;
49

  
50
    /**Calculates intersection points between a line and an ellipse
51
      @return intersection points*/
52
    void lineEllipseIntersection( const QPointF& lineStart, const QPointF& lineEnd, const QPointF& ellipseMid, double r1, double r2, QList<QPointF>& result ) const;
53
};
54

  
55
class QgsPieDiagram: public QgsDiagram
56
{
57
  public:
58
    QgsPieDiagram();
59
    ~QgsPieDiagram();
60

  
61
    void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
62
    QString diagramName() const { return "Pie"; }
63

  
64
  private:
65
    QBrush mCategoryBrush;
66
    QPen mPen;
67
};
68

  
69
#endif // QGSDIAGRAM_H
src/core/qgsdiagram.cpp (Revision 0)
1
#include "qgsdiagram.h"
2
#include "qgsdiagramrendererv2.h"
3
#include "qgsrendercontext.h"
4

  
5
#include <QPainter>
6

  
7
QgsTextDiagram::QgsTextDiagram(): mOrientation( Vertical ), mShape( Circle )
8
{
9
  mPen.setWidthF( 2.0 );
10
  mPen.setColor( QColor( 0, 0, 0 ) );
11
  mPen.setCapStyle( Qt::FlatCap );
12
  mBrush.setStyle( Qt::SolidPattern );
13
}
14

  
15
QgsTextDiagram::~QgsTextDiagram()
16
{
17
}
18

  
19
void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
20
{
21
  QPainter* p = c.painter();
22
  if ( !p )
23
  {
24
    return;
25
  }
26

  
27
  //convert from mm to painter units
28
  double w = s.size.width() * c.scaleFactor();
29
  double h = s.size.height() * c.scaleFactor();
30

  
31
  double baseX = position.x();
32
  double baseY = position.y() - h;
33

  
34
  QList<QPointF> textPositions; //midpoints for text placement
35
  int nCategories = s.categoryIndices.size();
36
  for( int i = 0; i < nCategories; ++i )
37
  {
38
    if( mOrientation == Horizontal )
39
    {
40
      textPositions.push_back( QPointF( baseX + (w / nCategories) * i + w / nCategories / 2.0 , baseY + h / 2.0 ) );
41
    }
42
    else //vertical
43
    {
44
      textPositions.push_back( QPointF( baseX + w / 2.0, baseY + h / nCategories * i + w / nCategories / 2.0 ) );
45
    }
46
  }
47

  
48
  mPen.setColor( QColor( 0, 0, 0 ) );
49
  p->setPen( mPen );
50
  mBrush.setColor( s.backgroundColor );
51
  p->setBrush( mBrush );
52
  p->setFont( s.font );
53

  
54
  //draw shapes
55
  QPointF center( baseX + w / 2.0, baseY + h / 2.0 );
56
  double r1 = w / 2.0; double r2 = h / 2.0;
57
  QList<QPointF> intersect; //intersections between shape and separation lines
58

  
59
  switch( mShape )
60
  {
61
    case Circle:
62
    p->drawEllipse( baseX, baseY, w, h );
63
    //draw separator lines
64
    for( int i = 1; i < nCategories; ++i )
65
    {
66
      if( mOrientation == Horizontal )
67
      {
68
        lineEllipseIntersection( QPointF( baseX + w / nCategories * i, baseY ), QPointF( baseX + w / nCategories * i, baseY + h ), center, r1, r2, intersect );
69
      }
... This diff was truncated because it exceeds the maximum size that can be displayed.