bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature &feature ) const { feature.setValid( false ); gdal::ogr_feature_unique_ptr fet; #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) if ( !QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers( mSource->mDriverName ) ) { OGRLayerH nextFeatureBelongingLayer; bool found = false; // First pass: try to read from the last feature, in the hope the dataset // returns them in increasing feature id number (and as we use a std::set // for mFilterFids, we get them in increasing number by the iterator) // Second pass: reset before reading for ( int passNumber = 0; passNumber < 2; passNumber++ ) { while ( fet.reset( GDALDatasetGetNextFeature( mConn->ds, &nextFeatureBelongingLayer, nullptr, nullptr, nullptr ) ), fet ) { if ( nextFeatureBelongingLayer == mOgrLayer ) { if ( OGR_F_GetFID( fet.get() ) == FID_TO_NUMBER( id ) ) { found = true; break; } } } if ( found || passNumber == 1 ) { break; } GDALDatasetResetReading( mConn->ds ); } if ( !found ) { return false; } } else #endif { fet.reset( OGR_L_GetFeature( mOgrLayer, FID_TO_NUMBER( id ) ) ); } if ( !fet ) { return false; } if ( !readFeature( std::move( fet ), feature ) ) return false; feature.setValid( true ); geometryToDestinationCrs( feature, mTransform ); return true; }
bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature& feature ) const { feature.setValid( false ); OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( id ) ); if ( !fet ) { return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); return true; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; if ( !mRequest.filterRect().isNull() && !feature.constGeometry() ) continue; // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while close(); return false; }
bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } // skip features without geometry if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom ) { OGR_F_Destroy( fet ); close(); return false; } readFeature( fet, feature ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; QgsRectangle selectionRect; while (( fet = OGR_L_GetNextFeature( P->ogrLayer ) ) ) { // skip features without geometry if ( !P->mFetchFeaturesWithoutGeom && !OGR_F_GetGeometryRef( fet ) ) { OGR_F_Destroy( fet ); continue; } readFeature( fet, feature ); if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) { //precise test for intersection with search rectangle //first make QgsRectangle from OGRPolygon OGREnvelope env; memset( &env, 0, sizeof( env ) ); if ( mSelectionRectangle ) OGR_G_GetEnvelope( mSelectionRectangle, &env ); if ( env.MinX != 0 || env.MinY != 0 || env.MaxX != 0 || env.MaxY != 0 ) //if envelope is invalid, skip the precise intersection test { selectionRect.set( env.MinX, env.MinY, env.MaxX, env.MaxY ); if ( !feature.geometry() || !feature.geometry()->intersects( selectionRect ) ) { OGR_F_Destroy( fet ); continue; } } } // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }