QGIS API Documentation  2.12.0-Lyon
qgslabel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslabel.cpp - render vector labels
3  -------------------
4  begin : August 2004
5  copyright : (C) 2004 by Radim Blazek
6  email : [email protected]
7  ***************************************************************************/
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include <cmath>
18 #include <limits>
19 
20 #include <QString>
21 #include <QFont>
22 #include <QFontMetrics>
23 
24 #include <QPainter>
25 #include <QDomNode>
26 #include <QDomElement>
27 
28 #include "qgis.h"
29 #include "qgsfeature.h"
30 #include "qgsgeometry.h"
31 #include "qgsfield.h"
32 #include "qgslogger.h"
33 #include "qgsrectangle.h"
34 #include "qgsmaptopixel.h"
35 #include "qgscoordinatetransform.h"
36 #include "qgsrendercontext.h"
37 
38 #include "qgslabelattributes.h"
39 #include "qgslabel.h"
40 
41 // use M_PI define PI 3.141592654
42 #ifdef Q_OS_WIN
43 #undef M_PI
44 #define M_PI 4*atan(1.0)
45 #endif
46 
47 QgsLabel::QgsLabel( const QgsFields & fields )
48  : mMinScale( 0 )
49  , mMaxScale( 100000000 )
50  , mScaleBasedVisibility( false )
51 {
52  mFields = fields;
53  mLabelFieldIdx.resize( LabelFieldCount );
54  for ( int i = 0; i < LabelFieldCount; i++ )
55  {
56  mLabelFieldIdx[i] = -1;
57  }
58  mLabelAttributes = new QgsLabelAttributes( true );
59 }
60 
62 {
63  delete mLabelAttributes;
64 }
65 
67 {
68  int idx = mLabelFieldIdx[attr];
69  return idx < 0 ? QString() : feature.attribute( idx ).toString();
70 }
71 
73  QgsFeature &feature, bool selected,
74  QgsLabelAttributes *classAttributes )
75 {
76  Q_UNUSED( classAttributes );
77 
78  if ( mLabelAttributes->selectedOnly() && !selected )
79  return;
80 
81  QPen pen;
82  QFont font;
83  QString value;
84  QString text;
85 
86  /* Calc scale (not nice) */
87  QgsPoint point;
88  point = renderContext.mapToPixel().transform( 0, 0 );
89  double x1 = point.x();
90  point = renderContext.mapToPixel().transform( 1000, 0 );
91  double x2 = point.x();
92  double scale = ( x2 - x1 ) * 0.001;
93 
94  /* Text */
95  value = fieldValue( Text, feature );
96  if ( value.isEmpty() )
97  {
98  text = mLabelAttributes->text();
99  }
100  else
101  {
102  text = value;
103  }
104 
105  /* Font */
106  value = fieldValue( Family, feature );
107  if ( value.isEmpty() )
108  {
109  font.setFamily( mLabelAttributes->family() );
110  }
111  else
112  {
113  font.setFamily( value );
114  }
115 
116  double size;
117  value = fieldValue( Size, feature );
118  if ( value.isEmpty() )
119  {
120  size = mLabelAttributes->size();
121  }
122  else
123  {
124  size = value.toDouble();
125  }
126  int sizeType;
127  value = fieldValue( SizeType, feature );
128  if ( value.isEmpty() )
129  sizeType = mLabelAttributes->sizeType();
130  else
131  {
132  value = value.toLower();
133  if ( value.compare( "mapunits" ) == 0 )
134  sizeType = QgsLabelAttributes::MapUnits;
135  else
137  }
138  if ( sizeType == QgsLabelAttributes::MapUnits )
139  {
140  size *= scale;
141  }
142  else //point units
143  {
144  double sizeMM = size * 0.3527;
145  size = sizeMM * renderContext.scaleFactor();
146  }
147 
148  //Request font larger (multiplied by rasterScaleFactor) as a workaround for the Qt font bug
149  //and scale the painter down by rasterScaleFactor when drawing the label
150  size *= renderContext.rasterScaleFactor();
151 
152  if (( int )size <= 0 )
153  // skip too small labels
154  return;
155 
156  font.setPixelSize( size );
157 
158  value = fieldValue( Color, feature );
159  if ( value.isEmpty() )
160  {
161  pen.setColor( mLabelAttributes->color() );
162  }
163  else
164  {
165  pen.setColor( QColor( value ) );
166  }
167 
168  value = fieldValue( Bold, feature );
169  if ( value.isEmpty() )
170  {
171  font.setBold( mLabelAttributes->bold() );
172  }
173  else
174  {
175  font.setBold(( bool ) value.toInt() );
176  }
177 
178  value = fieldValue( Italic, feature );
179  if ( value.isEmpty() )
180  {
181  font.setItalic( mLabelAttributes->italic() );
182  }
183  else
184  {
185  font.setItalic(( bool ) value.toInt() );
186  }
187 
188  value = fieldValue( Underline, feature );
189  if ( value.isEmpty() )
190  {
191  font.setUnderline( mLabelAttributes->underline() );
192  }
193  else
194  {
195  font.setUnderline(( bool ) value.toInt() );
196  }
197 
198  value = fieldValue( StrikeOut, feature );
199  if ( value.isEmpty() )
200  {
201  font.setStrikeOut( mLabelAttributes->strikeOut() );
202  }
203  else
204  {
205  font.setStrikeOut(( bool ) value.toInt() );
206  }
207 
208  //
209  QgsPoint overridePoint;
210  bool useOverridePoint = false;
211  value = fieldValue( XCoordinate, feature );
212  if ( !value.isEmpty() )
213  {
214  overridePoint.setX( value.toDouble() );
215  useOverridePoint = true;
216  }
217  value = fieldValue( YCoordinate, feature );
218  if ( !value.isEmpty() )
219  {
220  overridePoint.setY( value.toDouble() );
221  useOverridePoint = true;
222  }
223 
224  /* Alignment */
225  int alignment;
226  QFontMetrics fm( font );
227  int width, height;
228 
229  if ( mLabelAttributes->multilineEnabled() )
230  {
231  QStringList texts = text.split( "\n" );
232 
233  width = 0;
234  for ( int i = 0; i < texts.size(); i++ )
235  {
236  int w = fm.width( texts[i] );
237  if ( w > width )
238  width = w;
239  }
240 
241  height = fm.height() * texts.size();
242  }
243  else
244  {
245  width = fm.width( text );
246  height = fm.height();
247  }
248 
249  int dx = 0;
250  int dy = 0;
251 
252  value = fieldValue( Alignment, feature );
253  if ( value.isEmpty() )
254  {
255  alignment = mLabelAttributes->alignment();
256  }
257  else
258  {
259  value = value.toLower();
260 
261  alignment = 0;
262 
263  if ( value.contains( "left" ) )
264  alignment |= Qt::AlignLeft;
265  else if ( value.contains( "right" ) )
266  alignment |= Qt::AlignRight;
267  else
268  alignment |= Qt::AlignHCenter;
269 
270  if ( value.contains( "bottom" ) )
271  alignment |= Qt::AlignBottom;
272  else if ( value.contains( "top" ) )
273  alignment |= Qt::AlignTop;
274  else
275  alignment |= Qt::AlignVCenter;
276  }
277 
278  if ( alignment & Qt::AlignLeft )
279  {
280  dx = 0;
281  }
282  else if ( alignment & Qt::AlignHCenter )
283  {
284  dx = -width / 2;
285  }
286  else if ( alignment & Qt::AlignRight )
287  {
288  dx = -width;
289  }
290 
291  if ( alignment & Qt::AlignBottom )
292  {
293  dy = 0;
294  }
295  else if ( alignment & Qt::AlignVCenter )
296  {
297  dy = height / 2;
298  }
299  else if ( alignment & Qt::AlignTop )
300  {
301  dy = height;
302  }
303 
304  // Offset
305  double xoffset, yoffset;
306  value = fieldValue( XOffset, feature );
307  if ( value.isEmpty() )
308  {
309  xoffset = mLabelAttributes->xOffset();
310  }
311  else
312  {
313  xoffset = value.toDouble();
314  }
315  value = fieldValue( YOffset, feature );
316  if ( value.isEmpty() )
317  {
318  yoffset = mLabelAttributes->yOffset();
319  }
320  else
321  {
322  yoffset = value.toDouble();
323  }
324 
325  // recalc offset to pixels
326  if ( mLabelAttributes->offsetType() == QgsLabelAttributes::MapUnits )
327  {
328  xoffset *= scale;
329  yoffset *= scale;
330  }
331  else
332  {
333  xoffset = xoffset * 0.3527 * renderContext.scaleFactor();
334  yoffset = yoffset * 0.3527 * renderContext.scaleFactor();
335  }
336 
337  // Angle
338  double ang;
339  value = fieldValue( Angle, feature );
340  if ( value.isEmpty() )
341  {
342  ang = mLabelAttributes->angle();
343  }
344  else
345  {
346  ang = value.toDouble();
347  }
348 
349 
350  // Work out a suitable position to put the label for the
351  // feature. For multi-geometries, put the same label on each
352  // part.
353  if ( useOverridePoint )
354  {
355  renderLabel( renderContext, overridePoint, text, font, pen, dx, dy,
356  xoffset, yoffset, ang, width, height, alignment );
357  }
358  else
359  {
360  std::vector<labelpoint> points;
361  labelPoint( points, feature );
362  for ( uint i = 0; i < points.size(); ++i )
363  {
364  renderLabel( renderContext, points[i].p, text, font, pen, dx, dy,
365  xoffset, yoffset, mLabelAttributes->angleIsAuto() ? points[i].angle : ang, width, height, alignment );
366  }
367  }
368 }
369 
370 void QgsLabel::renderLabel( QgsRenderContext &renderContext,
371  QgsPoint point,
372  const QString& text, const QFont& font, const QPen& pen,
373  int dx, int dy,
374  double xoffset, double yoffset,
375  double ang,
376  int width, int height, int alignment )
377 {
378  QPainter *painter = renderContext.painter();
379 
380  // Convert point to projected units
381  if ( renderContext.coordinateTransform() )
382  {
383  try
384  {
385  point = renderContext.coordinateTransform()->transform( point );
386  }
387  catch ( QgsCsException &cse )
388  {
389  Q_UNUSED( cse ); // unused otherwise
390  QgsDebugMsg( "Caught transform error. Skipping rendering this label" );
391  return;
392  }
393  }
394 
395  // and then to canvas units
396  renderContext.mapToPixel().transform( &point );
397  double x = point.x();
398  double y = point.y();
399 
400  double rad = ang * M_PI / 180;
401 
402  x = x + xoffset * cos( rad ) - yoffset * sin( rad );
403  y = y - xoffset * sin( rad ) - yoffset * cos( rad );
404 
405  painter->save();
406  painter->setFont( font );
407  painter->translate( x, y );
408  //correct oversampled font size back by scaling painter down
409  painter->scale( 1.0 / renderContext.rasterScaleFactor(), 1.0 / renderContext.rasterScaleFactor() );
410  painter->rotate( -ang );
411 
412  //
413  // Draw a buffer behind the text if one is desired
414  //
415  if ( mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled() )
416  {
417  double myBufferSize = mLabelAttributes->bufferSize() * 0.3527 * renderContext.scaleFactor() * renderContext.rasterScaleFactor();
418  QPen bufferPen;
419  if ( mLabelAttributes->bufferColorIsSet() )
420  {
421  bufferPen.setColor( mLabelAttributes->bufferColor() );
422  }
423  else //default to a white buffer
424  {
425  bufferPen.setColor( Qt::white );
426  }
427  painter->setPen( bufferPen );
428 
429  double bufferStepSize; //hack to distinguish pixel devices from logical devices
430  if (( renderContext.scaleFactor() - 1 ) > 1.5 )
431  {
432  bufferStepSize = 1;
433  }
434  else //draw more dense in case of logical devices
435  {
436  bufferStepSize = 1 / renderContext.rasterScaleFactor();
437  }
438 
439  for ( double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize )
440  {
441  for ( double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize )
442  {
443  if ( mLabelAttributes->multilineEnabled() )
444  painter->drawText( QRectF( i, j - height, width, height ), alignment, text );
445  else
446  painter->drawText( QPointF( i, j ), text );
447  }
448  }
449  }
450 
451  painter->setPen( pen );
452  if ( mLabelAttributes->multilineEnabled() )
453  painter->drawText( dx, dy - height, width, height, alignment, text );
454  else
455  painter->drawText( dx, dy, text );
456  painter->restore();
457 }
458 
460 {
461  for ( uint i = 0; i < LabelFieldCount; i++ )
462  {
463  if ( mLabelFieldIdx[i] == -1 )
464  continue;
465  bool found = false;
466  for ( QgsAttributeList::iterator it = fields.begin(); it != fields.end(); ++it )
467  {
468  if ( *it == mLabelFieldIdx[i] )
469  {
470  found = true;
471  break;
472  }
473  }
474  if ( !found )
475  {
476  fields.append( mLabelFieldIdx[i] );
477  }
478  }
479 }
480 
481 void QgsLabel::setFields( const QgsFields & fields )
482 {
483  mFields = fields;
484 }
485 
487 {
488  return mFields;
489 }
490 
491 void QgsLabel::setLabelField( int attr, int fieldIndex )
492 {
493  if ( attr >= LabelFieldCount )
494  return;
495 
496  mLabelFieldIdx[attr] = fieldIndex;
497 }
498 
499 QString QgsLabel::labelField( int attr ) const
500 {
501  if ( attr >= LabelFieldCount )
502  return QString();
503 
504  int fieldIndex = mLabelFieldIdx[attr];
505  if ( fieldIndex < 0 || fieldIndex >= mFields.count() )
506  return QString();
507  return mFields[fieldIndex].name();
508 }
509 
511 {
512  return mLabelAttributes;
513 }
514 
515 void QgsLabel::labelPoint( std::vector<labelpoint>& points, QgsFeature & feature )
516 {
517  const QgsGeometry *geometry = feature.constGeometry();
518  const unsigned char *geom = geometry->asWkb();
519  size_t geomlen = geometry->wkbSize();
520  QGis::WkbType wkbType = geometry->wkbType();
521  labelpoint point;
522 
523  switch ( wkbType )
524  {
525  case QGis::WKBPoint25D:
526  case QGis::WKBPoint:
528  case QGis::WKBLineString:
529  case QGis::WKBPolygon25D:
530  case QGis::WKBPolygon:
531  {
532  labelPoint( point, geom, geomlen );
533  points.push_back( point );
534  }
535  break;
536 
538  case QGis::WKBMultiPoint:
543  // Return a position for each individual in the multi-feature
544  {
545  Q_ASSERT( 1 + sizeof( wkbType ) + sizeof( int ) <= geomlen );
546  geom += 1 + sizeof( wkbType );
547  int nFeatures = *( unsigned int * )geom;
548  geom += sizeof( int );
549 
550  const unsigned char *feature = geom;
551  for ( int i = 0; i < nFeatures && feature; ++i )
552  {
553  feature = labelPoint( point, feature, geom + geomlen - feature );
554  points.push_back( point );
555  }
556  }
557  break;
558  default:
559  QgsDebugMsg( "Unknown geometry type of " + QString::number( wkbType ) );
560  }
561 }
562 
563 const unsigned char* QgsLabel::labelPoint( labelpoint& point, const unsigned char *geom, size_t geomlen )
564 {
565  // verify that local types match sizes as WKB spec
566  Q_ASSERT( sizeof( int ) == 4 );
567  Q_ASSERT( sizeof( QGis::WkbType ) == 4 );
568  Q_ASSERT( sizeof( double ) == 8 );
569 
570  if ( geom == NULL )
571  {
572  QgsDebugMsg( "empty wkb" );
573  return NULL;
574  }
575 
576  QGis::WkbType wkbType;
577 #ifndef QT_NO_DEBUG
578  const unsigned char *geomend = geom + geomlen;
579  Q_ASSERT( geom + 1 + sizeof( wkbType ) <= geomend );
580 #else
581  Q_UNUSED( geomlen );
582 #endif
583 
584  geom++; // skip endianness
585  memcpy( &wkbType, geom, sizeof( wkbType ) );
586  geom += sizeof( wkbType );
587 
588  int dims = 2;
589 
590  switch ( wkbType )
591  {
592  case QGis::WKBPoint25D:
593  case QGis::WKBPoint:
594  {
595 #ifndef QT_NO_DEBUG
596  Q_ASSERT( geom + 2*sizeof( double ) <= geomend );
597 #endif
598  double *pts = ( double * )geom;
599  point.p.set( pts[0], pts[1] );
600  point.angle = 0.0;
601  geom += 2 * sizeof( double );
602  }
603  break;
604 
606  dims = 3;
607  //intentional fall-through
608  case QGis::WKBLineString: // Line center
609  {
610 #ifndef QT_NO_DEBUG
611  Q_ASSERT( geom + sizeof( int ) <= geomend );
612 #endif
613  int nPoints = *( unsigned int * )geom;
614  geom += sizeof( int );
615 
616 #ifndef QT_NO_DEBUG
617  Q_ASSERT( geom + nPoints*sizeof( double )*dims <= geomend );
618 #endif
619 
620  // get line center
621  double *pts = ( double * )geom;
622  double tl = 0.0;
623  for ( int i = 1; i < nPoints; i++ )
624  {
625  double dx = pts[dims*i] - pts[dims*( i-1 )];
626  double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
627  tl += sqrt( dx * dx + dy * dy );
628  }
629  tl /= 2.0;
630 
631  // find line center
632  double l = 0.0;
633  for ( int i = 1; i < nPoints; i++ )
634  {
635  double dx = pts[dims*i] - pts[dims*( i-1 )];
636  double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
637  double dl = sqrt( dx * dx + dy * dy );
638 
639  if ( l + dl > tl )
640  {
641  double k = ( tl - l ) / dl;
642 
643  point.p.set( pts[dims*( i-1 )] + k * dx,
644  pts[dims*( i-1 )+1] + k * dy );
645  point.angle = atan2( dy, dx ) * 180.0 * M_1_PI;
646  break;
647  }
648 
649  l += dl;
650  }
651 
652  geom += nPoints * sizeof( double ) * dims;
653  }
654  break;
655 
656  case QGis::WKBPolygon25D:
657  dims = 3;
658  //intentional fall-through
659  case QGis::WKBPolygon: // centroid of outer ring
660  {
661 #ifndef QT_NO_DEBUG
662  Q_ASSERT( geom + sizeof( int ) <= geomend );
663 #endif
664  int nRings = *( unsigned int * )geom;
665  geom += sizeof( int );
666 
667  for ( int i = 0; i < nRings; ++i )
668  {
669 #ifndef QT_NO_DEBUG
670  Q_ASSERT( geom + sizeof( int ) <= geomend );
671 #endif
672  int nPoints = *( unsigned int * )geom;
673  geom += sizeof( int );
674 
675 #ifndef QT_NO_DEBUG
676  Q_ASSERT( geom + nPoints*sizeof( double )*dims <= geomend );
677 #endif
678 
679  if ( i == 0 )
680  {
681  double sx = 0.0, sy = 0.0;
682  double *pts = ( double* ) geom;
683  for ( int j = 0; j < nPoints - 1; j++ )
684  {
685  sx += pts[dims*j];
686  sy += pts[dims*j+1];
687  }
688  point.p.set( sx / ( nPoints - 1 ),
689  sy / ( nPoints - 1 ) );
690  point.angle = 0.0;
691  }
692 
693  geom += nPoints * sizeof( double ) * dims;
694  }
695  }
696  break;
697 
698  default:
699  // To get here is a bug because our caller should be filtering
700  // on wkb type.
701  QgsDebugMsg( "unsupported wkb type" );
702  return NULL;
703  }
704 
705  return geom;
706 }
707 
708 bool QgsLabel::readLabelField( QDomElement &el, int attr, const QString& prefix = "field" )
709 {
710  QString name = prefix + "name";
711 
712  if ( el.hasAttribute( name ) )
713  {
714  name = el.attribute( name );
715 
716  int idx = 0;
717  for ( ; idx < mFields.count(); ++idx )
718  {
719  if ( mFields.at( idx ).name() == name )
720  {
721  break;
722  }
723  }
724 
725  if ( idx != mFields.count() )
726  {
727  mLabelFieldIdx[attr] = idx;
728  return true;
729  }
730  }
731  else if ( el.hasAttribute( prefix ) )
732  {
733  QString value = el.attribute( prefix );
734  mLabelFieldIdx[attr] = value.isEmpty() ? -1 : value.toInt();
735  return true;
736  }
737 
738  mLabelFieldIdx[attr] = -1;
739  return false;
740 }
741 
742 
743 void QgsLabel::readXML( const QDomNode& node )
744 {
745  QgsDebugMsg( " called for layer label properties, got node " + node.nodeName() );
746 
747  QDomNode scratchNode; // Dom node re-used to get current QgsLabel attribute
748  QDomElement el;
749 
750  int red, green, blue;
751  int type;
752 
753  /* Text */
754  scratchNode = node.namedItem( "label" );
755 
756  if ( scratchNode.isNull() )
757  {
758  QgsDebugMsg( "couldn't find QgsLabel ``label'' attribute" );
759  }
760  else
761  {
762  el = scratchNode.toElement();
763  mLabelAttributes->setText( el.attribute( "text", "" ) );
764  readLabelField( el, Text );
765  }
766 
767  /* Family */
768  scratchNode = node.namedItem( "family" );
769 
770  if ( scratchNode.isNull() )
771  {
772  QgsDebugMsg( "couldn't find QgsLabel ``family'' attribute" );
773  }
774  else
775  {
776  el = scratchNode.toElement();
777  mLabelAttributes->setFamily( el.attribute( "name", "" ) );
778  readLabelField( el, Family );
779  }
780 
781  /* Size */
782  scratchNode = node.namedItem( "size" );
783 
784  if ( scratchNode.isNull() )
785  {
786  QgsDebugMsg( "couldn't find QgsLabel ``size'' attribute" );
787  }
788  else
789  {
790  el = scratchNode.toElement();
791  if ( !el.hasAttribute( "unitfield" ) && !el.hasAttribute( "unitfieldname" ) )
792  {
793  type = QgsLabelAttributes::unitsCode( el.attribute( "units", "" ) );
794  mLabelAttributes->setSize( el.attribute( "value", "0.0" ).toDouble(), type );
795  }
796  else
797  {
798  readLabelField( el, SizeType, "unitfield" );
799  }
800  readLabelField( el, Size );
801  }
802 
803  /* Bold */
804  scratchNode = node.namedItem( "bold" );
805 
806  if ( scratchNode.isNull() )
807  {
808  QgsDebugMsg( "couldn't find QgsLabel ``bold'' attribute" );
809  }
810  else
811  {
812  el = scratchNode.toElement();
813  mLabelAttributes->setBold(( bool )el.attribute( "on", "0" ).toInt() );
814  readLabelField( el, Bold );
815  }
816 
817  /* Italic */
818  scratchNode = node.namedItem( "italic" );
819 
820  if ( scratchNode.isNull() )
821  {
822  QgsDebugMsg( "couldn't find QgsLabel ``italic'' attribute" );
823  }
824  else
825  {
826  el = scratchNode.toElement();
827  mLabelAttributes->setItalic(( bool )el.attribute( "on", "0" ).toInt() );
828  readLabelField( el, Italic );
829  }
830 
831  /* Underline */
832  scratchNode = node.namedItem( "underline" );
833 
834  if ( scratchNode.isNull() )
835  {
836  QgsDebugMsg( "couldn't find QgsLabel ``underline'' attribute" );
837  }
838  else
839  {
840  el = scratchNode.toElement();
841  mLabelAttributes->setUnderline(( bool )el.attribute( "on", "0" ).toInt() );
842  readLabelField( el, Underline );
843  }
844 
845  /* Strikeout */
846  scratchNode = node.namedItem( "strikeout" );
847 
848  if ( scratchNode.isNull() )
849  {
850  QgsDebugMsg( "couldn't find QgsLabel ``strikeout'' attribute" );
851  }
852  else
853  {
854  el = scratchNode.toElement();
855  mLabelAttributes->setStrikeOut(( bool )el.attribute( "on", "0" ).toInt() );
856  readLabelField( el, StrikeOut );
857  }
858 
859  /* Color */
860  scratchNode = node.namedItem( "color" );
861 
862  if ( scratchNode.isNull() )
863  {
864  QgsDebugMsg( "couldn't find QgsLabel ``color'' attribute" );
865  }
866  else
867  {
868  el = scratchNode.toElement();
869 
870  red = el.attribute( "red", "0" ).toInt();
871  green = el.attribute( "green", "0" ).toInt();
872  blue = el.attribute( "blue", "0" ).toInt();
873 
874  mLabelAttributes->setColor( QColor( red, green, blue ) );
875 
876  readLabelField( el, Color );
877  }
878 
879  /* X */
880  scratchNode = node.namedItem( "x" );
881 
882  if ( scratchNode.isNull() )
883  {
884  QgsDebugMsg( "couldn't find QgsLabel ``x'' attribute" );
885  }
886  else
887  {
888  el = scratchNode.toElement();
889  readLabelField( el, XCoordinate );
890  }
891 
892  /* Y */
893  scratchNode = node.namedItem( "y" );
894 
895  if ( scratchNode.isNull() )
896  {
897  QgsDebugMsg( "couldn't find QgsLabel ``y'' attribute" );
898  }
899  else
900  {
901  el = scratchNode.toElement();
902  readLabelField( el, YCoordinate );
903  }
904 
905 
906  /* X,Y offset */
907  scratchNode = node.namedItem( "offset" );
908 
909  if ( scratchNode.isNull() )
910  {
911  QgsDebugMsg( "couldn't find QgsLabel ``offset'' attribute" );
912  }
913  else
914  {
915  double xoffset, yoffset;
916 
917  el = scratchNode.toElement();
918 
919  type = QgsLabelAttributes::unitsCode( el.attribute( "units", "" ) );
920  xoffset = el.attribute( "x", "0.0" ).toDouble();
921  yoffset = el.attribute( "y", "0.0" ).toDouble();
922 
923  mLabelAttributes->setOffset( xoffset, yoffset, type );
924  readLabelField( el, XOffset, "xfield" );
925  readLabelField( el, YOffset, "yfield" );
926  }
927 
928  /* Angle */
929  scratchNode = node.namedItem( "angle" );
930 
931  if ( scratchNode.isNull() )
932  {
933  QgsDebugMsg( "couldn't find QgsLabel ``angle'' attribute" );
934  }
935  else
936  {
937  el = scratchNode.toElement();
938  mLabelAttributes->setAngle( el.attribute( "value", "0.0" ).toDouble() );
939  readLabelField( el, Angle );
940  mLabelAttributes->setAutoAngle( el.attribute( "auto", "0" ) == "1" );
941  }
942 
943  /* Alignment */
944  scratchNode = node.namedItem( "alignment" );
945 
946  if ( scratchNode.isNull() )
947  {
948  QgsDebugMsg( "couldn't find QgsLabel ``alignment'' attribute" );
949  }
950  else
951  {
952  el = scratchNode.toElement();
953  mLabelAttributes->setAlignment( QgsLabelAttributes::alignmentCode( el.attribute( "value", "" ) ) );
954  readLabelField( el, Alignment );
955  }
956 
957 
958  // Buffer
959  scratchNode = node.namedItem( "buffercolor" );
960 
961  if ( scratchNode.isNull() )
962  {
963  QgsDebugMsg( "couldn't find QgsLabel ``buffercolor'' attribute" );
964  }
965  else
966  {
967  el = scratchNode.toElement();
968 
969  red = el.attribute( "red", "0" ).toInt();
970  green = el.attribute( "green", "0" ).toInt();
971  blue = el.attribute( "blue", "0" ).toInt();
972 
973  mLabelAttributes->setBufferColor( QColor( red, green, blue ) );
974  readLabelField( el, BufferColor );
975  }
976 
977  scratchNode = node.namedItem( "buffersize" );
978 
979  if ( scratchNode.isNull() )
980  {
981  QgsDebugMsg( "couldn't find QgsLabel ``bffersize'' attribute" );
982  }
983  else
984  {
985  el = scratchNode.toElement();
986 
987  type = QgsLabelAttributes::unitsCode( el.attribute( "units", "" ) );
988  mLabelAttributes->setBufferSize( el.attribute( "value", "0.0" ).toDouble(), type );
989  readLabelField( el, BufferSize );
990  }
991 
992  scratchNode = node.namedItem( "bufferenabled" );
993 
994  if ( scratchNode.isNull() )
995  {
996  QgsDebugMsg( "couldn't find QgsLabel ``bufferenabled'' attribute" );
997  }
998  else
999  {
1000  el = scratchNode.toElement();
1001 
1002  mLabelAttributes->setBufferEnabled(( bool )el.attribute( "on", "0" ).toInt() );
1003  readLabelField( el, BufferEnabled );
1004  }
1005 
1006  scratchNode = node.namedItem( "multilineenabled" );
1007 
1008  if ( scratchNode.isNull() )
1009  {
1010  QgsDebugMsg( "couldn't find QgsLabel ``multilineenabled'' attribute" );
1011  }
1012  else
1013  {
1014  el = scratchNode.toElement();
1015 
1016  mLabelAttributes->setMultilineEnabled(( bool )el.attribute( "on", "0" ).toInt() );
1017  readLabelField( el, MultilineEnabled );
1018  }
1019 
1020  scratchNode = node.namedItem( "selectedonly" );
1021 
1022  if ( scratchNode.isNull() )
1023  {
1024  QgsDebugMsg( "couldn't find QgsLabel ``selectedonly'' attribute" );
1025  }
1026  else
1027  {
1028  el = scratchNode.toElement();
1029  mLabelAttributes->setSelectedOnly(( bool )el.attribute( "on", "0" ).toInt() );
1030  }
1031 
1032 } // QgsLabel::readXML()
1033 
1034 
1035 
1036 void QgsLabel::writeXML( QDomNode & layer_node, QDomDocument & document ) const
1037 {
1038  QDomElement labelattributes = document.createElement( "labelattributes" );
1039 
1040  // Text
1041  QDomElement label = document.createElement( "label" );
1042  label.setAttribute( "text", mLabelAttributes->text() );
1043  if ( mLabelAttributes->textIsSet() && mLabelFieldIdx[Text] != -1 )
1044  {
1045  label.setAttribute( "fieldname", labelField( Text ) );
1046  }
1047  else
1048  {
1049  label.setAttribute( "fieldname", "" );
1050  }
1051  labelattributes.appendChild( label );
1052 
1053  // Family
1054  QDomElement family = document.createElement( "family" );
1055  if ( mLabelAttributes->familyIsSet() && !mLabelAttributes->family().isNull() )
1056  {
1057  if ( mLabelFieldIdx[Family] != -1 )
1058  {
1059  family.setAttribute( "name", mLabelAttributes->family() );
1060  family.setAttribute( "fieldname", labelField( Family ) );
1061  }
1062  else
1063  {
1064  family.setAttribute( "name", mLabelAttributes->family() );
1065  family.setAttribute( "fieldname", "" );
1066  }
1067  }
1068  else
1069  {
1070  family.setAttribute( "name", "Arial" );
1071  family.setAttribute( "fieldname", "" );
1072  }
1073  labelattributes.appendChild( family );
1074 
1075  // size and units
1076  QDomElement size = document.createElement( "size" );
1077  size.setAttribute( "value", QString::number( mLabelAttributes->size() ) );
1078  if ( mLabelAttributes->sizeIsSet() )
1079  {
1080  if ( mLabelFieldIdx[Size] != -1 )
1081  {
1082  if ( mLabelFieldIdx[SizeType] != -1 )
1083  {
1084  size.setAttribute( "unitfieldname", labelField( SizeType ) );
1085  }
1086  else
1087  {
1088  size.setAttribute( "units", QgsLabelAttributes::unitsName( mLabelAttributes->sizeType() ) );
1089  }
1090  size.setAttribute( "fieldname", labelField( Size ) );
1091  }
1092  else
1093  {
1094  size.setAttribute( "units", QgsLabelAttributes::unitsName( mLabelAttributes->sizeType() ) );
1095  size.setAttribute( "fieldname", "" );
1096  }
1097  }
1098  else
1099  {
1100  size.setAttribute( "value", "12" );
1101  size.setAttribute( "units", "Points" );
1102  size.setAttribute( "fieldname", "" );
1103  }
1104  labelattributes.appendChild( size );
1105 
1106  // bold
1107  QDomElement bold = document.createElement( "bold" );
1108  if ( mLabelAttributes->boldIsSet() )
1109  {
1110  bold.setAttribute( "on", mLabelAttributes->bold() );
1111  if ( mLabelFieldIdx[Bold] != -1 )
1112  {
1113  bold.setAttribute( "fieldname", labelField( Bold ) );
1114  }
1115  else
1116  {
1117  bold.setAttribute( "fieldname", "" );
1118  }
1119  }
1120  else
1121  {
1122  bold.setAttribute( "on", 0 );
1123  bold.setAttribute( "fieldname", 0 );
1124  }
1125  labelattributes.appendChild( bold );
1126 
1127  // italics
1128  QDomElement italic = document.createElement( "italic" );
1129  if ( mLabelAttributes->italicIsSet() )
1130  {
1131  italic.setAttribute( "on", mLabelAttributes->italic() );
1132  if ( mLabelFieldIdx[Italic] != -1 )
1133  {
1134  italic.setAttribute( "fieldname", labelField( Italic ) );
1135  }
1136  else
1137  {
1138  italic.setAttribute( "fieldname", "" );
1139  }
1140  }
1141  else
1142  {
1143  italic.setAttribute( "on", "0" );
1144  italic.setAttribute( "fieldname", "" );
1145  }
1146  labelattributes.appendChild( italic );
1147 
1148  // underline
1149  QDomElement underline = document.createElement( "underline" );
1150  if ( mLabelAttributes->underlineIsSet() )
1151  {
1152  underline.setAttribute( "on", mLabelAttributes->underline() );
1153  if ( mLabelFieldIdx[Underline] != -1 )
1154  {
1155  underline.setAttribute( "fieldname", labelField( Underline ) );
1156  }
1157  else
1158  {
1159  underline.setAttribute( "fieldname", "" );
1160  }
1161  }
1162  else
1163  {
1164  underline.setAttribute( "on", 0 );
1165  underline.setAttribute( "fieldname", "" );
1166  }
1167  labelattributes.appendChild( underline );
1168 
1169  // strikeout
1170  QDomElement strikeOut = document.createElement( "strikeout" );
1171  if ( mLabelAttributes->strikeOutIsSet() )
1172  {
1173  strikeOut.setAttribute( "on", mLabelAttributes->strikeOut() );
1174  if ( mLabelFieldIdx[StrikeOut] != -1 )
1175  {
1176  strikeOut.setAttribute( "fieldname", labelField( StrikeOut ) );
1177  }
1178  else
1179  {
1180  strikeOut.setAttribute( "fieldname", "" );
1181  }
1182  }
1183  else
1184  {
1185  strikeOut.setAttribute( "on", 0 );
1186  strikeOut.setAttribute( "fieldname", "" );
1187  }
1188  labelattributes.appendChild( strikeOut );
1189 
1190  // color
1191  QDomElement color = document.createElement( "color" );
1192  if ( mLabelAttributes->colorIsSet() )
1193  {
1194  color.setAttribute( "red", mLabelAttributes->color().red() );
1195  color.setAttribute( "green", mLabelAttributes->color().green() );
1196  color.setAttribute( "blue", mLabelAttributes->color().blue() );
1197  if ( mLabelFieldIdx[Color] != -1 )
1198  {
1199  color.setAttribute( "fieldname", labelField( Color ) );
1200  }
1201  else
1202  {
1203  color.setAttribute( "fieldname", "" );
1204  }
1205  }
1206  else
1207  {
1208  color.setAttribute( "red", 0 );
1209  color.setAttribute( "green", 0 );
1210  color.setAttribute( "blue", 0 );
1211  color.setAttribute( "fieldname", "" );
1212  }
1213  labelattributes.appendChild( color );
1214 
1215  /* X */
1216  QDomElement x = document.createElement( "x" );
1217  if ( mLabelFieldIdx[XCoordinate] != -1 )
1218  {
1219  x.setAttribute( "fieldname", labelField( XCoordinate ) );
1220  }
1221  else
1222  {
1223  x.setAttribute( "fieldname", "" );
1224  }
1225  labelattributes.appendChild( x );
1226 
1227  /* Y */
1228  QDomElement y = document.createElement( "y" );
1229  if ( mLabelFieldIdx[YCoordinate] != -1 )
1230  {
1231  y.setAttribute( "fieldname", labelField( YCoordinate ) );
1232  }
1233  else
1234  {
1235  y.setAttribute( "fieldname", "" );
1236  }
1237  labelattributes.appendChild( y );
1238 
1239  // offset
1240  if ( mLabelAttributes->offsetIsSet() )
1241  {
1242  QDomElement offset = document.createElement( "offset" );
1243  offset.setAttribute( "units", QgsLabelAttributes::unitsName( mLabelAttributes->offsetType() ) );
1244  offset.setAttribute( "x", QString::number( mLabelAttributes->xOffset() ) );
1245  offset.setAttribute( "xfieldname", labelField( XOffset ) );
1246  offset.setAttribute( "y", QString::number( mLabelAttributes->yOffset() ) );
1247  offset.setAttribute( "yfieldname", labelField( YOffset ) );
1248  labelattributes.appendChild( offset );
1249  }
1250 
1251  // Angle
1252  QDomElement angle = document.createElement( "angle" );
1253  if ( mLabelAttributes->angleIsSet() )
1254  {
1255  angle.setAttribute( "value", QString::number( mLabelAttributes->angle() ) );
1256  if ( mLabelFieldIdx[Angle] != -1 )
1257  {
1258  angle.setAttribute( "fieldname", labelField( Angle ) );
1259  }
1260  else
1261  {
1262  angle.setAttribute( "fieldname", "" );
1263  }
1264  }
1265  else
1266  {
1267  angle.setAttribute( "value", "" );
1268  angle.setAttribute( "fieldname", "" );
1269  }
1270  angle.setAttribute( "auto", mLabelAttributes->angleIsAuto() ? "1" : "0" );
1271  labelattributes.appendChild( angle );
1272 
1273  // alignment
1274  if ( mLabelAttributes->alignmentIsSet() )
1275  {
1276  QDomElement alignment = document.createElement( "alignment" );
1277  alignment.setAttribute( "value", QgsLabelAttributes::alignmentName( mLabelAttributes->alignment() ) );
1278  alignment.setAttribute( "fieldname", labelField( Alignment ) );
1279  labelattributes.appendChild( alignment );
1280  }
1281 
1282  // buffer color
1283  QDomElement buffercolor = document.createElement( "buffercolor" );
1284  if ( mLabelAttributes->bufferColorIsSet() )
1285  {
1286  buffercolor.setAttribute( "red", mLabelAttributes->bufferColor().red() );
1287  buffercolor.setAttribute( "green", mLabelAttributes->bufferColor().green() );
1288  buffercolor.setAttribute( "blue", mLabelAttributes->bufferColor().blue() );
1289  if ( mLabelFieldIdx[BufferColor] != -1 )
1290  {
1291  buffercolor.setAttribute( "fieldname", labelField( BufferColor ) );
1292  }
1293  else
1294  {
1295  buffercolor.setAttribute( "fieldname", "" );
1296  }
1297  }
1298  else
1299  {
1300  buffercolor.setAttribute( "red", "" );
1301  buffercolor.setAttribute( "green", "" );
1302  buffercolor.setAttribute( "blue", "" );
1303  buffercolor.setAttribute( "fieldname", "" );
1304  }
1305  labelattributes.appendChild( buffercolor );
1306 
1307  // buffer size
1308  QDomElement buffersize = document.createElement( "buffersize" );
1309  if ( mLabelAttributes->bufferSizeIsSet() )
1310  {
1311  buffersize.setAttribute( "value", QString::number( mLabelAttributes->bufferSize() ) );
1312  buffersize.setAttribute( "units", QgsLabelAttributes::unitsName( mLabelAttributes->bufferSizeType() ) );
1313  if ( mLabelFieldIdx[BufferSize] != -1 )
1314  {
1315  buffersize.setAttribute( "fieldname", labelField( BufferSize ) );
1316  }
1317  else
1318  {
1319  buffersize.setAttribute( "fieldname", "" );
1320  }
1321  }
1322  else
1323  {
1324  buffersize.setAttribute( "value", "" );
1325  buffersize.setAttribute( "units", "" );
1326  buffersize.setAttribute( "fieldname", "" );
1327  }
1328  labelattributes.appendChild( buffersize );
1329 
1330  // buffer enabled
1331  QDomElement bufferenabled = document.createElement( "bufferenabled" );
1332  if ( mLabelAttributes->bufferEnabled() )
1333  {
1334  bufferenabled.setAttribute( "on", mLabelAttributes->bufferEnabled() );
1335  if ( mLabelFieldIdx[BufferEnabled] != -1 )
1336  {
1337  bufferenabled.setAttribute( "fieldname", labelField( BufferEnabled ) );
1338  }
1339  else
1340  {
1341  bufferenabled.setAttribute( "fieldname", "" );
1342  }
1343  }
1344  else
1345  {
1346  bufferenabled.setAttribute( "on", "" );
1347  bufferenabled.setAttribute( "fieldname", "" );
1348  }
1349  labelattributes.appendChild( bufferenabled );
1350 
1351  // multiline enabled
1352  QDomElement multilineenabled = document.createElement( "multilineenabled" );
1353  if ( mLabelAttributes->multilineEnabled() )
1354  {
1355  multilineenabled.setAttribute( "on", mLabelAttributes->multilineEnabled() );
1356  if ( mLabelFieldIdx[MultilineEnabled] != -1 )
1357  {
1358  multilineenabled.setAttribute( "fieldname", labelField( MultilineEnabled ) );
1359  }
1360  else
1361  {
1362  multilineenabled.setAttribute( "fieldname", "" );
1363  }
1364  }
1365  else
1366  {
1367  multilineenabled.setAttribute( "on", "" );
1368  multilineenabled.setAttribute( "fieldname", "" );
1369  }
1370  labelattributes.appendChild( multilineenabled );
1371 
1372  QDomElement selectedonly = document.createElement( "selectedonly" );
1373  if ( mLabelAttributes->selectedOnly() )
1374  {
1375  selectedonly.setAttribute( "on", mLabelAttributes->selectedOnly() );
1376  }
1377  else
1378  {
1379  selectedonly.setAttribute( "on", "" );
1380  }
1381  labelattributes.appendChild( selectedonly );
1382 
1383  layer_node.appendChild( labelattributes );
1384 }
1385 
1386 void QgsLabel::setScaleBasedVisibility( bool theVisibilityFlag )
1387 {
1388  mScaleBasedVisibility = theVisibilityFlag;
1389 }
1390 
1392 {
1393  return mScaleBasedVisibility;
1394 }
1395 
1396 void QgsLabel::setMinScale( float theMinScale )
1397 {
1398  mMinScale = theMinScale;
1399 }
1400 
1401 float QgsLabel::minScale() const
1402 {
1403  return mMinScale;
1404 }
1405 
1406 void QgsLabel::setMaxScale( float theMaxScale )
1407 {
1408  mMaxScale = theMaxScale;
1409 }
1410 
1411 float QgsLabel::maxScale() const
1412 {
1413  return mMaxScale;
1414 }
void setBufferColor(const QColor &color)
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:72
double bufferSize() const
void setMultilineEnabled(bool useMultiline)
void setBold(bool enable)
void setLabelField(int attr, int fieldIndex)
Set label field.
Definition: qgslabel.cpp:491
void setSize(double size, int type)
void setUnderline(bool enable)
void setSelectedOnly(bool selectedonly)
static int unitsCode(const QString &name)
QDomNode appendChild(const QDomNode &newChild)
void setFamily(const QString &family)
bool alignmentIsSet() const
size_t wkbSize() const
Returns the size of the WKB in asWkb().
QString attribute(const QString &name, const QString &defValue) const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
float maxScale() const
Definition: qgslabel.cpp:1411
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
static QString alignmentName(int alignment)
void scale(qreal sx, qreal sy)
QgsPoint transform(const QgsPoint &p) const
Transform the point from map (world) coordinates to device coordinates.
void renderLabel(QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0)
render label
Definition: qgslabel.cpp:72
void setUnderline(bool enable)
void save()
Container of fields for a vector layer.
Definition: qgsfield.h:177
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
void setFields(const QgsFields &fields)
Set available fields.
Definition: qgslabel.cpp:481
QgsPoint transform(const QgsPoint &p, TransformDirection direction=ForwardTransform) const
Transform the point from Source Coordinate System to Destination Coordinate System If the direction i...
double scaleFactor() const
WkbType
Used for symbology operations.
Definition: qgis.h:56
void rotate(qreal angle)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:176
const QgsCoordinateTransform * coordinateTransform() const
double toDouble(bool *ok) const
float minScale() const
Definition: qgslabel.cpp:1401
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
int size() const
QgsLabelAttributes * labelAttributes()
Pointer to default attributes.
Definition: qgslabel.cpp:510
bool isNull() const
QDomElement toElement() const
void setAutoAngle(bool state)
void setBold(bool enable)
static QString unitsName(int units)
void setPixelSize(int pixelSize)
QColor bufferColor() const
void setFont(const QFont &font)
QString number(int n, int base)
void append(const T &value)
static int alignmentCode(const QString &name)
bool hasAttribute(const QString &name) const
int red() const
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
const QColor & color() const
void setBufferSize(double size, int type)
int toInt(bool *ok, int base) const
void setScaleBasedVisibility(bool theVisibilityFlag)
Accessor and mutator for the scale based visilibility flag.
Definition: qgslabel.cpp:1386
QString nodeName() const
bool isEmpty() const
#define M_PI
bool scaleBasedVisibility() const
Definition: qgslabel.cpp:1391
void drawText(const QPointF &position, const QString &text)
double rasterScaleFactor() const
int count() const
Return number of items.
Definition: qgsfield.cpp:311
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QString labelField(int attr) const
label field
Definition: qgslabel.cpp:499
QgsFields & fields()
Available vector fields.
Definition: qgslabel.cpp:486
void setColor(const QColor &color)
void setText(const QString &text)
void readXML(const QDomNode &node)
Reads the renderer configuration from an XML file.
Definition: qgslabel.cpp:743
bool multilineEnabled() const
void setAngle(double angle)
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:331
A class to represent a point.
Definition: qgspoint.h:63
void writeXML(QDomNode &label_node, QDomDocument &document) const
Writes the contents of the renderer to a configuration file.
Definition: qgslabel.cpp:1036
QString fieldValue(int attr, QgsFeature &feature)
Get field value if : 1) field name is not empty 2) field exists 3) value is defined otherwise returns...
Definition: qgslabel.cpp:66
int green() const
bool bufferSizeIsSet() const
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
iterator end()
QString toLower() const
QDomNode namedItem(const QString &name) const
bool contains(QChar ch, Qt::CaseSensitivity cs) const
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:103
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:111
int width(const QString &text, int len) const
const QString family() const
void setItalic(bool enable)
void setStrikeOut(bool enable)
void restore()
void addRequiredFields(QgsAttributeList &fields) const
add vector of required fields to existing list of fields
Definition: qgslabel.cpp:459
int blue() const
Contains information about the context of a rendering operation.
void setMaxScale(float theMaxScale)
Accessor and mutator for the maximum scale member.
Definition: qgslabel.cpp:1406
void setAlignment(int alignment)
QPainter * painter()
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:238
void setOffset(double x, double y, int type)
QgsLabel(const QgsFields &fields)
Definition: qgslabel.cpp:47
bool strikeOutIsSet() const
void setFamily(const QString &family)
int height() const
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:70
void setStrikeOut(bool enable)
void translate(const QPointF &offset)
const QgsMapToPixel & mapToPixel() const
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
~QgsLabel()
Definition: qgslabel.cpp:61
bool underlineIsSet() const
void setMinScale(float theMinScale)
Accessor and mutator for the minimum scale member.
Definition: qgslabel.cpp:1396
Custom exception class for Coordinate Reference System related exceptions.
QDomElement createElement(const QString &tagName)
A class to store attributes needed for label rendering.
void setColor(const QColor &color)
int compare(const QString &other) const
void setBufferEnabled(bool useBufferFlag)
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QString toString() const
bool bufferColorIsSet() const
iterator begin()
void setItalic(bool enable)
const QString text() const