100916_data_defined_label_position.diff

Marco Hugentobler, 2010-09-16 12:23 AM

Download (33.4 KB)

View differences:

src/app/qgslabelinggui.h (Arbeitskopie)
45 45
    void updatePreview();
46 46
    void updateOptions();
47 47

  
48
    void on_mXCoordinateComboBox_currentIndexChanged( const QString & text );
49
    void on_mYCoordinateComboBox_currentIndexChanged( const QString & text );
50

  
48 51
  protected:
49 52
    void populatePlacementMethods();
50 53
    void populateFieldNames();
......
57 60
  private:
58 61
    QgsPalLabeling* mLBL;
59 62
    QgsVectorLayer* mLayer;
63

  
64
    void disableDataDefinedAlignment();
65
    void enableDataDefinedAlignment();
60 66
};
61 67

  
62 68
#endif
src/app/qgslabelinggui.cpp (Arbeitskopie)
123 123
  chkMergeLines->setChecked( lyr.mergeLines );
124 124
  chkMultiLine->setChecked( lyr.multiLineLabels );
125 125
  mMinSizeSpinBox->setValue( lyr.minFeatureSize );
126
  chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
126 127

  
127 128
  bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
128 129
  chkScaleBasedVisibility->setChecked( scaleBased );
......
238 239
  {
239 240
    lyr.bufferSize = 0;
240 241
  }
242
  if ( chkAddDirectionSymbol->isChecked() )
243
  {
244
    lyr.addDirectionSymbol = true;
245
  }
246
  else
247
  {
248
    lyr.addDirectionSymbol = false;
249
  }
241 250
  lyr.minFeatureSize = mMinSizeSpinBox->value();
242 251

  
252

  
243 253
  //data defined labeling
244 254
  setDataDefinedProperty( mSizeAttributeComboBox, QgsPalLayerSettings::Size, lyr );
245 255
  setDataDefinedProperty( mColorAttributeComboBox, QgsPalLayerSettings::Color, lyr );
......
250 260
  setDataDefinedProperty( mFontFamilyAttributeComboBox, QgsPalLayerSettings::Family, lyr );
251 261
  setDataDefinedProperty( mBufferSizeAttributeComboBox, QgsPalLayerSettings:: BufferSize, lyr );
252 262
  setDataDefinedProperty( mBufferColorAttributeComboBox, QgsPalLayerSettings::BufferColor, lyr );
263
  setDataDefinedProperty( mXCoordinateComboBox, QgsPalLayerSettings::PositionX, lyr );
264
  setDataDefinedProperty( mYCoordinateComboBox, QgsPalLayerSettings::PositionY, lyr );
265
  setDataDefinedProperty( mHorizontalAlignmentComboBox, QgsPalLayerSettings::Hali, lyr );
266
  setDataDefinedProperty( mVerticalAlignmentComboBox, QgsPalLayerSettings::Vali, lyr );
253 267

  
254 268
  return lyr;
255 269
}
......
308 322
  comboList << mFontFamilyAttributeComboBox;
309 323
  comboList << mBufferSizeAttributeComboBox;
310 324
  comboList << mBufferColorAttributeComboBox;
325
  comboList << mXCoordinateComboBox;
326
  comboList << mYCoordinateComboBox;
327
  comboList << mHorizontalAlignmentComboBox;
328
  comboList << mVerticalAlignmentComboBox;
311 329

  
312 330
  QList<QComboBox*>::iterator comboIt = comboList.begin();
313 331
  for ( ; comboIt != comboList.end(); ++comboIt )
......
335 353
  setCurrentComboValue( mFontFamilyAttributeComboBox, s, QgsPalLayerSettings::Family );
336 354
  setCurrentComboValue( mBufferSizeAttributeComboBox, s , QgsPalLayerSettings::BufferSize );
337 355
  setCurrentComboValue( mBufferColorAttributeComboBox, s, QgsPalLayerSettings::BufferColor );
