Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgscachedfeatureiterator.cpp 3 : : -------------------------------------- 4 : : Date : 12.2.2013 5 : : Copyright : (C) 2013 Matthias Kuhn 6 : : Email : matthias at opengis dot ch 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 "qgscachedfeatureiterator.h" 17 : : #include "qgsvectorlayercache.h" 18 : : #include "qgsexception.h" 19 : : #include "qgsvectorlayer.h" 20 : : 21 : 0 : QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest ) 22 : 0 : : QgsAbstractFeatureIterator( featureRequest ) 23 : 0 : , mVectorLayerCache( vlCache ) 24 : 0 : { 25 : 0 : if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() ) 26 : : { 27 : 0 : mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() ); 28 : 0 : } 29 : : try 30 : : { 31 : 0 : mFilterRect = filterRectToSourceCrs( mTransform ); 32 : 0 : } 33 : : catch ( QgsCsException & ) 34 : : { 35 : : // can't reproject mFilterRect 36 : 0 : close(); 37 : : return; 38 : 0 : } 39 : 0 : if ( !mFilterRect.isNull() ) 40 : : { 41 : : // update request to be the unprojected filter rect 42 : 0 : mRequest.setFilterRect( mFilterRect ); 43 : 0 : } 44 : : 45 : 0 : switch ( featureRequest.filterType() ) 46 : : { 47 : : case QgsFeatureRequest::FilterFids: 48 : 0 : mFeatureIds = featureRequest.filterFids(); 49 : 0 : break; 50 : : 51 : : case QgsFeatureRequest::FilterFid: 52 : 0 : mFeatureIds = QgsFeatureIds() << featureRequest.filterFid(); 53 : 0 : break; 54 : : 55 : : default: 56 : 0 : mFeatureIds = qgis::listToSet( mVectorLayerCache->mCache.keys() ); 57 : 0 : break; 58 : : } 59 : : 60 : 0 : mFeatureIdIterator = mFeatureIds.constBegin(); 61 : : 62 : 0 : if ( mFeatureIdIterator == mFeatureIds.constEnd() ) 63 : 0 : close(); 64 : 0 : } 65 : : 66 : 0 : bool QgsCachedFeatureIterator::fetchFeature( QgsFeature &f ) 67 : : { 68 : 0 : f.setValid( false ); 69 : : 70 : 0 : if ( mClosed ) 71 : 0 : return false; 72 : : 73 : 0 : while ( mFeatureIdIterator != mFeatureIds.constEnd() ) 74 : : { 75 : 0 : if ( !mVectorLayerCache->mCache.contains( *mFeatureIdIterator ) ) 76 : : { 77 : 0 : ++mFeatureIdIterator; 78 : 0 : continue; 79 : : } 80 : : 81 : 0 : f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() ); 82 : 0 : ++mFeatureIdIterator; 83 : 0 : if ( mRequest.acceptFeature( f ) ) 84 : : { 85 : 0 : f.setValid( true ); 86 : 0 : geometryToDestinationCrs( f, mTransform ); 87 : 0 : return true; 88 : : } 89 : : } 90 : 0 : close(); 91 : 0 : return false; 92 : 0 : } 93 : : 94 : 0 : bool QgsCachedFeatureIterator::rewind() 95 : : { 96 : 0 : mFeatureIdIterator = mFeatureIds.constBegin(); 97 : 0 : return true; 98 : : } 99 : : 100 : 0 : bool QgsCachedFeatureIterator::close() 101 : : { 102 : 0 : mClosed = true; 103 : 0 : mFeatureIds.clear(); 104 : 0 : return true; 105 : : } 106 : : 107 : 0 : QgsCachedFeatureWriterIterator::QgsCachedFeatureWriterIterator( QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest ) 108 : 0 : : QgsAbstractFeatureIterator( featureRequest ) 109 : 0 : , mVectorLayerCache( vlCache ) 110 : 0 : { 111 : 0 : if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() ) 112 : : { 113 : 0 : mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs(), mRequest.transformContext() ); 114 : 0 : } 115 : : try 116 : : { 117 : 0 : mFilterRect = filterRectToSourceCrs( mTransform ); 118 : 0 : } 119 : : catch ( QgsCsException & ) 120 : : { 121 : : // can't reproject mFilterRect 122 : 0 : close(); 123 : : return; 124 : 0 : } 125 : 0 : if ( !mFilterRect.isNull() ) 126 : : { 127 : : // update request to be the unprojected filter rect 128 : 0 : mRequest.setFilterRect( mFilterRect ); 129 : 0 : } 130 : : 131 : 0 : mFeatIt = vlCache->layer()->getFeatures( mRequest ); 132 : 0 : } 133 : : 134 : 0 : bool QgsCachedFeatureWriterIterator::fetchFeature( QgsFeature &f ) 135 : : { 136 : 0 : if ( mClosed ) 137 : : { 138 : 0 : f.setValid( false ); 139 : 0 : return false; 140 : : } 141 : 0 : if ( mFeatIt.nextFeature( f ) ) 142 : : { 143 : : // As long as features can be fetched from the provider: Write them to cache 144 : 0 : mVectorLayerCache->cacheFeature( f ); 145 : 0 : mFids.insert( f.id() ); 146 : 0 : geometryToDestinationCrs( f, mTransform ); 147 : 0 : return true; 148 : : } 149 : : else 150 : : { 151 : : // Once no more features can be fetched: Inform the cache, that 152 : : // the request has been completed 153 : 0 : mVectorLayerCache->requestCompleted( mRequest, mFids ); 154 : 0 : return false; 155 : : } 156 : 0 : } 157 : : 158 : 0 : bool QgsCachedFeatureWriterIterator::rewind() 159 : : { 160 : 0 : mFids.clear(); 161 : 0 : return mFeatIt.rewind(); 162 : : } 163 : : 164 : 0 : bool QgsCachedFeatureWriterIterator::close() 165 : : { 166 : 0 : mClosed = true; 167 : 0 : return mFeatIt.close(); 168 : : }