Skip to content
Permalink
Browse files
Correctly handle tin wkb types when querying ogr sublayers
  • Loading branch information
nyalldawson committed Jul 12, 2021
1 parent 59f7b4c commit aba7f13919efbcaa9031c455cca37dda1c6194ec
@@ -711,20 +711,7 @@ OGRwkbGeometryType QgsOgrProvider::getOgrGeomType( const QString &driverName, OG
if ( !nextFeature )
break;

OGRGeometryH geometry = OGR_F_GetGeometryRef( nextFeature.get() );
if ( geometry )
{
geomType = OGR_G_GetGeometryType( geometry );

// Shapefile MultiPatch can be reported as GeometryCollectionZ of TINZ
if ( wkbFlatten( geomType ) == wkbGeometryCollection &&
driverName == QLatin1String( "ESRI Shapefile" ) &&
OGR_G_GetGeometryCount( geometry ) >= 1 &&
wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geometry, 0 ) ) ) == wkbTIN )
{
geomType = wkbMultiPolygon25D;
}
}
geomType = QgsOgrProviderUtils::resolveGeometryTypeForFeature( nextFeature.get(), driverName );
if ( geomType != wkbNone )
break;
}
@@ -2025,6 +2025,28 @@ QString QgsOgrProviderUtils::ogrWkbGeometryTypeName( OGRwkbGeometryType type )
return geom;
}

OGRwkbGeometryType QgsOgrProviderUtils::resolveGeometryTypeForFeature( OGRFeatureH feature, const QString &driverName )
{
if ( OGRGeometryH geom = OGR_F_GetGeometryRef( feature ) )
{
OGRwkbGeometryType gType = OGR_G_GetGeometryType( geom );

// Shapefile MultiPatch can be reported as GeometryCollectionZ of TINZ
if ( wkbFlatten( gType ) == wkbGeometryCollection &&
driverName == QLatin1String( "ESRI Shapefile" ) &&
OGR_G_GetGeometryCount( geom ) >= 1 &&
wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
{
gType = wkbMultiPolygon25D;
}
return gType;
}
else
{
return wkbNone;
}
}

QString QgsOgrProviderUtils::expandAuthConfig( const QString &dsName )
{
QString uri( dsName );
@@ -2378,10 +2400,9 @@ QList< QgsProviderSublayerDetails > QgsOgrProviderUtils::querySubLayerList( int
gdal::ogr_feature_unique_ptr fet;
while ( fet.reset( layer->GetNextFeature() ), fet )
{
OGRGeometryH geom = OGR_F_GetGeometryRef( fet.get() );
if ( geom )
const OGRwkbGeometryType gType = QgsOgrProviderUtils::ogrWkbSingleFlatten( resolveGeometryTypeForFeature( fet.get(), driverName ) );
if ( gType != wkbNone )
{
OGRwkbGeometryType gType = QgsOgrProviderUtils::ogrWkbSingleFlatten( OGR_G_GetGeometryType( geom ) );
fCount[gType] = fCount.value( gType ) + 1;
}

@@ -241,6 +241,9 @@ class CORE_EXPORT QgsOgrProviderUtils

static QString ogrWkbGeometryTypeName( OGRwkbGeometryType type );

//! Resolves the geometry type for a feature, with special handling for some drivers
static OGRwkbGeometryType resolveGeometryTypeForFeature( OGRFeatureH feature, const QString &driverName );

static QString analyzeURI( QString const &uri,
bool &isSubLayer,
int &layerIndex,
@@ -1530,6 +1530,30 @@ def test_provider_sublayer_details(self):
self.assertEqual(res[0].wkbType(), QgsWkbTypes.LineString)
self.assertEqual(res[0].geometryColumnName(), '')

# geometry collection sublayers -- requires a scan to resolve geometry type
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, 'multipatch.shp'))
self.assertEqual(len(res), 1)
self.assertEqual(res[0].layerNumber(), 0)
self.assertEqual(res[0].name(), "multipatch")
self.assertEqual(res[0].description(), '')
self.assertEqual(res[0].uri(), TEST_DATA_DIR + "/multipatch.shp")
self.assertEqual(res[0].providerKey(), "ogr")
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Unknown)
self.assertEqual(res[0].geometryColumnName(), '')

# retry with retrieving geometry types
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, 'multipatch.shp'), Qgis.SublayerQueryFlag.ResolveGeometryType)
self.assertEqual(len(res), 1)
self.assertEqual(res[0].layerNumber(), 0)
self.assertEqual(res[0].name(), "multipatch")
self.assertEqual(res[0].description(), '')
self.assertEqual(res[0].uri(), TEST_DATA_DIR + "/multipatch.shp")
self.assertEqual(res[0].providerKey(), "ogr")
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Polygon)
self.assertEqual(res[0].geometryColumnName(), '')

# single layer geopackage -- sublayers MUST have the layerName set on the uri,
# in case more layers are added in future to the gpkg
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, 'curved_polys.gpkg'))

0 comments on commit aba7f13

Please sign in to comment.