QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
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
74
75Qgis::VectorLayerTypeFlags QgsVectorDataProvider::vectorLayerTypeFlags() const
76{
78
79 return Qgis::VectorLayerTypeFlags();
80}
81
91
98
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
247
249{
251
252 Q_UNUSED( field )
253 return true;
254}
255
256QgsVectorDataProvider::Capabilities QgsVectorDataProvider::capabilities() const
257{
259
261}
262
264{
266
267 // Use UTF-8 if no encoding is specified
268 if ( e.isEmpty() )
269 {
270 mEncoding = QTextCodec::codecForName( "UTF-8" );
271 }
272 else
273 {
274 mEncoding = QTextCodec::codecForName( e.toLocal8Bit().constData() );
275 }
276 if ( !mEncoding && e != QLatin1String( "System" ) )
277 {
278 if ( !e.isEmpty() )
279 {
280 // can we use the OGR proxy codec?
281 if ( QgsOgrProxyTextCodec::supportedCodecs().contains( e, Qt::CaseInsensitive ) )
282 {
283 //from the Qt docs (https://doc.qt.io/qt-5/qtextcodec.html#QTextCodec-1)
284 // "The QTextCodec should always be constructed on the heap (i.e. with new).
285 // Qt takes ownership and will delete it when the application terminates."
286 mEncoding = new QgsOgrProxyTextCodec( e.toLocal8Bit() );
287 }
288 else
289 {
290 QgsMessageLog::logMessage( tr( "Codec %1 not found. Falling back to system locale" ).arg( e ) );
291 mEncoding = QTextCodec::codecForName( "System" );
292 }
293 }
294 }
295
296 if ( !mEncoding )
297 mEncoding = QTextCodec::codecForLocale();
298
299 Q_ASSERT( mEncoding );
300}
301
303{
305
306 if ( mEncoding )
307 {
308 return mEncoding->name();
309 }
310
311 return QString();
312}
313
315{
317
318 QStringList abilitiesList;
319
320 const int abilities = capabilities();
321
322 if ( abilities & QgsVectorDataProvider::AddFeatures )
323 {
324 abilitiesList += tr( "Add Features" );
325 }
326
328 {
329 abilitiesList += tr( "Delete Features" );
330 }
331
333 {
334 abilitiesList += tr( "Change Attribute Values" );
335 }
336
337 if ( abilities & QgsVectorDataProvider::AddAttributes )
338 {
339 abilitiesList += tr( "Add Attributes" );
340 }
341
343 {
344 abilitiesList += tr( "Delete Attributes" );
345 }
346
348 {
349 abilitiesList += tr( "Rename Attributes" );
350 }
351
353 {
354 // TODO: Tighten up this test. See QgsOgrProvider for details.
355 abilitiesList += tr( "Create Spatial Index" );
356 }
357
359 {
360 abilitiesList += tr( "Create Attribute Indexes" );
361 }
362
363 if ( abilities & QgsVectorDataProvider::SelectAtId )
364 {
365 abilitiesList += tr( "Fast Access to Features at ID" );
366 }
367
369 {
370 abilitiesList += tr( "Change Geometries" );
371 }
372
374 {
375 abilitiesList += tr( "Presimplify Geometries" );
376 }
377
379 {
380 abilitiesList += tr( "Presimplify Geometries with Validity Check" );
381 }
382
384 {
385 abilitiesList += tr( "Simultaneous Geometry and Attribute Updates" );
386 }
387
389 {
390 abilitiesList += tr( "Transactions" );
391 }
392
394 {
395 abilitiesList += tr( "Curved Geometries" );
396 }
397
399 {
400 abilitiesList += tr( "Feature Symbology" );
401 }
402
403 return abilitiesList.join( QLatin1String( ", " ) );
404}
405
406Qgis::VectorDataProviderAttributeEditCapabilities QgsVectorDataProvider::attributeEditCapabilities() const
407{
408 return Qgis::VectorDataProviderAttributeEditCapabilities();
409}
410
411int QgsVectorDataProvider::fieldNameIndex( const QString &fieldName ) const
412{
414
415 return fields().lookupField( fieldName );
416}
417
418QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
419{
421
422 QMap<QString, int> resultMap;
423
424 const QgsFields fieldsCopy = fields();
425 for ( int i = 0; i < fieldsCopy.count(); ++i )
426 {
427 resultMap.insert( fieldsCopy.at( i ).name(), i );
428 }
429
430 return resultMap;
431}
432
439
446
447QList<QgsVectorDataProvider::NativeType> QgsVectorDataProvider::nativeTypes() const
448{
450
451 return mNativeTypes;
452}
453
460
462{
464
465 QgsDebugMsgLevel( QStringLiteral( "field name = %1 type = %2 length = %3 precision = %4" )
466 .arg( field.name(),
467 QVariant::typeToName( field.type() ) )
468 .arg( field.length() )
469 .arg( field.precision() ), 2 );
470
471 for ( const NativeType &nativeType : mNativeTypes )
472 {
473 QgsDebugMsgLevel( QStringLiteral( "native field type = %1 min length = %2 max length = %3 min precision = %4 max precision = %5" )
474 .arg( QVariant::typeToName( nativeType.mType ) )
475 .arg( nativeType.mMinLen )
476 .arg( nativeType.mMaxLen )
477 .arg( nativeType.mMinPrec )
478 .arg( nativeType.mMaxPrec ), 2 );
479
480 if ( field.type() != nativeType.mType )
481 continue;
482
483 if ( field.length() > 0 )
484 {
485 // source length limited
486 if ( ( nativeType.mMinLen > 0 && field.length() < nativeType.mMinLen ) ||
487 ( nativeType.mMaxLen > 0 && field.length() > nativeType.mMaxLen ) )
488 {
489 // source length exceeds destination limits
490 continue;
491 }
492 }
493
494 if ( field.precision() > 0 )
495 {
496 // source precision limited
497 if ( ( nativeType.mMinPrec > 0 && field.precision() < nativeType.mMinPrec ) ||
498 ( nativeType.mMaxPrec > 0 && field.precision() > nativeType.mMaxPrec ) )
499 {
500 // source precision exceeds destination limits
501 continue;
502 }
503 }
504
505 QgsDebugMsgLevel( QStringLiteral( "native type matches" ), 3 );
506 return true;
507 }
508
509 QgsDebugError( QStringLiteral( "no sufficient native type found" ) );
510 return false;
511}
512
513QVariant QgsVectorDataProvider::minimumValue( int index ) const
514{
516
517 if ( index < 0 || index >= fields().count() )
518 {
519 QgsDebugError( "Warning: access requested to invalid field index: " + QString::number( index ) );
520 return QVariant();
521 }
522
524
525 if ( !mCacheMinValues.contains( index ) )
526 return QVariant();
527
528 return mCacheMinValues[index];
529}
530
531QVariant QgsVectorDataProvider::maximumValue( int index ) const
532{
534
535 if ( index < 0 || index >= fields().count() )
536 {
537 QgsDebugError( "Warning: access requested to invalid field index: " + QString::number( index ) );
538 return QVariant();
539 }
540
542
543 if ( !mCacheMaxValues.contains( index ) )
544 return QVariant();
545
546 return mCacheMaxValues[index];
547}
548
549QStringList QgsVectorDataProvider::uniqueStringsMatching( int index, const QString &substring, int limit, QgsFeedback *feedback ) const
550{
552
553 QStringList results;
554
555 // Safety belt
556 if ( index < 0 || index >= fields().count() )
557 return results;
558
559 QgsFeature f;
560 QgsAttributeList keys;
561 keys.append( index );
562
563 QgsFeatureRequest request;
564 request.setSubsetOfAttributes( keys );
566 const QString fieldName = fields().at( index ).name();
567 request.setFilterExpression( QStringLiteral( "\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
568 QgsFeatureIterator fi = getFeatures( request );
569
570 QSet<QString> set;
571
572 while ( fi.nextFeature( f ) )
573 {
574 const QString value = f.attribute( index ).toString();
575 if ( !set.contains( value ) )
576 {
577 results.append( value );
578 set.insert( value );
579 }
580
581 if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->isCanceled() ) )
582 break;
583 }
584 return results;
585}
586
588 const QgsAggregateCalculator::AggregateParameters &parameters, QgsExpressionContext *context, bool &ok, QgsFeatureIds *fids ) const
589{
590 // non fatal for now -- the "aggregate" functions are not thread safe and call this
592
593 //base implementation does nothing
594 Q_UNUSED( aggregate )
595 Q_UNUSED( index )
596 Q_UNUSED( parameters )
597 Q_UNUSED( context )
598 Q_UNUSED( fids )
599
600 ok = false;
601 return QVariant();
602}
603
605{
607
608 mCacheMinMaxDirty = true;
609 mCacheMinValues.clear();
610 mCacheMaxValues.clear();
611}
612
614{
616
617 if ( !mCacheMinMaxDirty )
618 return;
619
620 const QgsFields flds = fields();
621 for ( int i = 0; i < flds.count(); ++i )
622 {
623 if ( flds.at( i ).type() == QVariant::Int )
624 {
625 mCacheMinValues[i] = QVariant( std::numeric_limits<int>::max() );
626 mCacheMaxValues[i] = QVariant( std::numeric_limits<int>::lowest() );
627 }
628 else if ( flds.at( i ).type() == QVariant::LongLong )
629 {
630 mCacheMinValues[i] = QVariant( std::numeric_limits<qlonglong>::max() );
631 mCacheMaxValues[i] = QVariant( std::numeric_limits<qlonglong>::lowest() );
632 }
633 else if ( flds.at( i ).type() == QVariant::Double )
634 {
635 mCacheMinValues[i] = QVariant( std::numeric_limits<double>::max() );
636 mCacheMaxValues[i] = QVariant( std::numeric_limits<double>::lowest() );
637
638 }
639 else
640 {
641 mCacheMinValues[i] = QVariant();
642 mCacheMaxValues[i] = QVariant();
643 }
644 }
645
646 QgsFeature f;
647 const QgsAttributeList keys = mCacheMinValues.keys();
648 QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys )
649 .setFlags( QgsFeatureRequest::NoGeometry ) );
650
651 while ( fi.nextFeature( f ) )
652 {
653 const QgsAttributes attrs = f.attributes();
654 for ( const int attributeIndex : keys )
655 {
656 const QVariant &varValue = attrs.at( attributeIndex );
657
658 if ( QgsVariantUtils::isNull( varValue ) )
659 continue;
660
661 switch ( flds.at( attributeIndex ).type() )
662 {
663 case QVariant::Int:
664 {
665 const int value = varValue.toInt();
666 if ( value < mCacheMinValues[ attributeIndex ].toInt() )
667 mCacheMinValues[ attributeIndex ] = value;
668 if ( value > mCacheMaxValues[ attributeIndex ].toInt() )
669 mCacheMaxValues[ attributeIndex ] = value;
670 break;
671 }
672 case QVariant::LongLong:
673 {
674 const qlonglong value = varValue.toLongLong();
675 if ( value < mCacheMinValues[ attributeIndex ].toLongLong() )
676 mCacheMinValues[ attributeIndex ] = value;
677 if ( value > mCacheMaxValues[ attributeIndex ].toLongLong() )
678 mCacheMaxValues[ attributeIndex ] = value;
679 break;
680 }
681 case QVariant::Double:
682 {
683 const double value = varValue.toDouble();
684 if ( value < mCacheMinValues[ attributeIndex ].toDouble() )
685 mCacheMinValues[attributeIndex ] = value;
686 if ( value > mCacheMaxValues[ attributeIndex ].toDouble() )
687 mCacheMaxValues[ attributeIndex ] = value;
688 break;
689 }
690 case QVariant::DateTime:
691 {
692 const QDateTime value = varValue.toDateTime();
693 if ( value < mCacheMinValues[ attributeIndex ].toDateTime() || !mCacheMinValues[ attributeIndex ].isValid() )
694 mCacheMinValues[attributeIndex ] = value;
695 if ( value > mCacheMaxValues[ attributeIndex ].toDateTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
696 mCacheMaxValues[ attributeIndex ] = value;
697 break;
698 }
699 case QVariant::Date:
700 {
701 const QDate value = varValue.toDate();
702 if ( value < mCacheMinValues[ attributeIndex ].toDate() || !mCacheMinValues[ attributeIndex ].isValid() )
703 mCacheMinValues[attributeIndex ] = value;
704 if ( value > mCacheMaxValues[ attributeIndex ].toDate() || !mCacheMaxValues[ attributeIndex ].isValid() )
705 mCacheMaxValues[ attributeIndex ] = value;
706 break;
707 }
708 case QVariant::Time:
709 {
710 const QTime value = varValue.toTime();
711 if ( value < mCacheMinValues[ attributeIndex ].toTime() || !mCacheMinValues[ attributeIndex ].isValid() )
712 mCacheMinValues[attributeIndex ] = value;
713 if ( value > mCacheMaxValues[ attributeIndex ].toTime() || !mCacheMaxValues[ attributeIndex ].isValid() )
714 mCacheMaxValues[ attributeIndex ] = value;
715 break;
716 }
717 default:
718 {
719 const QString value = varValue.toString();
720 if ( QgsVariantUtils::isNull( mCacheMinValues[ attributeIndex ] ) || value < mCacheMinValues[attributeIndex ].toString() )
721 {
722 mCacheMinValues[attributeIndex] = value;
723 }
724 if ( QgsVariantUtils::isNull( mCacheMaxValues[attributeIndex] ) || value > mCacheMaxValues[attributeIndex].toString() )
725 {
726 mCacheMaxValues[attributeIndex] = value;
727 }
728 break;
729 }
730 }
731 }
732 }
733
734 mCacheMinMaxDirty = false;
735}
736
737QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, const QString &value )
738{
739 QVariant v( value );
740
741 if ( !v.convert( type ) || value.isNull() )
742 v = QVariant( type );
743
744 return v;
745}
746
753
754static bool _compareEncodings( const QString &s1, const QString &s2 )
755{
756 return s1.toLower() < s2.toLower();
757}
758
759static bool _removeDuplicateEncodings( const QString &s1, const QString &s2 )
760{
761 return s1.compare( s2, Qt::CaseInsensitive ) == 0;
762}
763
765{
766 static std::once_flag initialized;
767 std::call_once( initialized, [ = ]
768 {
769 const auto codecs { QTextCodec::availableCodecs() };
770 for ( const QByteArray &codec : codecs )
771 {
772 sEncodings << codec;
773 }
774#if 0
775 smEncodings << "BIG5";
776 smEncodings << "BIG5-HKSCS";
777 smEncodings << "EUCJP";
778 smEncodings << "EUCKR";
779 smEncodings << "GB2312";
780 smEncodings << "GBK";
781 smEncodings << "GB18030";
782 smEncodings << "JIS7";
783 smEncodings << "SHIFT-JIS";
784 smEncodings << "TSCII";
785 smEncodings << "UTF-8";
786 smEncodings << "UTF-16";
787 smEncodings << "KOI8-R";
788 smEncodings << "KOI8-U";
789 smEncodings << "ISO8859-1";
790 smEncodings << "ISO8859-2";
791 smEncodings << "ISO8859-3";
792 smEncodings << "ISO8859-4";
793 smEncodings << "ISO8859-5";
794 smEncodings << "ISO8859-6";
795 smEncodings << "ISO8859-7";
796 smEncodings << "ISO8859-8";
797 smEncodings << "ISO8859-8-I";
798 smEncodings << "ISO8859-9";
799 smEncodings << "ISO8859-10";
800 smEncodings << "ISO8859-11";
801 smEncodings << "ISO8859-12";
802 smEncodings << "ISO8859-13";
803 smEncodings << "ISO8859-14";
804 smEncodings << "ISO8859-15";
805 smEncodings << "IBM 850";
806 smEncodings << "IBM 866";
807 smEncodings << "CP874";
808 smEncodings << "CP1250";
809 smEncodings << "CP1251";
810 smEncodings << "CP1252";
811 smEncodings << "CP1253";
812 smEncodings << "CP1254";
813 smEncodings << "CP1255";
814 smEncodings << "CP1256";
815 smEncodings << "CP1257";
816 smEncodings << "CP1258";
817 smEncodings << "Apple Roman";
818 smEncodings << "TIS-620";
819 smEncodings << "System";
820#endif
821
822 // Do case-insensitive sorting of encodings then remove duplicates
823 std::sort( sEncodings.begin(), sEncodings.end(), _compareEncodings );
824 const auto last = std::unique( sEncodings.begin(), sEncodings.end(), _removeDuplicateEncodings );
825 sEncodings.erase( last, sEncodings.end() );
826
827 } );
828
829 return sEncodings;
830}
831
833{
835
836 mErrors.clear();
837}
838
840{
842
843 return !mErrors.isEmpty();
844}
845
847{
849
850 return mErrors;
851}
852
854{
856
857 return nullptr;
858}
859
861{
863
864 return nullptr;
865}
866
867void QgsVectorDataProvider::pushError( const QString &msg ) const
868{
870
871 QgsDebugError( msg );
872 mErrors << msg;
873 emit raiseError( msg );
874}
875
876QSet<QgsMapLayerDependency> QgsVectorDataProvider::dependencies() const
877{
879
880 return QSet<QgsMapLayerDependency>();
881}
882
891
892void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes )
893{
895
896 mNativeTypes = nativeTypes;
897}
898
900{
901 // non fatal for now -- the "rasterize" processing algorithm is not thread safe and calls this
903
904 return mEncoding;
905}
906
908{
909 if ( geometry.isNull() )
910 {
911 return QgsGeometry();
912 }
913
914 const QgsAbstractGeometry *convertedGeometry = geometry.constGet();
915 if ( !convertedGeometry )
916 {
917 return QgsGeometry();
918 }
919
920
921 //geom is already in the provider geometry type
922 if ( convertedGeometry->wkbType() == providerGeometryType )
923 {
924 return QgsGeometry();
925 }
926
927 std::unique_ptr< QgsAbstractGeometry > outputGeom;
928
929 //convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
930 if ( QgsWkbTypes::flatType( providerGeometryType ) == Qgis::WkbType::CircularString )
931 {
932 QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( convertedGeometry );
933 if ( compoundCurve )
934 {
935 if ( compoundCurve->nCurves() == 1 )
936 {
937 const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( compoundCurve->curveAt( 0 ) );
938 if ( circularString )
939 {
940 outputGeom.reset( circularString->clone() );
941 }
942 }
943 }
944 }
945
946 //convert to curved type if necessary
947 if ( !QgsWkbTypes::isCurvedType( convertedGeometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeometryType ) )
948 {
949 QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : convertedGeometry->toCurveType();
950 if ( curveGeom )
951 {
952 outputGeom.reset( curveGeom );
953 }
954 }
955
956 //convert to linear type from curved type
957 if ( QgsWkbTypes::isCurvedType( convertedGeometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeometryType ) )
958 {
959 QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : convertedGeometry->segmentize();
960 if ( segmentizedGeom )
961 {
962 outputGeom.reset( segmentizedGeom );
963 }
964 }
965
966 //convert to multitype if necessary
967 if ( QgsWkbTypes::isMultiType( providerGeometryType ) && !QgsWkbTypes::isMultiType( convertedGeometry->wkbType() ) )
968 {
969 std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeometryType ) );
970 QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
971 if ( geomCollection )
972 {
973 if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : convertedGeometry->clone() ) )
974 {
975 outputGeom.reset( collGeom.release() );
976 }
977 }
978 }
979
980 //convert to single type if there's a single part of compatible type
981 if ( !QgsWkbTypes::isMultiType( providerGeometryType ) && QgsWkbTypes::isMultiType( convertedGeometry->wkbType() ) )
982 {
983 const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( convertedGeometry );
984 if ( collection )
985 {
986 if ( collection->numGeometries() == 1 )
987 {
988 const QgsAbstractGeometry *firstGeom = collection->geometryN( 0 );
989 if ( firstGeom && firstGeom->wkbType() == providerGeometryType )
990 {
991 outputGeom.reset( firstGeom->clone() );
992 }
993 }
994 }
995 }
996
997 //set z/m types
998 if ( QgsWkbTypes::hasZ( providerGeometryType ) )
999 {
1000 if ( !outputGeom )
1001 {
1002 outputGeom.reset( convertedGeometry->clone() );
1003 }
1004 outputGeom->addZValue();
1005 }
1006
1007 if ( QgsWkbTypes::hasM( providerGeometryType ) )
1008 {
1009 if ( !outputGeom )
1010 {
1011 outputGeom.reset( convertedGeometry->clone() );
1012 }
1013 outputGeom->addMValue();
1014 }
1015
1016 if ( outputGeom )
1017 {
1018 return QgsGeometry( outputGeom.release() );
1019 }
1020
1021 return QgsGeometry();
1022}
1023
1025{
1027
1028 return false;
1029}
1030
1031QStringList QgsVectorDataProvider::sEncodings;
1032
1033QList<QgsRelation> QgsVectorDataProvider::discoverRelations( const QgsVectorLayer *, const QList<QgsVectorLayer *> & ) const
1034{
1036
1037 return QList<QgsRelation>();
1038}
1039
1045
1052
@ SqlQuery
SQL query layer.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:182
@ 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
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.
Circular string geometry type.
QgsCircularString * clone() const override
Clones the geometry by performing a deep copy.
Compound curve geometry type.
int nCurves() const
Returns the number of curves in the geometry.
const QgsCurve * curveAt(int i) const
Returns the curve at the specified index.
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 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.
@ NoFeaturesAvailable
There are certainly no features available in this source.
@ FeaturesAvailable
There is at least one feature available in this source.
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
QgsFeatureId id
Definition qgsfeature.h:64
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
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.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
QString name
Definition qgsfield.h:62
int precision
Definition qgsfield.h:59
int length
Definition qgsfield.h:58
QVariant::Type type
Definition qgsfield.h:60
Container of fields for a vector layer.
Definition qgsfields.h:45
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
int numGeometries() const
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.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(Qgis::WkbType t)
Returns empty geometry from wkb type.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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.
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 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).
Q_DECL_DEPRECATED 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 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...
virtual Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the provider's supported attribute editing capabilities.
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)
Returns true if the WKB type is a multi type.
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QMap< int, QString > QgsFieldNameMap
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
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugError(str)
Definition qgslogger.h:38
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
QList< int > QgsAttributeList
QSet< int > QgsAttributeIds
QHash< int, QString > QgsAttrPalIndexNameHash
A bundle of parameters controlling aggregate calculation.
Setting options for creating vector data providers.