LCOV - code coverage report
Current view: top level - core - qgsxmlutils.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 36 237 15.2 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       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                 :            : #include "qgsprocessingparameters.h"
      24                 :            : #include "qgsremappingproxyfeaturesink.h"
      25                 :            : 
      26                 :          0 : QgsUnitTypes::DistanceUnit QgsXmlUtils::readMapUnits( const QDomElement &element )
      27                 :            : {
      28                 :          0 :   if ( "unknown" == element.text() )
      29                 :            :   {
      30                 :          0 :     return QgsUnitTypes::DistanceUnknownUnit;
      31                 :            :   }
      32                 :            :   else
      33                 :            :   {
      34                 :          0 :     QgsUnitTypes::DistanceUnit unit = QgsUnitTypes::decodeDistanceUnit( element.text() );
      35                 :          0 :     return unit == QgsUnitTypes::DistanceUnknownUnit ? QgsUnitTypes::DistanceDegrees : unit;
      36                 :            :   }
      37                 :          0 : }
      38                 :            : 
      39                 :          0 : QgsRectangle QgsXmlUtils::readRectangle( const QDomElement &element )
      40                 :            : {
      41                 :          0 :   QgsRectangle aoi;
      42                 :            : 
      43                 :          0 :   QDomNode xminNode = element.namedItem( QStringLiteral( "xmin" ) );
      44                 :          0 :   QDomNode yminNode = element.namedItem( QStringLiteral( "ymin" ) );
      45                 :          0 :   QDomNode xmaxNode = element.namedItem( QStringLiteral( "xmax" ) );
      46                 :          0 :   QDomNode ymaxNode = element.namedItem( QStringLiteral( "ymax" ) );
      47                 :            : 
      48                 :          0 :   QDomElement exElement = xminNode.toElement();
      49                 :          0 :   double xmin = exElement.text().toDouble();
      50                 :          0 :   aoi.setXMinimum( xmin );
      51                 :            : 
      52                 :          0 :   exElement = yminNode.toElement();
      53                 :          0 :   double ymin = exElement.text().toDouble();
      54                 :          0 :   aoi.setYMinimum( ymin );
      55                 :            : 
      56                 :          0 :   exElement = xmaxNode.toElement();
      57                 :          0 :   double xmax = exElement.text().toDouble();
      58                 :          0 :   aoi.setXMaximum( xmax );
      59                 :            : 
      60                 :          0 :   exElement = ymaxNode.toElement();
      61                 :          0 :   double ymax = exElement.text().toDouble();
      62                 :          0 :   aoi.setYMaximum( ymax );
      63                 :            : 
      64                 :            :   return aoi;
      65                 :          0 : }
      66                 :            : 
      67                 :            : 
      68                 :            : 
      69                 :          0 : QDomElement QgsXmlUtils::writeMapUnits( QgsUnitTypes::DistanceUnit units, QDomDocument &doc )
      70                 :            : {
      71                 :          0 :   QString unitsString = QgsUnitTypes::encodeUnit( units );
      72                 :            :   // maintain compatibility with old projects
      73                 :          0 :   if ( units == QgsUnitTypes::DistanceUnknownUnit )
      74                 :          0 :     unitsString = QStringLiteral( "unknown" );
      75                 :            : 
      76                 :          0 :   QDomElement unitsNode = doc.createElement( QStringLiteral( "units" ) );
      77                 :          0 :   unitsNode.appendChild( doc.createTextNode( unitsString ) );
      78                 :          0 :   return unitsNode;
      79                 :          0 : }
      80                 :            : 
      81                 :          0 : QDomElement QgsXmlUtils::writeRectangle( const QgsRectangle &rect, QDomDocument &doc, const QString &elementName )
      82                 :            : {
      83                 :          0 :   QDomElement xMin = doc.createElement( QStringLiteral( "xmin" ) );
      84                 :          0 :   QDomElement yMin = doc.createElement( QStringLiteral( "ymin" ) );
      85                 :          0 :   QDomElement xMax = doc.createElement( QStringLiteral( "xmax" ) );
      86                 :          0 :   QDomElement yMax = doc.createElement( QStringLiteral( "ymax" ) );
      87                 :            : 
      88                 :          0 :   QDomText xMinText = doc.createTextNode( qgsDoubleToString( rect.xMinimum() ) );
      89                 :          0 :   QDomText yMinText = doc.createTextNode( qgsDoubleToString( rect.yMinimum() ) );
      90                 :          0 :   QDomText xMaxText = doc.createTextNode( qgsDoubleToString( rect.xMaximum() ) );
      91                 :          0 :   QDomText yMaxText = doc.createTextNode( qgsDoubleToString( rect.yMaximum() ) );
      92                 :            : 
      93                 :          0 :   xMin.appendChild( xMinText );
      94                 :          0 :   yMin.appendChild( yMinText );
      95                 :          0 :   xMax.appendChild( xMaxText );
      96                 :          0 :   yMax.appendChild( yMaxText );
      97                 :            : 
      98                 :          0 :   QDomElement extentNode = doc.createElement( elementName );
      99                 :          0 :   extentNode.appendChild( xMin );
     100                 :          0 :   extentNode.appendChild( yMin );
     101                 :          0 :   extentNode.appendChild( xMax );
     102                 :          0 :   extentNode.appendChild( yMax );
     103                 :          0 :   return extentNode;
     104                 :          0 : }
     105                 :            : 
     106                 :          0 : QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc )
     107                 :            : {
     108                 :          0 :   QDomElement element = doc.createElement( QStringLiteral( "Option" ) );
     109                 :          0 :   switch ( value.type() )
     110                 :            :   {
     111                 :            :     case QVariant::Invalid:
     112                 :            :     {
     113                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invalid" ) );
     114                 :          0 :       break;
     115                 :            :     }
     116                 :            : 
     117                 :            :     case QVariant::Map:
     118                 :            :     {
     119                 :          0 :       QVariantMap map = value.toMap();
     120                 :            : 
     121                 :          0 :       for ( auto option = map.constBegin(); option != map.constEnd(); ++option )
     122                 :            :       {
     123                 :          0 :         QDomElement optionElement = writeVariant( option.value(), doc );
     124                 :          0 :         optionElement.setAttribute( QStringLiteral( "name" ), option.key() );
     125                 :          0 :         element.appendChild( optionElement );
     126                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "Map" ) );
     127                 :          0 :       }
     128                 :            :       break;
     129                 :          0 :     }
     130                 :            : 
     131                 :            :     case QVariant::List:
     132                 :            :     {
     133                 :          0 :       QVariantList list = value.toList();
     134                 :            : 
     135                 :          0 :       const auto constList = list;
     136                 :          0 :       for ( const QVariant &value : constList )
     137                 :            :       {
     138                 :          0 :         QDomElement valueElement = writeVariant( value, doc );
     139                 :          0 :         element.appendChild( valueElement );
     140                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) );
     141                 :          0 :       }
     142                 :            :       break;
     143                 :          0 :     }
     144                 :            : 
     145                 :            :     case QVariant::StringList:
     146                 :            :     {
     147                 :          0 :       QStringList list = value.toStringList();
     148                 :            : 
     149                 :          0 :       const auto constList = list;
     150                 :          0 :       for ( const QString &value : constList )
     151                 :            :       {
     152                 :          0 :         QDomElement valueElement = writeVariant( value, doc );
     153                 :          0 :         element.appendChild( valueElement );
     154                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "StringList" ) );
     155                 :          0 :       }
     156                 :            :       break;
     157                 :          0 :     }
     158                 :            : 
     159                 :            :     case QVariant::Int:
     160                 :            :     case QVariant::UInt:
     161                 :            :     case QVariant::Bool:
     162                 :            :     case QVariant::Double:
     163                 :            :     case QVariant::LongLong:
     164                 :            :     case QVariant::ULongLong:
     165                 :            :     case QVariant::String:
     166                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) );
     167                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.toString() );
     168                 :          0 :       break;
     169                 :            : 
     170                 :            :     case QVariant::Char:
     171                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) );
     172                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.isNull() ? QString() : value.toString() );
     173                 :          0 :       break;
     174                 :            : 
     175                 :            :     case QVariant::Color:
     176                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "color" ) );
     177                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.value< QColor >().isValid() ? QgsSymbolLayerUtils::encodeColor( value.value< QColor >() ) : QString() );
     178                 :          0 :       break;
     179                 :            : 
     180                 :            :     case QVariant::DateTime:
     181                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "datetime" ) );
     182                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.value< QDateTime >().isValid() ? value.toDateTime().toString( Qt::ISODate ) : QString() );
     183                 :          0 :       break;
     184                 :            : 
     185                 :            :     case QVariant::Date:
     186                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "date" ) );
     187                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.value< QDate >().isValid() ? value.toDate().toString( Qt::ISODate ) : QString() );
     188                 :          0 :       break;
     189                 :            : 
     190                 :            :     case QVariant::Time:
     191                 :          0 :       element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "time" ) );
     192                 :          0 :       element.setAttribute( QStringLiteral( "value" ), value.value< QTime >().isValid() ? value.toTime().toString( Qt::ISODate ) : QString() );
     193                 :          0 :       break;
     194                 :            : 
     195                 :            :     case QVariant::UserType:
     196                 :            :     {
     197                 :          0 :       if ( value.canConvert< QgsProperty >() )
     198                 :            :       {
     199                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProperty" ) );
     200                 :          0 :         const QDomElement propertyElem = QgsXmlUtils::writeVariant( value.value< QgsProperty >().toVariant(), doc );
     201                 :          0 :         element.appendChild( propertyElem );
     202                 :            :         break;
     203                 :          0 :       }
     204                 :          0 :       else if ( value.canConvert< QgsCoordinateReferenceSystem >() )
     205                 :            :       {
     206                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsCoordinateReferenceSystem" ) );
     207                 :          0 :         const QgsCoordinateReferenceSystem crs = value.value< QgsCoordinateReferenceSystem >();
     208                 :          0 :         crs.writeXml( element, doc );
     209                 :            :         break;
     210                 :          0 :       }
     211                 :          0 :       else if ( value.canConvert< QgsGeometry >() )
     212                 :            :       {
     213                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsGeometry" ) );
     214                 :          0 :         const QgsGeometry geom = value.value< QgsGeometry >();
     215                 :          0 :         element.setAttribute( QStringLiteral( "value" ), geom.asWkt() );
     216                 :            :         break;
     217                 :          0 :       }
     218                 :          0 :       else if ( value.canConvert< QgsProcessingOutputLayerDefinition >() )
     219                 :            :       {
     220                 :          0 :         QDomElement valueElement = writeVariant( value.value< QgsProcessingOutputLayerDefinition >().toVariant(), doc );
     221                 :          0 :         element.appendChild( valueElement );
     222                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProcessingOutputLayerDefinition" ) );
     223                 :            :         break;
     224                 :          0 :       }
     225                 :          0 :       else if ( value.canConvert< QgsProcessingFeatureSourceDefinition >() )
     226                 :            :       {
     227                 :          0 :         QDomElement valueElement = writeVariant( value.value< QgsProcessingFeatureSourceDefinition >().toVariant(), doc );
     228                 :          0 :         element.appendChild( valueElement );
     229                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsProcessingFeatureSourceDefinition" ) );
     230                 :            :         break;
     231                 :          0 :       }
     232                 :          0 :       else if ( value.canConvert< QgsRemappingSinkDefinition >() )
     233                 :            :       {
     234                 :          0 :         QDomElement valueElement = writeVariant( value.value< QgsRemappingSinkDefinition >().toVariant(), doc );
     235                 :          0 :         element.appendChild( valueElement );
     236                 :          0 :         element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsRemappingSinkDefinition" ) );
     237                 :            :         break;
     238                 :          0 :       }
     239                 :            :       Q_ASSERT_X( false, "QgsXmlUtils::writeVariant", QStringLiteral( "unsupported user variant type %1" ).arg( QMetaType::typeName( value.userType() ) ).toLocal8Bit() );
     240                 :          0 :       break;
     241                 :            :     }
     242                 :            : 
     243                 :            :     default:
     244                 :            :       Q_ASSERT_X( false, "QgsXmlUtils::writeVariant", QStringLiteral( "unsupported variant type %1" ).arg( QVariant::typeToName( value.type() ) ).toLocal8Bit() );
     245                 :          0 :       break;
     246                 :            :   }
     247                 :            : 
     248                 :          0 :   return element;
     249                 :          0 : }
     250                 :            : 
     251                 :      21246 : QVariant QgsXmlUtils::readVariant( const QDomElement &element )
     252                 :            : {
     253                 :      42492 :   QString type = element.attribute( QStringLiteral( "type" ) );
     254                 :            : 
     255                 :      21246 :   if ( type == QLatin1String( "invalid" ) )
     256                 :            :   {
     257                 :          0 :     return QVariant();
     258                 :            :   }
     259                 :      21246 :   else if ( type == QLatin1String( "int" ) )
     260                 :            :   {
     261                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).toInt();
     262                 :            :   }
     263                 :      21246 :   else if ( type == QLatin1String( "uint" ) )
     264                 :            :   {
     265                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).toUInt();
     266                 :            :   }
     267                 :      21246 :   else if ( type == QLatin1String( "qlonglong" ) )
     268                 :            :   {
     269                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).toLongLong();
     270                 :            :   }
     271                 :      21246 :   else if ( type == QLatin1String( "qulonglong" ) )
     272                 :            :   {
     273                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).toULongLong();
     274                 :            :   }
     275                 :      21246 :   else if ( type == QLatin1String( "double" ) )
     276                 :            :   {
     277                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).toDouble();
     278                 :            :   }
     279                 :      21246 :   else if ( type == QLatin1String( "QString" ) )
     280                 :            :   {
     281                 :      33484 :     return element.attribute( QStringLiteral( "value" ) );
     282                 :            :   }
     283                 :       4504 :   else if ( type == QLatin1String( "QChar" ) )
     284                 :            :   {
     285                 :          0 :     const QString res = element.attribute( QStringLiteral( "value" ) );
     286                 :          0 :     return res.isEmpty() ? QChar() : res.at( 0 );
     287                 :          0 :   }
     288                 :       4504 :   else if ( type == QLatin1String( "bool" ) )
     289                 :            :   {
     290                 :          0 :     return element.attribute( QStringLiteral( "value" ) ) == QLatin1String( "true" );
     291                 :            :   }
     292                 :       4504 :   else if ( type == QLatin1String( "color" ) )
     293                 :            :   {
     294                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).isEmpty() ? QColor() : QgsSymbolLayerUtils::decodeColor( element.attribute( QStringLiteral( "value" ) ) );
     295                 :            :   }
     296                 :       4504 :   else if ( type == QLatin1String( "datetime" ) )
     297                 :            :   {
     298                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).isEmpty() ? QDateTime() : QDateTime::fromString( element.attribute( QStringLiteral( "value" ) ), Qt::ISODate );
     299                 :            :   }
     300                 :       4504 :   else if ( type == QLatin1String( "date" ) )
     301                 :            :   {
     302                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).isEmpty() ? QDate() : QDate::fromString( element.attribute( QStringLiteral( "value" ) ), Qt::ISODate );
     303                 :            :   }
     304                 :       4504 :   else if ( type == QLatin1String( "time" ) )
     305                 :            :   {
     306                 :          0 :     return element.attribute( QStringLiteral( "value" ) ).isEmpty() ? QTime() : QTime::fromString( element.attribute( QStringLiteral( "value" ) ), Qt::ISODate );
     307                 :            :   }
     308                 :       4504 :   else if ( type == QLatin1String( "Map" ) )
     309                 :            :   {
     310                 :       2374 :     QVariantMap map;
     311                 :       2374 :     QDomNodeList options = element.childNodes();
     312                 :            : 
     313                 :      20710 :     for ( int i = 0; i < options.count(); ++i )
     314                 :            :     {
     315                 :      18336 :       QDomElement elem = options.at( i ).toElement();
     316                 :      18336 :       if ( elem.tagName() == QLatin1String( "Option" ) )
     317                 :      36672 :         map.insert( elem.attribute( QStringLiteral( "name" ) ), readVariant( elem ) );
     318                 :      18336 :     }
     319                 :       2374 :     return map;
     320                 :       2374 :   }
     321                 :       2130 :   else if ( type == QLatin1String( "List" ) )
     322                 :            :   {
     323                 :          0 :     QVariantList list;
     324                 :          0 :     QDomNodeList values = element.childNodes();
     325                 :          0 :     for ( int i = 0; i < values.count(); ++i )
     326                 :            :     {
     327                 :          0 :       QDomElement elem = values.at( i ).toElement();
     328                 :          0 :       list.append( readVariant( elem ) );
     329                 :          0 :     }
     330                 :          0 :     return list;
     331                 :          0 :   }
     332                 :       2130 :   else if ( type == QLatin1String( "StringList" ) )
     333                 :            :   {
     334                 :          0 :     QStringList list;
     335                 :          0 :     QDomNodeList values = element.childNodes();
     336                 :          0 :     for ( int i = 0; i < values.count(); ++i )
     337                 :            :     {
     338                 :          0 :       QDomElement elem = values.at( i ).toElement();
     339                 :          0 :       list.append( readVariant( elem ).toString() );
     340                 :          0 :     }
     341                 :          0 :     return list;
     342                 :          0 :   }
     343                 :       2130 :   else if ( type == QLatin1String( "QgsProperty" ) )
     344                 :            :   {
     345                 :          0 :     const QDomNodeList values = element.childNodes();
     346                 :          0 :     if ( values.isEmpty() )
     347                 :          0 :       return QVariant();
     348                 :            : 
     349                 :          0 :     QgsProperty p;
     350                 :          0 :     if ( p.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ) ) )
     351                 :          0 :       return p;
     352                 :            : 
     353                 :          0 :     return QVariant();
     354                 :          0 :   }
     355                 :       2130 :   else if ( type == QLatin1String( "QgsCoordinateReferenceSystem" ) )
     356                 :            :   {
     357                 :          0 :     QgsCoordinateReferenceSystem crs;
     358                 :          0 :     crs.readXml( element );
     359                 :          0 :     return crs;
     360                 :          0 :   }
     361                 :       2130 :   else if ( type == QLatin1String( "QgsGeometry" ) )
     362                 :            :   {
     363                 :          0 :     return QgsGeometry::fromWkt( element.attribute( "value" ) );
     364                 :            :   }
     365                 :       2130 :   else if ( type == QLatin1String( "QgsProcessingOutputLayerDefinition" ) )
     366                 :            :   {
     367                 :          0 :     QgsProcessingOutputLayerDefinition res;
     368                 :          0 :     const QDomNodeList values = element.childNodes();
     369                 :          0 :     if ( values.isEmpty() )
     370                 :          0 :       return QVariant();
     371                 :            : 
     372                 :          0 :     if ( res.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ).toMap() ) )
     373                 :          0 :       return res;
     374                 :            : 
     375                 :          0 :     return QVariant();
     376                 :          0 :   }
     377                 :       2130 :   else if ( type == QLatin1String( "QgsProcessingFeatureSourceDefinition" ) )
     378                 :            :   {
     379                 :          0 :     QgsProcessingFeatureSourceDefinition res;
     380                 :          0 :     const QDomNodeList values = element.childNodes();
     381                 :          0 :     if ( values.isEmpty() )
     382                 :          0 :       return QVariant();
     383                 :            : 
     384                 :          0 :     if ( res.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ).toMap() ) )
     385                 :          0 :       return res;
     386                 :            : 
     387                 :          0 :     return QVariant();
     388                 :          0 :   }
     389                 :       2130 :   else if ( type == QLatin1String( "QgsRemappingSinkDefinition" ) )
     390                 :            :   {
     391                 :          0 :     QgsRemappingSinkDefinition res;
     392                 :          0 :     const QDomNodeList values = element.childNodes();
     393                 :          0 :     if ( values.isEmpty() )
     394                 :          0 :       return QVariant();
     395                 :            : 
     396                 :          0 :     if ( res.loadVariant( QgsXmlUtils::readVariant( values.at( 0 ).toElement() ).toMap() ) )
     397                 :          0 :       return QVariant::fromValue( res );
     398                 :            : 
     399                 :          0 :     return QVariant();
     400                 :          0 :   }
     401                 :            :   else
     402                 :            :   {
     403                 :       2130 :     return QVariant();
     404                 :            :   }
     405                 :      21246 : }

Generated by: LCOV version 1.14