QGIS API Documentation  2.12.0-Lyon
qgssymbolv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbolv2.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgssymbolv2.h"
17 #include "qgssymbollayerv2.h"
18 
19 #include "qgslinesymbollayerv2.h"
20 #include "qgsmarkersymbollayerv2.h"
21 #include "qgsfillsymbollayerv2.h"
22 
23 #include "qgslogger.h"
24 #include "qgsrendercontext.h" // for bigSymbolPreview
25 
26 #include "qgsproject.h"
27 #include "qgsstylev2.h"
28 #include "qgspainteffect.h"
29 #include "qgseffectstack.h"
30 
31 #include "qgsdatadefined.h"
32 
33 #include <QColor>
34 #include <QImage>
35 #include <QPainter>
36 #include <QSize>
37 #include <QSvgGenerator>
38 
39 #include <cmath>
40 
41 inline
42 QgsDataDefined* rotateWholeSymbol( double additionalRotation, const QgsDataDefined& dd )
43 {
44  QgsDataDefined* rotatedDD = new QgsDataDefined( dd );
45  QString exprString = dd.useExpression() ? dd.expressionString() : dd.field();
46  rotatedDD->setExpressionString( QString::number( additionalRotation ) + " + (" + exprString + ")" );
47  rotatedDD->setUseExpression( true );
48  return rotatedDD;
49 }
50 
51 inline
52 QgsDataDefined* scaleWholeSymbol( double scaleFactor, const QgsDataDefined& dd )
53 {
54  QgsDataDefined* scaledDD = new QgsDataDefined( dd );
55  QString exprString = dd.useExpression() ? dd.expressionString() : dd.field();
56  scaledDD->setExpressionString( QString::number( scaleFactor ) + "*(" + exprString + ")" );
57  scaledDD->setUseExpression( true );
58  return scaledDD;
59 }
60 
61 inline
62 QgsDataDefined* scaleWholeSymbol( double scaleFactorX, double scaleFactorY, const QgsDataDefined& dd )
63 {
64  QgsDataDefined* scaledDD = new QgsDataDefined( dd );
65  QString exprString = dd.useExpression() ? dd.expressionString() : dd.field();
66  scaledDD->setExpressionString(
67  ( scaleFactorX ? "tostring(" + QString::number( scaleFactorX ) + "*(" + exprString + "))" : "'0'" ) +
68  "|| ',' || " +
69  ( scaleFactorY ? "tostring(" + QString::number( scaleFactorY ) + "*(" + exprString + "))" : "'0'" ) );
70  scaledDD->setUseExpression( true );
71  return scaledDD;
72 }
73 
74 
76 
78  : mType( type )
79  , mLayers( layers )
80  , mAlpha( 1.0 )
81  , mRenderHints( 0 )
82  , mClipFeaturesToExtent( true )
83  , mLayer( 0 )
84 {
85 
86  // check they're all correct symbol layers
87  for ( int i = 0; i < mLayers.count(); i++ )
88  {
89  if ( mLayers[i] == NULL )
90  {
91  mLayers.removeAt( i-- );
92  }
93  else if ( !isSymbolLayerCompatible( mLayers[i]->type() ) )
94  {
95  delete mLayers[i];
96  mLayers.removeAt( i-- );
97  }
98  }
99 }
100 
102 {
103  // delete all symbol layers (we own them, so it's okay)
104  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
105  delete *it;
106 }
107 
109 {
110  if ( mLayers.empty() )
111  {
112  return QgsSymbolV2::Mixed;
113  }
114 
116 
117  QgsSymbolV2::OutputUnit unit = ( *it )->outputUnit();
118 
119  for ( ; it != mLayers.constEnd(); ++it )
120  {
121  if (( *it )->outputUnit() != unit )
122  {
123  return QgsSymbolV2::Mixed;
124  }
125  }
126  return unit;
127 }
128 
130 {
131  if ( mLayers.empty() )
132  {
133  return QgsMapUnitScale();
134  }
135 
137  if ( it == mLayers.constEnd() )
138  return QgsMapUnitScale();
139 
140  QgsMapUnitScale scale = ( *it )->mapUnitScale();
141  ++it;
142 
143  for ( ; it != mLayers.constEnd(); ++it )
144  {
145  if (( *it )->mapUnitScale() != scale )
146  {
147  return QgsMapUnitScale();
148  }
149  }
150  return scale;
151 }
152 
154 {
156  for ( ; it != mLayers.end(); ++it )
157  {
158  ( *it )->setOutputUnit( u );
159  }
160 }
161 
163 {
165  for ( ; it != mLayers.end(); ++it )
166  {
167  ( *it )->setMapUnitScale( scale );
168  }
169 }
170 
172 {
173  QgsSymbolV2* s = 0;
174 
175  // override global default if project has a default for this type
177  switch ( geomType )
178  {
179  case QGis::Point :
180  defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Marker", "" );
181  break;
182  case QGis::Line :
183  defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Line", "" );
184  break;
185  case QGis::Polygon :
186  defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Fill", "" );
187  break;
188  default: defaultSymbol = ""; break;
189  }
190  if ( defaultSymbol != "" )
191  s = QgsStyleV2::defaultStyle()->symbol( defaultSymbol );
192 
193  // if no default found for this type, get global default (as previously)
194  if ( ! s )
195  {
196  switch ( geomType )
197  {
198  case QGis::Point: s = new QgsMarkerSymbolV2(); break;
199  case QGis::Line: s = new QgsLineSymbolV2(); break;
200  case QGis::Polygon: s = new QgsFillSymbolV2(); break;
201  default: QgsDebugMsg( "unknown layer's geometry type" ); return NULL;
202  }
203  }
204 
205  // set alpha transparency
206  s->setAlpha( QgsProject::instance()->readDoubleEntry( "DefaultStyles", "/AlphaInt", 255 ) / 255.0 );
207 
208  // set random color, it project prefs allow
209  if ( defaultSymbol == "" ||
210  QgsProject::instance()->readBoolEntry( "DefaultStyles", "/RandomColors", true ) )
211  {
212  s->setColor( QColor::fromHsv( qrand() % 360, 64 + qrand() % 192, 128 + qrand() % 128 ) );
213  }
214 
215  return s;
216 }
217 
219 {
220  if ( layer < 0 || layer >= mLayers.count() )
221  return NULL;
222 
223  return mLayers[layer];
224 }
225 
226 
228 {
229  // fill symbol can contain also line symbol layers for drawing of outlines
230  if ( mType == Fill && t == Line )
231  return true;
232 
233  return mType == t;
234 }
235 
236 
238 {
239  if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
240  return false;
241  if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
242  return false;
243 
244  mLayers.insert( index, layer );
245  return true;
246 }
247 
248 
250 {
251  if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
252  return false;
253 
254  mLayers.append( layer );
255  return true;
256 }
257 
258 
260 {
261  if ( index < 0 || index >= mLayers.count() )
262  return false;
263 
264  delete mLayers[index];
265  mLayers.removeAt( index );
266  return true;
267 }
268 
269 
271 {
272  if ( index < 0 || index >= mLayers.count() )
273  return NULL;
274 
275  return mLayers.takeAt( index );
276 }
277 
278 
280 {
281  if ( index < 0 || index >= mLayers.count() )
282  return false;
283  if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
284  return false;
285 
286  delete mLayers[index]; // first delete the original layer
287  mLayers[index] = layer; // set new layer
288  return true;
289 }
290 
291 
292 void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsFields* fields )
293 {
294  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, 0, fields, mapUnitScale() );
295 
296 
297  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
298  ( *it )->startRender( symbolContext );
299 }
300 
302 {
303  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, 0, 0, mapUnitScale() );
304 
305  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
306  ( *it )->stopRender( symbolContext );
307 
308  mLayer = NULL;
309 }
310 
311 void QgsSymbolV2::setColor( const QColor& color )
312 {
313  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
314  {
315  if ( !( *it )->isLocked() )
316  ( *it )->setColor( color );
317  }
318 }
319 
321 {
322  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
323  {
324  // return color of the first unlocked layer
325  if ( !( *it )->isLocked() )
326  return ( *it )->color();
327  }
328  return QColor( 0, 0, 0 );
329 }
330 
331 void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size, QgsRenderContext* customContext )
332 {
333  QgsRenderContext context = customContext ? *customContext : QgsSymbolLayerV2Utils::createRenderContext( painter );
334  context.setForceVectorOutput( true );
335  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, 0, 0, mapUnitScale() );
336 
337  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
338  {
339  if ( mType == Fill && ( *it )->type() == Line )
340  {
341  // line symbol layer would normally draw just a line
342  // so we override this case to force it to draw a polygon outline
344 
345  // from QgsFillSymbolLayerV2::drawPreviewIcon()
346  QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
347  lsl->startRender( symbolContext );
348  lsl->renderPolygonOutline( poly, NULL, symbolContext );
349  lsl->stopRender( symbolContext );
350  }
351  else
352  ( *it )->drawPreviewIcon( symbolContext, size );
353  }
354 }
355 
356 void QgsSymbolV2::exportImage( const QString& path, const QString& format, const QSize& size )
357 {
358  if ( format.toLower() == "svg" )
359  {
360  QSvgGenerator generator;
361  generator.setFileName( path );
362  generator.setSize( size );
363  generator.setViewBox( QRect( 0, 0, size.height(), size.height() ) );
364 
365  QPainter painter( &generator );
366  drawPreviewIcon( &painter, size );
367  painter.end();
368  }
369  else
370  {
371  QImage image = asImage( size );
372  image.save( path );
373  }
374 }
375 
377 {
378  QImage image( size, QImage::Format_ARGB32_Premultiplied );
379  image.fill( 0 );
380 
381  QPainter p( &image );
382  p.setRenderHint( QPainter::Antialiasing );
383 
384  drawPreviewIcon( &p, size, customContext );
385 
386  return image;
387 }
388 
389 
391 {
392  QImage preview( QSize( 100, 100 ), QImage::Format_ARGB32_Premultiplied );
393  preview.fill( 0 );
394 
395  QPainter p( &preview );
396  p.setRenderHint( QPainter::Antialiasing );
397  p.translate( 0.5, 0.5 ); // shift by half a pixel to avoid blurring due antialising
398 
399  if ( mType == QgsSymbolV2::Marker )
400  {
401  p.setPen( QPen( Qt::gray ) );
402  p.drawLine( 0, 50, 100, 50 );
403  p.drawLine( 50, 0, 50, 100 );
404  }
405 
407  if ( expressionContext )
408  context.setExpressionContext( *expressionContext );
409 
410  startRender( context );
411 
412  if ( mType == QgsSymbolV2::Line )
413  {
414  QPolygonF poly;
415  poly << QPointF( 0, 50 ) << QPointF( 99, 50 );
416  static_cast<QgsLineSymbolV2*>( this )->renderPolyline( poly, 0, context );
417  }
418  else if ( mType == QgsSymbolV2::Fill )
419  {
420  QPolygonF polygon;
421  polygon << QPointF( 20, 20 ) << QPointF( 80, 20 ) << QPointF( 80, 80 ) << QPointF( 20, 80 ) << QPointF( 20, 20 );
422  static_cast<QgsFillSymbolV2*>( this )->renderPolygon( polygon, NULL, 0, context );
423  }
424  else // marker
425  {
426  static_cast<QgsMarkerSymbolV2*>( this )->renderPoint( QPointF( 50, 50 ), 0, context );
427  }
428 
429  stopRender( context );
430  return preview;
431 }
432 
433 
435 {
436  QString t;
437  switch ( type() )
438  {
439  case QgsSymbolV2::Marker: t = "MARKER"; break;
440  case QgsSymbolV2::Line: t = "LINE"; break;
441  case QgsSymbolV2::Fill: t = "FILL"; break;
442  default: Q_ASSERT( 0 && "unknown symbol type" );
443  }
444  QString s = QString( "%1 SYMBOL (%2 layers) color %3" ).arg( t ).arg( mLayers.count() ).arg( QgsSymbolLayerV2Utils::encodeColor( color() ) );
445 
446  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
447  {
448  // TODO:
449  }
450  return s;
451 }
452 
453 void QgsSymbolV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
454 {
455  props[ "alpha" ] = QString::number( alpha() );
456  double scaleFactor = 1.0;
457  props[ "uom" ] = QgsSymbolLayerV2Utils::encodeSldUom( outputUnit(), &scaleFactor );
458  props[ "uomScale" ] = scaleFactor != 1 ? QString::number( scaleFactor ) : "";
459 
460  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
461  {
462  ( *it )->toSld( doc, element, props );
463  }
464 }
465 
467 {
469  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
470  {
471  QgsSymbolLayerV2* layer = ( *it )->clone();
472  layer->setLocked(( *it )->isLocked() );
473  layer->setRenderingPass(( *it )->renderingPass() );
474  lst.append( layer );
475  }
476  return lst;
477 }
478 
480 {
481  QSet<QString> attributes;
483  for ( ; sIt != mLayers.constEnd(); ++sIt )
484  {
485  if ( *sIt )
486  {
487  attributes.unite(( *sIt )->usedAttributes() );
488  }
489  }
490  return attributes;
491 }
492 
494 
495 
496 QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints, const QgsFeature* f, const QgsFields* fields, const QgsMapUnitScale& mapUnitScale )
497  : mRenderContext( c ), mOutputUnit( u ), mMapUnitScale( mapUnitScale ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints ), mFeature( f ), mFields( fields )
498 {
499 
500 }
501 
503 {
504 
505 }
506 
508 {
509  mRenderContext.expressionContext().setOriginalValueVariable( value );
510 }
511 
512 double QgsSymbolV2RenderContext::outputLineWidth( double width ) const
513 {
514  return QgsSymbolLayerV2Utils::convertToPainterUnits( mRenderContext, width, mOutputUnit, mMapUnitScale );
515 }
516 
517 double QgsSymbolV2RenderContext::outputPixelSize( double size ) const
518 {
519  return size * QgsSymbolLayerV2Utils::pixelSizeScaleFactor( mRenderContext, mOutputUnit, mMapUnitScale );
520 }
521 
523 {
524  // This is just a dummy implementation of assignment.
525  // sip 4.7 generates a piece of code that needs this function to exist.
526  // It's not generated automatically by the compiler because of
527  // mRenderContext member which is a reference (and thus can't be changed).
528  Q_ASSERT( false );
529  return *this;
530 }
531 
533 
535 {
537  if ( sl == NULL )
538  return NULL;
539 
540  QgsSymbolLayerV2List layers;
541  layers.append( sl );
542  return new QgsMarkerSymbolV2( layers );
543 }
544 
546 {
548  if ( sl == NULL )
549  return NULL;
550 
551  QgsSymbolLayerV2List layers;
552  layers.append( sl );
553  return new QgsLineSymbolV2( layers );
554 }
555 
557 {
559  if ( sl == NULL )
560  return NULL;
561 
562  QgsSymbolLayerV2List layers;
563  layers.append( sl );
564  return new QgsFillSymbolV2( layers );
565 }
566 
568 
570  : QgsSymbolV2( Marker, layers )
571 {
572  if ( mLayers.count() == 0 )
574 }
575 
576 void QgsMarkerSymbolV2::setAngle( double ang )
577 {
578  double origAngle = angle();
579  double angleDiff = ang - origAngle;
580  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
581  {
583  layer->setAngle( layer->angle() + angleDiff );
584  }
585 }
586 
588 {
590 
591  if ( it == mLayers.end() )
592  return 0;
593 
594  // return angle of the first symbol layer
595  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
596  return layer->angle();
597 }
598 
599 void QgsMarkerSymbolV2::setLineAngle( double lineAng )
600 {
601  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
602  {
604  layer->setLineAngle( lineAng );
605  }
606 }
607 
609 {
610  const double symbolRotation = angle();
611 
612  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
613  {
614  QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2 *>( *it );
615  if ( dd.hasDefaultValues() )
616  {
617  layer->removeDataDefinedProperty( "angle" );
618  }
619  else
620  {
621  if ( qgsDoubleNear( layer->angle(), symbolRotation ) )
622  {
623  layer->setDataDefinedProperty( "angle", new QgsDataDefined( dd ) );
624  }
625  else
626  {
627  QgsDataDefined* rotatedDD = rotateWholeSymbol( layer->angle() - symbolRotation, dd );
628  layer->setDataDefinedProperty( "angle", rotatedDD );
629  }
630  }
631  }
632 }
633 
635 {
636  const double symbolRotation = angle();
637  QgsDataDefined* symbolDD = 0;
638 
639  // find the base of the "en masse" pattern
640  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
641  {
642  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
643  if ( layer->angle() == symbolRotation && layer->getDataDefinedProperty( "angle" ) )
644  {
645  symbolDD = layer->getDataDefinedProperty( "angle" );
646  break;
647  }
648  }
649 
650  if ( !symbolDD )
651  return QgsDataDefined();
652 
653  // check that all layer's angle expressions match the "en masse" pattern
654  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
655  {
656  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
657 
658  QgsDataDefined* layerAngleDD = layer->getDataDefinedProperty( "angle" );
659 
660  if ( qgsDoubleNear( layer->angle(), symbolRotation ) )
661  {
662  if ( !layerAngleDD || *layerAngleDD != *symbolDD )
663  return QgsDataDefined();
664  }
665  else
666  {
667  QScopedPointer< QgsDataDefined > rotatedDD( rotateWholeSymbol( layer->angle() - symbolRotation, *symbolDD ) );
668  if ( !layerAngleDD || *layerAngleDD != *( rotatedDD.data() ) )
669  return QgsDataDefined();
670  }
671  }
672  return QgsDataDefined( *symbolDD );
673 }
674 
675 
677 {
678  double origSize = size();
679 
680  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
681  {
682  QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
683  if ( layer->size() == origSize )
684  layer->setSize( s );
685  else if ( origSize != 0 )
686  {
687  // proportionally scale size
688  layer->setSize( layer->size() * s / origSize );
689  }
690  // also scale offset to maintain relative position
691  if ( origSize != 0 && ( layer->offset().x() || layer->offset().y() ) )
692  layer->setOffset( QPointF( layer->offset().x() * s / origSize,
693  layer->offset().y() * s / origSize ) );
694  }
695 }
696 
698 {
699  // return size of the largest symbol
700  double maxSize = 0;
701  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
702  {
703  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
704  double lsize = layer->size();
705  if ( lsize > maxSize )
706  maxSize = lsize;
707  }
708  return maxSize;
709 }
710 
712 {
713  const double symbolSize = size();
714 
715  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
716  {
717  QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2 *>( *it );
718 
719  if ( dd.hasDefaultValues() )
720  {
721  layer->removeDataDefinedProperty( "size" );
722  layer->removeDataDefinedProperty( "offset" );
723  }
724  else
725  {
726  if ( symbolSize == 0 || qgsDoubleNear( layer->size(), symbolSize ) )
727  {
728  layer->setDataDefinedProperty( "size", new QgsDataDefined( dd ) );
729  }
730  else
731  {
732  layer->setDataDefinedProperty( "size", scaleWholeSymbol( layer->size() / symbolSize, dd ) );
733  }
734 
735  if ( layer->offset().x() || layer->offset().y() )
736  {
737  layer->setDataDefinedProperty( "offset", scaleWholeSymbol(
738  layer->offset().x() / symbolSize,
739  layer->offset().y() / symbolSize, dd ) );
740  }
741  }
742  }
743 }
744 
746 {
747  const double symbolSize = size();
748 
749  QgsDataDefined* symbolDD = 0;
750 
751  // find the base of the "en masse" pattern
752  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
753  {
754  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
755  if ( layer->size() == symbolSize && layer->getDataDefinedProperty( "size" ) )
756  {
757  symbolDD = layer->getDataDefinedProperty( "size" );
758  break;
759  }
760  }
761 
762  if ( !symbolDD )
763  return QgsDataDefined();
764 
765  // check that all layers size expressions match the "en masse" pattern
766  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
767  {
768  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
769 
770  QgsDataDefined* layerSizeDD = layer->getDataDefinedProperty( "size" );
771  QgsDataDefined* layerOffsetDD = layer->getDataDefinedProperty( "offset" );
772 
773  if ( qgsDoubleNear( layer->size(), symbolSize ) )
774  {
775  if ( !layerSizeDD || *layerSizeDD != *symbolDD )
776  return QgsDataDefined();
777  }
778  else
779  {
780  if ( symbolSize == 0 )
781  return QgsDataDefined();
782 
783  QScopedPointer< QgsDataDefined > scaledDD( scaleWholeSymbol( layer->size() / symbolSize, *symbolDD ) );
784  if ( !layerSizeDD || *layerSizeDD != *( scaledDD.data() ) )
785  return QgsDataDefined();
786  }
787 
788  QScopedPointer< QgsDataDefined > scaledOffsetDD( scaleWholeSymbol( layer->offset().x() / symbolSize, layer->offset().y() / symbolSize, *symbolDD ) );
789  if ( layerOffsetDD && *layerOffsetDD != *( scaledOffsetDD.data() ) )
790  return QgsDataDefined();
791  }
792 
793  return QgsDataDefined( *symbolDD );
794 }
795 
797 {
798  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
799  {
800  QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
801  layer->setScaleMethod( scaleMethod );
802  }
803 }
804 
806 {
808 
809  if ( it == mLayers.end() )
810  return DEFAULT_SCALE_METHOD;
811 
812  // return scale method of the first symbol layer
813  const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
814  return layer->scaleMethod();
815 }
816 
817 void QgsMarkerSymbolV2::renderPointUsingLayer( QgsMarkerSymbolLayerV2* layer, const QPointF& point, QgsSymbolV2RenderContext& context )
818 {
819  static QPointF nullPoint( 0, 0 );
820 
821  QgsPaintEffect* effect = layer->paintEffect();
822  if ( effect && effect->enabled() )
823  {
824  QPainter* p = context.renderContext().painter();
825  p->save();
826  p->translate( point );
827 
828  effect->begin( context.renderContext() );
829  layer->renderPoint( nullPoint, context );
830  effect->end( context.renderContext() );
831 
832  p->restore();
833  }
834  else
835  {
836  layer->renderPoint( point, context );
837  }
838 }
839 
840 void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
841 {
842  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f, 0, mapUnitScale() );
843 
844  if ( layer != -1 )
845  {
846  if ( layer >= 0 && layer < mLayers.count() )
847  {
848  renderPointUsingLayer(( QgsMarkerSymbolLayerV2* ) mLayers[layer], point, symbolContext );
849  }
850  return;
851  }
852 
853  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
854  {
855  renderPointUsingLayer(( QgsMarkerSymbolLayerV2* ) * it, point, symbolContext );
856  }
857 }
858 
860 {
861  QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() );
862  cloneSymbol->setAlpha( mAlpha );
863  cloneSymbol->setLayer( mLayer );
865  return cloneSymbol;
866 }
867 
868 
870 // LINE
871 
873  : QgsSymbolV2( Line, layers )
874 {
875  if ( mLayers.count() == 0 )
877 }
878 
880 {
881  double origWidth = width();
882 
883  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
884  {
885  QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
886  if ( layer->width() == origWidth )
887  {
888  layer->setWidth( w );
889  }
890  else if ( origWidth != 0 )
891  {
892  // proportionally scale the width
893  layer->setWidth( layer->width() * w / origWidth );
894  }
895  // also scale offset to maintain relative position
896  if ( origWidth != 0 && layer->offset() )
897  layer->setOffset( layer->offset() * w / origWidth );
898  }
899 }
900 
902 {
903  double maxWidth = 0;
904  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
905  {
906  const QgsLineSymbolLayerV2* layer = ( const QgsLineSymbolLayerV2* ) * it;
907  double width = layer->width();
908  if ( width > maxWidth )
909  maxWidth = width;
910  }
911  return maxWidth;
912 }
913 
915 {
916  const double symbolWidth = width();
917 
918  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
919  {
920  QgsLineSymbolLayerV2* layer = static_cast<QgsLineSymbolLayerV2*>( *it );
921 
922  if ( dd.hasDefaultValues() )
923  {
924  layer->removeDataDefinedProperty( "width" );
925  layer->removeDataDefinedProperty( "offset" );
926  }
927  else
928  {
929  if ( symbolWidth == 0 || qgsDoubleNear( layer->width(), symbolWidth ) )
930  {
931  layer->setDataDefinedProperty( "width", new QgsDataDefined( dd ) );
932  }
933  else
934  {
935  layer->setDataDefinedProperty( "width", scaleWholeSymbol( layer->width() / symbolWidth, dd ) );
936  }
937 
938  if ( layer->offset() )
939  {
940  layer->setDataDefinedProperty( "offset", scaleWholeSymbol( layer->offset() / symbolWidth, dd ) );
941  }
942  }
943  }
944 }
945 
947 {
948  const double symbolWidth = width();
949 
950  QgsDataDefined* symbolDD = 0;
951 
952  // find the base of the "en masse" pattern
953  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
954  {
955  const QgsLineSymbolLayerV2* layer = static_cast<const QgsLineSymbolLayerV2*>( *it );
956  if ( layer->width() == symbolWidth && layer->getDataDefinedProperty( "width" ) )
957  {
958  symbolDD = layer->getDataDefinedProperty( "width" );
959  break;
960  }
961  }
962 
963  if ( !symbolDD )
964  return QgsDataDefined();
965 
966  // check that all layers width expressions match the "en masse" pattern
967  for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
968  {
969  const QgsLineSymbolLayerV2* layer = static_cast<const QgsLineSymbolLayerV2*>( *it );
970 
971  QgsDataDefined* layerWidthDD = layer->getDataDefinedProperty( "width" );
972  QgsDataDefined* layerOffsetDD = layer->getDataDefinedProperty( "offset" );
973 
974  if ( qgsDoubleNear( layer->width(), symbolWidth ) )
975  {
976  if ( !layerWidthDD || *layerWidthDD != *symbolDD )
977  return QgsDataDefined();
978  }
979  else
980  {
981  if ( symbolWidth == 0 )
982  return QgsDataDefined();
983 
984  QScopedPointer< QgsDataDefined > scaledDD( scaleWholeSymbol( layer->width() / symbolWidth, *symbolDD ) );
985  if ( !layerWidthDD || *layerWidthDD != *( scaledDD.data() ) )
986  return QgsDataDefined();
987  }
988 
989  QScopedPointer< QgsDataDefined > scaledOffsetDD( scaleWholeSymbol( layer->offset() / symbolWidth, *symbolDD ) );
990  if ( layerOffsetDD && *layerOffsetDD != *( scaledOffsetDD.data() ) )
991  return QgsDataDefined();
992  }
993 
994  return QgsDataDefined( *symbolDD );
995 }
996 
997 void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
998 {
999  //save old painter
1000  QPainter* renderPainter = context.painter();
1001  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f, 0, mapUnitScale() );
1002 
1003  if ( layer != -1 )
1004  {
1005  if ( layer >= 0 && layer < mLayers.count() )
1006  {
1007  renderPolylineUsingLayer(( QgsLineSymbolLayerV2* ) mLayers[layer], points, symbolContext );
1008  }
1009  return;
1010  }
1011 
1012  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
1013  {
1014  renderPolylineUsingLayer(( QgsLineSymbolLayerV2* ) * it, points, symbolContext );
1015  }
1016 
1017  context.setPainter( renderPainter );
1018 }
1019 
1020 void QgsLineSymbolV2::renderPolylineUsingLayer( QgsLineSymbolLayerV2 *layer, const QPolygonF &points, QgsSymbolV2RenderContext &context )
1021 {
1022  QgsPaintEffect* effect = layer->paintEffect();
1023  if ( effect && effect->enabled() )
1024  {
1025  QPainter* p = context.renderContext().painter();
1026  p->save();
1027  p->translate( points.boundingRect().topLeft() );
1028 
1029  effect->begin( context.renderContext() );
1030  layer->renderPolyline( points.translated( -points.boundingRect().topLeft() ), context );
1031  effect->end( context.renderContext() );
1032 
1033  p->restore();
1034  }
1035  else
1036  {
1037  layer->renderPolyline( points, context );
1038  }
1039 }
1040 
1041 
1043 {
1044  QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() );
1045  cloneSymbol->setAlpha( mAlpha );
1046  cloneSymbol->setLayer( mLayer );
1048  return cloneSymbol;
1049 }
1050 
1052 // FILL
1053 
1055  : QgsSymbolV2( Fill, layers )
1056 {
1057  if ( mLayers.count() == 0 )
1059 }
1060 
1061 void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
1062 {
1063  QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f, 0, mapUnitScale() );
1064 
1065  if ( layer != -1 )
1066  {
1067  if ( layer >= 0 && layer < mLayers.count() )
1068  {
1069  renderPolygonUsingLayer( mLayers[layer], points, rings, symbolContext );
1070  }
1071  return;
1072  }
1073 
1074  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
1075  {
1076  renderPolygonUsingLayer( *it, points, rings, symbolContext );
1077  }
1078 }
1079 
1080 void QgsFillSymbolV2::renderPolygonUsingLayer( QgsSymbolLayerV2* layer, const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
1081 {
1082  QgsSymbolV2::SymbolType layertype = layer->type();
1083 
1084  QgsPaintEffect* effect = layer->paintEffect();
1085  if ( effect && effect->enabled() )
1086  {
1087  QRectF bounds = polygonBounds( points, rings );
1088  QList<QPolygonF>* translatedRings = translateRings( rings, -bounds.left(), -bounds.top() );
1089 
1090  QPainter* p = context.renderContext().painter();
1091  p->save();
1092  p->translate( bounds.topLeft() );
1093 
1094  effect->begin( context.renderContext() );
1095  if ( layertype == QgsSymbolV2::Fill )
1096  {
1097  (( QgsFillSymbolLayerV2* )layer )->renderPolygon( points.translated( -bounds.topLeft() ), translatedRings, context );
1098  }
1099  else if ( layertype == QgsSymbolV2::Line )
1100  {
1101  (( QgsLineSymbolLayerV2* )layer )->renderPolygonOutline( points.translated( -bounds.topLeft() ), translatedRings, context );
1102  }
1103  delete translatedRings;
1104 
1105  effect->end( context.renderContext() );
1106  p->restore();
1107  }
1108  else
1109  {
1110  if ( layertype == QgsSymbolV2::Fill )
1111  {
1112  (( QgsFillSymbolLayerV2* )layer )->renderPolygon( points, rings, context );
1113  }
1114  else if ( layertype == QgsSymbolV2::Line )
1115  {
1116  (( QgsLineSymbolLayerV2* )layer )->renderPolygonOutline( points, rings, context );
1117  }
1118  }
1119 }
1120 
1121 QRectF QgsFillSymbolV2::polygonBounds( const QPolygonF& points, const QList<QPolygonF>* rings ) const
1122 {
1123  QRectF bounds = points.boundingRect();
1124  if ( rings )
1125  {
1127  for ( ; it != rings->constEnd(); ++it )
1128  {
1129  bounds = bounds.united(( *it ).boundingRect() );
1130  }
1131  }
1132  return bounds;
1133 }
1134 
1135 QList<QPolygonF>* QgsFillSymbolV2::translateRings( const QList<QPolygonF>* rings, double dx, double dy ) const
1136 {
1137  if ( !rings )
1138  return 0;
1139 
1140  QList<QPolygonF>* translatedRings = new QList<QPolygonF>;
1142  for ( ; it != rings->constEnd(); ++it )
1143  {
1144  translatedRings->append(( *it ).translated( dx, dy ) );
1145  }
1146  return translatedRings;
1147 }
1148 
1150 {
1151  QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() );
1152  cloneSymbol->setAlpha( mAlpha );
1153  cloneSymbol->setLayer( mLayer );
1155  return cloneSymbol;
1156 }
1157 
1159 {
1160  for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
1161  {
1162  QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
1163  layer->setAngle( angle );
1164  }
1165 }
1166 
1167 
QgsFillSymbolV2(const QgsSymbolLayerV2List &layers=QgsSymbolLayerV2List())
void setForceVectorOutput(bool force)
void setLocked(bool locked)
bool deleteSymbolLayer(int index)
delete symbol layer at specified index
QgsSymbolV2RenderContext(QgsRenderContext &c, QgsSymbolV2::OutputUnit u, qreal alpha=1.0, bool selected=false, int renderHints=0, const QgsFeature *f=0, const QgsFields *fields=0, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale())
static unsigned index
void setViewBox(const QRect &viewBox)
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
static QgsMarkerSymbolV2 * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent...
Definition: qgssymbolv2.h:206
OutputUnit
The unit of the output.
Definition: qgssymbolv2.h:55
int width() const
bool mClipFeaturesToExtent
Definition: qgssymbolv2.h:240
void setDataDefinedAngle(const QgsDataDefined &dd)
Set data defined angle for whole symbol (including all symbol layers).
A container class for data source field mapping or expression.
bool end()
void setSize(const QSize &size)
virtual double width() const
void setRenderHint(RenderHint hint, bool on)
const QgsVectorLayer * mLayer
Definition: qgssymbolv2.h:242
SymbolType type() const
Definition: qgssymbolv2.h:95
QSet< QString > usedAttributes() const
QString field() const
Get the field which this QgsDataDefined represents.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void setDataDefinedSize(const QgsDataDefined &dd)
Set data defined size for whole symbol (including all symbol layers).
bool save(const QString &fileName, const char *format, int quality) const
static QString encodeColor(const QColor &color)
static QString encodeSldUom(QgsSymbolV2::OutputUnit unit, double *scaleFactor)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
double size() const
QgsDataDefined dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
static QgsFillSymbolV2 * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
void setOffset(QPointF offset)
void removeAt(int i)
QPolygonF translated(qreal dx, qreal dy) const
bool enabled() const
Returns whether the effect is enabled.
Base class for visual effects which can be applied to QPicture drawings.
bool changeSymbolLayer(int index, QgsSymbolLayerV2 *layer)
delete layer at specified index and set a new one
ScaleMethod scaleMethod()
void save()
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
void exportImage(const QString &path, const QString &format, const QSize &size)
export symbol as image format. PNG and SVG supported
QgsMapUnitScale mapUnitScale() const
Container of fields for a vector layer.
Definition: qgsfield.h:177
qreal top() const
Line symbol.
Definition: qgssymbolv2.h:71
QString expressionString() const
Returns the expression string of this QgsDataDefined.
T takeAt(int i)
GeometryType
Definition: qgis.h:104
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:176
void drawLine(const QLineF &line)
SymbolType mType
Definition: qgssymbolv2.h:233
static QgsSymbolLayerV2 * create(const QgsStringMap &properties=QgsStringMap())
virtual void removeDataDefinedProperty(const QString &property)
Removes a data defined property from the layer.
qreal left() const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:268
static double pixelSizeScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns scale factor painter units -> pixel dimensions.
void setWidth(double width)
QgsDataDefined * scaleWholeSymbol(double scaleFactor, const QgsDataDefined &dd)
Definition: qgssymbolv2.cpp:52
Marker symbol.
Definition: qgssymbolv2.h:70
QgsDataDefined dataDefinedWidth() const
Returns data defined size for whole symbol (including all symbol layers).
void setMapUnitScale(const QgsMapUnitScale &scale)
void setAngle(double angle)
const QgsVectorLayer * layer() const
Definition: qgssymbolv2.h:222
virtual void startRender(QgsSymbolV2RenderContext &context)=0
QColor fromHsv(int h, int s, int v, int a)
void setUseExpression(bool use)
Controls if the field or the expression part is active.
void setColor(const QColor &color)
Mixed units in symbol layers.
Definition: qgssymbolv2.h:59
static QgsRenderContext createRenderContext(QPainter *p)
Creates a render context for a pixel based device.
QString number(int n, int base)
QgsSymbolLayerV2List mLayers
Definition: qgssymbolv2.h:234
int count(const T &value) const
qreal x() const
qreal y() const
void append(const T &value)
double width() const
QgsSymbolLayerV2List cloneLayers() const
void setOffset(double offset)
bool appendSymbolLayer(QgsSymbolLayerV2 *layer)
Append symbol layer at the end of the list Ownership will be transferred.
bool empty() const
virtual void renderPoint(const QPointF &point, QgsSymbolV2RenderContext &context)=0
void fill(uint pixelValue)
static double convertToPainterUnits(const QgsRenderContext &c, double size, QgsSymbolV2::OutputUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale())
Converts a size from the specied units to painter units.
void setLineAngle(double lineAngle)
Sets the line angle modification for the symbol's angle.
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
qreal alpha() const
Get alpha transparency 1 for opaque, 0 for invisible.
Definition: qgssymbolv2.h:191
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
static QgsSymbolLayerV2 * create(const QgsStringMap &properties=QgsStringMap())
void setPen(const QColor &color)
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
void setRenderingPass(int renderingPass)
#define DEFAULT_SCALE_METHOD
void setLayer(const QgsVectorLayer *layer)
Definition: qgssymbolv2.h:221
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
virtual void setWidth(double width)
static QgsStyleV2 * defaultStyle()
return default application-wide style
Definition: qgsstylev2.cpp:51
QPointF topLeft() const
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
QgsMarkerSymbolV2(const QgsSymbolLayerV2List &layers=QgsSymbolLayerV2List())
void setAngle(double angle)
double angle() const
void setAngle(double angle)
virtual QgsSymbolV2 * clone() const override
void setPainter(QPainter *p)
void setSize(double size)
qreal mAlpha
Symbol opacity (in the range 0 - 1)
Definition: qgssymbolv2.h:237
QgsSymbolV2RenderContext & operator=(const QgsSymbolV2RenderContext &)
QRectF united(const QRectF &rectangle) const
virtual void renderPolygonOutline(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolV2RenderContext &context)
QgsSymbolV2(SymbolType type, const QgsSymbolLayerV2List &layers)
Definition: qgssymbolv2.cpp:77
QgsDataDefined * rotateWholeSymbol(double additionalRotation, const QgsDataDefined &dd)
Definition: qgssymbolv2.cpp:42
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
void setLineAngle(double lineAngle)
Sets the line angle modification for the symbol's angle.
QgsSymbolV2::ScaleMethod scaleMethod() const
QgsSymbolV2::SymbolType type() const
bool useExpression() const
Returns if the field or the expression part is active.
T * data() const
virtual QgsSymbolV2 * clone() const override
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
virtual ~QgsSymbolV2()
virtual void renderPolyline(const QPolygonF &points, QgsSymbolV2RenderContext &context)=0
QgsSymbolV2 * symbol(const QString &name)
return a NEW copy of symbol
Definition: qgsstylev2.cpp:166
void setFileName(const QString &fileName)
QgsExpressionContext & expressionContext()
Gets the expression context.
SymbolType
Type of the symbol.
Definition: qgssymbolv2.h:68
void restore()
bool isSymbolLayerCompatible(SymbolType t)
check whether a symbol layer type can be used within the symbol (marker-marker, line-line, fill-fill/line)
void setDataDefinedWidth(const QgsDataDefined &dd)
Set data defined width for whole symbol (including all symbol layers).
Contains information about the context of a rendering operation.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
QRectF boundingRect() const
QPainter * painter()
QgsDataDefined dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
void stopRender(QgsRenderContext &context)
bool insertSymbolLayer(int index, QgsSymbolLayerV2 *layer)
Insert symbol layer to specified index Ownership will be transferred.
QSet< T > & unite(const QSet< T > &other)
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
ScaleMethod
Scale method.
Definition: qgssymbolv2.h:78
Struct for storing maximum and minimum scales for measurements in map units.
QImage bigSymbolPreviewImage(QgsExpressionContext *expressionContext=0)
Returns a large (roughly 100x100 pixel) preview image for the symbol.
void insert(int i, const T &value)
double offset() const
QgsRenderContext & renderContext()
Definition: qgssymbolv2.h:254
virtual QgsDataDefined * getDataDefinedProperty(const QString &property) const
Returns the data defined property corresponding to the specified property key.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:353
int height() const
Fill symbol.
Definition: qgssymbolv2.h:72
QgsSymbolV2::OutputUnit outputUnit() const
void translate(const QPointF &offset)
QgsSymbolLayerV2 * takeSymbolLayer(int index)
Remove symbol layer from the list and return pointer to it.
bool hasDefaultValues() const
Returns whether the data defined container is set to all the default values, ie, disabled, with empty expression and no assigned field.
double outputPixelSize(double size) const
double outputLineWidth(double width) const
QgsSymbolLayerV2 * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
QImage asImage(QSize size, QgsRenderContext *customContext=0)
Generate symbol as image.
const_iterator constEnd() const
QString dump() const
const_iterator constBegin() const
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=0)
Draw icon of the symbol that occupyies area given by size using the painter.
void setSize(double size)
void setAngle(double angle)
QPointF offset() const
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
virtual QgsSymbolV2 * clone() const override
virtual void end(QgsRenderContext &context)
Ends interception of paint operations to a render context, and draws the result to the render context...
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
virtual void stopRender(QgsSymbolV2RenderContext &context)=0
void setExpressionString(const QString &expr)
Sets the expression for this QgsDataDefined.
void setOutputUnit(QgsSymbolV2::OutputUnit u)
void setAlpha(qreal alpha)
Set alpha transparency 1 for opaque, 0 for invisible.
Definition: qgssymbolv2.h:193
iterator begin()
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
static QgsSymbolLayerV2 * create(const QgsStringMap &properties=QgsStringMap())
virtual void begin(QgsRenderContext &context)
Begins intercepting paint operations to a render context.
QgsLineSymbolV2(const QgsSymbolLayerV2List &layers=QgsSymbolLayerV2List())
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
QColor color() const
int mRenderHints
Definition: qgssymbolv2.h:239
virtual Q_DECL_DEPRECATED void setDataDefinedProperty(const QString &property, const QString &expressionString)
Sets a data defined expression for a property.