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