QGIS API Documentation  3.6.0-Noosa (5873452)
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 
24 {
25  if ( "unknown" == element.text() )
26  {
28  }
29  else
30  {
33  }
34 }
35 
36 QgsRectangle QgsXmlUtils::readRectangle( const QDomElement &element )
37 {
38  QgsRectangle aoi;
39 
40  QDomNode xminNode = element.namedItem( QStringLiteral( "xmin" ) );
41  QDomNode yminNode = element.namedItem( QStringLiteral( "ymin" ) );
42  QDomNode xmaxNode = element.namedItem( QStringLiteral( "xmax" ) );
43  QDomNode ymaxNode = element.namedItem( QStringLiteral( "ymax" ) );
44 
45  QDomElement exElement = xminNode.toElement();
46  double xmin = exElement.text().toDouble();
47  aoi.setXMinimum( xmin );
48 
49  exElement = yminNode.toElement();
50  double ymin = exElement.text().toDouble();
51  aoi.setYMinimum( ymin );
52 
53  exElement = xmaxNode.toElement();
54  double xmax = exElement.text().toDouble();
55  aoi.setXMaximum( xmax );
56 
57  exElement = ymaxNode.toElement();
58  double ymax = exElement.text().toDouble();
59  aoi.setYMaximum( ymax );
60 
61  return aoi;
62 }
63 
64 
65 
66 QDomElement QgsXmlUtils::writeMapUnits( QgsUnitTypes::DistanceUnit units, QDomDocument &doc )
67 {
68  QString unitsString = QgsUnitTypes::encodeUnit( units );
69  // maintain compatibility with old projects
70  if ( units == QgsUnitTypes::DistanceUnknownUnit )
71  unitsString = QStringLiteral( "unknown" );
72 
73  QDomElement unitsNode = doc.createElement( QStringLiteral( "units" ) );
74  unitsNode.appendChild( doc.createTextNode( unitsString ) );
75  return unitsNode;
76 }
77 
78 QDomElement QgsXmlUtils::writeRectangle( const QgsRectangle &rect, QDomDocument &doc )
79 {
80  QDomElement xMin = doc.createElement( QStringLiteral( "xmin" ) );
81  QDomElement yMin = doc.createElement( QStringLiteral( "ymin" ) );
82  QDomElement xMax = doc.createElement( QStringLiteral( "xmax" ) );
83  QDomElement yMax = doc.createElement( QStringLiteral( "ymax" ) );
84 
85  QDomText xMinText = doc.createTextNode( qgsDoubleToString( rect.xMinimum() ) );
86  QDomText yMinText = doc.createTextNode( qgsDoubleToString( rect.yMinimum() ) );
87  QDomText xMaxText = doc.createTextNode( qgsDoubleToString( rect.xMaximum() ) );
88  QDomText yMaxText = doc.createTextNode( qgsDoubleToString( rect.yMaximum() ) );
89 
90  xMin.appendChild( xMinText );
91  yMin.appendChild( yMinText );
92  xMax.appendChild( xMaxText );
93  yMax.appendChild( yMaxText );
94 
95  QDomElement extentNode = doc.createElement( QStringLiteral( "extent" ) );
96  extentNode.appendChild( xMin );
97  extentNode.appendChild( yMin );
98  extentNode.appendChild( xMax );
99  extentNode.appendChild( yMax );
100  return extentNode;
101 }
102 
103 QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc )
104 {
105  QDomElement element = doc.createElement( QStringLiteral( "Option" ) );
106  switch ( value.type() )
107  {
108  case QVariant::Invalid:
109  {
110  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invalid" ) );
111  break;
112  }
113 
114  case QVariant::Map:
115  {
116  QVariantMap map = value.toMap();
117 
118  for ( auto option = map.constBegin(); option != map.constEnd(); ++option )
119  {
120  QDomElement optionElement = writeVariant( option.value(), doc );
121  optionElement.setAttribute( QStringLiteral( "name" ), option.key() );
122  element.appendChild( optionElement );
123  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "Map" ) );
124  }
125  break;
126  }
127 
128  case QVariant::List:
129  {
130  QVariantList list = value.toList();
131 
132  Q_FOREACH ( const QVariant &value, list )
133  {
134  QDomElement valueElement = writeVariant( value, doc );
135  element.appendChild( valueElement );
136  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) );
137  }
138  break;
139  }
140 
141  case QVariant::StringList:
142  {
143  QStringList list = value.toStringList();
144 
145  Q_FOREACH ( const QString &value, list )
146  {
147  QDomElement valueElement = writeVariant( value, doc );
148  element.appendChild( valueElement );
149  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "StringList" ) );
150  }
151  break;
152  }
153 
154  case QVariant::Int:
155  case QVariant::Bool:
156  case QVariant::Double:
157  case QVariant::String:
158  element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) );
159  element.setAttribute( QStringLiteral( "value" ), value.toString() );
160  break;
161 
162  case QVariant::UserType:
163  {
164  if ( value.canConvert< QgsProperty >() )
165  {
166  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProperty" ) );
167  const QDomElement propertyElem = QgsXmlUtils::writeVariant( value.value< QgsProperty >().toVariant(), doc );
168  element.appendChild( propertyElem );
169  break;
170  }
171  else if ( value.canConvert< QgsCoordinateReferenceSystem >() )
172  {
173  element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsCoordinateReferenceSystem" ) );
175  crs.writeXml( element, doc );
176  break;
177  }
179  }
180 
181  default:
182  Q_ASSERT_X( false, "QgsXmlUtils::writeVariant", QStringLiteral( "unsupported variant type %1" ).arg( QVariant::typeToName( value.type() ) ).toLocal8Bit() );
183  break;
184  }
185 
186  return element;
187 }
188 
189 QVariant QgsXmlUtils::readVariant( const QDomElement &element )
190 {
191  QString type = element.attribute( QStringLiteral( "type" ) );
192 
193  if ( type == QLatin1String( "invalid" ) )
194  {
195  return QVariant();
196  }
197  else if ( type == QLatin1String( "int" ) )
198  {
199  return element.attribute( QStringLiteral( "value" ) ).toInt();
200  }
201  else if ( type == QLatin1String( "double" ) )
202  {
203  return element.attribute( QStringLiteral( "value" ) ).toDouble();
204  }
205  else if ( type == QLatin1String( "QString" ) )
206  {
207  return element.attribute( QStringLiteral( "value" ) );
208  }
209  else if ( type == QLatin1String( "bool" ) )
210  {
211  return element.attribute( QStringLiteral( "value" ) ) == QLatin1String( "true" );
212  }
213  else if ( type == QLatin1String( "Map" ) )
214  {
215  QVariantMap map;
216  QDomNodeList options = element.childNodes();
217 
218  for ( int i = 0; i < options.count(); ++i )
219  {
220  QDomElement elem = options.at( i ).toElement();
221  if ( elem.tagName() == QLatin1String( "Option" ) )
222  map.insert( elem.attribute( QStringLiteral( "name" ) ), readVariant( elem ) );
223  }
224  return map;
225  }
226  else if ( type == QLatin1String( "List" ) )
227  {
228  QVariantList list;
229  QDomNodeList values = element.childNodes();
230  for ( int i = 0; i < values.count(); ++i )
231  {
232  QDomElement elem = values.at( i ).toElement();
233  list.append( readVariant( elem ) );
234  }
235  return list;
236  }
237  else if ( type == QLatin1String( "StringList" ) )
238  {
239  QStringList list;
240  QDomNodeList values = element.childNodes();
241  for ( int i = 0; i < values.count(); ++i )
242  {
243  QDomElement elem = values.at( i ).toElement();
244  list.append( readVariant( elem ).toString() );
245  }
246  return list;
247  }
248  else if ( type == QLatin1String( "QgsProperty" ) )
249  {
250  const QDomNodeList values = element.childNodes();
251  if ( values.isEmpty() )
252  return QVariant();
253 
254  QgsProperty p;
255  if ( p.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ) ) )
256  return p;
257 
258  return QVariant();
259  }
260  else if ( type == QLatin1String( "QgsCoordinateReferenceSystem" ) )
261  {
263  crs.readXml( element );
264  return crs;
265  }
266  else
267  {
268  return QVariant();
269  }
270 }
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:78
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
const QgsCoordinateReferenceSystem & crs
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:656
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:23
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:225
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:66
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:62
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
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:54
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
Unknown distance unit.
Definition: qgsunittypes.h:65
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:36
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