Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsvectordataprovider.cpp - DataProvider Interface for vector layers 3 : : -------------------------------------- 4 : : Date : 26-Oct-2004 5 : : Copyright : (C) 2004 by Marco Hugentobler 6 : : email : marco.hugentobler@autoform.ch 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 : : 16 : : #include <QTextCodec> 17 : : 18 : : #include <cfloat> 19 : : #include <climits> 20 : : #include <limits> 21 : : 22 : : #include "qgsvectordataprovider.h" 23 : : #include "qgscircularstring.h" 24 : : #include "qgscompoundcurve.h" 25 : : #include "qgsfeature.h" 26 : : #include "qgsfeatureiterator.h" 27 : : #include "qgsfeaturerequest.h" 28 : : #include "qgsfeedback.h" 29 : : #include "qgsfields.h" 30 : : #include "qgsgeometry.h" 31 : : #include "qgsgeometrycollection.h" 32 : : #include "qgsgeometryfactory.h" 33 : : #include "qgslogger.h" 34 : : #include "qgsmessagelog.h" 35 : : #include "qgssettings.h" 36 : : #include "qgsogrproxytextcodec.h" 37 : : #include <mutex> 38 : : 39 : 78 : QgsVectorDataProvider::QgsVectorDataProvider( const QString &uri, const ProviderOptions &options, 40 : : QgsDataProvider::ReadFlags flags ) 41 : 78 : : QgsDataProvider( uri, options, flags ) 42 : 78 : , mTemporalCapabilities( std::make_unique< QgsVectorDataProviderTemporalCapabilities >() ) 43 : 312 : { 44 : 78 : } 45 : : 46 : 0 : QString QgsVectorDataProvider::storageType() const 47 : : { 48 : 0 : return QStringLiteral( "Generic vector file" ); 49 : : } 50 : : 51 : 0 : bool QgsVectorDataProvider::empty() const 52 : : { 53 : 0 : QgsFeature f; 54 : 0 : QgsFeatureRequest request; 55 : 0 : request.setNoAttributes(); 56 : 0 : request.setFlags( QgsFeatureRequest::NoGeometry ); 57 : 0 : request.setLimit( 1 ); 58 : 0 : if ( getFeatures( request ).nextFeature( f ) ) 59 : 0 : return false; 60 : : else 61 : 0 : return true; 62 : 0 : } 63 : : 64 : 0 : QgsFeatureSource::FeatureAvailability QgsVectorDataProvider::hasFeatures() const 65 : : { 66 : 0 : if ( empty() ) 67 : 0 : return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable; 68 : : else 69 : 0 : return QgsFeatureSource::FeatureAvailability::FeaturesAvailable; 70 : 0 : } 71 : : 72 : 0 : QgsCoordinateReferenceSystem QgsVectorDataProvider::sourceCrs() const 73 : : { 74 : 0 : return crs(); 75 : : } 76 : : 77 : 0 : QgsRectangle QgsVectorDataProvider::sourceExtent() const 78 : : { 79 : 0 : return extent(); 80 : : } 81 : : 82 : 0 : QString QgsVectorDataProvider::dataComment() const 83 : : { 84 : 0 : return QString(); 85 : : } 86 : : 87 : 0 : bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist, Flags flags ) 88 : : { 89 : 0 : Q_UNUSED( flist ) 90 : : Q_UNUSED( flags ) 91 : 0 : return false; 92 : : } 93 : : 94 : 0 : QString QgsVectorDataProvider::lastError() const 95 : : { 96 : 0 : return mErrors.isEmpty() ? QString() : mErrors.last(); 97 : : } 98 : : 99 : 0 : bool QgsVectorDataProvider::deleteFeatures( const QgsFeatureIds &ids ) 100 : : { 101 : 0 : Q_UNUSED( ids ) 102 : 0 : return false; 103 : : } 104 : : 105 : 0 : bool QgsVectorDataProvider::truncate() 106 : : { 107 : 0 : if ( !( capabilities() & DeleteFeatures ) ) 108 : 0 : return false; 109 : : 110 : 0 : QgsFeatureIds toDelete; 111 : 0 : QgsFeatureIterator it = getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setNoAttributes() ); 112 : 0 : QgsFeature f; 113 : 0 : while ( it.nextFeature( f ) ) 114 : 0 : toDelete << f.id(); 115 : : 116 : 0 : return deleteFeatures( toDelete ); 117 : 0 : } 118 : : 119 : 0 : bool QgsVectorDataProvider::addAttributes( const QList<QgsField> &attributes ) 120 : : { 121 : 0 : Q_UNUSED( attributes ) 122 : 0 : return false; 123 : : } 124 : : 125 : 0 : bool QgsVectorDataProvider::deleteAttributes( const QgsAttributeIds &attributes ) 126 : : { 127 : 0 : Q_UNUSED( attributes ) 128 : 0 : return false; 129 : : } 130 : : 131 : 0 : bool QgsVectorDataProvider::renameAttributes( const QgsFieldNameMap &renamedAttributes ) 132 : : { 133 : 0 : Q_UNUSED( renamedAttributes ) 134 : 0 : return false; 135 : : } 136 : : 137 : 0 : bool QgsVectorDataProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map ) 138 : : { 139 : 0 : Q_UNUSED( attr_map ) 140 : 0 : return false; 141 : : } 142 : : 143 : 0 : QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const 144 : : { 145 : : Q_UNUSED( fieldId ) 146 : 0 : return QVariant(); 147 : : } 148 : : 149 : 0 : QString QgsVectorDataProvider::defaultValueClause( int fieldIndex ) const 150 : : { 151 : : Q_UNUSED( fieldIndex ) 152 : 0 : return QString(); 153 : : } 154 : : 155 : 0 : QgsFieldConstraints::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const 156 : : { 157 : 0 : QgsFields f = fields(); 158 : 0 : if ( fieldIndex < 0 || fieldIndex >= f.count() ) 159 : 0 : return QgsFieldConstraints::Constraints(); 160 : : 161 : 0 : return f.at( fieldIndex ).constraints().constraints(); 162 : 0 : } 163 : : 164 : 0 : bool QgsVectorDataProvider::skipConstraintCheck( int, QgsFieldConstraints::Constraint, const QVariant & ) const 165 : : { 166 : 0 : return false; 167 : : } 168 : : 169 : 0 : bool QgsVectorDataProvider::changeGeometryValues( const QgsGeometryMap &geometry_map ) 170 : : { 171 : 0 : Q_UNUSED( geometry_map ) 172 : 0 : return false; 173 : : } 174 : : 175 : 0 : bool QgsVectorDataProvider::changeFeatures( const QgsChangedAttributesMap &attr_map, 176 : : const QgsGeometryMap &geometry_map ) 177 : : { 178 : 0 : if ( !( capabilities() & ChangeAttributeValues ) || !( capabilities() & ChangeGeometries ) ) 179 : 0 : return false; 180 : : 181 : 0 : bool result = true; 182 : 0 : result = result && changeAttributeValues( attr_map ); 183 : 0 : result = result && changeGeometryValues( geometry_map ); 184 : 0 : return result; 185 : 0 : } 186 : : 187 : 0 : bool QgsVectorDataProvider::createSpatialIndex() 188 : : { 189 : 0 : return false; 190 : : } 191 : : 192 : 0 : bool QgsVectorDataProvider::createAttributeIndex( int field ) 193 : : { 194 : : Q_UNUSED( field ) 195 : 0 : return true; 196 : : } 197 : : 198 : 0 : QgsVectorDataProvider::Capabilities QgsVectorDataProvider::capabilities() const 199 : : { 200 : 0 : return QgsVectorDataProvider::NoCapabilities; 201 : : } 202 : : 203 : 187 : void QgsVectorDataProvider::setEncoding( const QString &e ) 204 : : { 205 : 187 : mEncoding = QTextCodec::codecForName( e.toLocal8Bit().constData() ); 206 : 187 : if ( !mEncoding && e != QLatin1String( "System" ) ) 207 : : { 208 : 62 : if ( !e.isEmpty() ) 209 : : { 210 : : // can we use the OGR proxy codec? 211 : 0 : if ( QgsOgrProxyTextCodec::supportedCodecs().contains( e, Qt::CaseInsensitive ) ) 212 : : { 213 : : //from the Qt docs (https://doc.qt.io/qt-5/qtextcodec.html#QTextCodec-1) 214 : : // "The QTextCodec should always be constructed on the heap (i.e. with new). 215 : : // Qt takes ownership and will delete it when the application terminates." 216 : 0 : mEncoding = new QgsOgrProxyTextCodec( e.toLocal8Bit() ); 217 : 0 : } 218 : : else 219 : : { 220 : 0 : QgsMessageLog::logMessage( tr( "Codec %1 not found. Falling back to system locale" ).arg( e ) ); 221 : 0 : mEncoding = QTextCodec::codecForName( "System" ); 222 : : } 223 : 0 : } 224 : 62 : } 225 : : 226 : 187 : if ( !mEncoding ) 227 : 62 : mEncoding = QTextCodec::codecForLocale(); 228 : : 229 : : Q_ASSERT( mEncoding ); 230 : 187 : } 231 : : 232 : 186 : QString QgsVectorDataProvider::encoding() const 233 : : { 234 : 186 : if ( mEncoding ) 235 : : { 236 : 123 : return mEncoding->name(); 237 : : } 238 : : 239 : 63 : return QString(); 240 : 186 : } 241 : : 242 : 0 : QString QgsVectorDataProvider::capabilitiesString() const 243 : : { 244 : 0 : QStringList abilitiesList; 245 : : 246 : 0 : int abilities = capabilities(); 247 : : 248 : 0 : if ( abilities & QgsVectorDataProvider::AddFeatures ) 249 : : { 250 : 0 : abilitiesList += tr( "Add Features" ); 251 : 0 : } 252 : : 253 : 0 : if ( abilities & QgsVectorDataProvider::DeleteFeatures ) 254 : : { 255 : 0 : abilitiesList += tr( "Delete Features" ); 256 : 0 : } 257 : : 258 : 0 : if ( abilities & QgsVectorDataProvider::ChangeAttributeValues ) 259 : : { 260 : 0 : abilitiesList += tr( "Change Attribute Values" ); 261 : 0 : } 262 : : 263 : 0 : if ( abilities & QgsVectorDataProvider::AddAttributes ) 264 : : { 265 : 0 : abilitiesList += tr( "Add Attributes" ); 266 : 0 : } 267 : : 268 : 0 : if ( abilities & QgsVectorDataProvider::DeleteAttributes ) 269 : : { 270 : 0 : abilitiesList += tr( "Delete Attributes" ); 271 : 0 : } 272 : : 273 : 0 : if ( abilities & QgsVectorDataProvider::RenameAttributes ) 274 : : { 275 : 0 : abilitiesList += tr( "Rename Attributes" ); 276 : 0 : } 277 : : 278 : 0 : if ( abilities & QgsVectorDataProvider::CreateSpatialIndex ) 279 : : { 280 : : // TODO: Tighten up this test. See QgsOgrProvider for details. 281 : 0 : abilitiesList += tr( "Create Spatial Index" ); 282 : 0 : } 283 : : 284 : 0 : if ( abilities & QgsVectorDataProvider::CreateAttributeIndex ) 285 : : { 286 : 0 : abilitiesList += tr( "Create Attribute Indexes" ); 287 : 0 : } 288 : : 289 : 0 : if ( abilities & QgsVectorDataProvider::SelectAtId ) 290 : : { 291 : 0 : abilitiesList += tr( "Fast Access to Features at ID" ); 292 : 0 : } 293 : : 294 : 0 : if ( abilities & QgsVectorDataProvider::ChangeGeometries ) 295 : : { 296 : 0 : abilitiesList += tr( "Change Geometries" ); 297 : 0 : } 298 : : 299 : 0 : if ( abilities & QgsVectorDataProvider::SimplifyGeometries ) 300 : : { 301 : 0 : abilitiesList += tr( "Presimplify Geometries" ); 302 : 0 : } 303 : : 304 : 0 : if ( abilities & QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation ) 305 : : { 306 : 0 : abilitiesList += tr( "Presimplify Geometries with Validity Check" ); 307 : 0 : } 308 : : 309 : 0 : if ( abilities & QgsVectorDataProvider::ChangeFeatures ) 310 : : { 311 : 0 : abilitiesList += tr( "Simultaneous Geometry and Attribute Updates" ); 312 : 0 : } 313 : : 314 : 0 : if ( abilities & QgsVectorDataProvider::TransactionSupport ) 315 : : { 316 : 0 : abilitiesList += tr( "Transactions" ); 317 : 0 : } 318 : : 319 : 0 : if ( abilities & QgsVectorDataProvider::CircularGeometries ) 320 : : { 321 : 0 : abilitiesList += tr( "Curved Geometries" ); 322 : 0 : } 323 : : 324 : 0 : if ( abilities & QgsVectorDataProvider::FeatureSymbology ) 325 : : { 326 : 0 : abilitiesList += tr( "Feature Symbology" ); 327 : 0 : } 328 : : 329 : 0 : return abilitiesList.join( QLatin1String( ", " ) ); 330 : 0 : } 331 : : 332 : : 333 : 0 : int QgsVectorDataProvider::fieldNameIndex( const QString &fieldName ) const 334 : : { 335 : 0 : return fields().lookupField( fieldName ); 336 : 0 : } 337 : : 338 : 0 : QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const 339 : : { 340 : 0 : QMap<QString, int> resultMap; 341 : : 342 : 0 : QgsFields fieldsCopy = fields(); 343 : 0 : for ( int i = 0; i < fieldsCopy.count(); ++i ) 344 : : { 345 : 0 : resultMap.insert( fieldsCopy.at( i ).name(), i ); 346 : 0 : } 347 : : 348 : 0 : return resultMap; 349 : 0 : } 350 : : 351 : 32 : QgsAttributeList QgsVectorDataProvider::attributeIndexes() const 352 : : { 353 : 32 : return fields().allAttributesList(); 354 : 0 : } 355 : : 356 : 0 : QgsAttributeList QgsVectorDataProvider::pkAttributeIndexes() const 357 : : { 358 : 0 : return QgsAttributeList(); 359 : : } 360 : : 361 : 0 : QList<QgsVectorDataProvider::NativeType> QgsVectorDataProvider::nativeTypes() const 362 : : { 363 : 0 : return mNativeTypes; 364 : : } 365 : : 366 : 0 : QgsAttrPalIndexNameHash QgsVectorDataProvider::palAttributeIndexNames() const 367 : : { 368 : 0 : return QgsAttrPalIndexNameHash(); 369 : : } 370 : : 371 : 0 : bool QgsVectorDataProvider::supportedType( const QgsField &field ) const 372 : : { 373 : 0 : QgsDebugMsgLevel( QStringLiteral( "field name = %1 type = %2 length = %3 precision = %4" ) 374 : : .arg( field.name(), 375 : : QVariant::typeToName( field.type() ) ) 376 : : .arg( field.length() ) 377 : : .arg( field.precision() ), 2 ); 378 : : 379 : 0 : for ( const NativeType &nativeType : mNativeTypes ) 380 : : { 381 : 0 : QgsDebugMsgLevel( QStringLiteral( "native field type = %1 min length = %2 max length = %3 min precision = %4 max precision = %5" ) 382 : : .arg( QVariant::typeToName( nativeType.mType ) ) 383 : : .arg( nativeType.mMinLen ) 384 : : .arg( nativeType.mMaxLen ) 385 : : .arg( nativeType.mMinPrec ) 386 : : .arg( nativeType.mMaxPrec ), 2 ); 387 : : 388 : 0 : if ( field.type() != nativeType.mType ) 389 : 0 : continue; 390 : : 391 : 0 : if ( field.length() > 0 ) 392 : : { 393 : : // source length limited 394 : 0 : if ( ( nativeType.mMinLen > 0 && field.length() < nativeType.mMinLen ) || 395 : 0 : ( nativeType.mMaxLen > 0 && field.length() > nativeType.mMaxLen ) ) 396 : : { 397 : : // source length exceeds destination limits 398 : 0 : continue; 399 : : } 400 : 0 : } 401 : : 402 : 0 : if ( field.precision() > 0 ) 403 : : { 404 : : // source precision limited 405 : 0 : if ( ( nativeType.mMinPrec > 0 && field.precision() < nativeType.mMinPrec ) || 406 : 0 : ( nativeType.mMaxPrec > 0 && field.precision() > nativeType.mMaxPrec ) ) 407 : : { 408 : : // source precision exceeds destination limits 409 : 0 : continue; 410 : : } 411 : 0 : } 412 : : 413 : 0 : QgsDebugMsgLevel( QStringLiteral( "native type matches" ), 3 ); 414 : 0 : return true; 415 : : } 416 : : 417 : 0 : QgsDebugMsg( QStringLiteral( "no sufficient native type found" ) ); 418 : 0 : return false; 419 : 0 : } 420 : : 421 : 0 : QVariant QgsVectorDataProvider::minimumValue( int index ) const 422 : : { 423 : 0 : if ( index < 0 || index >= fields().count() ) 424 : : { 425 : 0 : QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) ); 426 : 0 : return QVariant(); 427 : : } 428 : : 429 : 0 : fillMinMaxCache(); 430 : : 431 : 0 : if ( !mCacheMinValues.contains( index ) ) 432 : 0 : return QVariant(); 433 : : 434 : 0 : return mCacheMinValues[index]; 435 : 0 : } 436 : : 437 : 0 : QVariant QgsVectorDataProvider::maximumValue( int index ) const 438 : : { 439 : 0 : if ( index < 0 || index >= fields().count() ) 440 : : { 441 : 0 : QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) ); 442 : 0 : return QVariant(); 443 : : } 444 : : 445 : 0 : fillMinMaxCache(); 446 : : 447 : 0 : if ( !mCacheMaxValues.contains( index ) ) 448 : 0 : return QVariant(); 449 : : 450 : 0 : return mCacheMaxValues[index]; 451 : 0 : } 452 : : 453 : : 454 : 0 : QStringList QgsVectorDataProvider::uniqueStringsMatching( int index, const QString &substring, int limit, QgsFeedback *feedback ) const 455 : : { 456 : 0 : QStringList results; 457 : : 458 : : // Safety belt 459 : 0 : if ( index < 0 || index >= fields().count() ) 460 : 0 : return results; 461 : : 462 : 0 : QgsFeature f; 463 : 0 : QgsAttributeList keys; 464 : 0 : keys.append( index ); 465 : : 466 : 0 : QgsFeatureRequest request; 467 : 0 : request.setSubsetOfAttributes( keys ); 468 : 0 : request.setFlags( QgsFeatureRequest::NoGeometry ); 469 : 0 : QString fieldName = fields().at( index ).name(); 470 : 0 : request.setFilterExpression( QStringLiteral( "\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) ); 471 : 0 : QgsFeatureIterator fi = getFeatures( request ); 472 : : 473 : 0 : QSet<QString> set; 474 : : 475 : 0 : while ( fi.nextFeature( f ) ) 476 : : { 477 : 0 : QString value = f.attribute( index ).toString(); 478 : 0 : if ( !set.contains( value ) ) 479 : : { 480 : 0 : results.append( value ); 481 : 0 : set.insert( value ); 482 : 0 : } 483 : : 484 : 0 : if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->isCanceled() ) ) 485 : 0 : break; 486 : 0 : } 487 : 0 : return results; 488 : 0 : } 489 : : 490 : 0 : QVariant QgsVectorDataProvider::aggregate( QgsAggregateCalculator::Aggregate aggregate, int index, 491 : : const QgsAggregateCalculator::AggregateParameters ¶meters, QgsExpressionContext *context, bool &ok, QgsFeatureIds *fids ) const 492 : : { 493 : : //base implementation does nothing 494 : : Q_UNUSED( aggregate ) 495 : : Q_UNUSED( index ) 496 : 0 : Q_UNUSED( parameters ) 497 : : Q_UNUSED( context ) 498 : : Q_UNUSED( fids ) 499 : : 500 : 0 : ok = false; 501 : 0 : return QVariant(); 502 : : } 503 : : 504 : 38 : void QgsVectorDataProvider::clearMinMaxCache() 505 : : { 506 : 38 : mCacheMinMaxDirty = true; 507 : 38 : mCacheMinValues.clear(); 508 : 38 : mCacheMaxValues.clear(); 509 : 38 : } 510 : : 511 : 0 : void QgsVectorDataProvider::fillMinMaxCache() const 512 : : { 513 : 0 : if ( !mCacheMinMaxDirty ) 514 : 0 : return; 515 : : 516 : 0 : QgsFields flds = fields(); 517 : 0 : for ( int i = 0; i < flds.count(); ++i ) 518 : : { 519 : 0 : if ( flds.at( i ).type() == QVariant::Int ) 520 : : { 521 : 0 : mCacheMinValues[i] = QVariant( std::numeric_limits<int>::max() ); 522 : 0 : mCacheMaxValues[i] = QVariant( std::numeric_limits<int>::lowest() ); 523 : 0 : } 524 : 0 : else if ( flds.at( i ).type() == QVariant::LongLong ) 525 : : { 526 : 0 : mCacheMinValues[i] = QVariant( std::numeric_limits<qlonglong>::max() ); 527 : 0 : mCacheMaxValues[i] = QVariant( std::numeric_limits<qlonglong>::lowest() ); 528 : 0 : } 529 : 0 : else if ( flds.at( i ).type() == QVariant::Double ) 530 : : { 531 : 0 : mCacheMinValues[i] = QVariant( std::numeric_limits<double>::max() ); 532 : 0 : mCacheMaxValues[i] = QVariant( std::numeric_limits<double>::lowest() ); 533 : : 534 : 0 : } 535 : : else 536 : : { 537 : 0 : mCacheMinValues[i] = QVariant(); 538 : 0 : mCacheMaxValues[i] = QVariant(); 539 : : } 540 : 0 : } 541 : : 542 : 0 : QgsFeature f; 543 : 0 : const QgsAttributeList keys = mCacheMinValues.keys(); 544 : 0 : QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ) 545 : 0 : .setFlags( QgsFeatureRequest::NoGeometry ) ); 546 : : 547 : 0 : while ( fi.nextFeature( f ) ) 548 : : { 549 : 0 : QgsAttributes attrs = f.attributes(); 550 : 0 : for ( int attributeIndex : keys ) 551 : : { 552 : 0 : const QVariant &varValue = attrs.at( attributeIndex ); 553 : : 554 : 0 : if ( varValue.isNull() ) 555 : 0 : continue; 556 : : 557 : 0 : switch ( flds.at( attributeIndex ).type() ) 558 : : { 559 : : case QVariant::Int: 560 : : { 561 : 0 : int value = varValue.toInt(); 562 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toInt() ) 563 : 0 : mCacheMinValues[ attributeIndex ] = value; 564 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toInt() ) 565 : 0 : mCacheMaxValues[ attributeIndex ] = value; 566 : 0 : break; 567 : : } 568 : : case QVariant::LongLong: 569 : : { 570 : 0 : qlonglong value = varValue.toLongLong(); 571 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toLongLong() ) 572 : 0 : mCacheMinValues[ attributeIndex ] = value; 573 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toLongLong() ) 574 : 0 : mCacheMaxValues[ attributeIndex ] = value; 575 : 0 : break; 576 : : } 577 : : case QVariant::Double: 578 : : { 579 : 0 : double value = varValue.toDouble(); 580 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toDouble() ) 581 : 0 : mCacheMinValues[attributeIndex ] = value; 582 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toDouble() ) 583 : 0 : mCacheMaxValues[ attributeIndex ] = value; 584 : 0 : break; 585 : : } 586 : : case QVariant::DateTime: 587 : : { 588 : 0 : QDateTime value = varValue.toDateTime(); 589 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toDateTime() || !mCacheMinValues[ attributeIndex ].isValid() ) 590 : 0 : mCacheMinValues[attributeIndex ] = value; 591 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toDateTime() || !mCacheMaxValues[ attributeIndex ].isValid() ) 592 : 0 : mCacheMaxValues[ attributeIndex ] = value; 593 : : break; 594 : 0 : } 595 : : case QVariant::Date: 596 : : { 597 : 0 : QDate value = varValue.toDate(); 598 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toDate() || !mCacheMinValues[ attributeIndex ].isValid() ) 599 : 0 : mCacheMinValues[attributeIndex ] = value; 600 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toDate() || !mCacheMaxValues[ attributeIndex ].isValid() ) 601 : 0 : mCacheMaxValues[ attributeIndex ] = value; 602 : 0 : break; 603 : : } 604 : : case QVariant::Time: 605 : : { 606 : 0 : QTime value = varValue.toTime(); 607 : 0 : if ( value < mCacheMinValues[ attributeIndex ].toTime() || !mCacheMinValues[ attributeIndex ].isValid() ) 608 : 0 : mCacheMinValues[attributeIndex ] = value; 609 : 0 : if ( value > mCacheMaxValues[ attributeIndex ].toTime() || !mCacheMaxValues[ attributeIndex ].isValid() ) 610 : 0 : mCacheMaxValues[ attributeIndex ] = value; 611 : 0 : break; 612 : : } 613 : : default: 614 : : { 615 : 0 : QString value = varValue.toString(); 616 : 0 : if ( mCacheMinValues[ attributeIndex ].isNull() || value < mCacheMinValues[attributeIndex ].toString() ) 617 : : { 618 : 0 : mCacheMinValues[attributeIndex] = value; 619 : 0 : } 620 : 0 : if ( mCacheMaxValues[attributeIndex].isNull() || value > mCacheMaxValues[attributeIndex].toString() ) 621 : : { 622 : 0 : mCacheMaxValues[attributeIndex] = value; 623 : 0 : } 624 : : break; 625 : 0 : } 626 : : } 627 : : } 628 : 0 : } 629 : : 630 : 0 : mCacheMinMaxDirty = false; 631 : 0 : } 632 : : 633 : 0 : QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, const QString &value ) 634 : : { 635 : 0 : QVariant v( value ); 636 : : 637 : 0 : if ( !v.convert( type ) || value.isNull() ) 638 : 0 : v = QVariant( type ); 639 : : 640 : 0 : return v; 641 : 0 : } 642 : : 643 : 5 : QgsTransaction *QgsVectorDataProvider::transaction() const 644 : : { 645 : 5 : return nullptr; 646 : : } 647 : : 648 : 0 : static bool _compareEncodings( const QString &s1, const QString &s2 ) 649 : : { 650 : 0 : return s1.toLower() < s2.toLower(); 651 : 0 : } 652 : : 653 : 0 : QStringList QgsVectorDataProvider::availableEncodings() 654 : : { 655 : : static std::once_flag initialized; 656 : 0 : std::call_once( initialized, [ = ] 657 : : { 658 : 0 : const auto codecs { QTextCodec::availableCodecs() }; 659 : 0 : for ( const QByteArray &codec : codecs ) 660 : : { 661 : 0 : sEncodings << codec; 662 : : } 663 : : #if 0 664 : : smEncodings << "BIG5"; 665 : : smEncodings << "BIG5-HKSCS"; 666 : : smEncodings << "EUCJP"; 667 : : smEncodings << "EUCKR"; 668 : : smEncodings << "GB2312"; 669 : : smEncodings << "GBK"; 670 : : smEncodings << "GB18030"; 671 : : smEncodings << "JIS7"; 672 : : smEncodings << "SHIFT-JIS"; 673 : : smEncodings << "TSCII"; 674 : : smEncodings << "UTF-8"; 675 : : smEncodings << "UTF-16"; 676 : : smEncodings << "KOI8-R"; 677 : : smEncodings << "KOI8-U"; 678 : : smEncodings << "ISO8859-1"; 679 : : smEncodings << "ISO8859-2"; 680 : : smEncodings << "ISO8859-3"; 681 : : smEncodings << "ISO8859-4"; 682 : : smEncodings << "ISO8859-5"; 683 : 78 : smEncodings << "ISO8859-6"; 684 : : smEncodings << "ISO8859-7"; 685 : : smEncodings << "ISO8859-8"; 686 : : smEncodings << "ISO8859-8-I"; 687 : 78 : smEncodings << "ISO8859-9"; 688 : : smEncodings << "ISO8859-10"; 689 : : smEncodings << "ISO8859-11"; 690 : : smEncodings << "ISO8859-12"; 691 : : smEncodings << "ISO8859-13"; 692 : : smEncodings << "ISO8859-14"; 693 : : smEncodings << "ISO8859-15"; 694 : : smEncodings << "IBM 850"; 695 : : smEncodings << "IBM 866"; 696 : : smEncodings << "CP874"; 697 : : smEncodings << "CP1250"; 698 : : smEncodings << "CP1251"; 699 : : smEncodings << "CP1252"; 700 : : smEncodings << "CP1253"; 701 : : smEncodings << "CP1254"; 702 : : smEncodings << "CP1255"; 703 : : smEncodings << "CP1256"; 704 : : smEncodings << "CP1257"; 705 : : smEncodings << "CP1258"; 706 : : smEncodings << "Apple Roman"; 707 : : smEncodings << "TIS-620"; 708 : : smEncodings << "System"; 709 : : #endif 710 : : 711 : : // Do case-insensitive sorting of encodings 712 : 0 : std::sort( sEncodings.begin(), sEncodings.end(), _compareEncodings ); 713 : : 714 : 0 : } ); 715 : : 716 : 0 : return sEncodings; 717 : : } 718 : : 719 : 0 : void QgsVectorDataProvider::clearErrors() 720 : : { 721 : 0 : mErrors.clear(); 722 : 0 : } 723 : : 724 : 0 : bool QgsVectorDataProvider::hasErrors() const 725 : : { 726 : 0 : return !mErrors.isEmpty(); 727 : : } 728 : : 729 : 0 : QStringList QgsVectorDataProvider::errors() const 730 : : { 731 : 0 : return mErrors; 732 : : } 733 : : 734 : 14 : bool QgsVectorDataProvider::isSaveAndLoadStyleToDatabaseSupported() const 735 : : { 736 : 14 : return false; 737 : : } 738 : : 739 : 0 : bool QgsVectorDataProvider::isDeleteStyleFromDatabaseSupported() const 740 : : { 741 : 0 : return false; 742 : : } 743 : : 744 : 0 : QgsFeatureRenderer *QgsVectorDataProvider::createRenderer( const QVariantMap & ) const 745 : : { 746 : 0 : return nullptr; 747 : : } 748 : : 749 : 0 : QgsAbstractVectorLayerLabeling *QgsVectorDataProvider::createLabeling( const QVariantMap & ) const 750 : : { 751 : 0 : return nullptr; 752 : : } 753 : : 754 : 0 : void QgsVectorDataProvider::pushError( const QString &msg ) const 755 : : { 756 : 0 : QgsDebugMsg( msg ); 757 : 0 : mErrors << msg; 758 : 0 : emit raiseError( msg ); 759 : 0 : } 760 : : 761 : 1 : QSet<QgsMapLayerDependency> QgsVectorDataProvider::dependencies() const 762 : : { 763 : 1 : return QSet<QgsMapLayerDependency>(); 764 : : } 765 : : 766 : 0 : QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geom ) const 767 : : { 768 : 0 : if ( geom.isNull() ) 769 : : { 770 : 0 : return QgsGeometry(); 771 : : } 772 : : 773 : 0 : const QgsAbstractGeometry *geometry = geom.constGet(); 774 : 0 : if ( !geometry ) 775 : : { 776 : 0 : return QgsGeometry(); 777 : : } 778 : : 779 : 0 : QgsWkbTypes::Type providerGeomType = wkbType(); 780 : : 781 : : //geom is already in the provider geometry type 782 : 0 : if ( geometry->wkbType() == providerGeomType ) 783 : : { 784 : 0 : return QgsGeometry(); 785 : : } 786 : : 787 : 0 : std::unique_ptr< QgsAbstractGeometry > outputGeom; 788 : : 789 : : //convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string) 790 : 0 : if ( QgsWkbTypes::flatType( providerGeomType ) == QgsWkbTypes::CircularString ) 791 : : { 792 : 0 : QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( geometry ); 793 : 0 : if ( compoundCurve ) 794 : : { 795 : 0 : if ( compoundCurve->nCurves() == 1 ) 796 : : { 797 : 0 : const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( compoundCurve->curveAt( 0 ) ); 798 : 0 : if ( circularString ) 799 : : { 800 : 0 : outputGeom.reset( circularString->clone() ); 801 : 0 : } 802 : 0 : } 803 : 0 : } 804 : 0 : } 805 : : 806 : : //convert to curved type if necessary 807 : 0 : if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) ) 808 : : { 809 : 0 : QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : geometry->toCurveType(); 810 : 0 : if ( curveGeom ) 811 : : { 812 : 0 : outputGeom.reset( curveGeom ); 813 : 0 : } 814 : 0 : } 815 : : 816 : : //convert to linear type from curved type 817 : 0 : if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) ) 818 : : { 819 : 0 : QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize(); 820 : 0 : if ( segmentizedGeom ) 821 : : { 822 : 0 : outputGeom.reset( segmentizedGeom ); 823 : 0 : } 824 : 0 : } 825 : : 826 : : //convert to multitype if necessary 827 : 0 : if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) ) 828 : : { 829 : 0 : std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) ); 830 : 0 : QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() ); 831 : 0 : if ( geomCollection ) 832 : : { 833 : 0 : if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) ) 834 : : { 835 : 0 : outputGeom.reset( collGeom.release() ); 836 : 0 : } 837 : 0 : } 838 : 0 : } 839 : : 840 : : //set z/m types 841 : 0 : if ( QgsWkbTypes::hasZ( providerGeomType ) ) 842 : : { 843 : 0 : if ( !outputGeom ) 844 : : { 845 : 0 : outputGeom.reset( geometry->clone() ); 846 : 0 : } 847 : 0 : outputGeom->addZValue(); 848 : 0 : } 849 : : 850 : 0 : if ( QgsWkbTypes::hasM( providerGeomType ) ) 851 : : { 852 : 0 : if ( !outputGeom ) 853 : : { 854 : 0 : outputGeom.reset( geometry->clone() ); 855 : 0 : } 856 : 0 : outputGeom->addMValue(); 857 : 0 : } 858 : : 859 : 0 : if ( outputGeom ) 860 : : { 861 : 0 : return QgsGeometry( outputGeom.release() ); 862 : : } 863 : : 864 : 0 : return QgsGeometry(); 865 : 0 : } 866 : : 867 : 78 : void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes ) 868 : : { 869 : 78 : mNativeTypes = nativeTypes; 870 : 78 : } 871 : : 872 : 1113 : QTextCodec *QgsVectorDataProvider::textEncoding() const 873 : : { 874 : 1113 : return mEncoding; 875 : : } 876 : : 877 : 0 : bool QgsVectorDataProvider::cancelReload() 878 : : { 879 : 0 : return false; 880 : : } 881 : : 882 : 5 : QStringList QgsVectorDataProvider::sEncodings; 883 : : 884 : 0 : QList<QgsRelation> QgsVectorDataProvider::discoverRelations( const QgsVectorLayer *, const QList<QgsVectorLayer *> & ) const 885 : : { 886 : 0 : return QList<QgsRelation>(); 887 : : } 888 : : 889 : 0 : void QgsVectorDataProvider::handlePostCloneOperations( QgsVectorDataProvider * ) 890 : : { 891 : : 892 : 0 : } 893 : : 894 : 78 : QgsVectorDataProviderTemporalCapabilities *QgsVectorDataProvider::temporalCapabilities() 895 : : { 896 : 78 : return mTemporalCapabilities.get(); 897 : : } 898 : : 899 : 0 : const QgsVectorDataProviderTemporalCapabilities *QgsVectorDataProvider::temporalCapabilities() const 900 : : { 901 : 0 : return mTemporalCapabilities.get(); 902 : : }