QGIS API Documentation  3.27.0-Master (bef583a8ef)
qgsvectordataprovider.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectordataprovider.cpp - DataProvider Interface for vector layers
3  --------------------------------------
4  Date : 26-Oct-2004
5  Copyright : (C) 2004 by Marco Hugentobler
6  email : [email protected]
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 
40  QgsDataProvider::ReadFlags flags )
41  : QgsDataProvider( uri, options, flags )
42  , mTemporalCapabilities( std::make_unique< QgsVectorDataProviderTemporalCapabilities >() )
43 {
44 }
45 
47 {
48  return QStringLiteral( "Generic vector file" );
49 }
50 
52 {
53  QgsFeature f;
54  QgsFeatureRequest request;
55  request.setNoAttributes();
57  request.setLimit( 1 );
58  if ( getFeatures( request ).nextFeature( f ) )
59  return false;
60  else
61  return true;
62 }
63 
65 {
67 }
68 
69 Qgis::VectorLayerTypeFlags QgsVectorDataProvider::vectorLayerTypeFlags() const
70 {
71  return Qgis::VectorLayerTypeFlags();
72 }
73 
75 {
76  if ( empty() )
77  return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
78  else
79  return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
80 }
81 
83 {
84  return crs();
85 }
86 
88 {
89  return extent();
90 }
91 
93 {
94  return QString();
95 }
96 
98 {
99  Q_UNUSED( flist )
100  Q_UNUSED( flags )
101  return false;
102 }
103 
105 {
106  return mErrors.isEmpty() ? QString() : mErrors.last();
107 }
108 
110 {
111  Q_UNUSED( ids )
112  return false;
113 }
114 
116 {
117  if ( !( capabilities() & DeleteFeatures ) )
118  return false;
119 
120  QgsFeatureIds toDelete;
121  QgsFeatureIterator it = getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setNoAttributes() );
122  QgsFeature f;
123  while ( it.nextFeature( f ) )
124  toDelete << f.id();
125 
126  return deleteFeatures( toDelete );
127 }
128 
129 bool QgsVectorDataProvider::addAttributes( const QList<QgsField> &attributes )
130 {
131  Q_UNUSED( attributes )
132  return false;
133 }
134 
136 {
137  Q_UNUSED( attributes )
138  return false;
139 }
140 
142 {
143  Q_UNUSED( renamedAttributes )
144  return false;
145 }
146 
148 {
149  Q_UNUSED( attr_map )
150  return false;
151 }
152 
153 QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const
154 {
155  Q_UNUSED( fieldId )
156  return QVariant();
157 }
158 
159 QString QgsVectorDataProvider::defaultValueClause( int fieldIndex ) const
160 {
161  Q_UNUSED( fieldIndex )
162  return QString();
163 }
164 
165 QgsFieldConstraints::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const
166 {
167  const QgsFields f = fields();
168  if ( fieldIndex < 0 || fieldIndex >= f.count() )
169  return QgsFieldConstraints::Constraints();
170 
171  return f.at( fieldIndex ).constraints().constraints();
172 }
173 
175 {
176  return false;
177 }
178 
180 {
181  Q_UNUSED( geometry_map )
182  return false;
183 }
184 
186  const QgsGeometryMap &geometry_map )
187 {
189  return false;
190 
191  bool result = true;
192  result = result && changeAttributeValues( attr_map );
193  result = result && changeGeometryValues( geometry_map );
194  return result;
195 }
196 
198 {
199  return false;
200 }
201 
203 {
204  Q_UNUSED( field )
205  return true;
206 }
207 
208 QgsVectorDataProvider::Capabilities QgsVectorDataProvider::capabilities() const
209 {
211 }
212 
213 void QgsVectorDataProvider::setEncoding( const QString &e )
214 {
215  mEncoding = QTextCodec::codecForName( e.toLocal8Bit().constData() );
216  if ( !mEncoding && e != QLatin1String( "System" ) )
217  {
218  if ( !e.isEmpty() )
219  {
220  // can we use the OGR proxy codec?
221  if ( QgsOgrProxyTextCodec::supportedCodecs().contains( e, Qt::CaseInsensitive ) )
222  {
223  //from the Qt docs (https://doc.qt.io/qt-5/qtextcodec.html#QTextCodec-1)
224  // "The QTextCodec should always be constructed on the heap (i.e. with new).
225  // Qt takes ownership and will delete it when the application terminates."
226  mEncoding = new QgsOgrProxyTextCodec( e.toLocal8Bit() );
227  }
228  else
229  {
230  QgsMessageLog::logMessage( tr( "Codec %1 not found. Falling back to system locale" ).arg( e ) );
231  mEncoding = QTextCodec::codecForName( "System" );
232  }
233  }
234  }
235 
236  if ( !mEncoding )
237  mEncoding = QTextCodec::codecForLocale();
238 
239  Q_ASSERT( mEncoding );
240 }
241 
243 {
244  if ( mEncoding )
245  {
246  return mEncoding->name();
247  }
248 
249  return QString();
250 }
251 
253 {
254  QStringList abilitiesList;
255 
256  const int abilities = capabilities();
257 
258  if ( abilities & QgsVectorDataProvider::AddFeatures )
259  {
260  abilitiesList += tr( "Add Features" );
261  }
262 
263  if ( abilities & QgsVectorDataProvider::DeleteFeatures )
264  {
265  abilitiesList += tr( "Delete Features" );
266  }
267 
269  {
270  abilitiesList += tr( "Change Attribute Values" );
271  }
272 
273  if ( abilities & QgsVectorDataProvider::AddAttributes )
274  {
275  abilitiesList += tr( "Add Attributes" );
276  }
277 
278  if ( abilities & QgsVectorDataProvider::DeleteAttributes )
279  {
280  abilitiesList += tr( "Delete Attributes" );
281  }
282 
283  if ( abilities & QgsVectorDataProvider::RenameAttributes )
284  {
285  abilitiesList += tr( "Rename Attributes" );
286  }
287 
289  {
290  // TODO: Tighten up this test. See QgsOgrProvider for details.
291  abilitiesList += tr( "Create Spatial Index" );
292  }
293 
295  {
296  abilitiesList += tr( "Create Attribute Indexes" );
297  }
298 
299  if ( abilities & QgsVectorDataProvider::SelectAtId )
300  {
301  abilitiesList += tr( "Fast Access to Features at ID" );
302  }
303 
304  if ( abilities & QgsVectorDataProvider::ChangeGeometries )
305  {
306  abilitiesList += tr( "Change Geometries" );
307  }
308 
310  {
311  abilitiesList += tr( "Presimplify Geometries" );
312  }
313 
315  {
316  abilitiesList += tr( "Presimplify Geometries with Validity Check" );
317  }
318 
319  if ( abilities & QgsVectorDataProvider::ChangeFeatures )
320  {
321  abilitiesList += tr( "Simultaneous Geometry and Attribute Updates" );
322  }
323 
325  {
326  abilitiesList += tr( "Transactions" );
327  }
328 
330  {
331  abilitiesList += tr( "Curved Geometries" );
332  }
333 
334  if ( abilities & QgsVectorDataProvider::FeatureSymbology )
335  {
336  abilitiesList += tr( "Feature Symbology" );
337  }
338 
339  return abilitiesList.join( QLatin1String( ", " ) );
340 }
341 
342 
343 int QgsVectorDataProvider::fieldNameIndex( const QString &fieldName ) const
344 {
345  return fields().lookupField( fieldName );
346 }
347 
348 QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
349 {
350  QMap<QString, int> resultMap;
351 
352  const QgsFields fieldsCopy = fields();
353  for ( int i = 0; i < fieldsCopy.count(); ++i )
354  {
355  resultMap.insert( fieldsCopy.at( i ).name(), i );
356  }
357 
358  return resultMap;
359 }
360 
362 {
363  return fields().allAttributesList();
364 }
365 
367 {
368  return QgsAttributeList();
369 }
370 
371 QList<QgsVectorDataProvider::NativeType> QgsVectorDataProvider::nativeTypes() const
372 {
373  return mNativeTypes;
374 }
375 
377 {
378  return QgsAttrPalIndexNameHash();
379 }
380 
382 {
383  QgsDebugMsgLevel( QStringLiteral( "field name = %1 type = %2 length = %3 precision = %4" )
384  .arg( field.name(),
385  QVariant::typeToName( field.type() ) )
386  .arg( field.length() )
387  .arg( field.precision() ), 2 );
388 
389  for ( const NativeType &nativeType : mNativeTypes )
390  {
391  QgsDebugMsgLevel( QStringLiteral( "native field type = %1 min length = %2 max length = %3 min precision = %4 max precision = %5" )
392  .arg( QVariant::typeToName( nativeType.mType ) )
393  .arg( nativeType.mMinLen )
394  .arg( nativeType.mMaxLen )
395  .arg( nativeType.mMinPrec )
396  .arg( nativeType.mMaxPrec ), 2 );
397 
398  if ( field.type() != nativeType.mType )
399  continue;
400 
401  if ( field.length() > 0 )
402  {
403  // source length limited
404  if ( ( nativeType.mMinLen > 0 && field.length() < nativeType.mMinLen ) ||
405  ( nativeType.mMaxLen > 0 && field.length() > nativeType.mMaxLen ) )
406  {
407  // source length exceeds destination limits
408  continue;
409  }
410  }
411 
412  if ( field.precision() > 0 )
413  {
414  // source precision limited
415  if ( ( nativeType.mMinPrec > 0 && field.precision() < nativeType.mMinPrec ) ||
416  ( nativeType.mMaxPrec > 0 && field.precision() > nativeType.mMaxPrec ) )
417  {
418  // source precision exceeds destination limits
419  continue;
420  }
421  }
422 
423  QgsDebugMsgLevel( QStringLiteral( "native type matches" ), 3 );
424  return true;
425  }
426 
427  QgsDebugMsg( QStringLiteral( "no sufficient native type found" ) );
428  return false;
429 }
430 
431 QVariant QgsVectorDataProvider::minimumValue( int index ) const
432 {
433  if ( index < 0 || index >= fields().count() )
434  {
435  QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
436  return QVariant();
437  }
438 
439  fillMinMaxCache();
440 
441  if ( !mCacheMinValues.contains( index ) )
442  return QVariant();
443 
444  return mCacheMinValues[index];
445 }
446 
447 QVariant QgsVectorDataProvider::maximumValue( int index ) const
448 {
449  if ( index < 0 || index >= fields().count() )
450  {
451  QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
452  return QVariant();
453  }
454 
455  fillMinMaxCache();
456 
457  if ( !mCacheMaxValues.contains( index ) )
458  return QVariant();
459 
460  return mCacheMaxValues[index];
461 }
462 
463 
464 QStringList QgsVectorDataProvider::uniqueStringsMatching( int index, const QString &substring, int limit, QgsFeedback *feedback ) const
465 {
466  QStringList results;
467 
468  // Safety belt
469  if ( index < 0 || index >= fields().count() )
470  return results;
471 
472  QgsFeature f;
473  QgsAttributeList keys;
474  keys.append( index );
475 
476  QgsFeatureRequest request;
477  request.setSubsetOfAttributes( keys );
479  const QString fieldName = fields().at( index ).name();
480  request.setFilterExpression( QStringLiteral( "\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
481  QgsFeatureIterator fi = getFeatures( request );
482 
483  QSet<QString> set;
484 
485  while ( fi.nextFeature( f ) )
486  {
487  const QString value = f.attribute( index ).toString();
488  if ( !set.contains( value ) )
489  {
490  results.append( value );
491  set.insert( value );
492  }
493 
494  if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->isCanceled() ) )
495  break;
496  }
497  return results;
498 }
499 
501  const QgsAggregateCalculator::AggregateParameters &parameters, QgsExpressionContext *context, bool &ok, QgsFeatureIds *fids ) const
502 {
503  //base implementation does nothing
504  Q_UNUSED( aggregate )
505  Q_UNUSED( index )
506  Q_UNUSED( parameters )
507  Q_UNUSED( context )
508  Q_UNUSED( fids )
509 
510  ok = false;
511  return QVariant();
512 }
513 
515 {
516  mCacheMinMaxDirty = true;
517  mCacheMinValues.clear();
518  mCacheMaxValues.clear();
519 }
520 
522 {
523  if ( !mCacheMinMaxDirty )
524  return;
525 
526  const QgsFields flds = fields();
527  for ( int i = 0; i < flds.count(); ++i )
528  {
529  if ( flds.at( i ).type() == QVariant::Int )
530  {
531  mCacheMinValues[i] = QVariant( std::numeric_limits<int>::max() );
532  mCacheMaxValues[i] = QVariant( std::numeric_limits<int>::lowest() );
533  }
534  else if ( flds.at( i ).type() == QVariant::LongLong )
535  {
536  mCacheMinValues[i] = QVariant( std::numeric_limits<qlonglong>::max() );
537  mCacheMaxValues[i] = QVariant( std::numeric_limits<qlonglong>::lowest() );
538  }
539  else if ( flds.at( i ).type() == QVariant::Double )
540  {
541  mCacheMinValues[i] = QVariant( std::numeric_limits<double>::max() );
542  mCacheMaxValues[i] = QVariant( std::numeric_limits<double>::lowest() );
543 
544  }
545  else
546  {
547  mCacheMinValues[i] = QVariant();
548  mCacheMaxValues[i] = QVariant();
549  }
550  }
551 
552  QgsFeature f;
553  const QgsAttributeList keys = mCacheMinValues.keys();
554  QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys )
555  .setFlags( QgsFeatureRequest::NoGeometry ) );
556 
557  while ( fi.nextFeature( f ) )
558  {
559  const QgsAttributes attrs = f.attributes();
560  for ( const int attributeIndex : keys )
561  {
562  const QVariant &varValue = attrs.at( attributeIndex );
563 
564  if ( varValue.isNull() )
565  continue;
566 
567  switch ( flds.at( attributeIndex ).type() )
568  {
569  case QVariant::Int:
570  {
571  const int value = varValue.toInt();
572  if ( value < mCacheMinValues[ attributeIndex ].toInt() )
573  mCacheMinValues[ attributeIndex ] = value;
574  if ( value > mCacheMaxValues[ attributeIndex ].toInt() )
575  mCacheMaxValues[ attributeIndex ] = value;
576  break;
577  }
578  case QVariant::LongLong:
579  {
580  const qlonglong value = varValue.toLongLong();
581  if ( value < mCacheMinValues[ attributeIndex ].toLongLong() )
582  mCacheMinValues[ attributeIndex ] = value;
583  if ( value > mCacheMaxValues[ attributeIndex ].toLongLong() )
584  mCacheMaxValues[ attributeIndex ] = value;
585  break;
586  }
587  case QVariant::Double:
588  {
589  const double value = varValue.toDouble();
590  if ( value < mCacheMinValues[ attributeIndex ].toDouble() )
591  mCacheMinValues[attributeIndex ] = value;
592  if ( value > mCacheMaxValues[ attributeIndex ].toDouble() )
593  mCacheMaxValues[ attributeIndex ] = value;
594  break;
595  }
596  case QVariant::DateTime:
597  {
598  const QDateTime value = varValue.toDateTime();
599  if ( value < mCacheMinValues[ attributeIndex ].toDateTime() || !mCacheMinValues[ attributeIndex ].isValid() )
600  mCacheMinValues[attributeIndex ] = value;
601  if ( value > mCacheMaxValues[ attributeIndex ].toDateTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
602  mCacheMaxValues[ attributeIndex ] = value;
603  break;
604  }
605  case QVariant::Date:
606  {
607  const QDate value = varValue.toDate();
608  if ( value < mCacheMinValues[ attributeIndex ].toDate() || !mCacheMinValues[ attributeIndex ].isValid() )
609  mCacheMinValues[attributeIndex ] = value;
610  if ( value > mCacheMaxValues[ attributeIndex ].toDate() || !mCacheMaxValues[ attributeIndex ].isValid() )
611  mCacheMaxValues[ attributeIndex ] = value;
612  break;
613  }
614  case QVariant::Time:
615  {
616  const QTime value = varValue.toTime();
617  if ( value < mCacheMinValues[ attributeIndex ].toTime() || !mCacheMinValues[ attributeIndex ].isValid() )
618  mCacheMinValues[attributeIndex ] = value;
619  if ( value > mCacheMaxValues[ attributeIndex ].toTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
620  mCacheMaxValues[ attributeIndex ] = value;
621  break;
622  }
623  default:
624  {
625  const QString value = varValue.toString();
626  if ( mCacheMinValues[ attributeIndex ].isNull() || value < mCacheMinValues[attributeIndex ].toString() )
627  {
628  mCacheMinValues[attributeIndex] = value;
629  }
630  if ( mCacheMaxValues[attributeIndex].isNull() || value > mCacheMaxValues[attributeIndex].toString() )
631  {
632  mCacheMaxValues[attributeIndex] = value;
633  }
634  break;
635  }
636  }
637  }
638  }
639 
640  mCacheMinMaxDirty = false;
641 }
642 
643 QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, const QString &value )
644 {
645  QVariant v( value );
646 
647  if ( !v.convert( type ) || value.isNull() )
648  v = QVariant( type );
649 
650  return v;
651 }
652 
654 {
655  return nullptr;
656 }
657 
658 static bool _compareEncodings( const QString &s1, const QString &s2 )
659 {
660  return s1.toLower() < s2.toLower();
661 }
662 
664 {
665  static std::once_flag initialized;
666  std::call_once( initialized, [ = ]
667  {
668  const auto codecs { QTextCodec::availableCodecs() };
669  for ( const QByteArray &codec : codecs )
670  {
671  sEncodings << codec;
672  }
673 #if 0
674  smEncodings << "BIG5";
675  smEncodings << "BIG5-HKSCS";
676  smEncodings << "EUCJP";
677  smEncodings << "EUCKR";
678  smEncodings << "GB2312";
679  smEncodings << "GBK";
680  smEncodings << "GB18030";
681  smEncodings << "JIS7";
682  smEncodings << "SHIFT-JIS";
683  smEncodings << "TSCII";
684  smEncodings << "UTF-8";
685  smEncodings << "UTF-16";
686  smEncodings << "KOI8-R";
687  smEncodings << "KOI8-U";
688  smEncodings << "ISO8859-1";
689  smEncodings << "ISO8859-2";
690  smEncodings << "ISO8859-3";
691  smEncodings << "ISO8859-4";
692  smEncodings << "ISO8859-5";
693  smEncodings << "ISO8859-6";
694  smEncodings << "ISO8859-7";
695  smEncodings << "ISO8859-8";
696  smEncodings << "ISO8859-8-I";
697  smEncodings << "ISO8859-9";
698  smEncodings << "ISO8859-10";
699  smEncodings << "ISO8859-11";
700  smEncodings << "ISO8859-12";
701  smEncodings << "ISO8859-13";
702  smEncodings << "ISO8859-14";
703  smEncodings << "ISO8859-15";
704  smEncodings << "IBM 850";
705  smEncodings << "IBM 866";
706  smEncodings << "CP874";
707  smEncodings << "CP1250";
708  smEncodings << "CP1251";
709  smEncodings << "CP1252";
710  smEncodings << "CP1253";
711  smEncodings << "CP1254";
712  smEncodings << "CP1255";
713  smEncodings << "CP1256";
714  smEncodings << "CP1257";
715  smEncodings << "CP1258";
716  smEncodings << "Apple Roman";
717  smEncodings << "TIS-620";
718  smEncodings << "System";
719 #endif
720 
721  // Do case-insensitive sorting of encodings
722  std::sort( sEncodings.begin(), sEncodings.end(), _compareEncodings );
723 
724  } );
725 
726  return sEncodings;
727 }
728 
730 {
731  mErrors.clear();
732 }
733 
735 {
736  return !mErrors.isEmpty();
737 }
738 
739 QStringList QgsVectorDataProvider::errors() const
740 {
741  return mErrors;
742 }
743 
745 {
746  return false;
747 }
748 
750 {
751  return false;
752 }
753 
755 {
756  return nullptr;
757 }
758 
760 {
761  return nullptr;
762 }
763 
764 void QgsVectorDataProvider::pushError( const QString &msg ) const
765 {
766  QgsDebugMsg( msg );
767  mErrors << msg;
768  emit raiseError( msg );
769 }
770 
771 QSet<QgsMapLayerDependency> QgsVectorDataProvider::dependencies() const
772 {
773  return QSet<QgsMapLayerDependency>();
774 }
775 
777 {
778  if ( geom.isNull() )
779  {
780  return QgsGeometry();
781  }
782 
783  const QgsAbstractGeometry *geometry = geom.constGet();
784  if ( !geometry )
785  {
786  return QgsGeometry();
787  }
788 
789  const QgsWkbTypes::Type providerGeomType = wkbType();
790 
791  //geom is already in the provider geometry type
792  if ( geometry->wkbType() == providerGeomType )
793  {
794  return QgsGeometry();
795  }
796 
797  std::unique_ptr< QgsAbstractGeometry > outputGeom;
798 
799  //convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
800  if ( QgsWkbTypes::flatType( providerGeomType ) == QgsWkbTypes::CircularString )
801  {
802  QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( geometry );
803  if ( compoundCurve )
804  {
805  if ( compoundCurve->nCurves() == 1 )
806  {
807  const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( compoundCurve->curveAt( 0 ) );
808  if ( circularString )
809  {
810  outputGeom.reset( circularString->clone() );
811  }
812  }
813  }
814  }
815 
816  //convert to curved type if necessary
817  if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) )
818  {
819  QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : geometry->toCurveType();
820  if ( curveGeom )
821  {
822  outputGeom.reset( curveGeom );
823  }
824  }
825 
826  //convert to linear type from curved type
827  if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) )
828  {
829  QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
830  if ( segmentizedGeom )
831  {
832  outputGeom.reset( segmentizedGeom );
833  }
834  }
835 
836  //convert to multitype if necessary
837  if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
838  {
839  std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) );
840  QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
841  if ( geomCollection )
842  {
843  if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) )
844  {
845  outputGeom.reset( collGeom.release() );
846  }
847  }
848  }
849 
850  //convert to single type if there's a single part of compatible type
851  if ( !QgsWkbTypes::isMultiType( providerGeomType ) && QgsWkbTypes::isMultiType( geometry->wkbType() ) )
852  {
853  const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry );
854  if ( collection )
855  {
856  if ( collection->numGeometries() == 1 )
857  {
858  const QgsAbstractGeometry *firstGeom = collection->geometryN( 0 );
859  if ( firstGeom && firstGeom->wkbType() == providerGeomType )
860  {
861  outputGeom.reset( firstGeom->clone() );
862  }
863  }
864  }
865  }
866 
867  //set z/m types
868  if ( QgsWkbTypes::hasZ( providerGeomType ) )
869  {
870  if ( !outputGeom )
871  {
872  outputGeom.reset( geometry->clone() );
873  }
874  outputGeom->addZValue();
875  }
876 
877  if ( QgsWkbTypes::hasM( providerGeomType ) )
878  {
879  if ( !outputGeom )
880  {
881  outputGeom.reset( geometry->clone() );
882  }
883  outputGeom->addMValue();
884  }
885 
886  if ( outputGeom )
887  {
888  return QgsGeometry( outputGeom.release() );
889  }
890 
891  return QgsGeometry();
892 }
893 
894 void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes )
895 {
896  mNativeTypes = nativeTypes;
897 }
898 
900 {
901  return mEncoding;
902 }
903 
905 {
906  return false;
907 }
908 
909 QStringList QgsVectorDataProvider::sEncodings;
910 
911 QList<QgsRelation> QgsVectorDataProvider::discoverRelations( const QgsVectorLayer *, const QList<QgsVectorLayer *> & ) const
912 {
913  return QList<QgsRelation>();
914 }
915 
917 {
918 
919 }
920 
922 {
923  return mTemporalCapabilities.get();
924 }
925 
927 {
928  return mTemporalCapabilities.get();
929 }
@ SqlQuery
SQL query layer.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
virtual QgsAbstractGeometry * toCurveType() const =0
Returns the geometry converted to the more generic curve type.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
Aggregate
Available aggregates to calculate.
A vector of attributes.
Definition: qgsattributes.h:58
Circular string geometry type.
QgsCircularString * clone() const override
Clones the geometry by performing a deep copy.
Compound curve geometry type.
const QgsCurve * curveAt(int i) const SIP_HOLDGIL
Returns the curve at the specified index.
int nCurves() const SIP_HOLDGIL
Returns the number of curves in the geometry.
This class represents a coordinate reference system (CRS).
Abstract base class for spatial data provider implementations.
virtual Qgis::DataProviderFlags flags() const
Returns the generic data provider flags.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
virtual bool isValid() const =0
Returns true if this is a valid layer.
virtual QgsRectangle extent() const =0
Returns the extent of the layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
FeatureAvailability
Possible return value for hasFeatures() to determine if a source is empty.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:320
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
Constraint
Constraints which may be present on a field.
Q_GADGET Constraints constraints
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString name
Definition: qgsfield.h:60
int precision
Definition: qgsfield.h:57
int length
Definition: qgsfield.h:56
QVariant::Type type
Definition: qgsfield.h:58
QgsFieldConstraints constraints
Definition: qgsfield.h:63
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfields.cpp:376
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:349
Geometry collection.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(QgsWkbTypes::Type t)
Returns empty geometry from wkb type.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Q_GADGET bool isNull
Definition: qgsgeometry.h:127
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A QTextCodec implementation which relies on OGR to do the text conversion.
static QStringList supportedCodecs()
Returns a list of supported text codecs.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
This class allows including a set of layers in a database-side transaction, provided the layer data p...
Implementation of data provider temporal properties for QgsVectorDataProviders.
This is the base class for vector data providers.
void pushError(const QString &msg) const
Push a notification about errors that happened in this providers scope.
QgsRectangle sourceExtent() const override
Returns the extent of all geometries from the source.
virtual bool cancelReload()
Cancels the current reloading of data.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
void setNativeTypes(const QList< QgsVectorDataProvider::NativeType > &nativeTypes)
Set the list of native types supported by this provider.
virtual QList< QgsRelation > discoverRelations(const QgsVectorLayer *target, const QList< QgsVectorLayer * > &layers) const
Discover the available relations with the given layers.
static QStringList availableEncodings()
Returns a list of available encodings.
virtual QString dataComment() const override
Returns a short comment for the data that this provider is providing access to (e....
@ SimplifyGeometries
Supports simplification of geometries on provider side according to a distance tolerance.
@ SimplifyGeometriesWithTopologicalValidation
Supports topological simplification of geometries on provider side according to a distance tolerance.
@ CircularGeometries
Supports circular geometry types (circularstring, compoundcurve, curvepolygon)
@ SelectAtId
Fast access to features using their ID.
@ ChangeFeatures
Supports joint updates for attributes and geometry. Providers supporting this should still define Cha...
@ ChangeGeometries
Allows modifications of geometries.
@ DeleteAttributes
Allows deletion of attributes (fields)
@ DeleteFeatures
Allows deletion of features.
@ CreateAttributeIndex
Can create indexes on provider's fields.
@ TransactionSupport
Supports transactions.
@ NoCapabilities
Provider has no capabilities.
@ AddAttributes
Allows addition of new attributes (fields)
@ CreateSpatialIndex
Allows creation of spatial index.
@ FeatureSymbology
Provider is able retrieve embedded symbology associated with individual features. Since QGIS 3....
@ RenameAttributes
Supports renaming attributes (fields). Since QGIS 2.16.
@ ChangeAttributeValues
Allows modification of attribute values.
@ AddFeatures
Allows adding features.
QgsWkbTypes::Type wkbType() const override=0
Returns the geometry type which is returned by this layer.
bool supportedType(const QgsField &field) const
check if provider supports type of field
virtual bool isSaveAndLoadStyleToDatabaseSupported() const
It returns false by default.
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
virtual QgsAttrPalIndexNameHash palAttributeIndexNames() const
Returns list of indexes to names for QgsPalLabeling fix.
QgsCoordinateReferenceSystem sourceCrs() const override
Returns the coordinate reference system for features in the source.
virtual QgsFeatureRenderer * createRenderer(const QVariantMap &configuration=QVariantMap()) const
Creates a new vector layer feature renderer, using provider backend specific information.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
void clearMinMaxCache()
Invalidates the min/max cache.
virtual bool truncate()
Removes all features from the layer.
virtual bool isDeleteStyleFromDatabaseSupported() const
It returns false by default.
virtual QStringList uniqueStringsMatching(int index, const QString &substring, int limit=-1, QgsFeedback *feedback=nullptr) const
Returns unique string values of an attribute which contain a specified subset string.
void raiseError(const QString &msg) const
Signals an error in this provider.
QTextCodec * textEncoding() const
Gets this providers encoding.
virtual bool isSqlQuery() const
Returns true if the layer is a query (SQL) layer.
void clearErrors()
Clear recorded errors.
QStringList errors() const
Gets recorded errors.
virtual bool empty() const
Returns true if the layer does not contain any feature.
QgsVectorDataProvider(const QString &uri=QString(), const QgsDataProvider::ProviderOptions &providerOptions=QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags flags=QgsDataProvider::ReadFlags())
Constructor for a vector data provider.
QList< QgsVectorDataProvider::NativeType > nativeTypes() const
Returns the names of the supported types.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
virtual void handlePostCloneOperations(QgsVectorDataProvider *source)
Handles any post-clone operations required after this vector data provider was cloned from the source...
QgsGeometry convertToProviderType(const QgsGeometry &geom) const
Converts the geometry to the provider type if possible / necessary.
virtual bool changeFeatures(const QgsChangedAttributesMap &attr_map, const QgsGeometryMap &geometry_map)
Changes attribute values and geometries of existing features.
virtual QSet< QgsMapLayerDependency > dependencies() const
Gets the list of layer ids on which this layer depends.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index.
virtual void setEncoding(const QString &e)
Set encoding used for accessing data from layer.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
QgsFeatureSource::FeatureAvailability hasFeatures() const override
Will always return FeatureAvailability::FeaturesAvailable or FeatureAvailability::NoFeaturesAvailable...
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features from the provider.
virtual Qgis::VectorLayerTypeFlags vectorLayerTypeFlags() const
Returns the vector layer type flags.
QVariant maximumValue(int index) const override
Returns the maximum value of an attribute.
virtual bool createAttributeIndex(int field)
Create an attribute index on the datasource.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
QMap< QString, int > fieldNameMap() const
Returns a map where the key is the name of the field and the value is its index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override=0
Query the provider for features specified in request.
virtual QgsAttributeList attributeIndexes() const
Returns list of indexes to fetch all attributes in nextFeature()
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider.
QVariant minimumValue(int index) const override
Returns the minimum value of an attribute.
virtual QVariant aggregate(QgsAggregateCalculator::Aggregate aggregate, int index, const QgsAggregateCalculator::AggregateParameters &parameters, QgsExpressionContext *context, bool &ok, QgsFeatureIds *fids=nullptr) const
Calculates an aggregated value from the layer's features.
void fillMinMaxCache() const
Populates the cache of minimum and maximum attribute values.
QString encoding() const
Returns the encoding which is used for accessing data.
virtual QVariant defaultValue(int fieldIndex) const
Returns any literal default values which are present at the provider for a specified field index.
QgsFieldConstraints::Constraints fieldConstraints(int fieldIndex) const
Returns any constraints which are present at the provider for a specified field index.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
virtual QgsAbstractVectorLayerLabeling * createLabeling(const QVariantMap &configuration=QVariantMap()) const
Creates labeling settings, using provider backend specific information.
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
virtual bool renameAttributes(const QgsFieldNameMap &renamedAttributes)
Renames existing attributes.
virtual bool deleteAttributes(const QgsAttributeIds &attributes)
Deletes existing attributes from the provider.
virtual bool skipConstraintCheck(int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value=QVariant()) const
Returns true if a constraint check should be skipped for a specified field (e.g., if the value return...
static QVariant convertValue(QVariant::Type type, const QString &value)
bool hasErrors() const
Provider has errors to report.
QgsVectorDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
QString capabilitiesString() const
Returns the above in friendly format.
Represents a vector layer which manages a vector based data sets.
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:862
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static bool isCurvedType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a curved type or can contain curved geometries.
Definition: qgswkbtypes.h:911
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1080
QMap< int, QString > QgsFieldNameMap
Definition: qgsattributes.h:44
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:877
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:868
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QList< int > QgsAttributeList
Definition: qgsfield.h:26
const QgsField & field
Definition: qgsfield.h:463
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QSet< int > QgsAttributeIds
QHash< int, QString > QgsAttrPalIndexNameHash
A bundle of parameters controlling aggregate calculation.
Setting options for creating vector data providers.