QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgsellipsesymbollayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsellipsesymbollayer.cpp
3  ---------------------
4  begin : June 2011
5  copyright : (C) 2011 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
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 #include "qgsellipsesymbollayer.h"
16 #include "qgsdxfexport.h"
17 #include "qgsexpression.h"
18 #include "qgsfeature.h"
19 #include "qgsrendercontext.h"
20 #include "qgsvectorlayer.h"
21 #include "qgslogger.h"
22 #include "qgsunittypes.h"
23 #include "qgsproperty.h"
24 #include "qgssymbollayerutils.h"
25 
26 #include <QPainter>
27 #include <QSet>
28 #include <QDomDocument>
29 #include <QDomElement>
30 
32  : mSymbolName( QStringLiteral( "circle" ) )
33  , mStrokeColor( QColor( 35, 35, 35 ) )
34 {
35  mColor = Qt::white;
36  mPen.setColor( mStrokeColor );
37  mPen.setStyle( mStrokeStyle );
38  mPen.setJoinStyle( mPenJoinStyle );
39  mPen.setWidth( 1.0 );
40  mBrush.setColor( mColor );
41  mBrush.setStyle( Qt::SolidPattern );
42  mOffset = QPointF( 0, 0 );
43  mAngle = 0;
44 }
45 
46 QgsSymbolLayer *QgsEllipseSymbolLayer::create( const QVariantMap &properties )
47 {
49  if ( properties.contains( QStringLiteral( "symbol_name" ) ) )
50  {
51  layer->setSymbolName( properties[ QStringLiteral( "symbol_name" )].toString() );
52  }
53  if ( properties.contains( QStringLiteral( "size" ) ) )
54  {
55  layer->setSize( properties[QStringLiteral( "size" )].toDouble() );
56  }
57  if ( properties.contains( QStringLiteral( "size_unit" ) ) )
58  {
59  layer->setSizeUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "size_unit" )].toString() ) );
60  }
61  if ( properties.contains( QStringLiteral( "size_map_unit_scale" ) ) )
62  {
63  layer->setSizeMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "size_map_unit_scale" )].toString() ) );
64  }
65  if ( properties.contains( QStringLiteral( "symbol_width" ) ) )
66  {
67  layer->setSymbolWidth( properties[QStringLiteral( "symbol_width" )].toDouble() );
68  }
69  if ( properties.contains( QStringLiteral( "symbol_width_unit" ) ) )
70  {
71  layer->setSymbolWidthUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "symbol_width_unit" )].toString() ) );
72  }
73  if ( properties.contains( QStringLiteral( "symbol_width_map_unit_scale" ) ) )
74  {
75  layer->setSymbolWidthMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "symbol_width_map_unit_scale" )].toString() ) );
76  }
77  if ( properties.contains( QStringLiteral( "symbol_height" ) ) )
78  {
79  layer->setSymbolHeight( properties[QStringLiteral( "symbol_height" )].toDouble() );
80  }
81  if ( properties.contains( QStringLiteral( "symbol_height_unit" ) ) )
82  {
83  layer->setSymbolHeightUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "symbol_height_unit" )].toString() ) );
84  }
85  if ( properties.contains( QStringLiteral( "symbol_height_map_unit_scale" ) ) )
86  {
87  layer->setSymbolHeightMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "symbol_height_map_unit_scale" )].toString() ) );
88  }
89  if ( properties.contains( QStringLiteral( "angle" ) ) )
90  {
91  layer->setAngle( properties[QStringLiteral( "angle" )].toDouble() );
92  }
93  if ( properties.contains( QStringLiteral( "outline_style" ) ) )
94  {
95  layer->setStrokeStyle( QgsSymbolLayerUtils::decodePenStyle( properties[QStringLiteral( "outline_style" )].toString() ) );
96  }
97  else if ( properties.contains( QStringLiteral( "line_style" ) ) )
98  {
99  layer->setStrokeStyle( QgsSymbolLayerUtils::decodePenStyle( properties[QStringLiteral( "line_style" )].toString() ) );
100  }
101  if ( properties.contains( QStringLiteral( "joinstyle" ) ) )
102  {
103  layer->setPenJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( properties[QStringLiteral( "joinstyle" )].toString() ) );
104  }
105  if ( properties.contains( QStringLiteral( "outline_width" ) ) )
106  {
107  layer->setStrokeWidth( properties[QStringLiteral( "outline_width" )].toDouble() );
108  }
109  else if ( properties.contains( QStringLiteral( "line_width" ) ) )
110  {
111  layer->setStrokeWidth( properties[QStringLiteral( "line_width" )].toDouble() );
112  }
113  if ( properties.contains( QStringLiteral( "outline_width_unit" ) ) )
114  {
115  layer->setStrokeWidthUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "outline_width_unit" )].toString() ) );
116  }
117  else if ( properties.contains( QStringLiteral( "line_width_unit" ) ) )
118  {
119  layer->setStrokeWidthUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "line_width_unit" )].toString() ) );
120  }
121  if ( properties.contains( QStringLiteral( "outline_width_map_unit_scale" ) ) )
122  {
123  layer->setStrokeWidthMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "outline_width_map_unit_scale" )].toString() ) );
124  }
125  if ( properties.contains( QStringLiteral( "fill_color" ) ) )
126  {
127  //pre 2.5 projects used "fill_color"
128  layer->setFillColor( QgsSymbolLayerUtils::decodeColor( properties[QStringLiteral( "fill_color" )].toString() ) );
129  }
130  else if ( properties.contains( QStringLiteral( "color" ) ) )
131  {
132  layer->setFillColor( QgsSymbolLayerUtils::decodeColor( properties[QStringLiteral( "color" )].toString() ) );
133  }
134  if ( properties.contains( QStringLiteral( "outline_color" ) ) )
135  {
136  layer->setStrokeColor( QgsSymbolLayerUtils::decodeColor( properties[QStringLiteral( "outline_color" )].toString() ) );
137  }
138  else if ( properties.contains( QStringLiteral( "line_color" ) ) )
139  {
140  layer->setStrokeColor( QgsSymbolLayerUtils::decodeColor( properties[QStringLiteral( "line_color" )].toString() ) );
141  }
142  if ( properties.contains( QStringLiteral( "offset" ) ) )
143  {
144  layer->setOffset( QgsSymbolLayerUtils::decodePoint( properties[QStringLiteral( "offset" )].toString() ) );
145  }
146  if ( properties.contains( QStringLiteral( "offset_unit" ) ) )
147  {
148  layer->setOffsetUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "offset_unit" )].toString() ) );
149  }
150  if ( properties.contains( QStringLiteral( "offset_map_unit_scale" ) ) )
151  {
152  layer->setOffsetMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "offset_map_unit_scale" )].toString() ) );
153  }
154  if ( properties.contains( QStringLiteral( "horizontal_anchor_point" ) ) )
155  {
156  layer->setHorizontalAnchorPoint( QgsMarkerSymbolLayer::HorizontalAnchorPoint( properties[ QStringLiteral( "horizontal_anchor_point" )].toInt() ) );
157  }
158  if ( properties.contains( QStringLiteral( "vertical_anchor_point" ) ) )
159  {
160  layer->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( properties[ QStringLiteral( "vertical_anchor_point" )].toInt() ) );
161  }
162 
163  //data defined properties
165 
166  return layer;
167 }
168 
170 {
171  double scaledWidth = mSymbolWidth;
172  double scaledHeight = mSymbolHeight;
173 
174  QColor brushColor = mColor;
175  brushColor.setAlphaF( brushColor.alphaF() * context.opacity() );
176  mBrush.setColor( brushColor );
177 
178  QColor penColor = mStrokeColor;
179  penColor.setAlphaF( penColor.alphaF() * context.opacity() );
180  mPen.setColor( penColor );
181 
183  {
184  bool ok;
185  context.setOriginalValueVariable( mStrokeWidth );
187  if ( exprVal.isValid() )
188  {
189  double width = exprVal.toDouble( &ok );
190  if ( ok )
191  {
192  width = context.renderContext().convertToPainterUnits( width, mStrokeWidthUnit, mStrokeWidthMapUnitScale );
193  mPen.setWidthF( width );
194  mSelPen.setWidthF( width );
195  }
196  }
197 
200  if ( exprVal.isValid() )
201  {
202  mPen.setStyle( QgsSymbolLayerUtils::decodePenStyle( exprVal.toString() ) );
203  mSelPen.setStyle( mPen.style() );
204  }
205 
208  if ( exprVal.isValid() )
209  {
210  mPen.setJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( exprVal.toString() ) );
211  mSelPen.setJoinStyle( mPen.joinStyle() );
212  }
213 
216  brushColor.setAlphaF( brushColor.alphaF() * context.opacity() );
217  mBrush.setColor( brushColor );
218 
221  penColor.setAlphaF( penColor.alphaF() * context.opacity() );
222  mPen.setColor( penColor );
223 
225  {
226  QString symbolName = mSymbolName;
227  context.setOriginalValueVariable( mSymbolName );
229  if ( exprVal.isValid() )
230  {
231  symbolName = exprVal.toString();
232  }
233  preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() );
234  }
235  }
236 
237  //offset and rotation
238  bool hasDataDefinedRotation = false;
239  QPointF offset;
240  double angle = 0;
241  calculateOffsetAndRotation( context, scaledWidth, scaledHeight, hasDataDefinedRotation, offset, angle );
242 
243  QPainter *p = context.renderContext().painter();
244  if ( !p )
245  {
246  return;
247  }
248 
249  QMatrix transform;
250  transform.translate( point.x() + offset.x(), point.y() + offset.y() );
251  if ( !qgsDoubleNear( angle, 0.0 ) )
252  {
253  transform.rotate( angle );
254  }
255 
256  p->setPen( context.selected() ? mSelPen : mPen );
257  p->setBrush( context.selected() ? mSelBrush : mBrush );
258  p->drawPath( transform.map( mPainterPath ) );
259 }
260 
261 
262 void QgsEllipseSymbolLayer::calculateOffsetAndRotation( QgsSymbolRenderContext &context,
263  double scaledWidth,
264  double scaledHeight,
265  bool &hasDataDefinedRotation,
266  QPointF &offset,
267  double &angle ) const
268 {
269  double offsetX = 0;
270  double offsetY = 0;
271  markerOffset( context, scaledWidth, scaledHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale );
272  offset = QPointF( offsetX, offsetY );
273 
274 //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
275  bool ok = true;
276  angle = mAngle + mLineAngle;
277  bool usingDataDefinedRotation = false;
279  {
280  context.setOriginalValueVariable( angle );
282  usingDataDefinedRotation = ok;
283  }
284 
285  hasDataDefinedRotation = context.renderHints() & QgsSymbol::DynamicRotation || usingDataDefinedRotation;
286  if ( hasDataDefinedRotation )
287  {
288  // For non-point markers, "dataDefinedRotation" means following the
289  // shape (shape-data defined). For them, "field-data defined" does
290  // not work at all. TODO: if "field-data defined" ever gets implemented
291  // we'll need a way to distinguish here between the two, possibly
292  // using another flag in renderHints()
293  const QgsFeature *f = context.feature();
294  if ( f )
295  {
296  const QgsGeometry g = f->geometry();
297  if ( !g.isNull() && g.type() == QgsWkbTypes::PointGeometry )
298  {
299  const QgsMapToPixel &m2p = context.renderContext().mapToPixel();
300  angle += m2p.mapRotation();
301  }
302  }
303  }
304 
305  if ( angle )
307 }
308 
310 {
311  return QStringLiteral( "EllipseMarker" );
312 }
313 
315 {
316  QgsMarkerSymbolLayer::startRender( context ); // get anchor point expressions
317  if ( !context.feature() || !dataDefinedProperties().hasActiveProperties() )
318  {
319  preparePath( mSymbolName, context );
320  }
321  mPen.setColor( mStrokeColor );
322  mPen.setStyle( mStrokeStyle );
323  mPen.setJoinStyle( mPenJoinStyle );
324  mPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) );
325  mBrush.setColor( mColor );
326 
327  QColor selBrushColor = context.renderContext().selectionColor();
328  QColor selPenColor = selBrushColor == mColor ? selBrushColor : mStrokeColor;
329  if ( context.opacity() < 1 && !SELECTION_IS_OPAQUE )
330  {
331  selBrushColor.setAlphaF( context.opacity() );
332  selPenColor.setAlphaF( context.opacity() );
333  }
334  mSelBrush = QBrush( selBrushColor );
335  mSelPen = QPen( selPenColor );
336  mSelPen.setStyle( mStrokeStyle );
337  mSelPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) );
338 }
339 
341 {
342 }
343 
345 {
347  m->setSymbolName( mSymbolName );
348  m->setSymbolWidth( mSymbolWidth );
349  m->setSymbolHeight( mSymbolHeight );
350  m->setStrokeStyle( mStrokeStyle );
351  m->setOffset( mOffset );
354  m->setStrokeStyle( mStrokeStyle );
355  m->setPenJoinStyle( mPenJoinStyle );
356  m->setStrokeWidth( mStrokeWidth );
357  m->setColor( color() );
358  m->setStrokeColor( mStrokeColor );
359  m->setSymbolWidthUnit( mSymbolWidthUnit );
360  m->setSymbolWidthMapUnitScale( mSymbolWidthMapUnitScale );
361  m->setSymbolHeightUnit( mSymbolHeightUnit );
362  m->setSymbolHeightMapUnitScale( mSymbolHeightMapUnitScale );
363  m->setStrokeWidthUnit( mStrokeWidthUnit );
364  m->setStrokeWidthMapUnitScale( mStrokeWidthMapUnitScale );
365  m->setAngle( mAngle );
368 
370  copyPaintEffect( m );
371  return m;
372 }
373 
374 void QgsEllipseSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
375 {
376  QDomElement symbolizerElem = doc.createElement( QStringLiteral( "se:PointSymbolizer" ) );
377  if ( !props.value( QStringLiteral( "uom" ), QString() ).toString().isEmpty() )
378  symbolizerElem.setAttribute( QStringLiteral( "uom" ), props.value( QStringLiteral( "uom" ), QString() ).toString() );
379  element.appendChild( symbolizerElem );
380 
381  // <Geometry>
382  QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( QStringLiteral( "geom" ), QString() ).toString() );
383 
384  writeSldMarker( doc, symbolizerElem, props );
385 }
386 
387 void QgsEllipseSymbolLayer::writeSldMarker( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
388 {
389  // <Graphic>
390  QDomElement graphicElem = doc.createElement( QStringLiteral( "se:Graphic" ) );
391  element.appendChild( graphicElem );
392 
393  double strokeWidth = QgsSymbolLayerUtils::rescaleUom( mStrokeWidth, mStrokeWidthUnit, props );
394  double symbolWidth = QgsSymbolLayerUtils::rescaleUom( mSymbolWidth, mSymbolWidthUnit, props );
395  QgsSymbolLayerUtils::wellKnownMarkerToSld( doc, graphicElem, mSymbolName, mColor, mStrokeColor, mStrokeStyle, strokeWidth, symbolWidth );
396 
397  // <Rotation>
399 
400  QString angleFunc = props.value( QStringLiteral( "angle" ), QString() ).toString();
401  if ( angleFunc.isEmpty() ) // symbol has no angle set
402  {
403  if ( ddRotation && ddRotation.isActive() )
404  {
405  angleFunc = ddRotation.asExpression();
406  }
407  else if ( !qgsDoubleNear( mAngle, 0.0 ) )
408  angleFunc = QString::number( mAngle );
409  }
410  else if ( ddRotation && ddRotation.isActive() )
411  {
412  // the symbol has an angle and the symbol layer have a rotation
413  // property set
414  angleFunc = QStringLiteral( "%1 + %2" ).arg( angleFunc, ddRotation.asExpression() );
415  }
416  else if ( !qgsDoubleNear( mAngle, 0.0 ) )
417  {
418  // both the symbol and the symbol layer have angle value set
419  bool ok;
420  double angle = angleFunc.toDouble( &ok );
421  if ( !ok )
422  {
423  // its a string (probably a property name or a function)
424  angleFunc = QStringLiteral( "%1 + %2" ).arg( angleFunc ).arg( mAngle );
425  }
426  else if ( !qgsDoubleNear( angle + mAngle, 0.0 ) )
427  {
428  // it's a double value
429  angleFunc = QString::number( angle + mAngle );
430  }
431  }
432  QgsSymbolLayerUtils::createRotationElement( doc, graphicElem, angleFunc );
433 
434  // <Displacement>
437 
438  // store w/h factor in a <VendorOption>
439  double widthHeightFactor = mSymbolWidth / mSymbolHeight;
440  QDomElement factorElem = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "widthHeightFactor" ), QString::number( widthHeightFactor ) );
441  graphicElem.appendChild( factorElem );
442 }
443 
445 {
446  QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
447 
448  QDomElement graphicElem = element.firstChildElement( QStringLiteral( "Graphic" ) );
449  if ( graphicElem.isNull() )
450  return nullptr;
451 
452  QString name = QStringLiteral( "circle" );
453  QColor fillColor, strokeColor;
454  double strokeWidth, size;
455  double widthHeightFactor = 1.0;
456  Qt::PenStyle strokeStyle;
457 
458  QgsStringMap vendorOptions = QgsSymbolLayerUtils::getVendorOptionList( graphicElem );
459  for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
460  {
461  if ( it.key() == QLatin1String( "widthHeightFactor" ) )
462  {
463  bool ok;
464  double v = it.value().toDouble( &ok );
465  if ( ok && !qgsDoubleNear( v, 0.0 ) && v > 0 )
466  widthHeightFactor = v;
467  }
468  }
469 
471  return nullptr;
472 
473  QString uom = element.attribute( QStringLiteral( "uom" ) );
476 
477  double angle = 0.0;
478  QString angleFunc;
479  if ( QgsSymbolLayerUtils::rotationFromSldElement( graphicElem, angleFunc ) )
480  {
481  bool ok;
482  double d = angleFunc.toDouble( &ok );
483  if ( ok )
484  angle = d;
485  }
486 
488  m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
489  m->setSymbolName( name );
490  m->setFillColor( fillColor );
494  m->setSymbolWidth( size );
495  m->setSymbolHeight( size / widthHeightFactor );
496  m->setAngle( angle );
497  return m;
498 }
499 
501 {
502  QVariantMap map;
503  map[QStringLiteral( "symbol_name" )] = mSymbolName;
504  map[QStringLiteral( "symbol_width" )] = QString::number( mSymbolWidth );
505  map[QStringLiteral( "symbol_width_unit" )] = QgsUnitTypes::encodeUnit( mSymbolWidthUnit );
506  map[QStringLiteral( "symbol_width_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mSymbolWidthMapUnitScale );
507  map[QStringLiteral( "symbol_height" )] = QString::number( mSymbolHeight );
508  map[QStringLiteral( "symbol_height_unit" )] = QgsUnitTypes::encodeUnit( mSymbolHeightUnit );
509  map[QStringLiteral( "symbol_height_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mSymbolHeightMapUnitScale );
510  map[QStringLiteral( "angle" )] = QString::number( mAngle );
511  map[QStringLiteral( "outline_style" )] = QgsSymbolLayerUtils::encodePenStyle( mStrokeStyle );
512  map[QStringLiteral( "outline_width" )] = QString::number( mStrokeWidth );
513  map[QStringLiteral( "outline_width_unit" )] = QgsUnitTypes::encodeUnit( mStrokeWidthUnit );
514  map[QStringLiteral( "outline_width_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mStrokeWidthMapUnitScale );
515  map[QStringLiteral( "joinstyle" )] = QgsSymbolLayerUtils::encodePenJoinStyle( mPenJoinStyle );
516  map[QStringLiteral( "color" )] = QgsSymbolLayerUtils::encodeColor( mColor );
517  map[QStringLiteral( "outline_color" )] = QgsSymbolLayerUtils::encodeColor( mStrokeColor );
518  map[QStringLiteral( "offset" )] = QgsSymbolLayerUtils::encodePoint( mOffset );
519  map[QStringLiteral( "offset_unit" )] = QgsUnitTypes::encodeUnit( mOffsetUnit );
520  map[QStringLiteral( "offset_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetMapUnitScale );
521  map[QStringLiteral( "size" )] = QString::number( mSize );
522  map[QStringLiteral( "size_unit" )] = QgsUnitTypes::encodeUnit( mSizeUnit );
523  map[QStringLiteral( "size_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mSizeMapUnitScale );
524  map[QStringLiteral( "horizontal_anchor_point" )] = QString::number( mHorizontalAnchorPoint );
525  map[QStringLiteral( "vertical_anchor_point" )] = QString::number( mVerticalAnchorPoint );
526  return map;
527 }
528 
529 QSizeF QgsEllipseSymbolLayer::calculateSize( QgsSymbolRenderContext &context, double *scaledWidth, double *scaledHeight )
530 {
531  double width = 0;
532 
533  if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) ) //1. priority: data defined setting on symbol layer le
534  {
535  context.setOriginalValueVariable( mSymbolWidth );
537  }
538  else //2. priority: global width setting
539  {
540  width = mSymbolWidth;
541  }
542  if ( scaledWidth )
543  {
544  *scaledWidth = width;
545  }
546  width = context.renderContext().convertToPainterUnits( width, mSymbolWidthUnit, mSymbolHeightMapUnitScale );
547 
548  double height = 0;
549  if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) ) //1. priority: data defined setting on symbol layer level
550  {
551  context.setOriginalValueVariable( mSymbolHeight );
553  }
554  else //2. priority: global height setting
555  {
556  height = mSymbolHeight;
557  }
558  if ( scaledHeight )
559  {
560  *scaledHeight = height;
561  }
562  height = context.renderContext().convertToPainterUnits( height, mSymbolHeightUnit, mSymbolHeightMapUnitScale );
563  return QSizeF( width, height );
564 }
565 
566 void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRenderContext &context, double *scaledWidth, double *scaledHeight, const QgsFeature * )
567 {
568  mPainterPath = QPainterPath();
569 
570  QSizeF size = calculateSize( context, scaledWidth, scaledHeight );
571 
572  if ( symbolName == QLatin1String( "circle" ) )
573  {
574  mPainterPath.addEllipse( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) );
575  }
576  else if ( symbolName == QLatin1String( "semi_circle" ) )
577  {
578  mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 );
579  mPainterPath.lineTo( 0, 0 );
580  }
581  else if ( symbolName == QLatin1String( "rectangle" ) )
582  {
583  mPainterPath.addRect( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) );
584  }
585  else if ( symbolName == QLatin1String( "diamond" ) )
586  {
587  mPainterPath.moveTo( -size.width() / 2.0, 0 );
588  mPainterPath.lineTo( 0, size.height() / 2.0 );
589  mPainterPath.lineTo( size.width() / 2.0, 0 );
590  mPainterPath.lineTo( 0, -size.height() / 2.0 );
591  mPainterPath.lineTo( -size.width() / 2.0, 0 );
592  }
593  else if ( symbolName == QLatin1String( "cross" ) )
594  {
595  mPainterPath.moveTo( 0, -size.height() / 2.0 );
596  mPainterPath.lineTo( 0, size.height() / 2.0 );
597  mPainterPath.moveTo( -size.width() / 2.0, 0 );
598  mPainterPath.lineTo( size.width() / 2.0, 0 );
599  }
600  else if ( symbolName == QLatin1String( "triangle" ) )
601  {
602  mPainterPath.moveTo( 0, -size.height() / 2.0 );
603  mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 );
604  mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 );
605  mPainterPath.lineTo( 0, -size.height() / 2.0 );
606  }
607  else if ( symbolName == QLatin1String( "left_half_triangle" ) )
608  {
609  mPainterPath.moveTo( 0, size.height() / 2.0 );
610  mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 );
611  mPainterPath.lineTo( 0, -size.height() / 2.0 );
612  mPainterPath.lineTo( 0, size.height() / 2.0 );
613  }
614  else if ( symbolName == QLatin1String( "right_half_triangle" ) )
615  {
616  mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 );
617  mPainterPath.lineTo( 0, size.height() / 2.0 );
618  mPainterPath.lineTo( 0, -size.height() / 2.0 );
619  mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 );
620  }
621 }
622 
624 {
625  if ( mSymbolWidth >= mSymbolHeight )
626  {
627  mSymbolHeight = mSymbolHeight * size / mSymbolWidth;
628  mSymbolWidth = size;
629  }
630  else
631  {
632  mSymbolWidth = mSymbolWidth * size / mSymbolHeight;
633  mSymbolHeight = size;
634  }
636 }
637 
639 {
640  mSymbolWidth = w;
641  QgsMarkerSymbolLayer::setSize( mSymbolWidth >= mSymbolHeight ? mSymbolWidth : mSymbolHeight );
642 }
643 
645 {
646  mSymbolHeight = h;
647  QgsMarkerSymbolLayer::setSize( mSymbolWidth >= mSymbolHeight ? mSymbolWidth : mSymbolHeight );
648 }
649 
651 {
653  mSymbolWidthUnit = unit;
654  mSymbolHeightUnit = unit;
655  mStrokeWidthUnit = unit;
656 }
657 
659 {
661  if ( mSymbolWidthUnit != unit || mSymbolHeightUnit != unit || mStrokeWidthUnit != unit )
662  {
664  }
665  return unit;
666 }
667 
669 {
670  return mSymbolWidthUnit == QgsUnitTypes::RenderMapUnits || mSymbolWidthUnit == QgsUnitTypes::RenderMetersInMapUnits
671  || mSymbolHeightUnit == QgsUnitTypes::RenderMapUnits || mSymbolHeightUnit == QgsUnitTypes::RenderMetersInMapUnits
672  || mStrokeWidthUnit == QgsUnitTypes::RenderMapUnits || mStrokeWidthUnit == QgsUnitTypes::RenderMetersInMapUnits
674 }
675 
677 {
679  mSymbolWidthMapUnitScale = scale;
680  mSymbolHeightMapUnitScale = scale;
681  mStrokeWidthMapUnitScale = scale;
682 }
683 
685 {
686  if ( QgsMarkerSymbolLayer::mapUnitScale() == mSymbolWidthMapUnitScale &&
687  mSymbolWidthMapUnitScale == mSymbolHeightMapUnitScale &&
688  mSymbolHeightMapUnitScale == mStrokeWidthMapUnitScale )
689  {
690  return mSymbolWidthMapUnitScale;
691  }
692  return QgsMapUnitScale();
693 }
694 
695 QRectF QgsEllipseSymbolLayer::bounds( QPointF point, QgsSymbolRenderContext &context )
696 {
697  QSizeF size = calculateSize( context );
698 
699  bool hasDataDefinedRotation = false;
700  QPointF offset;
701  double angle = 0;
702  calculateOffsetAndRotation( context, size.width(), size.height(), hasDataDefinedRotation, offset, angle );
703 
704  QMatrix transform;
705 
706  // move to the desired position
707  transform.translate( point.x() + offset.x(), point.y() + offset.y() );
708 
709  if ( !qgsDoubleNear( angle, 0.0 ) )
710  transform.rotate( angle );
711 
712  double penWidth = mStrokeWidth;
714  {
715  context.setOriginalValueVariable( mStrokeWidth );
717 
718  if ( exprVal.isValid() )
719  {
720  bool ok;
721  double strokeWidth = exprVal.toDouble( &ok );
722  if ( ok )
723  {
724  penWidth = strokeWidth;
725  }
726  }
727  }
728  penWidth = context.renderContext().convertToPainterUnits( penWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale );
729 
731  {
734  if ( exprVal.isValid() && exprVal.toString() == QLatin1String( "no" ) )
735  {
736  penWidth = 0.0;
737  }
738  }
739  else if ( mStrokeStyle == Qt::NoPen )
740  penWidth = 0;
741 
742  //antialiasing, add 1 pixel
743  penWidth += 1;
744 
745  QRectF symbolBounds = transform.mapRect( QRectF( -size.width() / 2.0,
746  -size.height() / 2.0,
747  size.width(),
748  size.height() ) );
749 
750  //extend bounds by pen width / 2.0
751  symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
752  penWidth / 2.0, penWidth / 2.0 );
753 
754  return symbolBounds;
755 }
756 
757 bool QgsEllipseSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
758 {
759  //width
760  double symbolWidth = mSymbolWidth;
761 
762  if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) ) //1. priority: data defined setting on symbol layer le
763  {
764  context.setOriginalValueVariable( mSymbolWidth );
766  }
767  if ( mSymbolWidthUnit == QgsUnitTypes::RenderMillimeters )
768  {
769  symbolWidth *= mmMapUnitScaleFactor;
770  }
771 
772  //height
773  double symbolHeight = mSymbolHeight;
774  if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) ) //1. priority: data defined setting on symbol layer level
775  {
776  context.setOriginalValueVariable( mSymbolHeight );
778  }
779  if ( mSymbolHeightUnit == QgsUnitTypes::RenderMillimeters )
780  {
781  symbolHeight *= mmMapUnitScaleFactor;
782  }
783 
784  //stroke width
785  double strokeWidth = mStrokeWidth;
786 
788  {
789  context.setOriginalValueVariable( mStrokeWidth );
791  }
792  if ( mStrokeWidthUnit == QgsUnitTypes::RenderMillimeters )
793  {
795  }
796 
797  //fill color
798  QColor fc = mColor;
800  {
803  }
804 
805  //stroke color
806  QColor oc = mStrokeColor;
808  {
811  }
812 
813  //symbol name
814  QString symbolName = mSymbolName;
816  {
817  context.setOriginalValueVariable( mSymbolName );
819  }
820 
821  //offset
822  double offsetX = 0;
823  double offsetY = 0;
824  markerOffset( context, offsetX, offsetY );
825  QPointF off( offsetX, offsetY );
826 
827  //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
828  double rotation = 0.0;
830  {
831  context.setOriginalValueVariable( mAngle );
833  }
834  else if ( !qgsDoubleNear( mAngle + mLineAngle, 0.0 ) )
835  {
836  rotation = mAngle + mLineAngle;
837  }
838  rotation = -rotation; //rotation in Qt is counterclockwise
839  if ( rotation )
840  off = _rotatedOffset( off, rotation );
841 
842  QTransform t;
843  t.translate( shift.x() + offsetX, shift.y() + offsetY );
844 
845  if ( !qgsDoubleNear( rotation, 0.0 ) )
846  t.rotate( rotation );
847 
848  double halfWidth = symbolWidth / 2.0;
849  double halfHeight = symbolHeight / 2.0;
850 
851  if ( symbolName == QLatin1String( "circle" ) )
852  {
853  if ( qgsDoubleNear( halfWidth, halfHeight ) )
854  {
855  QgsPoint pt( t.map( QPointF( 0, 0 ) ) );
856  e.writeFilledCircle( layerName, oc, pt, halfWidth );
857  }
858  else
859  {
860  QgsPointSequence line;
861 
862  double stepsize = 2 * M_PI / 40;
863  for ( int i = 0; i < 39; ++i )
864  {
865  double angle = stepsize * i;
866  double x = halfWidth * std::cos( angle );
867  double y = halfHeight * std::sin( angle );
868  line << QgsPoint( t.map( QPointF( x, y ) ) );
869  }
870  //close ellipse with first point
871  line << line.at( 0 );
872 
873  if ( mBrush.style() != Qt::NoBrush )
874  e.writePolygon( QgsRingSequence() << line, layerName, QStringLiteral( "SOLID" ), fc );
875  if ( mPen.style() != Qt::NoPen )
876  e.writePolyline( line, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth );
877  }
878  }
879  else if ( symbolName == QLatin1String( "rectangle" ) )
880  {
882  p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) )
883  << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) )
884  << QgsPoint( t.map( QPointF( halfWidth, halfHeight ) ) )
885  << QgsPoint( t.map( QPointF( -halfWidth, halfHeight ) ) );
886  p << p[0];
887 
888  if ( mBrush.style() != Qt::NoBrush )
889  e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc );
890  if ( mPen.style() != Qt::NoPen )
891  e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth );
892  return true;
893  }
894  else if ( symbolName == QLatin1String( "cross" ) && mPen.style() != Qt::NoPen )
895  {
897  << QgsPoint( t.map( QPointF( -halfWidth, 0 ) ) )
898  << QgsPoint( t.map( QPointF( halfWidth, 0 ) ) ),
899  layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth );
901  << QgsPoint( t.map( QPointF( 0, halfHeight ) ) )
902  << QgsPoint( t.map( QPointF( 0, -halfHeight ) ) ),
903  layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth );
904  return true;
905  }
906  else if ( symbolName == QLatin1String( "triangle" ) )
907  {
909  p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) )
910  << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) )
911  << QgsPoint( t.map( QPointF( 0, halfHeight ) ) );
912  p << p[0];
913  if ( mBrush.style() != Qt::NoBrush )
914  e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc );
915  if ( mPen.style() != Qt::NoPen )
916  e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth );
917  return true;
918  }
919 
920  return false; //soon...
921 }
922 
923 
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
Exports QGIS layers to the DXF format.
Definition: qgsdxfexport.h:64
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
A symbol layer for rendering objects with major and minor axis (e.g.
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void setSymbolHeightMapUnitScale(const QgsMapUnitScale &scale)
void setSymbolWidthMapUnitScale(const QgsMapUnitScale &scale)
void setSymbolName(const QString &name)
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
void setStrokeColor(const QColor &c) override
Set stroke color.
void setStrokeStyle(Qt::PenStyle strokeStyle)
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setSize(double size) override
Sets the symbol size.
QgsMapUnitScale mapUnitScale() const override
QColor fillColor() const override
Gets fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setFillColor(const QColor &c) override
Set fill color.
Qt::PenStyle strokeStyle() const
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
QColor strokeColor() const override
Gets stroke color.
void setSymbolWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's width.
void setPenJoinStyle(Qt::PenJoinStyle style)
Set stroke join style.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's stroke width.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setSymbolHeightUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's height.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
QgsEllipseSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
Q_GADGET bool isNull
Definition: qgsgeometry.h:126
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:127
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
double mapRotation() const
Returns current map rotation in degrees (clockwise)
Struct for storing maximum and minimum scales for measurements in map units.
double mSize
Marker size.
virtual void setSize(double size)
Sets the symbol size.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
double mLineAngle
Line rotation angle (see setLineAngle() for details)
HorizontalAnchorPoint
Symbol horizontal anchor points.
void setAngle(double angle)
Sets the rotation angle for the marker.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF mOffset
Marker offset.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
QgsMapUnitScale mapUnitScale() const override
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
VerticalAnchorPoint
Symbol vertical anchor points.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
double mAngle
Marker rotation angle, in degrees clockwise from north.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
A store for object properties.
Definition: qgsproperty.h:232
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
bool isActive() const
Returns whether the property is currently active.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QColor decodeColor(const QString &str)
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString encodeColor(const QColor &color)
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyAngle
Symbol angle.
@ PropertyJoinStyle
Line join style.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyHeight
Symbol height.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyStrokeColor
Stroke color.
@ PropertyWidth
Symbol width.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
virtual QColor color() const
The fill color.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual void setColor(const QColor &color)
The fill color.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
Definition: qgssymbol.h:850
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgssymbol.h:794
const QgsFeature * feature() const
Returns the current feature being rendered.
Definition: qgssymbol.h:875
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
Definition: qgssymbol.cpp:1508
QgsSymbol::RenderHints renderHints() const
Returns the rendering hint flags for the symbol.
Definition: qgssymbol.h:862
qreal opacity() const
Returns the opacity for the symbol.
Definition: qgssymbol.h:837
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
Definition: qgssymbol.h:107
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:174
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:175
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:316
QMap< QString, QString > QgsStringMap
Definition: qgis.h:759
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39