356
  setCurrentComboValue( mXCoordinateComboBox, s, QgsPalLayerSettings::PositionX );
357
  setCurrentComboValue( mYCoordinateComboBox, s, QgsPalLayerSettings::PositionY );
358
  setCurrentComboValue( mHorizontalAlignmentComboBox, s, QgsPalLayerSettings::Hali );
359
  setCurrentComboValue( mVerticalAlignmentComboBox, s, QgsPalLayerSettings::Vali );
338 360
}
339 361

  
340 362
void QgsLabelingGui::changeTextColor()
......
418 440
    stackedOptions->setCurrentWidget( pageOptionsEmpty );
419 441
  }
420 442
}
443

  
444
void QgsLabelingGui::on_mXCoordinateComboBox_currentIndexChanged( const QString & text )
445
{
446
  if ( text.isEmpty() ) //no data defined alignment without data defined position
447
  {
448
    disableDataDefinedAlignment();
449
  }
450
  else if ( !mYCoordinateComboBox->currentText().isEmpty() )
451
  {
452
    enableDataDefinedAlignment();
453
  }
454
}
455

  
456
void QgsLabelingGui::on_mYCoordinateComboBox_currentIndexChanged( const QString & text )
457
{
458
  if ( text.isEmpty() ) //no data defined alignment without data defined position
459
  {
460
    disableDataDefinedAlignment();
461
  }
462
  else if ( !mXCoordinateComboBox->currentText().isEmpty() )
463
  {
464
    enableDataDefinedAlignment();
465
  }
466
}
467

  
468
void QgsLabelingGui::disableDataDefinedAlignment()
469
{
470
  mHorizontalAlignmentComboBox->setCurrentIndex( mHorizontalAlignmentComboBox->findText( "" ) );
471
  mHorizontalAlignmentComboBox->setEnabled( false );
472
  mVerticalAlignmentComboBox->setCurrentIndex( mVerticalAlignmentComboBox->findText( "" ) );
473
  mVerticalAlignmentComboBox->setEnabled( false );
474
}
475

  
476
void QgsLabelingGui::enableDataDefinedAlignment()
477
{
478
  mHorizontalAlignmentComboBox->setEnabled( true );
479
  mVerticalAlignmentComboBox->setEnabled( true );
480
}
src/core/qgspallabeling.cpp (Arbeitskopie)
132 132
  minFeatureSize = 0.0;
133 133
  vectorScaleFactor = 1.0;
134 134
  rasterCompressFactor = 1.0;
135
  addDirectionSymbol = false;
135 136
}
136 137

  
137 138
QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
......
156 157
  minFeatureSize = s.minFeatureSize;
157 158
  vectorScaleFactor = s.vectorScaleFactor;
158 159
  rasterCompressFactor = s.rasterCompressFactor;
160
  addDirectionSymbol = s.addDirectionSymbol;
159 161

  
160 162
  dataDefinedProperties = s.dataDefinedProperties;
161 163
  fontMetrics = NULL;
......
193 195
    return;
194 196
  }
195 197

  
196
  for ( int i = 0; i < 9; ++i )
198
  for ( int i = 0; i < 13; ++i )
197 199
  {
198 200
    QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator it = propertyMap.find(( QgsPalLayerSettings::DataDefinedProperties )i );
199 201
    QVariant propertyValue;
......
242 244
  _readDataDefinedProperty( layer, QgsPalLayerSettings::Family, propertyMap );
243 245
  _readDataDefinedProperty( layer, QgsPalLayerSettings::BufferSize, propertyMap );
244 246
  _readDataDefinedProperty( layer, QgsPalLayerSettings::BufferColor, propertyMap );
247
  _readDataDefinedProperty( layer,  QgsPalLayerSettings::PositionX, propertyMap );
248
  _readDataDefinedProperty( layer,  QgsPalLayerSettings::PositionY, propertyMap );
249
  _readDataDefinedProperty( layer,  QgsPalLayerSettings::Hali, propertyMap );
250
  _readDataDefinedProperty( layer,  QgsPalLayerSettings::Vali, propertyMap );
245 251
}
246 252

  
247 253
void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
......
269 275
  labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
