QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsxmlutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsxmlutils.cpp
3  ---------------------
4  begin : December 2013
5  copyright : (C) 2013 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 #include "qgsxmlutils.h"
16 
17 #include <QDomElement>
18 
19 #include "qgslogger.h"
20 #include "qgsrectangle.h"
21 #include "qgsproperty.h"
22 #include "qgssymbollayerutils.h"
23 
25 {
26  if ( "unknown" == element.text() )
27  {
29  }
30  else
31  {
34  }
35 }
36 
37 QgsRectangle QgsXmlUtils::readRectangle( const QDomElement &element )
38 {
39  QgsRectangle aoi;
40 
41  QDomNode xminNode = element.namedItem( QStringLiteral( "xmin" ) );
42  QDomNode yminNode = element.namedItem( QStringLiteral( "ymin" ) );
43  QDomNode xmaxNode = element.namedItem( QStringLiteral( "xmax" ) );
44  QDomNode ymaxNode = element.namedItem( QStringLiteral( "ymax" ) );
45 
46  QDomElement exElement = xminNode.toElement();
47  double xmin = exElement.text().toDouble();
48  aoi.setXMinimum( xmin );
49 
50  exElement = yminNode.toElement();
51  double ymin = exElement.text().toDouble();
52  aoi.setYMinimum( ymin );
53 
54  exElement = xmaxNode.toElement();
55  double xmax = exElement.text().toDouble();
56  aoi.setXMaximum( xmax );
57 
58  exElement = ymaxNode.toElement();
59  double ymax = exElement.text().toDouble();
60  aoi.setYMaximum( ymax );
61 
62  return aoi;
63 }
64 
65 
66 
67 QDomElement QgsXmlUtils::writeMapUnits( QgsUnitTypes::DistanceUnit units, QDomDocument &doc )
68 {
69  QString unitsString = QgsUnitTypes::encodeUnit( units );
70  // maintain compatibility with old projects
71  if ( units == QgsUnitTypes::DistanceUnknownUnit )
72  unitsString = QStringLiteral( "unknown" );
73 
74  QDomElement unitsNode = doc.createElement( QStringLiteral( "units" ) );
75  unitsNode.appendChild( doc.createTextNode( unitsString ) );
76  return unitsNode;
77 }
78 
79 QDomElement QgsXmlUtils::writeRectangle( const QgsRectangle &rect, QDomDocument &doc )
80 {
81  QDomElement xMin = doc.createElement( QStringLiteral( "xmin" ) );
82  QDomElement yMin = doc.createElement( QStringLiteral( "ymin" ) );
83  QDomElement xMax = doc.createElement( QStringLiteral( "xmax" ) );
84  QDomElement yMax = doc.createElement( QStringLiteral( "ymax" ) );
85 
86  QDomText xMinText = doc.createTextNode( qgsDoubleToString( rect.xMinimum() ) );
87  QDomText yMinText = doc.createTextNode( qgsDoubleToString( rect.yMinimum() ) );
88  QDomText xMaxText = doc.createTextNode( qgsDoubleToString( rect.xMaximum() ) );
89  QDomText yMaxText = doc.createTextNode( qgsDoubleToString( rect.yMaximum() ) );
90 
91  xMin.appendChild( xMinText );
92  yMin.appendChild( yMinText );
93  xMax.appendChild( xMaxText );
94  yMax.appendChild( yMaxText );
95 
96  QDomElement extentNode = doc.createElement( QStringLiteral( "extent" ) );
97  extentNode.appendChild( xMin );
98  extentNode.appendChild( yMin );
99  extentNode.appendChild( xMax );
100  extentNode.appendChild( yMax );
101  return extentNode;
102 }
103 
104 QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc )
105 {
106  QDomElement element = doc.createElement( QStringLiteral( "Option" ) );
107  switch ( value.type() )
108  {
109  case QVariant::Invalid:
110  {
111  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invalid" ) );
112  break;
113  }
114 
115  case QVariant::Map:
116  {
117  QVariantMap map = value.toMap();
118 
119  for ( auto option = map.constBegin(); option != map.constEnd(); ++option )
120  {
121  QDomElement optionElement = writeVariant( option.value(), doc );
122  optionElement.setAttribute( QStringLiteral( "name" ), option.key() );
123  element.appendChild( optionElement );
124  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "Map" ) );
125  }
126  break;
127  }
128 
129  case QVariant::List:
130  {
131  QVariantList list = value.toList();
132 
133  const auto constList = list;
134  for ( const QVariant &value : constList )
135  {
136  QDomElement valueElement = writeVariant( value, doc );
137  element.appendChild( valueElement );
138  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) );
139  }
140  break;
141  }
142 
143  case QVariant::StringList:
144  {
145  QStringList list = value.toStringList();
146 
147  const auto constList = list;
148  for ( const QString &value : constList )
149  {
150  QDomElement valueElement = writeVariant( value, doc );
151  element.appendChild( valueElement );
152  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "StringList" ) );
153  }
154  break;
155  }
156 
157  case QVariant::Int:
158  case QVariant::UInt:
159  case QVariant::Bool:
160  case QVariant::Double:
161  case QVariant::LongLong:
162  case QVariant::ULongLong:
163  case QVariant::String:
164  element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) );
165  element.setAttribute( QStringLiteral( "value" ), value.toString() );
166  break;
167 
168  case QVariant::Color:
169  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "color" ) );
170  element.setAttribute( QStringLiteral( "value" ), value.value< QColor >().isValid() ? QgsSymbolLayerUtils::encodeColor( value.value< QColor >() ) : QString() );
171  break;
172 
173  case QVariant::UserType:
174  {
175  if ( value.canConvert< QgsProperty >() )
176  {
177  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProperty" ) );
178  const QDomElement propertyElem = QgsXmlUtils::writeVariant( value.value< QgsProperty >().toVariant(), doc );
179  element.appendChild( propertyElem );
180  break;
181  }
182  else if ( value.canConvert< QgsCoordinateReferenceSystem >() )
183  {
184  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsCoordinateReferenceSystem" ) );
186  crs.writeXml( element, doc );
187  break;
188  }
189  else if ( value.canConvert< QgsGeometry >() )
190  {
191  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsGeometry" ) );
192  const QgsGeometry geom = value.value< QgsGeometry >();
193  element.setAttribute( QStringLiteral( "value" ), geom.asWkt() );
194  break;
195  }
197  }
198 
199  default:
200  Q_ASSERT_X( false, "QgsXmlUtils::writeVariant", QStringLiteral( "unsupported variant type %1" ).arg( QVariant::typeToName( value.type() ) ).toLocal8Bit() );
201  break;
202  }
203 
204  return element;
205 }
206 
207 QVariant QgsXmlUtils::readVariant( const QDomElement &element )
208 {
209  QString type = element.attribute( QStringLiteral( "type" ) );
210 
211  if ( type == QLatin1String( "invalid" ) )
212  {
213  return QVariant();
214  }
215  else if ( type == QLatin1String( "int" ) )
216  {
217  return element.attribute( QStringLiteral( "value" ) ).toInt();
218  }
219  else if ( type == QLatin1String( "uint" ) )
220  {
221  return element.attribute( QStringLiteral( "value" ) ).toUInt();
222  }
223  else if ( type == QLatin1String( "qlonglong" ) )
224  {
225  return element.attribute( QStringLiteral( "value" ) ).toLongLong();
226  }
227  else if ( type == QLatin1String( "qulonglong" ) )
228  {
229  return element.attribute( QStringLiteral( "value" ) ).toULongLong();
230  }
231  else if ( type == QLatin1String( "double" ) )
232  {
233  return element.attribute( QStringLiteral( "value" ) ).toDouble();
234  }
235  else if ( type == QLatin1String( "QString" ) )
236  {
237  return element.attribute( QStringLiteral( "value" ) );
238  }
239  else if ( type == QLatin1String( "bool" ) )
240  {
241  return element.attribute( QStringLiteral( "value" ) ) == QLatin1String( "true" );
242  }
243  else if ( type == QLatin1String( "color" ) )
244  {
245  return element.attribute( QStringLiteral( "value" ) ).isEmpty() ? QColor() : QgsSymbolLayerUtils::decodeColor( element.attribute( QStringLiteral( "value" ) ) );
246  }
247  else if ( type == QLatin1String( "Map" ) )
248  {
249  QVariantMap map;
250  QDomNodeList options = element.childNodes();
251 
252  for ( int i = 0; i < options.count(); ++i )
253  {
254  QDomElement elem = options.at( i ).toElement();
255  if ( elem.tagName() == QLatin1String( "Option" ) )
256  map.insert( elem.attribute( QStringLiteral( "name" ) ), readVariant( elem ) );
257  }
258  return map;
259  }
260  else if ( type == QLatin1String( "List" ) )
261  {
262  QVariantList list;
263  QDomNodeList values = element.childNodes();
264  for ( int i = 0; i < values.count(); ++i )
265  {
266  QDomElement elem = values.at( i ).toElement();
267  list.append( readVariant( elem ) );
268  }
269  return list;
270  }
271  else if ( type == QLatin1String( "StringList" ) )
272  {
273  QStringList list;
274  QDomNodeList values = element.childNodes();
275  for ( int i = 0; i < values.count(); ++i )
276  {
277  QDomElement elem = values.at( i ).toElement();
278  list.append( readVariant( elem ).toString() );
279  }
280  return list;
281  }
282  else if ( type == QLatin1String( "QgsProperty" ) )
283  {
284  const QDomNodeList values = element.childNodes();
285  if ( values.isEmpty() )
286  return QVariant();
287 
288  QgsProperty p;
289  if ( p.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ) ) )
290  return p;
291 
292  return QVariant();
293  }
294  else if ( type == QLatin1String( "QgsCoordinateReferenceSystem" ) )
295  {
297  crs.readXml( element );
298  return crs;
299  }
300  else if ( type == QLatin1String( "QgsGeometry" ) )
301  {
302  return QgsGeometry::fromWkt( element.attribute( "value" ) );
303  }
304  else
305  {
306  return QVariant();
307  }
308 }
A rectangle specified with double values.
Definition: qgsrectangle.h:41
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:135
static QDomElement writeRectangle(const QgsRectangle &rect, QDomDocument &doc)
Definition: qgsxmlutils.cpp:79
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
const QgsCoordinateReferenceSystem & crs
static QString encodeColor(const QColor &color)
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
#define FALLTHROUGH
Definition: qgis.h:681
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
static QgsUnitTypes::DistanceUnit readMapUnits(const QDomElement &element)
Decodes a distance unit from a DOM element.
Definition: qgsxmlutils.cpp:24
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:240
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:140
static QDomElement writeMapUnits(QgsUnitTypes::DistanceUnit units, QDomDocument &doc)
Encodes a distance unit to a DOM element.
Definition: qgsxmlutils.cpp:67
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:74
A store for object properties.
Definition: qgsproperty.h:229
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QString asWkt(int precision=17) const
Exports the geometry to WKT.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:66
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
Unknown distance unit.
Definition: qgsunittypes.h:77
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:145
This class represents a coordinate reference system (CRS).
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
static QgsRectangle readRectangle(const QDomElement &element)
Definition: qgsxmlutils.cpp:37
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:130
static QColor decodeColor(const QString &str)