QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgssymbologyv2conversion.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbologyv2conversion.cpp
3  ---------------------
4  begin : December 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  ***************************************************************************/
16 
17 #include "qgslogger.h"
18 
19 #include "qgsmarkersymbollayerv2.h"
20 #include "qgslinesymbollayerv2.h"
21 #include "qgsfillsymbollayerv2.h"
25 
26 
27 
29 {
33 };
34 
35 
36 static QgsOldSymbolMeta readSymbolMeta( const QDomNode& synode )
37 {
38  QgsOldSymbolMeta meta;
39 
40  QDomNode lvalnode = synode.namedItem( "lowervalue" );
41  if ( ! lvalnode.isNull() )
42  {
43  QDomElement lvalelement = lvalnode.toElement();
44  if ( lvalelement.attribute( "null" ).toInt() == 1 )
45  {
46  meta.lowerValue = QString::null;
47  }
48  else
49  {
50  meta.lowerValue = lvalelement.text();
51  }
52  }
53 
54  QDomNode uvalnode = synode.namedItem( "uppervalue" );
55  if ( ! uvalnode.isNull() )
56  {
57  QDomElement uvalelement = uvalnode.toElement();
58  meta.upperValue = uvalelement.text();
59  }
60 
61  QDomNode labelnode = synode.namedItem( "label" );
62  if ( ! labelnode.isNull() )
63  {
64  QDomElement labelelement = labelnode.toElement();
65  meta.label = labelelement.text();
66  }
67 
68  return meta;
69 }
70 
71 
72 static QColor readSymbolColor( const QDomNode& synode, bool fillColor )
73 {
74  QDomNode cnode = synode.namedItem( fillColor ? "fillcolor" : "outlinecolor" );
75  QDomElement celement = cnode.toElement();
76  int red = celement.attribute( "red" ).toInt();
77  int green = celement.attribute( "green" ).toInt();
78  int blue = celement.attribute( "blue" ).toInt();
79  return QColor( red, green, blue );
80 }
81 
82 static double readOutlineWidth( const QDomNode& synode )
83 {
84  QDomNode outlwnode = synode.namedItem( "outlinewidth" );
85  QDomElement outlwelement = outlwnode.toElement();
86  return outlwelement.text().toDouble();
87 }
88 
89 
90 static Qt::PenStyle readOutlineStyle( const QDomNode& synode )
91 {
92  QDomNode outlstnode = synode.namedItem( "outlinestyle" );
93  QDomElement outlstelement = outlstnode.toElement();
94  return QgsSymbologyV2Conversion::qString2PenStyle( outlstelement.text() );
95 }
96 
97 static Qt::BrushStyle readBrushStyle( const QDomNode& synode )
98 {
99  QDomNode fillpnode = synode.namedItem( "fillpattern" );
100  QDomElement fillpelement = fillpnode.toElement();
101  return QgsSymbologyV2Conversion::qString2BrushStyle( fillpelement.text() );
102 }
103 
104 static QString readMarkerSymbolName( const QDomNode& synode )
105 {
106  QDomNode psymbnode = synode.namedItem( "pointsymbol" );
107  if ( ! psymbnode.isNull() )
108  {
109  QDomElement psymbelement = psymbnode.toElement();
110  return psymbelement.text();
111  }
112  return QString( "hard:circle" );
113 }
114 
115 static float readMarkerSymbolSize( const QDomNode& synode )
116 {
117  QDomNode psizenode = synode.namedItem( "pointsize" );
118  if ( ! psizenode.isNull() )
119  {
120  QDomElement psizeelement = psizenode.toElement();
121  return psizeelement.text().toFloat();
122  }
123  return DEFAULT_POINT_SIZE;
124 }
125 
126 
127 
128 static QgsSymbolV2* readOldSymbol( const QDomNode& synode, QGis::GeometryType geomType )
129 {
130  switch ( geomType )
131  {
132  case QGis::Point:
133  {
134  QgsMarkerSymbolLayerV2* sl = nullptr;
135  double size = readMarkerSymbolSize( synode );
136  double angle = 0; // rotation only from classification field
137  QString symbolName = readMarkerSymbolName( synode );
138  if ( symbolName.startsWith( "hard:" ) )
139  {
140  // simple symbol marker
141  QColor color = readSymbolColor( synode, true );
142  QColor borderColor = readSymbolColor( synode, false );
144  sl = new QgsSimpleMarkerSymbolLayerV2( shape, size, angle );
145  sl->setColor( color );
146  sl->setOutlineColor( borderColor );
147  }
148  else
149  {
150  // svg symbol marker
151  QString name = symbolName.mid( 4 );
152  sl = new QgsSvgMarkerSymbolLayerV2( name, size, angle );
153  }
154  QgsSymbolLayerV2List layers;
155  layers.append( sl );
156  return new QgsMarkerSymbolV2( layers );
157  }
158 
159  case QGis::Line:
160  {
161  QColor color = readSymbolColor( synode, false );
162  double width = readOutlineWidth( synode );
163  Qt::PenStyle penStyle = readOutlineStyle( synode );
164  QgsLineSymbolLayerV2* sl = new QgsSimpleLineSymbolLayerV2( color, width, penStyle );
165 
166  QgsSymbolLayerV2List layers;
167  layers.append( sl );
168  return new QgsLineSymbolV2( layers );
169  }
170 
171  case QGis::Polygon:
172  {
173  QColor color = readSymbolColor( synode, true );
174  QColor borderColor = readSymbolColor( synode, false );
175  Qt::BrushStyle brushStyle = readBrushStyle( synode );
176  Qt::PenStyle borderStyle = readOutlineStyle( synode );
177  double borderWidth = readOutlineWidth( synode );
178  QgsFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, brushStyle, borderColor, borderStyle, borderWidth );
179 
180  QgsSymbolLayerV2List layers;
181  layers.append( sl );
182  return new QgsFillSymbolV2( layers );
183  }
184 
185  default:
186  return nullptr;
187  }
188 }
189 
190 
191 
193 {
194  QDomNode synode = rnode.namedItem( "symbol" );
195  if ( synode.isNull() )
196  return nullptr;
197 
198  QgsSymbolV2* sy2 = readOldSymbol( synode, geomType );
200  return r;
201 }
202 
203 
205 {
206  QDomNode modeNode = rnode.namedItem( "mode" );
207  QString modeValue = modeNode.toElement().text();
208  QDomNode classnode = rnode.namedItem( "classificationfield" );
209  QString classificationField = classnode.toElement().text();
210 
212  if ( modeValue == "Empty" )
213  {
215  }
216  else if ( modeValue == "Quantile" )
217  {
219  }
220  else //default
221  {
223  }
224 
225  // load ranges and symbols
226  QgsRangeList ranges;
227  QDomNode symbolnode = rnode.namedItem( "symbol" );
228  while ( !symbolnode.isNull() )
229  {
230  QgsSymbolV2* symbolv2 = readOldSymbol( symbolnode, geomType );
231  if ( symbolv2 )
232  {
233  QgsOldSymbolMeta meta = readSymbolMeta( symbolnode );
234  double lowerValue = meta.lowerValue.toDouble();
235  double upperValue = meta.upperValue.toDouble();
236  QString label = meta.label;
237  if ( label.isEmpty() )
238  label = QString( "%1 - %2" ).arg( lowerValue, -1, 'f', 3 ).arg( upperValue, -1, 'f', 3 );
239  ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbolv2, label ) );
240  }
241 
242  symbolnode = symbolnode.nextSibling();
243  }
244 
245  // create renderer
246  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( classificationField, ranges );
247  r->setMode( m );
248  return r;
249 }
250 
251 
252 
254 {
255  QDomNode classnode = rnode.namedItem( "classificationfield" );
256  QString classificationField = classnode.toElement().text();
257 
258  // read categories and symbols
259  QgsCategoryList cats;
260  QDomNode symbolnode = rnode.namedItem( "symbol" );
261  while ( !symbolnode.isNull() )
262  {
263  QgsSymbolV2* symbolv2 = readOldSymbol( symbolnode, geomType );
264  if ( symbolv2 )
265  {
266  QgsOldSymbolMeta meta = readSymbolMeta( symbolnode );
267  QVariant value = QVariant( meta.lowerValue );
268  QString label = meta.label;
269  if ( label.isEmpty() )
270  label = value.toString();
271  cats.append( QgsRendererCategoryV2( value, symbolv2, label, true ) );
272  }
273 
274  symbolnode = symbolnode.nextSibling();
275  }
276 
277  QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( classificationField, cats );
278  // source symbol and color ramp are not set (unknown)
279  return r;
280 }
281 
282 
283 
284 
286 {
287  QDomNode singlenode = layerNode.namedItem( "singlesymbol" );
288  QDomNode graduatednode = layerNode.namedItem( "graduatedsymbol" );
289  QDomNode continuousnode = layerNode.namedItem( "continuoussymbol" );
290  QDomNode uniquevaluenode = layerNode.namedItem( "uniquevalue" );
291 
292  if ( !singlenode.isNull() )
293  {
294  return readOldSingleSymbolRenderer( singlenode, geomType );
295  }
296  else if ( !graduatednode.isNull() )
297  {
298  return readOldGraduatedSymbolRenderer( graduatednode, geomType );
299  }
300  else if ( !continuousnode.isNull() )
301  {
302  return nullptr;
303  }
304  else if ( !uniquevaluenode.isNull() )
305  {
306  return readOldUniqueValueRenderer( uniquevaluenode, geomType );
307  }
308 
309  return nullptr;
310 }
311 
312 
313 /*
314 UNSUPPORTED RENDERER: continuous color
315 
316  QDomNode classnode = rnode.namedItem( "classificationfield" );
317  QDomNode polyoutlinenode = rnode.namedItem( "polygonoutline" );
318  QString polyoutline = polyoutlinenode.toElement().text();
319  if ( polyoutline == "0" )
320  drawPolygonOutline = false;
321  else if ( polyoutline == "1" )
322  drawPolygonOutline = true;
323  QDomNode lowernode = rnode.namedItem( "lowestsymbol" );
324  lowSymbol = readOldSymbol( lowernode.namedItem( "symbol" ), geomType );
325  QDomNode uppernode = rnode.namedItem( "highestsymbol" );
326  highSymbol = readOldSymbol( uppernode.namedItem( "symbol" ), geomType );
327 
328 UNSUPPORTED SYMBOL PROPERTY: point size units
329 
330  QDomNode psizeunitnodes = synode.namedItem( "pointsizeunits" );
331  if ( ! psizeunitnodes.isNull() )
332  {
333  QDomElement psizeunitelement = psizeunitnodes.toElement();
334  QgsDebugMsg( QString( "psizeunitelement:%1" ).arg( psizeunitelement.text() ) );
335  setPointSizeUnits( psizeunitelement.text().compare( "mapunits", Qt::CaseInsensitive ) == 0 );
336  }
337 
338 UNSUPPORTED SYMBOL PROPERTY: data-defined rotation / scale / symbol name
339 
340  rotationClassificationFieldName = synode.namedItem( "rotationclassificationfieldname" ).toElement().text();
341  scaleClassificationFieldName = synode.namedItem( "scaleclassificationfield" ).toElement().text();
342  symbolFieldName = synode.namedItem( "symbolfieldname" ).toElement().text();
343 
344 UNSUPPORTED SYMBOL PROPERTY: texture
345 
346  QDomNode texturepathnode = synode.namedItem( "texturepath" );
347  QDomElement texturepathelement = texturepathnode.toElement();
348  setCustomTexture( QgsProject::instance()->readPath( texturepathelement.text() ) );
349 */
350 
351 
352 
353 
354 
356 {
357  if ( penstyle == Qt::NoPen )
358  {
359  return "NoPen";
360  }
361  else if ( penstyle == Qt::SolidLine )
362  {
363  return "SolidLine";
364  }
365  else if ( penstyle == Qt::DashLine )
366  {
367  return "DashLine";
368  }
369  else if ( penstyle == Qt::DotLine )
370  {
371  return "DotLine";
372  }
373  else if ( penstyle == Qt::DashDotLine )
374  {
375  return "DashDotLine";
376  }
377  else if ( penstyle == Qt::DashDotDotLine )
378  {
379  return "DashDotDotLine";
380  }
381  else if ( penstyle == Qt::MPenStyle )
382  {
383  return "MPenStyle";
384  }
385  else //return a null string
386  {
387  return QString();
388  }
389 }
390 
391 Qt::PenStyle QgsSymbologyV2Conversion::qString2PenStyle( const QString& penString )
392 {
393  if ( penString == "NoPen" )
394  {
395  return Qt::NoPen;
396  }
397  else if ( penString == "SolidLine" )
398  {
399  return Qt::SolidLine;
400  }
401  else if ( penString == "DashLine" )
402  {
403  return Qt::DashLine;
404  }
405  else if ( penString == "DotLine" )
406  {
407  return Qt::DotLine;
408  }
409  else if ( penString == "DashDotLine" )
410  {
411  return Qt::DashDotLine;
412  }
413  else if ( penString == "DashDotDotLine" )
414  {
415  return Qt::DashDotDotLine;
416  }
417  else if ( penString == "MPenStyle" )
418  {
419  return Qt::MPenStyle;
420  }
421  else
422  {
423  return Qt::NoPen;
424  }
425 }
426 
428 {
429  if ( brushstyle == Qt::NoBrush )
430  {
431  return "NoBrush";
432  }
433  else if ( brushstyle == Qt::SolidPattern )
434  {
435  return "SolidPattern";
436  }
437  else if ( brushstyle == Qt::Dense1Pattern )
438  {
439  return "Dense1Pattern";
440  }
441  else if ( brushstyle == Qt::Dense2Pattern )
442  {
443  return "Dense2Pattern";
444  }
445  else if ( brushstyle == Qt::Dense3Pattern )
446  {
447  return "Dense3Pattern";
448  }
449  else if ( brushstyle == Qt::Dense4Pattern )
450  {
451  return "Dense4Pattern";
452  }
453  else if ( brushstyle == Qt::Dense5Pattern )
454  {
455  return "Dense5Pattern";
456  }
457  else if ( brushstyle == Qt::Dense6Pattern )
458  {
459  return "Dense6Pattern";
460  }
461  else if ( brushstyle == Qt::Dense7Pattern )
462  {
463  return "Dense7Pattern";
464  }
465  else if ( brushstyle == Qt::HorPattern )
466  {
467  return "HorPattern";
468  }
469  else if ( brushstyle == Qt::VerPattern )
470  {
471  return "VerPattern";
472  }
473  else if ( brushstyle == Qt::CrossPattern )
474  {
475  return "CrossPattern";
476  }
477  else if ( brushstyle == Qt::BDiagPattern )
478  {
479  return "BDiagPattern";
480  }
481  else if ( brushstyle == Qt::FDiagPattern )
482  {
483  return "FDiagPattern";
484  }
485  else if ( brushstyle == Qt::DiagCrossPattern )
486  {
487  return "DiagCrossPattern";
488  }
489  else if ( brushstyle == Qt::TexturePattern )
490  {
491  return "TexturePattern";
492  }
493  else //return a null string
494  {
495  QgsDebugMsg( "no matching pattern found" );
496  return " ";
497  }
498 }
499 
500 Qt::BrushStyle QgsSymbologyV2Conversion::qString2BrushStyle( const QString& brushString )
501 {
502  if ( brushString == "NoBrush" )
503  {
504  return Qt::NoBrush;
505  }
506  else if ( brushString == "SolidPattern" )
507  {
508  return Qt::SolidPattern;
509  }
510  else if ( brushString == "Dense1Pattern" )
511  {
512  return Qt::Dense1Pattern;
513  }
514  else if ( brushString == "Dense2Pattern" )
515  {
516  return Qt::Dense2Pattern;
517  }
518  else if ( brushString == "Dense3Pattern" )
519  {
520  return Qt::Dense3Pattern;
521  }
522  else if ( brushString == "Dense4Pattern" )
523  {
524  return Qt::Dense4Pattern;
525  }
526  else if ( brushString == "Dense5Pattern" )
527  {
528  return Qt::Dense5Pattern;
529  }
530  else if ( brushString == "Dense6Pattern" )
531  {
532  return Qt::Dense6Pattern;
533  }
534  else if ( brushString == "Dense7Pattern" )
535  {
536  return Qt::Dense7Pattern;
537  }
538  else if ( brushString == "HorPattern" )
539  {
540  return Qt::HorPattern;
541  }
542  else if ( brushString == "VerPattern" )
543  {
544  return Qt::VerPattern;
545  }
546  else if ( brushString == "CrossPattern" )
547  {
548  return Qt::CrossPattern;
549  }
550  else if ( brushString == "BDiagPattern" )
551  {
552  return Qt::BDiagPattern;
553  }
554  else if ( brushString == "FDiagPattern" )
555  {
556  return Qt::FDiagPattern;
557  }
558  else if ( brushString == "DiagCrossPattern" )
559  {
560  return Qt::DiagCrossPattern;
561  }
562  else if ( brushString == "TexturePattern" )
563  {
564  return Qt::TexturePattern;
565  }
566  else //return a null string
567  {
568  QgsDebugMsg( QString( "Brush style \"%1\" not found" ).arg( brushString ) );
569  return Qt::NoBrush;
570  }
571 }
static QString penStyle2QString(Qt::PenStyle penstyle)
static Qt::BrushStyle readBrushStyle(const QDomNode &synode)
GeometryType
Definition: qgis.h:115
static QgsOldSymbolMeta readSymbolMeta(const QDomNode &synode)
QString attribute(const QString &name, const QString &defValue) const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
static double readOutlineWidth(const QDomNode &synode)
static QgsFeatureRendererV2 * readOldUniqueValueRenderer(const QDomNode &rnode, QGis::GeometryType geomType)
static Shape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
static QgsSymbolV2 * readOldSymbol(const QDomNode &synode, QGis::GeometryType geomType)
double toDouble(bool *ok) const
static float readMarkerSymbolSize(const QDomNode &synode)
static QString readMarkerSymbolName(const QDomNode &synode)
QDomNode nextSibling() const
QDomElement toElement() const
void append(const T &value)
QString text() const
static Qt::PenStyle qString2PenStyle(const QString &string)
static QgsFeatureRendererV2 * readOldSingleSymbolRenderer(const QDomNode &rnode, QGis::GeometryType geomType)
int toInt(bool *ok, int base) const
bool isEmpty() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
static QgsFeatureRendererV2 * readOldGraduatedSymbolRenderer(const QDomNode &rnode, QGis::GeometryType geomType)
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)
QDomNode namedItem(const QString &name) const
static Qt::BrushStyle qString2BrushStyle(const QString &string)
const double DEFAULT_POINT_SIZE
Magic number that determines the default point size for point symbols.
Definition: qgis.h:486
bool isNull() const
static QColor readSymbolColor(const QDomNode &synode, bool fillColor)
QString mid(int position, int n) const
float toFloat(bool *ok) const
static Qt::PenStyle readOutlineStyle(const QDomNode &synode)
static QString brushStyle2QString(Qt::BrushStyle brushstyle)
Abstract base class for marker symbol layers.
static QgsFeatureRendererV2 * readOldRenderer(const QDomNode &layerNode, QGis::GeometryType geomType)
Read old renderer definition from XML and create matching new renderer.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an outline...