270 276
  mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
271 277
  multiLineLabels = layer->customProperty( "labeling/multiLineLabels" ).toBool();
278
  addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool();
272 279
  minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
273 280
  _readDataDefinedPropertyMap( layer, dataDefinedProperties );
274 281
}
......
299 306
  layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
300 307
  layer->setCustomProperty( "labeling/mergeLines", mergeLines );
301 308
  layer->setCustomProperty( "labeling/multiLineLabels", multiLineLabels );
309
  layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol );
302 310
  layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
303 311
  _writeDataDefinedPropertyMap( layer, dataDefinedProperties );
304 312
}
......
358 366
    return;
359 367
  }
360 368

  
369
  if ( addDirectionSymbol && !multiLineLabels && placement == QgsPalLayerSettings::Line ) //consider the space needed for the direction symbol
370
  {
371
    text.append( ">" );
372
  }
361 373
  QRectF labelRect = fm->boundingRect( text );
362 374
  double w, h;
363 375
  if ( !multiLineLabels )
......
391 403
{
392 404
  QString labelText = f.attributeMap()[fieldIndex].toString();
393 405
  double labelX, labelY; // will receive label size
406
  QFont labelFont = textFont;
394 407

  
395 408
  //data defined label size?
396 409
  QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size );
397 410
  if ( it != dataDefinedProperties.constEnd() )
398 411
  {
399
    QFont labelFont = textFont;
400 412
    //find out size
401 413
    QVariant size = f.attributeMap().value( *it );
402 414
    if ( size.isValid() )
......
430 442
    return;
431 443
  }
432 444

  
445
  //data defined position / alignment?
446
  bool dataDefinedPosition = false;
447
  double xPos, yPos;
448

  
449
  QMap< DataDefinedProperties, int >::const_iterator dPosXIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionX );
450
  if ( dPosXIt != dataDefinedProperties.constEnd() )
451
  {
452
    QMap< DataDefinedProperties, int >::const_iterator dPosYIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionY );
453
    if ( dPosYIt != dataDefinedProperties.constEnd() )
454
    {
455
      //data defined position
456
      dataDefinedPosition = true;
457
      xPos = f.attributeMap().value( *dPosXIt ).toDouble();
458
      yPos = f.attributeMap().value( *dPosYIt ).toDouble();
459

  
460
      //consider alignment settings (by adjusting xPos and yPos, which are lower/left in pal)
461

  
462
      //horizontal alignment
463
      QMap< DataDefinedProperties, int >::const_iterator haliIt = dataDefinedProperties.find( QgsPalLayerSettings::Hali );
464
      if ( haliIt != dataDefinedProperties.end() )
465
      {
466
        QString haliString = f.attributeMap().value( *haliIt ).toString();
467
        if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 )
468
        {
469
          xPos -= labelX / 2.0;
470
        }
471
        else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 )
472
        {
473
          xPos -= labelX;
474
        }
475
      }
476

  
477
      //vertical alignment
478
      QMap< DataDefinedProperties, int >::const_iterator valiIt = dataDefinedProperties.find( QgsPalLayerSettings::Vali );
479
      if ( valiIt != dataDefinedProperties.constEnd() )
480
      {
481
        QString valiString = f.attributeMap().value( *valiIt ).toString();
482
        if ( valiString.compare( "Bottom", Qt::CaseInsensitive ) != 0 )
483
        {
484
          if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 )
485
          {
486
            yPos -= labelY;
487
          }
488
          else
489
          {
490
            QFontMetrics labelFontMetrics( labelFont );
491
            double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height();
492

  
493
            if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 )
494
            {
495
              yPos -= labelY * descentRatio;
496
            }
497
            else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 )
