[OGR provider] Improve detection of layer geometry type

When a OGR layer is of geometry type "unknown", we use the
geometry of the first feature to guess the geometry type. But
if this feature has no geometry, then we assume that we have no
geometry for the whole layer. This is a bit extreme. Let us
allow to probe a few features before giving up.

Fixes #15065
This commit is contained in:
Even Rouault 2016-06-18 18:36:47 +02:00
parent 7b7c3773d8
commit 3b65568c73
2 changed files with 26 additions and 12 deletions

View File

@ -706,23 +706,26 @@ OGRwkbGeometryType QgsOgrProvider::getOgrGeomType( OGRLayerH ogrLayer )
// Some ogr drivers (e.g. GML) are not able to determine the geometry type of a layer like this.
// In such cases, we use virtual sublayers for each geometry if the layer contains
// multiple geometries (see subLayers) otherwise we guess geometry type from first feature
// multiple geometries (see subLayers) otherwise we guess geometry type from the first
// feature that has a geometry (limit us to a few features, not the whole layer)
if ( geomType == wkbUnknown )
{
geomType = wkbNone;
OGR_L_ResetReading( ogrLayer );
OGRFeatureH firstFeature = OGR_L_GetNextFeature( ogrLayer );
if ( firstFeature )
for ( int i = 0; i < 10; i++ )
{
OGRGeometryH firstGeometry = OGR_F_GetGeometryRef( firstFeature );
if ( firstGeometry )
OGRFeatureH nextFeature = OGR_L_GetNextFeature( ogrLayer );
if ( !nextFeature )
break;
OGRGeometryH geometry = OGR_F_GetGeometryRef( nextFeature );
if ( geometry )
{
geomType = OGR_G_GetGeometryType( firstGeometry );
geomType = OGR_G_GetGeometryType( geometry );
}
else
{
geomType = wkbNone;
}
OGR_F_Destroy( firstFeature );
OGR_F_Destroy( nextFeature );
if ( geomType != wkbNone )
break;
}
OGR_L_ResetReading( ogrLayer );
}

View File

@ -16,7 +16,7 @@ import os
import shutil
import tempfile
from qgis.core import QgsVectorLayer, QgsVectorDataProvider
from qgis.core import QgsVectorLayer, QgsVectorDataProvider, QgsWKBTypes
from qgis.testing import (
start_app,
unittest
@ -66,6 +66,17 @@ class PyQgsOGRProvider(unittest.TestCase):
self.assertTrue(vl.dataProvider().leaveUpdateMode())
self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write")
def testGeometryTypeKnownAtSecondFeature(self):
datasource = os.path.join(self.basetestpath, 'testGeometryTypeKnownAtSecondFeature.csv')
with open(datasource, 'wt') as f:
f.write('id,WKT\n')
f.write('1,\n')
f.write('2,POINT(2 49)\n')
vl = QgsVectorLayer(u'{}|layerid=0'.format(datasource), u'test', u'ogr')
self.assertTrue(vl.isValid())
self.assertEqual(vl.wkbType(), QgsWKBTypes.Point)
if __name__ == '__main__':
unittest.main()