Skip to content

Commit

Permalink
[OGR provider] Avoid considering mix of Polygon and CurvePolygon as 2…
Browse files Browse the repository at this point in the history
… sublayers

Fixes #15066
  • Loading branch information
rouault committed Jun 18, 2016
1 parent 3b65568 commit 22dfd76
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -655,11 +655,40 @@ QStringList QgsOgrProvider::subLayers() const
{
fCount[wkbUnknown] = 0;
}

#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
// When there are CurvePolygons, promote Polygons
if ( fCount.contains( wkbPolygon ) && fCount.contains( wkbCurvePolygon ) )
{
fCount[wkbCurvePolygon] += fCount.value( wkbPolygon );
fCount.remove( wkbPolygon );
}
// When there are CompoundCurves, promote LineStrings and CircularStrings
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbLineString );
fCount.remove( wkbLineString );
}
if ( fCount.contains( wkbCircularString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbCircularString );
fCount.remove( wkbCircularString );
}
#endif

#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
bool bIs25D = ( wkbHasZ( layerGeomType ) != 0 );
#else
bool bIs25D = (( layerGeomType & wkb25DBit ) != 0 );
#endif
QMap<OGRwkbGeometryType, int>::const_iterator countIt = fCount.constBegin();
for ( ; countIt != fCount.constEnd(); ++countIt )
{
#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
QString geom = ogrWkbGeometryTypeName(( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() );
#else
QString geom = ogrWkbGeometryTypeName(( bIs25D ) ? ( OGRwkbGeometryType )( countIt.key() | wkb25DBit ) : countIt.key() );
#endif

QString sl = QString( "%1:%2:%3:%4" ).arg( i ).arg( theLayerName ).arg( fCount.value( countIt.key() ) ).arg( geom );
QgsDebugMsg( "sub layer: " + sl );
Expand Down Expand Up @@ -2960,6 +2989,12 @@ OGRwkbGeometryType QgsOgrProvider::ogrWkbSingleFlatten( OGRwkbGeometryType type
return wkbLineString;
case wkbMultiPolygon:
return wkbPolygon;
#if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)
case wkbMultiCurve:
return wkbCompoundCurve;
case wkbMultiSurface:
return wkbCurvePolygon;
#endif
default:
return type;
}
Expand Down
39 changes: 39 additions & 0 deletions tests/src/python/test_provider_ogr.py
Expand Up @@ -22,10 +22,15 @@
unittest
)
from utilities import unitTestDataPath
from osgeo import gdal, ogr

start_app()
TEST_DATA_DIR = unitTestDataPath()


def GDAL_COMPUTE_VERSION(maj, min, rev):
return ((maj) * 1000000 + (min) * 10000 + (rev) * 100)

# Note - doesn't implement ProviderTestCase as most OGR provider is tested by the shapefile provider test


Expand Down Expand Up @@ -78,5 +83,39 @@ def testGeometryTypeKnownAtSecondFeature(self):
self.assertTrue(vl.isValid())
self.assertEqual(vl.wkbType(), QgsWKBTypes.Point)

@unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0))
def testMixOfPolygonCurvePolygon(self):

datasource = os.path.join(self.basetestpath, 'testMixOfPolygonCurvePolygon.csv')
with open(datasource, 'wt') as f:
f.write('id,WKT\n')
f.write('1,"POLYGON((0 0,0 1,1 1,0 0))"\n')
f.write('2,"CURVEPOLYGON((0 0,0 1,1 1,0 0))"\n')
f.write('3,"MULTIPOLYGON(((0 0,0 1,1 1,0 0)))"\n')
f.write('4,"MULTISURFACE(((0 0,0 1,1 1,0 0)))"\n')

vl = QgsVectorLayer(u'{}|layerid=0'.format(datasource), u'test', u'ogr')
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(vl.dataProvider().subLayers()[0], '0:testMixOfPolygonCurvePolygon:4:CurvePolygon')

@unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0))
def testMixOfLineStringCompoundCurve(self):

datasource = os.path.join(self.basetestpath, 'testMixOfLineStringCompoundCurve.csv')
with open(datasource, 'wt') as f:
f.write('id,WKT\n')
f.write('1,"LINESTRING(0 0,0 1)"\n')
f.write('2,"COMPOUNDCURVE((0 0,0 1))"\n')
f.write('3,"MULTILINESTRING((0 0,0 1))"\n')
f.write('4,"MULTICURVE((0 0,0 1))"\n')
f.write('5,"CIRCULARSTRING(0 0,1 1,2 0)"\n')

vl = QgsVectorLayer(u'{}|layerid=0'.format(datasource), u'test', u'ogr')
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(vl.dataProvider().subLayers()[0], '0:testMixOfLineStringCompoundCurve:5:CompoundCurve')


if __name__ == '__main__':
unittest.main()

0 comments on commit 22dfd76

Please sign in to comment.