498
            {
499
              yPos -= labelY * descentRatio;
500
              yPos -= labelY * 0.5 * ( 1 - descentRatio );
501
            }
502
          }
503
        }
504
      }
505
    }
506
  }
507

  
433 508
  QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), labelText, GEOSGeom_clone( geos_geom ) );
434 509

  
435 510
  // record the created geometry - it will be deleted at the end.
......
438 513
  // register feature to the layer
439 514
  try
440 515
  {
441
    if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData() ) )
516
    if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(), xPos, yPos, dataDefinedPosition ) )
442 517
      return;
443 518
  }
444 519
  catch ( std::exception* e )
......
871 946
  QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
872 947
  QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
873 948

  
949
  //add the direction symbol if needed
950
  if ( !txt.isEmpty() && lyr.placement == QgsPalLayerSettings::Line &&
951
       lyr.addDirectionSymbol && !lyr.multiLineLabels )
952
  {
953
    if ( label->getReversed() )
954
    {
955
      txt.prepend( "<" );
956
    }
957
    else
958
    {
959
      txt.append( ">" );
960
    }
961
  }
962

  
874 963
  //QgsDebugMsg( "drawLabel " + QString::number( drawBuffer ) + " " + txt );
875 964

  
876 965
  QStringList multiLineList;
src/core/pal/feature.h (Arbeitskopie)
86 86

  
87 87
      void setLabelInfo( LabelInfo* info ) { labelInfo = info; }
88 88
      void setDistLabel( double dist ) { distlabel = dist; }
89
      //Set label position of the feature to fixed x/y values
90
      void setFixedPosition( double x, double y ) { fixedPos = true; fixedPosX = x; fixedPosY = y;}
91
      bool fixedPosition() const { return fixedPos; }
89 92

  
90 93
    protected:
91 94
      Layer *layer;
......
97 100

  
98 101
      char *uid;
99 102

  
103
      bool fixedPos; //true in case of fixed position (only 1 candidate position with cost 0)
104
      double fixedPosX;
105
      double fixedPosY;
106

  
100 107
      // array of parts - possibly not necessary
101 108
      //int nPart;
102 109
      //FeaturePart** parts;
src/core/pal/labelposition.cpp (Arbeitskopie)
54 54

  
55 55
namespace pal
56 56
{
57
  LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature )
58
      : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 )
57
  LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed )
58
      : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 ), reversed( isReversed )
59 59
  {
60 60

  
61 61
    // alpha take his value bw 0 and 2*pi rad
src/core/pal/labelposition.h (Arbeitskopie)
74 74
      LabelPosition* nextPart;
75 75
      int partId;
76 76

  
77
      //True if label direction is the same as line / polygon ring direction.
78
      //Could be used by the application to draw a directional arrow ('<' or '>')
79
      //if the layer arrangement is P_LINE
80
      bool reversed;
81

  
77 82
      bool isInConflictSinglePart( LabelPosition* lp );
78 83
      bool isInConflictMultiPart( LabelPosition* lp );
79 84

  
......
93 98
      LabelPosition( int id, double x1, double y1,
94 99
                     double w, double h,
95 100
                     double alpha, double cost,
96
                     FeaturePart *feature );
101
                     FeaturePart *feature, bool isReversed = false );
97 102

  
98 103
      /** copy constructor */
99 104
      LabelPosition( const LabelPosition& other );
......
190 195
       * \return alpha to rotate text (in rad)
191 196
       */
192 197
      double getAlpha() const;
198
      bool getReversed() const { return reversed; }
193 199

  
194 200
      void print();
195 201

  
src/core/pal/layer.cpp (Arbeitskopie)
226 226

  
227 227

  
228 228

  
229
  bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText )
229
  bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
230
                               double labelPosX, double labelPosY, bool fixedPos )
230 231
  {
231 232
    if ( !geom_id || label_x < 0 || label_y < 0 )
232 233
      return false;
......
243 244
    GEOSGeometry *the_geom = userGeom->getGeosGeometry();
244 245

  
245 246
    Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y );
