QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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
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
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"
32#include "qgsgeometryfactory.h"
33#include "qgslogger.h"
34#include "qgsmessagelog.h"
36#include "qgsthreadingutils.h"
37#include <mutex>
38
40 QgsDataProvider::ReadFlags flags )
41 : QgsDataProvider( uri, options, flags )
42 , mTemporalCapabilities( std::make_unique< QgsVectorDataProviderTemporalCapabilities >() )
43{
44}
45
47{
49
50 return QStringLiteral( "Generic vector file" );
51}
52
54{
56
57 QgsFeature f;
58 QgsFeatureRequest request;
59 request.setNoAttributes();
61 request.setLimit( 1 );
62 if ( getFeatures( request ).nextFeature( f ) )
63 return false;
64 else
65 return true;
66}
67
69{
71
73}
74
75Qgis::VectorLayerTypeFlags QgsVectorDataProvider::vectorLayerTypeFlags() const
76{
78
79 return Qgis::VectorLayerTypeFlags();
80}
81
83{
85
86 if ( empty() )
87 return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
88 else
89 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
90}
91
93{
95
96 return crs();
97}
98
100{
102
103 return extent();
104}
105
107{
109
110 return QString();
111}
112
114{
116
117 Q_UNUSED( flist )
118 Q_UNUSED( flags )
119 return false;
120}
121
123{
125
126 return mErrors.isEmpty() ? QString() : mErrors.last();
127}
128
130{
132
133 Q_UNUSED( ids )
134 return false;
135}
136
138{
140
141 if ( !( capabilities() & DeleteFeatures ) )
142 return false;
143
144 QgsFeatureIds toDelete;
146 QgsFeature f;
147 while ( it.nextFeature( f ) )
148 toDelete << f.id();
149
150 return deleteFeatures( toDelete );
151}
152
153bool QgsVectorDataProvider::addAttributes( const QList<QgsField> &attributes )
154{
156
157 Q_UNUSED( attributes )
158 return false;
159}
160
162{
164
165 Q_UNUSED( attributes )
166 return false;
167}
168
170{
172
173 Q_UNUSED( renamedAttributes )
174 return false;
175}
176
178{
180
181 Q_UNUSED( attr_map )
182 return false;
183}
184
185QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const
186{
188
189 Q_UNUSED( fieldId )
190 return QVariant();
191}
192
193QString QgsVectorDataProvider::defaultValueClause( int fieldIndex ) const
194{
196
197 Q_UNUSED( fieldIndex )
198 return QString();
199}
200
201QgsFieldConstraints::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const
202{
204
205 const QgsFields f = fields();
206 if ( fieldIndex < 0 || fieldIndex >= f.count() )
207 return QgsFieldConstraints::Constraints();
208
209 return f.at( fieldIndex ).constraints().constraints();
210}
211
213{
215
216 return false;
217}
218
220{
222
223 Q_UNUSED( geometry_map )
224 return false;
225}
226
228 const QgsGeometryMap &geometry_map )
229{
231
233 return false;
234
235 bool result = true;
236 result = result && changeAttributeValues( attr_map );
237 result = result && changeGeometryValues( geometry_map );
238 return result;
239}
240
242{
244
245 return false;
246}
247
249{
251
252 Q_UNUSED( field )
253 return true;
254}
255
256QgsVectorDataProvider::Capabilities QgsVectorDataProvider::capabilities() const
257{
259
261}
262
264{
266
267 mEncoding = QTextCodec::codecForName( e.toLocal8Bit().constData() );
268 if ( !mEncoding && e != QLatin1String( "System" ) )
269 {
270 if ( !e.isEmpty() )
271 {
272 // can we use the OGR proxy codec?
273 if ( QgsOgrProxyTextCodec::supportedCodecs().contains( e, Qt::CaseInsensitive ) )
274 {
275 //from the Qt docs (https://doc.qt.io/qt-5/qtextcodec.html#QTextCodec-1)
276 // "The QTextCodec should always be constructed on the heap (i.e. with new).
277 // Qt takes ownership and will delete it when the application terminates."
278 mEncoding = new QgsOgrProxyTextCodec( e.toLocal8Bit() );
279 }
280 else
281 {
282 QgsMessageLog::logMessage( tr( "Codec %1 not found. Falling back to system locale" ).arg( e ) );
283 mEncoding = QTextCodec::codecForName( "System" );
284 }
285 }
286 }
287
288 if ( !mEncoding )
289 mEncoding = QTextCodec::codecForLocale();
290
291 Q_ASSERT( mEncoding );
292}
293
295{
297
298 if ( mEncoding )
299 {
300 return mEncoding->name();
301 }
302
303 return QString();
304}
305
307{
309
310 QStringList abilitiesList;
311
312 const int abilities = capabilities();
313
314 if ( abilities & QgsVectorDataProvider::AddFeatures )
315 {
316 abilitiesList += tr( "Add Features" );
317 }
318
320 {
321 abilitiesList += tr( "Delete Features" );
322 }
323
325 {
326 abilitiesList += tr( "Change Attribute Values" );
327 }
328
329 if ( abilities & QgsVectorDataProvider::AddAttributes )
330 {
331 abilitiesList += tr( "Add Attributes" );
332 }
333
335 {
336 abilitiesList += tr( "Delete Attributes" );
337 }
338
340 {
341 abilitiesList += tr( "Rename Attributes" );
342 }
343
345 {
346 // TODO: Tighten up this test. See QgsOgrProvider for details.
347 abilitiesList += tr( "Create Spatial Index" );
348 }
349
351 {
352 abilitiesList += tr( "Create Attribute Indexes" );
353 }
354
355 if ( abilities & QgsVectorDataProvider::SelectAtId )
356 {
357 abilitiesList += tr( "Fast Access to Features at ID" );
358 }
359
361 {
362 abilitiesList += tr( "Change Geometries" );
363 }
364
366 {
367 abilitiesList += tr( "Presimplify Geometries" );
368 }
369
371 {
372 abilitiesList += tr( "Presimplify Geometries with Validity Check" );
373 }
374
376 {
377 abilitiesList += tr( "Simultaneous Geometry and Attribute Updates" );
378 }
379
381 {
382 abilitiesList += tr( "Transactions" );
383 }
384
386 {
387 abilitiesList += tr( "Curved Geometries" );
388 }
389
391 {
392 abilitiesList += tr( "Feature Symbology" );
393 }
394
395 return abilitiesList.join( QLatin1String( ", " ) );
396}
397
398int QgsVectorDataProvider::fieldNameIndex( const QString &fieldName ) const
399{
401
402 return fields().lookupField( fieldName );
403}
404
405QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
406{
408
409 QMap<QString, int> resultMap;
410
411 const QgsFields fieldsCopy = fields();
412 for ( int i = 0; i < fieldsCopy.count(); ++i )
413 {
414 resultMap.insert( fieldsCopy.at( i ).name(), i );
415 }
416
417 return resultMap;
418}
419
421{
423
424 return fields().allAttributesList();
425}
426
428{
430
431 return QgsAttributeList();
432}
433
434QList<QgsVectorDataProvider::NativeType> QgsVectorDataProvider::nativeTypes() const
435{
437
438 return mNativeTypes;
439}
440
442{
444
446}
447
449{
451
452 QgsDebugMsgLevel( QStringLiteral( "field name = %1 type = %2 length = %3 precision = %4" )
453 .arg( field.name(),
454 QVariant::typeToName( field.type() ) )
455 .arg( field.length() )
456 .arg( field.precision() ), 2 );
457
458 for ( const NativeType &nativeType : mNativeTypes )
459 {
460 QgsDebugMsgLevel( QStringLiteral( "native field type = %1 min length = %2 max length = %3 min precision = %4 max precision = %5" )
461 .arg( QVariant::typeToName( nativeType.mType ) )
462 .arg( nativeType.mMinLen )
463 .arg( nativeType.mMaxLen )
464 .arg( nativeType.mMinPrec )
465 .arg( nativeType.mMaxPrec ), 2 );
466
467 if ( field.type() != nativeType.mType )
468 continue;
469
470 if ( field.length() > 0 )
471 {
472 // source length limited
473 if ( ( nativeType.mMinLen > 0 && field.length() < nativeType.mMinLen ) ||
474 ( nativeType.mMaxLen > 0 && field.length() > nativeType.mMaxLen ) )
475 {
476 // source length exceeds destination limits
477 continue;
478 }
479 }
480
481 if ( field.precision() > 0 )
482 {
483 // source precision limited
484 if ( ( nativeType.mMinPrec > 0 && field.precision() < nativeType.mMinPrec ) ||
485 ( nativeType.mMaxPrec > 0 && field.precision() > nativeType.mMaxPrec ) )
486 {
487 // source precision exceeds destination limits
488 continue;
489 }
490 }
491
492 QgsDebugMsgLevel( QStringLiteral( "native type matches" ), 3 );
493 return true;
494 }
495
496 QgsDebugMsg( QStringLiteral( "no sufficient native type found" ) );
497 return false;
498}
499
500QVariant QgsVectorDataProvider::minimumValue( int index ) const
501{
503
504 if ( index < 0 || index >= fields().count() )
505 {
506 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
507 return QVariant();
508 }
509
511
512 if ( !mCacheMinValues.contains( index ) )
513 return QVariant();
514
515 return mCacheMinValues[index];
516}
517
518QVariant QgsVectorDataProvider::maximumValue( int index ) const
519{
521
522 if ( index < 0 || index >= fields().count() )
523 {
524 QgsDebugMsg( "Warning: access requested to invalid field index: " + QString::number( index ) );
525 return QVariant();
526 }
527
529
530 if ( !mCacheMaxValues.contains( index ) )
531 return QVariant();
532
533 return mCacheMaxValues[index];
534}
535
536QStringList QgsVectorDataProvider::uniqueStringsMatching( int index, const QString &substring, int limit, QgsFeedback *feedback ) const
537{
539
540 QStringList results;
541
542 // Safety belt
543 if ( index < 0 || index >= fields().count() )
544 return results;
545
546 QgsFeature f;
547 QgsAttributeList keys;
548 keys.append( index );
549
550 QgsFeatureRequest request;
551 request.setSubsetOfAttributes( keys );
553 const QString fieldName = fields().at( index ).name();
554 request.setFilterExpression( QStringLiteral( "\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
555 QgsFeatureIterator fi = getFeatures( request );
556
557 QSet<QString> set;
558
559 while ( fi.nextFeature( f ) )
560 {
561 const QString value = f.attribute( index ).toString();
562 if ( !set.contains( value ) )
563 {
564 results.append( value );
565 set.insert( value );
566 }
567
568 if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->isCanceled() ) )
569 break;
570 }
571 return results;
572}
573
575 const QgsAggregateCalculator::AggregateParameters &parameters, QgsExpressionContext *context, bool &ok, QgsFeatureIds *fids ) const
576{
577 // non fatal for now -- the "aggregate" functions are not thread safe and call this
579
580 //base implementation does nothing
581 Q_UNUSED( aggregate )
582 Q_UNUSED( index )
583 Q_UNUSED( parameters )
584 Q_UNUSED( context )
585 Q_UNUSED( fids )
586
587 ok = false;
588 return QVariant();
589}
590
592{
594
595 mCacheMinMaxDirty = true;
596 mCacheMinValues.clear();
597 mCacheMaxValues.clear();
598}
599
601{
603
604 if ( !mCacheMinMaxDirty )
605 return;
606
607 const QgsFields flds = fields();
608 for ( int i = 0; i < flds.count(); ++i )
609 {
610 if ( flds.at( i ).type() == QVariant::Int )
611 {
612 mCacheMinValues[i] = QVariant( std::numeric_limits<int>::max() );
613 mCacheMaxValues[i] = QVariant( std::numeric_limits<int>::lowest() );
614 }
615 else if ( flds.at( i ).type() == QVariant::LongLong )
616 {
617 mCacheMinValues[i] = QVariant( std::numeric_limits<qlonglong>::max() );
618 mCacheMaxValues[i] = QVariant( std::numeric_limits<qlonglong>::lowest() );
619 }
620 else if ( flds.at( i ).type() == QVariant::Double )
621 {
622 mCacheMinValues[i] = QVariant( std::numeric_limits<double>::max() );
623 mCacheMaxValues[i] = QVariant( std::numeric_limits<double>::lowest() );
624
625 }
626 else
627 {
628 mCacheMinValues[i] = QVariant();
629 mCacheMaxValues[i] = QVariant();
630 }
631 }
632
633 QgsFeature f;
634 const QgsAttributeList keys = mCacheMinValues.keys();
635 QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys )
636 .setFlags( QgsFeatureRequest::NoGeometry ) );
637
638 while ( fi.nextFeature( f ) )
639 {
640 const QgsAttributes attrs = f.attributes();
641 for ( const int attributeIndex : keys )
642 {
643 const QVariant &varValue = attrs.at( attributeIndex );
644
645 if ( QgsVariantUtils::isNull( varValue ) )
646 continue;
647
648 switch ( flds.at( attributeIndex ).type() )
649 {
650 case QVariant::Int:
651 {
652 const int value = varValue.toInt();
653 if ( value < mCacheMinValues[ attributeIndex ].toInt() )
654 mCacheMinValues[ attributeIndex ] = value;
655 if ( value > mCacheMaxValues[ attributeIndex ].toInt() )
656 mCacheMaxValues[ attributeIndex ] = value;
657 break;
658 }
659 case QVariant::LongLong:
660 {
661 const qlonglong value = varValue.toLongLong();
662 if ( value < mCacheMinValues[ attributeIndex ].toLongLong() )
663 mCacheMinValues[ attributeIndex ] = value;
664 if ( value > mCacheMaxValues[ attributeIndex ].toLongLong() )
665 mCacheMaxValues[ attributeIndex ] = value;
666 break;
667 }
668 case QVariant::Double:
669 {
670 const double value = varValue.toDouble();
671 if ( value < mCacheMinValues[ attributeIndex ].toDouble() )
672 mCacheMinValues[attributeIndex ] = value;
673 if ( value > mCacheMaxValues[ attributeIndex ].toDouble() )
674 mCacheMaxValues[ attributeIndex ] = value;
675 break;
676 }
677 case QVariant::DateTime:
678 {
679 const QDateTime value = varValue.toDateTime();
680 if ( value < mCacheMinValues[ attributeIndex ].toDateTime() || !mCacheMinValues[ attributeIndex ].isValid() )
681 mCacheMinValues[attributeIndex ] = value;
682 if ( value > mCacheMaxValues[ attributeIndex ].toDateTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
683 mCacheMaxValues[ attributeIndex ] = value;
684 break;
685 }
686 case QVariant::Date:
687 {
688 const QDate value = varValue.toDate();
689 if ( value < mCacheMinValues[ attributeIndex ].toDate() || !mCacheMinValues[ attributeIndex ].isValid() )
690 mCacheMinValues[attributeIndex ] = value;
691 if ( value > mCacheMaxValues[ attributeIndex ].toDate() || !mCacheMaxValues[ attributeIndex ].isValid() )
692 mCacheMaxValues[ attributeIndex ] = value;
693 break;
694 }
695 case QVariant::Time:
696 {
697 const QTime value = varValue.toTime();
698 if ( value < mCacheMinValues[ attributeIndex ].toTime() || !mCacheMinValues[ attributeIndex ].isValid() )
699 mCacheMinValues[attributeIndex ] = value;
700 if ( value > mCacheMaxValues[ attributeIndex ].toTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
701 mCacheMaxValues[ attributeIndex ] = value;
702 break;
703 }
704 default:
705 {
706 const QString value = varValue.toString();
707 if ( QgsVariantUtils::isNull( mCacheMinValues[ attributeIndex ] ) || value < mCacheMinValues[attributeIndex ].toString() )
708 {
709 mCacheMinValues[attributeIndex] = value;
710 }
711 if ( QgsVariantUtils::isNull( mCacheMaxValues[attributeIndex] ) || value > mCacheMaxValues[attributeIndex].toString() )
712 {
713 mCacheMaxValues[attributeIndex] = value;
714 }
715 break;
716 }
717 }
718 }
719 }
720
721 mCacheMinMaxDirty = false;
722}
723
724QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, const QString &value )
725{
726 QVariant v( value );
727
728 if ( !v.convert( type ) || value.isNull() )
729 v = QVariant( type );
730
731 return v;
732}
733
735{
737
738 return nullptr;
739}
740
741static bool _compareEncodings( const QString &s1, const QString &s2 )
742{
743 return s1.toLower() < s2.toLower();
744}
745
747{
748 static std::once_flag initialized;
749 std::call_once( initialized, [ = ]
750 {
751 const auto codecs { QTextCodec::availableCodecs() };
752 for ( const QByteArray &codec : codecs )
753 {
754 sEncodings << codec;
755 }
756#if 0
757 smEncodings << "BIG5";
758 smEncodings << "BIG5-HKSCS";
759 smEncodings << "EUCJP";
760 smEncodings << "EUCKR";
761 smEncodings << "GB2312";
762 smEncodings << "GBK";
763 smEncodings << "GB18030";
764 smEncodings << "JIS7";
765 smEncodings << "SHIFT-JIS";
766 smEncodings << "TSCII";
767 smEncodings << "UTF-8";
768 smEncodings << "UTF-16";
769 smEncodings << "KOI8-R";
770 smEncodings << "KOI8-U";
771 smEncodings << "ISO8859-1";
772 smEncodings << "ISO8859-2";
773 smEncodings << "ISO8859-3";
774 smEncodings << "ISO8859-4";
775 smEncodings << "ISO8859-5";
776 smEncodings << "ISO8859-6";
777 smEncodings << "ISO8859-7";
778 smEncodings << "ISO8859-8";
779 smEncodings << "ISO8859-8-I";
780 smEncodings << "ISO8859-9";
781 smEncodings << "ISO8859-10";
782 smEncodings << "ISO8859-11";
783 smEncodings << "ISO8859-12";
784 smEncodings << "ISO8859-13";
785 smEncodings << "ISO8859-14";
786 smEncodings << "ISO8859-15";
787 smEncodings << "IBM 850";
788 smEncodings << "IBM 866";
789 smEncodings << "CP874";
790 smEncodings << "CP1250";
791 smEncodings << "CP1251";
792 smEncodings << "CP1252";
793 smEncodings << "CP1253";
794 smEncodings << "CP1254";
795 smEncodings << "CP1255";
796 smEncodings << "CP1256";
797 smEncodings << "CP1257";
798 smEncodings << "CP1258";
799 smEncodings << "Apple Roman";
800 smEncodings << "TIS-620";
801 smEncodings << "System";
802#endif
803
804 // Do case-insensitive sorting of encodings
805 std::sort( sEncodings.begin(), sEncodings.end(), _compareEncodings );
806
807 } );
808
809 return sEncodings;
810}
811
813{
815
816 mErrors.clear();
817}
818
820{
822
823 return !mErrors.isEmpty();
824}
825
827{
829
830 return mErrors;
831}
832
834{
836
837 return false;
838}
839
841{
843
844 return false;
845}
846
848{
850
851 return nullptr;
852}
853
855{
857
858 return nullptr;
859}
860
861void QgsVectorDataProvider::pushError( const QString &msg ) const
862{
864
865 QgsDebugMsg( msg );
866 mErrors << msg;
867 emit raiseError( msg );
868}
869
870QSet<QgsMapLayerDependency> QgsVectorDataProvider::dependencies() const
871{
873
874 return QSet<QgsMapLayerDependency>();
875}
876
878{
880
881 if ( geom.isNull() )
882 {
883 return QgsGeometry();
884 }
885
886 const QgsAbstractGeometry *geometry = geom.constGet();
887 if ( !geometry )
888 {
889 return QgsGeometry();
890 }
891
892 const Qgis::WkbType providerGeomType = wkbType();
893
894 //geom is already in the provider geometry type
895 if ( geometry->wkbType() == providerGeomType )
896 {
897 return QgsGeometry();
898 }
899
900 std::unique_ptr< QgsAbstractGeometry > outputGeom;
901
902 //convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
903 if ( QgsWkbTypes::flatType( providerGeomType ) == Qgis::WkbType::CircularString )
904 {
905 QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( geometry );
906 if ( compoundCurve )
907 {
908 if ( compoundCurve->nCurves() == 1 )
909 {
910 const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( compoundCurve->curveAt( 0 ) );
911 if ( circularString )
912 {
913 outputGeom.reset( circularString->clone() );
914 }
915 }
916 }
917 }
918
919 //convert to curved type if necessary
920 if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) )
921 {
922 QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : geometry->toCurveType();
923 if ( curveGeom )
924 {
925 outputGeom.reset( curveGeom );
926 }
927 }
928
929 //convert to linear type from curved type
930 if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) )
931 {
932 QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
933 if ( segmentizedGeom )
934 {
935 outputGeom.reset( segmentizedGeom );
936 }
937 }
938
939 //convert to multitype if necessary
940 if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
941 {
942 std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) );
943 QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
944 if ( geomCollection )
945 {
946 if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) )
947 {
948 outputGeom.reset( collGeom.release() );
949 }
950 }
951 }
952
953 //convert to single type if there's a single part of compatible type
954 if ( !QgsWkbTypes::isMultiType( providerGeomType ) && QgsWkbTypes::isMultiType( geometry->wkbType() ) )
955 {
956 const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry );
957 if ( collection )
958 {
959 if ( collection->numGeometries() == 1 )
960 {
961 const QgsAbstractGeometry *firstGeom = collection->geometryN( 0 );
962 if ( firstGeom && firstGeom->wkbType() == providerGeomType )
963 {
964 outputGeom.reset( firstGeom->clone() );
965 }
966 }
967 }
968 }
969
970 //set z/m types
971 if ( QgsWkbTypes::hasZ( providerGeomType ) )
972 {
973 if ( !outputGeom )
974 {
975 outputGeom.reset( geometry->clone() );
976 }
977 outputGeom->addZValue();
978 }
979
980 if ( QgsWkbTypes::hasM( providerGeomType ) )
981 {
982 if ( !outputGeom )
983 {
984 outputGeom.reset( geometry->clone() );
985 }
986 outputGeom->addMValue();
987 }
988
989 if ( outputGeom )
990 {
991 return QgsGeometry( outputGeom.release() );
992 }
993
994 return QgsGeometry();
995}
996
997void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes )
998{
1000
1001 mNativeTypes = nativeTypes;
1002}
1003
1005{
1006 // non fatal for now -- the "rasterize" processing algorithm is not thread safe and calls this
1008
1009 return mEncoding;
1010}
1011
1013{
1015
1016 return false;
1017}
1018
1019QStringList QgsVectorDataProvider::sEncodings;
1020
1021QList<QgsRelation> QgsVectorDataProvider::discoverRelations( const QgsVectorLayer *, const QList<QgsVectorLayer *> & ) const
1022{
1024
1025 return QList<QgsRelation>();
1026}
1027
1029{
1031
1032}
1033
1035{
1037
1038 return mTemporalCapabilities.get();
1039}
1040
1042{
1044
1045 return mTemporalCapabilities.get();
1046}
@ SqlQuery
SQL query layer.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:155
@ CircularString
CircularString.
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.
Qgis::WkbType wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
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:59
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:338
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.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:52
QString name
Definition: qgsfield.h:61
int precision
Definition: qgsfield.h:58
int length
Definition: qgsfield.h:57
QVariant::Type type
Definition: qgsfield.h:59
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:386
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:359
Geometry collection.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(Qgis::WkbType t)
Returns empty geometry from wkb type.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
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:166
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...
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
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.
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.
Qgis::WkbType wkbType() const override=0
Returns the geometry type which is returned by this layer.
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(Qgis::WkbType type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:759
static bool hasZ(Qgis::WkbType type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:977
static bool isCurvedType(Qgis::WkbType type) SIP_HOLDGIL
Returns true if the WKB type is a curved type or can contain curved geometries.
Definition: qgswkbtypes.h:808
static bool hasM(Qgis::WkbType type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1027
static Qgis::WkbType flatType(Qgis::WkbType type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:629
QMap< int, QString > QgsFieldNameMap
Definition: qgsattributes.h:45
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:915
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:906
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:920
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QList< int > QgsAttributeList
Definition: qgsfield.h:26
const QgsField & field
Definition: qgsfield.h:501
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
QSet< int > QgsAttributeIds
QHash< int, QString > QgsAttrPalIndexNameHash
A bundle of parameters controlling aggregate calculation.
Setting options for creating vector data providers.