Skip to content

Commit

Permalink
Fixes #16759 - ensures OSM layers use OGR random layer read/write
Browse files Browse the repository at this point in the history
To guarantee all features are rendered with large files
  • Loading branch information
stev-0 authored and nyalldawson committed Oct 3, 2018
1 parent 14b6843 commit f410b4a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
59 changes: 47 additions & 12 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -251,6 +251,20 @@ bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature &fea
return true;
}

bool QgsOgrFeatureIterator::checkFeature( gdal::ogr_feature_unique_ptr &fet, QgsFeature &feature )
{
if ( !readFeature( std::move( fet ), feature ) )
return false;

if ( !mFilterRect.isNull() && ( !feature.hasGeometry() || feature.geometry().isEmpty() ) )
return false;

// we have a feature, end this cycle
feature.setValid( true );
geometryToDestinationCrs( feature, mTransform );
return true;
}

bool QgsOgrFeatureIterator::fetchFeature( QgsFeature &feature )
{
QMutexLocker locker( mSharedDS ? &mSharedDS->mutex() : nullptr );
Expand Down Expand Up @@ -282,20 +296,41 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature &feature )

gdal::ogr_feature_unique_ptr fet;

while ( fet.reset( OGR_L_GetNextFeature( mOgrLayer ) ), fet )
{
if ( !readFeature( std::move( fet ), feature ) )
continue;

if ( !mFilterRect.isNull() && ( !feature.hasGeometry() || feature.geometry().isEmpty() ) )
continue;
// OSM layers (especially large ones) need the GDALDataset::GetNextFeature() call rather than OGRLayer::GetNextFeature()
// see more details here: https://trac.osgeo.org/gdal/wiki/rfc66_randomlayerreadwrite

// we have a feature, end this cycle
feature.setValid( true );
geometryToDestinationCrs( feature, mTransform );
return true;
#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
if ( mSource->mDriverName == QLatin1String( "OSM" ) )
{
OGRLayerH nextFeatureBelongingLayer;
while ( fet.reset( GDALDatasetGetNextFeature( mConn->ds, &nextFeatureBelongingLayer, nullptr, nullptr, nullptr ) ), fet )
{
if ( nextFeatureBelongingLayer == mOgrLayer && checkFeature( fet, feature ) )
{
return true;
}
}
}
else
{

} // while
while ( fet.reset( OGR_L_GetNextFeature( mOgrLayer ) ), fet )
{
if ( checkFeature( fet, feature ) )
{
return true;
}
}
}
#else
while ( fet.reset( OGR_L_GetNextFeature( mOgrLayer ) ), fet )
{
if ( checkFeature( fet, feature ) )
{
return true;
}
}
#endif

close();
return false;
Expand Down
1 change: 1 addition & 0 deletions src/providers/ogr/qgsogrfeatureiterator.h
Expand Up @@ -67,6 +67,7 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsOgr
bool close() override;

protected:
bool checkFeature( gdal::ogr_feature_unique_ptr &fet, QgsFeature &feature ) ;
bool fetchFeature( QgsFeature &feature ) override;
bool nextFeatureFilterExpression( QgsFeature &f ) override;

Expand Down

1 comment on commit f410b4a

@Gustry
Copy link
Contributor

@Gustry Gustry commented on f410b4a Oct 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit broke the getFeatures() iterator : https://issues.qgis.org/issues/20098
Thanks

Please sign in to comment.