247
    if ( fixedPos )
248
    {
249
      f->setFixedPosition( labelPosX, labelPosY );
250
    }
246 251

  
247 252
    bool first_feat = true;
248 253

  
......
314 319
    modMutex->unlock();
315 320

  
316 321
    // if using only biggest parts...
317
    if ( mode == LabelPerFeature && biggest_part != NULL )
322
    if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
318 323
    {
319 324
      addFeaturePart( biggest_part, labelText );
320 325
      first_feat = false;
src/core/pal/layer.h (Arbeitskopie)
283 283
       * @param label_x label width
284 284
       * @param label_y label height
285 285
       * @param userGeom user's geometry that implements the PalGeometry interface
286
       * @param labelPosX x position of the label (in case of fixed label position)
287
       * @param labelPosY y position of the label (in case of fixed label position)
288
       * @param fixedPos true if a single fixed position for this label is needed
286 289
       *
287 290
       * @throws PalException::FeatureExists
288 291
       *
289 292
       * @return true on success (i.e. valid geometry)
290 293
       */
291
      bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1, const char* labelText = NULL );
294
      bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1,
295
                            const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0, bool fixedPos = false );
292 296

  
293 297
      /** return pointer to feature or NULL if doesn't exist */
294 298
      Feature* getFeature( const char* geom_id );
src/core/pal/feature.cpp (Arbeitskopie)
61 61
namespace pal
62 62
{
63 63
  Feature::Feature( Layer* l, const char* geom_id, PalGeometry* userG, double lx, double ly )
64
      : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL )
64
      : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL ), fixedPos( false )
65 65
  {
66 66
    uid = new char[strlen( geom_id ) +1];
67 67
    strcpy( uid, geom_id );
......
599 599
          reversed = ( alpha >= M_PI / 2 || alpha < -M_PI / 2 );
600 600

  
601 601
        if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
602
          positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this ) ); // Line
602
          positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this, reversed ) ); // Line
603 603
        if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
604
          positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this ) );   // Line
604
          positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this, reversed ) );   // Line
605 605
        if ( flags & FLAG_ON_LINE )
606
          positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this ) ); // Line
606
          positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this, reversed ) ); // Line
607 607
      }
608 608
      else if ( f->layer->arrangement == P_HORIZ )
609 609
      {
......
1245 1245

  
1246 1246
    double delta = bbox_max[0] - bbox_min[0];
1247 1247

  
1248
    switch ( type )
1248
    if ( f->fixedPosition() )
1249 1249
    {
1250
      case GEOS_POINT:
1251
        if ( f->layer->getArrangement() == P_POINT_OVER )
1252
          nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
1253
        else
1254
          nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
1255
        break;
1256
      case GEOS_LINESTRING:
1257
        if ( f->layer->getArrangement() == P_CURVED )
1258
          nbp = setPositionForLineCurved( lPos, mapShape );
1259
        else
1260
          nbp = setPositionForLine( scale, lPos, mapShape, delta );
1261
        break;
1250
      nbp = 1;
1251
      *lPos = new LabelPosition *[nbp];
1252
      ( *lPos )[0] = new LabelPosition( 0, f->fixedPosX, f->fixedPosY, f->label_x, f->label_y, 0, 0.0,  this );
1253
    }
1254
    else
1255
    {
1256
      switch ( type )
1257
      {
1258
        case GEOS_POINT:
1259
          if ( f->layer->getArrangement() == P_POINT_OVER )
1260
            nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
1261
          else
1262
            nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
1263
          break;
1264
        case GEOS_LINESTRING:
1265
          if ( f->layer->getArrangement() == P_CURVED )
1266
            nbp = setPositionForLineCurved( lPos, mapShape );
1267
          else
1268
            nbp = setPositionForLine( scale, lPos, mapShape, delta );
1269
          break;
1262 1270

  
1263
      case GEOS_POLYGON:
1264
        switch ( f->layer->getArrangement() )
1265
        {
1266
          case P_POINT:
1267
          case P_POINT_OVER:
1268
            double cx, cy;
1269
            mapShape->getCentroid( cx, cy );
1270
            if ( f->layer->getArrangement() == P_POINT_OVER )
1271
              nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
1272
            else
1273
              nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
1274
            break;
1275
          case P_LINE:
1276
            nbp = setPositionForLine( scale, lPos, mapShape, delta );
1277
            break;
1278
          default:
1279
            nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
1280
            break;
1281
        }
1271
        case GEOS_POLYGON:
1272
          switch ( f->layer->getArrangement() )
1273
          {
1274
            case P_POINT:
1275
            case P_POINT_OVER:
1276
              double cx, cy;
1277
              mapShape->getCentroid( cx, cy );
1278
              if ( f->layer->getArrangement() == P_POINT_OVER )
1279
                nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
1280
              else
1281
                nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
1282
              break;
1283
            case P_LINE:
1284
              nbp = setPositionForLine( scale, lPos, mapShape, delta );
1285
              break;
1286
            default:
1287
              nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
1288
              break;
1289
          }
1290
      }
1282 1291
    }
1283 1292

  
1284 1293
    int rnbp = nbp;
src/core/qgspallabeling.h (Arbeitskopie)
83 83
      Family,
84 84
      BufferSize,
85 85
      BufferColor,
86
      PositionX, //x-coordinate data defined label position
87
      PositionY, //y-coordinate data defined label position
88
      Hali, //horizontal alignment for data defined label position (Left, Center, Right)
89
      Vali //vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
86 90
    };
