Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsfeaturesource.cpp 3 : : ------------------- 4 : : begin : May 2017 5 : : copyright : (C) 2017 by Nyall Dawson 6 : : email : nyall dot dawson at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #include "qgsfeaturesource.h" 19 : : #include "qgsfeaturerequest.h" 20 : : #include "qgsfeatureiterator.h" 21 : : #include "qgsmemoryproviderutils.h" 22 : : #include "qgsfeedback.h" 23 : : #include "qgsvectorlayer.h" 24 : : #include "qgsvectordataprovider.h" 25 : : 26 : 0 : QgsFeatureSource::FeatureAvailability QgsFeatureSource::hasFeatures() const 27 : : { 28 : 0 : return FeaturesMaybeAvailable; 29 : : } 30 : : 31 : 0 : QSet<QVariant> QgsFeatureSource::uniqueValues( int fieldIndex, int limit ) const 32 : : { 33 : 0 : if ( fieldIndex < 0 || fieldIndex >= fields().count() ) 34 : 0 : return QSet<QVariant>(); 35 : : 36 : 0 : QgsFeatureRequest req; 37 : 0 : req.setFlags( QgsFeatureRequest::NoGeometry ); 38 : 0 : req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex ); 39 : : 40 : 0 : QSet<QVariant> values; 41 : 0 : QgsFeatureIterator it = getFeatures( req ); 42 : 0 : QgsFeature f; 43 : 0 : while ( it.nextFeature( f ) ) 44 : : { 45 : 0 : values.insert( f.attribute( fieldIndex ) ); 46 : 0 : if ( limit > 0 && values.size() >= limit ) 47 : 0 : return values; 48 : : } 49 : 0 : return values; 50 : 0 : } 51 : : 52 : 0 : QVariant QgsFeatureSource::minimumValue( int fieldIndex ) const 53 : : { 54 : 0 : if ( fieldIndex < 0 || fieldIndex >= fields().count() ) 55 : 0 : return QVariant(); 56 : : 57 : 0 : QgsFeatureRequest req; 58 : 0 : req.setFlags( QgsFeatureRequest::NoGeometry ); 59 : 0 : req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex ); 60 : : 61 : 0 : QVariant min; 62 : 0 : QgsFeatureIterator it = getFeatures( req ); 63 : 0 : QgsFeature f; 64 : 0 : while ( it.nextFeature( f ) ) 65 : : { 66 : 0 : QVariant v = f.attribute( fieldIndex ); 67 : 0 : if ( !v.isNull() && ( qgsVariantLessThan( v, min ) || min.isNull() ) ) 68 : : { 69 : 0 : min = v; 70 : 0 : } 71 : 0 : } 72 : 0 : return min; 73 : 0 : } 74 : : 75 : 0 : QVariant QgsFeatureSource::maximumValue( int fieldIndex ) const 76 : : { 77 : 0 : if ( fieldIndex < 0 || fieldIndex >= fields().count() ) 78 : 0 : return QVariant(); 79 : : 80 : 0 : QgsFeatureRequest req; 81 : 0 : req.setFlags( QgsFeatureRequest::NoGeometry ); 82 : 0 : req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex ); 83 : : 84 : 0 : QVariant max; 85 : 0 : QgsFeatureIterator it = getFeatures( req ); 86 : 0 : QgsFeature f; 87 : 0 : while ( it.nextFeature( f ) ) 88 : : { 89 : 0 : QVariant v = f.attribute( fieldIndex ); 90 : 0 : if ( !v.isNull() && ( qgsVariantGreaterThan( v, max ) || max.isNull() ) ) 91 : : { 92 : 0 : max = v; 93 : 0 : } 94 : 0 : } 95 : 0 : return max; 96 : 0 : } 97 : : 98 : 0 : QgsRectangle QgsFeatureSource::sourceExtent() const 99 : : { 100 : 0 : QgsRectangle r; 101 : : 102 : 0 : QgsFeatureRequest req; 103 : 0 : req.setNoAttributes(); 104 : : 105 : 0 : QgsFeatureIterator it = getFeatures( req ); 106 : 0 : QgsFeature f; 107 : 0 : while ( it.nextFeature( f ) ) 108 : : { 109 : 0 : if ( f.hasGeometry() ) 110 : 0 : r.combineExtentWith( f.geometry().boundingBox() ); 111 : : } 112 : : return r; 113 : 0 : } 114 : : 115 : 0 : QgsFeatureIds QgsFeatureSource::allFeatureIds() const 116 : : { 117 : 0 : QgsFeatureIterator fit = getFeatures( QgsFeatureRequest() 118 : 0 : .setFlags( QgsFeatureRequest::NoGeometry ) 119 : 0 : .setNoAttributes() ); 120 : : 121 : 0 : QgsFeatureIds ids; 122 : : 123 : 0 : QgsFeature fet; 124 : 0 : while ( fit.nextFeature( fet ) ) 125 : : { 126 : 0 : ids << fet.id(); 127 : : } 128 : : 129 : 0 : return ids; 130 : 0 : } 131 : : 132 : 0 : QgsVectorLayer *QgsFeatureSource::materialize( const QgsFeatureRequest &request, QgsFeedback *feedback ) 133 : : { 134 : 0 : QgsWkbTypes::Type outWkbType = ( request.flags() & QgsFeatureRequest::NoGeometry ) ? QgsWkbTypes::NoGeometry : wkbType(); 135 : 0 : QgsCoordinateReferenceSystem crs = request.destinationCrs().isValid() ? request.destinationCrs() : sourceCrs(); 136 : : 137 : 0 : QgsAttributeList requestedAttrs = request.subsetOfAttributes(); 138 : : 139 : 0 : QgsFields outFields; 140 : 0 : if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) 141 : : { 142 : 0 : int i = 0; 143 : 0 : const QgsFields sourceFields = fields(); 144 : 0 : for ( const QgsField &field : sourceFields ) 145 : : { 146 : 0 : if ( requestedAttrs.contains( i ) ) 147 : 0 : outFields.append( field ); 148 : 0 : i++; 149 : : } 150 : 0 : } 151 : : else 152 : : { 153 : 0 : outFields = fields(); 154 : : } 155 : : 156 : 0 : std::unique_ptr< QgsVectorLayer > layer( QgsMemoryProviderUtils::createMemoryLayer( 157 : 0 : sourceName(), 158 : : outFields, 159 : 0 : outWkbType, 160 : : crs ) ); 161 : 0 : QgsFeature f; 162 : 0 : QgsFeatureIterator it = getFeatures( request ); 163 : 0 : int fieldCount = fields().count(); 164 : 0 : while ( it.nextFeature( f ) ) 165 : : { 166 : 0 : if ( feedback && feedback->isCanceled() ) 167 : 0 : break; 168 : : 169 : 0 : if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) 170 : : { 171 : : // remove unused attributes 172 : 0 : QgsAttributes attrs; 173 : 0 : for ( int i = 0; i < fieldCount; ++i ) 174 : : { 175 : 0 : if ( requestedAttrs.contains( i ) ) 176 : : { 177 : 0 : attrs.append( f.attributes().at( i ) ); 178 : 0 : } 179 : 0 : } 180 : : 181 : 0 : f.setAttributes( attrs ); 182 : 0 : } 183 : : 184 : 0 : layer->dataProvider()->addFeature( f, QgsFeatureSink::FastInsert ); 185 : : } 186 : : 187 : 0 : return layer.release(); 188 : 0 : } 189 : : 190 : 0 : QgsFeatureSource::SpatialIndexPresence QgsFeatureSource::hasSpatialIndex() const 191 : : { 192 : 0 : return SpatialIndexUnknown; 193 : : } 194 : :