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 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 for ( auto parameter : mWfsParameters.toStdMap() ) 208 { 209 const QString value = parameter.second.toString(); 210 211 if ( ! value.isEmpty() ) 212 { 213 const QString name = QgsWfsParameter::name( parameter.first ); 214 log( QStringLiteral( " - %1 : %2" ).arg( name, value ) ); 215 } 216 } 217 218 if ( !version().isEmpty() ) 219 log( QStringLiteral( " - VERSION : %1" ).arg( version() ) ); 220 } 221 outputFormatAsString() const222 QString QgsWfsParameters::outputFormatAsString() const 223 { 224 return mWfsParameters[ QgsWfsParameter::OUTPUTFORMAT ].toString(); 225 } 226 outputFormat() const227 QgsWfsParameters::Format QgsWfsParameters::outputFormat() const 228 { 229 QString fStr = outputFormatAsString(); 230 231 if ( fStr.isEmpty() ) 232 { 233 if ( versionAsNumber() >= QgsProjectVersion( 1, 1, 0 ) ) 234 return Format::GML3; 235 else 236 return Format::GML2; 237 } 238 239 Format f = Format::NONE; 240 if ( fStr.compare( QLatin1String( "text/xml; subtype=gml/2.1.2" ), Qt::CaseInsensitive ) == 0 ) 241 f = Format::GML2; 242 else if ( fStr.compare( QLatin1String( "text/xml; subtype=gml/3.1.1" ), Qt::CaseInsensitive ) == 0 ) 243 f = Format::GML3; 244 else if ( fStr.compare( QLatin1String( "application/vnd.geo+json" ), Qt::CaseInsensitive ) == 0 || 245 // Needs to check for space too, because a + sign in the query string is interpreted as a space 246 fStr.compare( QLatin1String( "application/vnd.geo json" ), Qt::CaseInsensitive ) == 0 || 247 fStr.compare( QLatin1String( "application/geo+json" ), Qt::CaseInsensitive ) == 0 || 248 fStr.compare( QLatin1String( "application/geo json" ), Qt::CaseInsensitive ) == 0 || 249 fStr.compare( QLatin1String( "application/json" ), Qt::CaseInsensitive ) == 0 || 250 fStr.compare( QLatin1String( "geojson" ), Qt::CaseInsensitive ) == 0 251 ) 252 f = Format::GeoJSON; 253 else if ( fStr.compare( QLatin1String( "gml2" ), Qt::CaseInsensitive ) == 0 ) 254 f = Format::GML2; 255 else if ( fStr.compare( QLatin1String( "gml3" ), Qt::CaseInsensitive ) == 0 ) 256 f = Format::GML3; 257 258 if ( f == Format::NONE && 259 request().compare( QLatin1String( "describefeaturetype" ), Qt::CaseInsensitive ) == 0 && 260 fStr.compare( QLatin1String( "xmlschema" ), Qt::CaseInsensitive ) == 0 ) 261 f = Format::GML2; 262 263 return f; 264 } 265 resultTypeAsString() const266 QString QgsWfsParameters::resultTypeAsString() const 267 { 268 return mWfsParameters[ QgsWfsParameter::RESULTTYPE ].toString(); 269 } 270 resultType() const271 QgsWfsParameters::ResultType QgsWfsParameters::resultType() const 272 { 273 QString rtStr = resultTypeAsString(); 274 if ( rtStr.isEmpty() ) 275 return ResultType::RESULTS; 276 277 ResultType rt = ResultType::RESULTS; 278 if ( rtStr.compare( QLatin1String( "hits" ), Qt::CaseInsensitive ) == 0 ) 279 rt = ResultType::HITS; 280 return rt; 281 } 282 propertyNames() const283 QStringList QgsWfsParameters::propertyNames() const 284 { 285 return mWfsParameters[ QgsWfsParameter::PROPERTYNAME ].toStringListWithExp(); 286 } 287 maxFeatures() const288 QString QgsWfsParameters::maxFeatures() const 289 { 290 return mWfsParameters[ QgsWfsParameter::MAXFEATURES ].toString(); 291 } 292 maxFeaturesAsInt() const293 int QgsWfsParameters::maxFeaturesAsInt() const 294 { 295 return mWfsParameters[ QgsWfsParameter::MAXFEATURES ].toInt(); 296 } 297 startIndex() const298 QString QgsWfsParameters::startIndex() const 299 { 300 return mWfsParameters[ QgsWfsParameter::STARTINDEX ].toString(); 301 } 302 startIndexAsInt() const303 int QgsWfsParameters::startIndexAsInt() const 304 { 305 return mWfsParameters[ QgsWfsParameter::STARTINDEX ].toInt(); 306 } 307 srsName() const308 QString QgsWfsParameters::srsName() const 309 { 310 return mWfsParameters[ QgsWfsParameter::SRSNAME ].toString(); 311 } 312 typeNames() const313 QStringList QgsWfsParameters::typeNames() const 314 { 315 return mWfsParameters[ QgsWfsParameter::TYPENAME ].toStringList(); 316 } 317 featureIds() const318 QStringList QgsWfsParameters::featureIds() const 319 { 320 return mWfsParameters[ QgsWfsParameter::FEATUREID ].toStringList(); 321 } 322 filters() const323 QStringList QgsWfsParameters::filters() const 324 { 325 return mWfsParameters[ QgsWfsParameter::FILTER ].toStringListWithExp(); 326 } 327 bbox() const328 QString QgsWfsParameters::bbox() const 329 { 330 return mWfsParameters[ QgsWfsParameter::BBOX ].toString(); 331 } 332 bboxAsRectangle() const333 QgsRectangle QgsWfsParameters::bboxAsRectangle() const 334 { 335 return mWfsParameters[ QgsWfsParameter::BBOX ].toRectangle(); 336 } 337 sortBy() const338 QStringList QgsWfsParameters::sortBy() const 339 { 340 return mWfsParameters[ QgsWfsParameter::SORTBY ].toStringListWithExp(); 341 } 342 expFilters() const343 QStringList QgsWfsParameters::expFilters() const 344 { 345 return mWfsParameters[ QgsWfsParameter::EXP_FILTER ].toStringListWithExp( QString( ) ); 346 } 347 geometryNameAsString() const348 QString QgsWfsParameters::geometryNameAsString() const 349 { 350 return mWfsParameters[ QgsWfsParameter::GEOMETRYNAME ].toString(); 351 } 352 versionAsNumber() const353 QgsProjectVersion QgsWfsParameters::versionAsNumber() const 354 { 355 QString vStr = version(); 356 QgsProjectVersion version; 357 358 if ( vStr.isEmpty() ) 359 version = QgsProjectVersion( 1, 1, 0 ); // default value 360 else if ( mVersions.contains( QgsProjectVersion( vStr ) ) ) 361 version = QgsProjectVersion( vStr ); 362 363 return version; 364 } 365 log(const QString & msg) const366 void QgsWfsParameters::log( const QString &msg ) const 367 { 368 QgsMessageLog::logMessage( msg, "Server", Qgis::Info ); 369 } 370 } 371