87 91

  
88 92
    QString fieldName;
......
103 107
    bool mergeLines;
104 108
    bool multiLineLabels; //draw labels on multiple lines if they contain '\n'
105 109
    double minFeatureSize; // minimum feature size to be labelled (in mm)
110
    // Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
111
    // Works only if Placement == Line
112
    bool addDirectionSymbol;
106 113

  
107 114
    // called from register feature hook
108 115
    void calculateLabelSize( const QFontMetrics* fm, QString text, double& labelX, double& labelY );
src/ui/qgslabelingguibase.ui (Arbeitskopie)
678 678
         </property>
679 679
        </widget>
680 680
       </item>
681
       <item row="7" column="0">
681
       <item row="8" column="0">
682 682
        <layout class="QHBoxLayout" name="horizontalLayout_19">
683 683
         <item>
684 684
          <widget class="QLabel" name="label_19">
......
696 696
         </item>
697 697
        </layout>
698 698
       </item>
699
       <item row="8" column="0">
699
       <item row="9" column="0">
700 700
        <layout class="QHBoxLayout" name="horizontalLayout_20">
701 701
         <item>
702 702
          <widget class="QCheckBox" name="chkNoObstacle">
......
733 733
         </item>
734 734
        </layout>
735 735
       </item>
736
       <item row="7" column="0">
737
        <widget class="QCheckBox" name="chkAddDirectionSymbol">
738
         <property name="text">
739
          <string>add direction symbol</string>
740
         </property>
741
        </widget>
742
       </item>
736 743
      </layout>
737 744
     </widget>
738 745
     <widget class="QWidget" name="tab_4">
739 746
      <attribute name="title">
740 747
       <string>Data defined settings</string>
741 748
      </attribute>
742
      <layout class="QGridLayout" name="gridLayout_4">
749
      <layout class="QGridLayout" name="gridLayout_3">
743 750
       <item row="0" column="0">
744 751
        <widget class="QGroupBox" name="mFontAttributePropertiesGroupBox">
745 752
         <property name="sizePolicy">
......
753 760
         </property>
754 761
         <layout class="QGridLayout" name="gridLayout">
755 762
          <item row="0" column="0">
756
           <layout class="QGridLayout" name="gridLayout_11">
757
            <item row="0" column="0">
758
             <widget class="QLabel" name="mSizeLabel">
