1 /*************************************************************************** 2 qgswfsparameters.cpp 3 -------------------- 4 begin : Sept 14, 2017 5 copyright : (C) 2017 by René-Luc Dhont 6 email : rldhont at 3liz dot com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #include "qgswfsparameters.h" 19 #include "qgsmessagelog.h" 20 21 namespace QgsWfs 22 { 23 // 24 // QgsWfsParameter 25 // QgsWfsParameter(const QgsWfsParameter::Name name,const QVariant::Type type,const QVariant defaultValue)26 QgsWfsParameter::QgsWfsParameter( const QgsWfsParameter::Name name, 27 const QVariant::Type type, 28 const QVariant defaultValue ) 29 : QgsServerParameterDefinition( type, defaultValue ) 30 , mName( name ) 31 { 32 } 33 toInt() const34 int QgsWfsParameter::toInt() const 35 { 36 bool ok = false; 37 const int val = QgsServerParameterDefinition::toInt( ok ); 38 39 if ( !ok ) 40 { 41 raiseError(); 42 } 43 44 return val; 45 } 46 toRectangle() const47 QgsRectangle QgsWfsParameter::toRectangle() const 48 { 49 QString value = toString(); 50 const QStringList corners = mValue.toString().split( ',' ); 51 if ( corners.size() == 5 ) 52 { 53 value.resize( value.size() - corners[4].size() - 1 ); 54 } 55 56 QgsServerParameterDefinition param; 57 param.mValue = QVariant( value ); 58 59 bool ok = false; 60 const QgsRectangle rectangle = param.toRectangle( ok ); 61 62 if ( !ok ) 63 { 64 const QString msg = QString( "%1 ('%2') cannot be converted into rectangle" ).arg( name( mName ), toString() ); 65 QgsServerParameterDefinition::raiseError( msg ); 66 } 67 68 return rectangle; 69 } 70 toStringListWithExp(const QString & exp) const71 QStringList QgsWfsParameter::toStringListWithExp( const QString &exp ) const 72 { 73 QStringList theList; 74 75 const QString val = mValue.toString(); 76 if ( val.isEmpty() ) 77 return theList; 78 79 if ( exp.isEmpty() ) 80 theList << val; 81 else 82 { 83 QRegExp rx( exp ); 84 if ( rx.indexIn( val, 0 ) == -1 ) 85 { 86 theList << val; 87 } 88 else 89 { 90 int pos = 0; 91 while ( ( pos = rx.indexIn( val, pos ) ) != -1 ) 92 { 93 theList << rx.cap( 1 ); 94 pos += rx.matchedLength(); 95 } 96 } 97 } 98 99 return theList; 100 } 101 raiseError() const102 void QgsWfsParameter::raiseError() const 103 { 104 const QString msg = QString( "%1 ('%2') cannot be converted into %3" ).arg( name( mName ), toString(), typeName() ); 105 QgsServerParameterDefinition::raiseError( msg ); 106 } 107 name(const QgsWfsParameter::Name name)108 QString QgsWfsParameter::name( const QgsWfsParameter::Name name ) 109 { 110 const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWfsParameter::Name>() ); 111 return metaEnum.valueToKey( name ); 112 } 113 name(const QString & name)114 QgsWfsParameter::Name QgsWfsParameter::name( const QString &name ) 115 { 116 const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWfsParameter::Name>() ); 117 return ( QgsWfsParameter::Name ) metaEnum.keyToValue( name.toUpper().toStdString().c_str() ); 118 } 119 120 // 121 // QgsWfsParameters 122 // QgsWfsParameters()123 QgsWfsParameters::QgsWfsParameters() 124 : QgsServerParameters() 125 { 126 // Available version number 127 mVersions.append( QgsProjectVersion( 1, 0, 0 ) ); 128 mVersions.append( QgsProjectVersion( 1, 1, 0 ) ); 129 130 const QgsWfsParameter pOutputFormat = QgsWfsParameter( QgsWfsParameter::OUTPUTFORMAT ); 131 save( pOutputFormat ); 132 133 const QgsWfsParameter pResultType = QgsWfsParameter( QgsWfsParameter::RESULTTYPE ); 134 save( pResultType ); 135 136 const QgsWfsParameter pPropertyName = QgsWfsParameter( QgsWfsParameter::PROPERTYNAME ); 137 save( pPropertyName ); 138 139 const QgsWfsParameter pMaxFeatures = QgsWfsParameter( QgsWfsParameter::MAXFEATURES, 140 QVariant::Int, 141 QVariant( -1 ) ); 142 save( pMaxFeatures ); 143 144 const QgsWfsParameter pStartIndex = QgsWfsParameter( QgsWfsParameter::STARTINDEX, 145 QVariant::Int, 146 QVariant( 0 ) ); 147 save( pStartIndex ); 148 149 const QgsWfsParameter pSrsName = QgsWfsParameter( QgsWfsParameter::SRSNAME ); 150 save( pSrsName ); 151 152 const QgsWfsParameter pTypeName = QgsWfsParameter( QgsWfsParameter::TYPENAME ); 153 save( pTypeName ); 154 155 const QgsWfsParameter pFeatureId = QgsWfsParameter( QgsWfsParameter::FEATUREID ); 156 save( pFeatureId ); 157 158 const QgsWfsParameter pFilter = QgsWfsParameter( QgsWfsParameter::FILTER ); 159 save( pFilter ); 160 161 const QgsWfsParameter pBbox = QgsWfsParameter( QgsWfsParameter::BBOX ); 162 save( pBbox ); 163 164 const QgsWfsParameter pSortBy = QgsWfsParameter( QgsWfsParameter::SORTBY ); 165 save( pSortBy ); 166 167 const QgsWfsParameter pExpFilter = QgsWfsParameter( QgsWfsParameter::EXP_FILTER ); 168 save( pExpFilter ); 169 170 const QgsWfsParameter pGeometryName = QgsWfsParameter( QgsWfsParameter::GEOMETRYNAME ); 171 save( pGeometryName ); 172 } 173 QgsWfsParameters(const QgsServerParameters & parameters)174 QgsWfsParameters::QgsWfsParameters( const QgsServerParameters ¶meters ) 175 : QgsWfsParameters() 176 { 177 load( parameters.urlQuery() ); 178 } 179 loadParameter(const QString & key,const QString & value)180 bool QgsWfsParameters::loadParameter( const QString &key, const QString &value ) 181 { 182 bool loaded = false; 183 184 const QgsWfsParameter::Name name = QgsWfsParameter::name( key ); 185 if ( name >= 0 ) 186 { 187 mWfsParameters[name].mValue = value; 188 if ( ! mWfsParameters[name].isValid() ) 189 { 190 mWfsParameters[name].raiseError(); 191 } 192 193 loaded = true; 194 } 195 196 return loaded; 197 } 198 save(const QgsWfsParameter & parameter)199 void QgsWfsParameters::save( const QgsWfsParameter ¶meter ) 200 { 201 mWfsParameters[ parameter.mName ] = parameter; 202 } 203 dump() const204 void QgsWfsParameters::dump() const 205 { 206 log( "WFS Request parameters:" ); 207 const auto map = mWfsParameters.toStdMap(); 208 for ( const auto ¶meter : map ) 209 { 210 const QString value = parameter.second.toString(); 211 212 if ( ! value.isEmpty() ) 213 { 214 const QString name = QgsWfsParameter::name( parameter.first ); 215 log( QStringLiteral( " - %1 : %2" ).arg( name, value ) ); 216 } 217 } 218 219 if ( !version().isEmpty() ) 220 log( QStringLiteral( " - VERSION : %1" ).arg( version() ) ); 221 } 222 outputFormatAsString() const223 QString QgsWfsParameters::outputFormatAsString() const 224 { 225 return mWfsParameters[ QgsWfsParameter::OUTPUTFORMAT ].toString(); 226 } 227 outputFormat() const228 QgsWfsParameters::Format QgsWfsParameters::outputFormat() const 229 { 230 const QString fStr = outputFormatAsString(); 231 232 if ( fStr.isEmpty() ) 233 { 234 if ( versionAsNumber() >= QgsProjectVersion( 1, 1, 0 ) ) 235 return Format::GML3; 236 else 237 return Format::GML2; 238 } 239 240 Format f = Format::NONE; 241 if ( fStr.compare( QLatin1String( "text/xml; subtype=gml/2.1.2" ), Qt::CaseInsensitive ) == 0 ) 242 f = Format::GML2; 243 else if ( fStr.compare( QLatin1String( "text/xml; subtype=gml/3.1.1" ), Qt::CaseInsensitive ) == 0 ) 244 f = Format::GML3; 245 else if ( fStr.compare( QLatin1String( "application/vnd.geo+json" ), Qt::CaseInsensitive ) == 0 || 246 // Needs to check for space too, because a + sign in the query string is interpreted as a space 247 fStr.compare( QLatin1String( "application/vnd.geo json" ), Qt::CaseInsensitive ) == 0 || 248 fStr.compare( QLatin1String( "application/geo+json" ), Qt::CaseInsensitive ) == 0 || 249 fStr.compare( QLatin1String( "application/geo json" ), Qt::CaseInsensitive ) == 0 || 250 fStr.compare( QLatin1String( "application/json" ), Qt::CaseInsensitive ) == 0 || 251 fStr.compare( QLatin1String( "geojson" ), Qt::CaseInsensitive ) == 0 252 ) 253 f = Format::GeoJSON; 254 else if ( fStr.compare( QLatin1String( "gml2" ), Qt::CaseInsensitive ) == 0 ) 255 f = Format::GML2; 256 else if ( fStr.compare( QLatin1String( "gml3" ), Qt::CaseInsensitive ) == 0 ) 257 f = Format::GML3; 258 259 if ( f == Format::NONE && 260 request().compare( QLatin1String( "describefeaturetype" ), Qt::CaseInsensitive ) == 0 && 261 fStr.compare( QLatin1String( "xmlschema" ), Qt::CaseInsensitive ) == 0 ) 262 f = Format::GML2; 263 264 return f; 265 } 266 resultTypeAsString() const267 QString QgsWfsParameters::resultTypeAsString() const 268 { 269 return mWfsParameters[ QgsWfsParameter::RESULTTYPE ].toString(); 270 } 271 resultType() const272 QgsWfsParameters::ResultType QgsWfsParameters::resultType() const 273 { 274 const QString rtStr = resultTypeAsString(); 275 if ( rtStr.isEmpty() ) 276 return ResultType::RESULTS; 277 278 ResultType rt = ResultType::RESULTS; 279 if ( rtStr.compare( QLatin1String( "hits" ), Qt::CaseInsensitive ) == 0 ) 280 rt = ResultType::HITS; 281 return rt; 282 } 283 propertyNames() const284 QStringList QgsWfsParameters::propertyNames() const 285 { 286 return mWfsParameters[ QgsWfsParameter::PROPERTYNAME ].toStringListWithExp(); 287 } 288 maxFeatures() const289 QString QgsWfsParameters::maxFeatures() const 290 { 291 return mWfsParameters[ QgsWfsParameter::MAXFEATURES ].toString(); 292 } 293 maxFeaturesAsInt() const294 int QgsWfsParameters::maxFeaturesAsInt() const 295 { 296 return mWfsParameters[ QgsWfsParameter::MAXFEATURES ].toInt(); 297 } 298 startIndex() const299 QString QgsWfsParameters::startIndex() const 300 { 301 return mWfsParameters[ QgsWfsParameter::STARTINDEX ].toString(); 302 } 303 startIndexAsInt() const304 int QgsWfsParameters::startIndexAsInt() const 305 { 306 return mWfsParameters[ QgsWfsParameter::STARTINDEX ].toInt(); 307 } 308 srsName() const309 QString QgsWfsParameters::srsName() const 310 { 311 return mWfsParameters[ QgsWfsParameter::SRSNAME ].toString(); 312 } 313 typeNames() const314 QStringList QgsWfsParameters::typeNames() const 315 { 316 return mWfsParameters[ QgsWfsParameter::TYPENAME ].toStringList(); 317 } 318 featureIds() const319 QStringList QgsWfsParameters::featureIds() const 320 { 321 return mWfsParameters[ QgsWfsParameter::FEATUREID ].toStringList(); 322 } 323 filters() const324 QStringList QgsWfsParameters::filters() const 325 { 326 return mWfsParameters[ QgsWfsParameter::FILTER ].toStringListWithExp(); 327 } 328 bbox() const329 QString QgsWfsParameters::bbox() const 330 { 331 return mWfsParameters[ QgsWfsParameter::BBOX ].toString(); 332 } 333 bboxAsRectangle() const334 QgsRectangle QgsWfsParameters::bboxAsRectangle() const 335 { 336 return mWfsParameters[ QgsWfsParameter::BBOX ].toRectangle(); 337 } 338 sortBy() const339 QStringList QgsWfsParameters::sortBy() const 340 { 341 return mWfsParameters[ QgsWfsParameter::SORTBY ].toStringListWithExp(); 342 } 343 expFilters() const344 QStringList QgsWfsParameters::expFilters() const 345 { 346 return mWfsParameters[ QgsWfsParameter::EXP_FILTER ].toStringListWithExp( QString( ) ); 347 } 348 geometryNameAsString() const349 QString QgsWfsParameters::geometryNameAsString() const 350 { 351 return mWfsParameters[ QgsWfsParameter::GEOMETRYNAME ].toString(); 352 } 353 versionAsNumber() const354 QgsProjectVersion QgsWfsParameters::versionAsNumber() const 355 { 356 const QString vStr = version(); 357 QgsProjectVersion version; 358 359 if ( vStr.isEmpty() ) 360 version = QgsProjectVersion( 1, 1, 0 ); // default value 361 else if ( mVersions.contains( QgsProjectVersion( vStr ) ) ) 362 version = QgsProjectVersion( vStr ); 363 364 return version; 365 } 366 log(const QString & msg) const367 void QgsWfsParameters::log( const QString &msg ) const 368 { 369 QgsMessageLog::logMessage( msg, "Server", Qgis::MessageLevel::Info ); 370 } 371 } 372