759
              <property name="text">
760
               <string>Size</string>
761
              </property>
762
             </widget>
763
            </item>
764
            <item row="0" column="1">
765
             <widget class="QComboBox" name="mSizeAttributeComboBox"/>
766
            </item>
767
            <item row="2" column="0">
768
             <widget class="QLabel" name="mBoldLabel">
769
              <property name="text">
770
               <string>Bold</string>
771
              </property>
772
             </widget>
773
            </item>
774
            <item row="2" column="1">
775
             <widget class="QComboBox" name="mBoldAttributeComboBox"/>
776
            </item>
777
            <item row="1" column="1">
778
             <widget class="QComboBox" name="mColorAttributeComboBox"/>
779
            </item>
780
            <item row="1" column="0">
781
             <widget class="QLabel" name="mColorLabel">
782
              <property name="text">
783
               <string>Color</string>
784
              </property>
785
             </widget>
786
            </item>
787
            <item row="3" column="1">
788
             <widget class="QComboBox" name="mItalicAttributeComboBox"/>
789
            </item>
790
            <item row="3" column="0">
791
             <widget class="QLabel" name="mItalicLabel">
792
              <property name="text">
793
               <string>Italic</string>
794
              </property>
795
             </widget>
796
            </item>
797
            <item row="4" column="1">
798
             <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
799
            </item>
800
            <item row="4" column="0">
801
             <widget class="QLabel" name="mUnderlineLabel">
802
              <property name="text">
803
               <string>Underline</string>
804
              </property>
805
             </widget>
806
            </item>
807
            <item row="6" column="1">
808
             <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
809
            </item>
810
            <item row="6" column="0">
811
             <widget class="QLabel" name="mFontFamilyLabel">
812
              <property name="text">
813
               <string>Font family</string>
814
              </property>
815
             </widget>
816
            </item>
817
            <item row="5" column="1">
818
             <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
819
            </item>
820
            <item row="5" column="0">
821
             <widget class="QLabel" name="mStrikeoutLabel">
822
              <property name="text">
823
               <string>Strikeout</string>
824
              </property>
825
             </widget>
826
            </item>
827
           </layout>
763
           <widget class="QLabel" name="mSizeLabel">
764
            <property name="text">
765
             <string>Size</string>
766
            </property>
767
           </widget>
828 768
          </item>
769
          <item row="0" column="1">
770
           <widget class="QComboBox" name="mSizeAttributeComboBox"/>
771
          </item>
772
          <item row="1" column="0">
773
           <widget class="QLabel" name="mColorLabel">
774
            <property name="text">
775
             <string>Color</string>
776
            </property>
777
           </widget>
778
          </item>
779
          <item row="1" column="1">
780
           <widget class="QComboBox" name="mColorAttributeComboBox"/>
781
          </item>
782
          <item row="2" column="0">
783
           <widget class="QLabel" name="mBoldLabel">
784
            <property name="text">
785
             <string>Bold</string>
786
            </property>
787
           </widget>
788
          </item>
789
          <item row="2" column="1">
790
           <widget class="QComboBox" name="mBoldAttributeComboBox"/>
791
          </item>
792
          <item row="3" column="0">
793
           <widget class="QLabel" name="mItalicLabel">
794
            <property name="text">
795
             <string>Italic</string>
796
            </property>
797
           </widget>
798
          </item>
799
          <item row="3" column="1">
800
           <widget class="QComboBox" name="mItalicAttributeComboBox"/>
801
          </item>
802
          <item row="4" column="0">
803
           <widget class="QLabel" name="mUnderlineLabel">
804
            <property name="text">
805
             <string>Underline</string>
806
            </property>
807
           </widget>
808
          </item>
809
          <item row="4" column="1">
810
           <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
811
          </item>
812
          <item row="5" column="0">
813
           <widget class="QLabel" name="mStrikeoutLabel">
814
            <property name="text">
815
             <string>Strikeout</string>
816
            </property>
817
           </widget>
818
          </item>
819
          <item row="5" column="1">
820
           <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
821
          </item>
822
          <item row="6" column="0">
823
           <widget class="QLabel" name="mFontFamilyLabel">
824
            <property name="text">
825
             <string>Font family</string>
826
            </property>
827
           </widget>
828
          </item>
829
          <item row="6" column="1">
830
           <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
831
          </item>
829 832
         </layout>
830 833
        </widget>
831 834
       </item>
......
834 837
         <property name="title">
835 838
          <string>Buffer properties</string>
836 839
         </property>
837
         <layout class="QGridLayout" name="gridLayout_3">
840
         <layout class="QGridLayout" name="gridLayout_2">
838 841
          <item row="0" column="0">
839
           <layout class="QGridLayout" name="gridLayout_2">
840
            <item row="0" column="0">
841
             <widget class="QLabel" name="mBufferSizeLabel">
842
              <property name="text">
843
               <string>Buffer size</string>
844
              </property>
845
             </widget>
846
            </item>
847
            <item row="0" column="1">
848
             <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
849
            </item>
850
            <item row="1" column="0">
851
             <widget class="QLabel" name="mBufferColorLabel">
852
              <property name="text">
853
               <string>Buffer color</string>
854
              </property>
855
             </widget>
856
            </item>
857
            <item row="1" column="1">
858
             <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
859
            </item>
860
           </layout>
842
           <widget class="QLabel" name="mBufferSizeLabel">
843
            <property name="text">
844
             <string>Buffer size</string>
845
            </property>
846
           </widget>
861 847
          </item>
848
          <item row="0" column="1">
849
           <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
850
          </item>
851
          <item row="1" column="0">
852
           <widget class="QLabel" name="mBufferColorLabel">
853
            <property name="text">
854
             <string>Buffer color</string>
855
            </property>
856
           </widget>
857
          </item>
858
          <item row="1" column="1">
859
           <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
860
          </item>
862 861
         </layout>
863 862
        </widget>
864 863
       </item>
865 864
       <item row="2" column="0">
865
        <widget class="QGroupBox" name="mPositionAttributeGroupBox">
866
         <property name="title">
867
          <string>Position</string>
868
         </property>
869
         <layout class="QGridLayout" name="gridLayout_4">
870
          <item row="0" column="0">
871
           <widget class="QLabel" name="mXCoordinateLabel">
872
            <property name="text">
873
             <string>X Coordinate</string>
874
            </property>
875
           </widget>
876
          </item>
877
          <item row="0" column="1">
878
           <widget class="QComboBox" name="mXCoordinateComboBox"/>
879
          </item>
880
          <item row="1" column="0">
881
           <widget class="QLabel" name="mYCoordinateLabel">
882
            <property name="text">
883
             <string>Y Coordinate</string>
884
            </property>
885
           </widget>
886
          </item>
887
          <item row="1" column="1">
888
           <widget class="QComboBox" name="mYCoordinateComboBox"/>
889
          </item>
890
          <item row="2" column="0">
891
           <widget class="QLabel" name="mHorizontalAlignmentLabel">
892
            <property name="text">
893
             <string>Horizontal alignment</string>
894
            </property>
895
           </widget>
896
          </item>
897
          <item row="2" column="1">
898
           <widget class="QComboBox" name="mHorizontalAlignmentComboBox"/>
899
          </item>
900
          <item row="3" column="0">
901
           <widget class="QLabel" name="mVerticalAlignmentLabel">
902
            <property name="text">
903
             <string>Vertical alignment</string>
904
            </property>
905
           </widget>
906
          </item>
907
          <item row="3" column="1">
908
           <widget class="QComboBox" name="mVerticalAlignmentComboBox"/>
909
          </item>
910
         </layout>
911
        </widget>
912
       </item>
913
       <item row="3" column="0">
866 914
        <spacer name="verticalSpacer">
867 915
         <property name="orientation">
868 916
          <enum>Qt::Vertical</enum>