mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[ogr] When querying sublayers, if an explicit geometry type is
part of the uri being queried then we should only return the sublayer with this same geometry type
This commit is contained in:
parent
c5f76191ae
commit
54634d9bec
@ -1162,6 +1162,17 @@ QList<QgsProviderSublayerDetails> QgsOgrProviderMetadata::querySublayers( const
|
||||
if ( originalUriLayerIdWasSpecified )
|
||||
layerId = uriLayerId;
|
||||
|
||||
QgsWkbTypes::Type originalGeometryTypeFilter = QgsWkbTypes::Unknown;
|
||||
bool originalUriGeometryTypeWasSpecified = false;
|
||||
const QString originalGeometryTypeString = uriParts.value( QStringLiteral( "geometryType" ) ).toString();
|
||||
if ( !originalGeometryTypeString.isEmpty() )
|
||||
{
|
||||
originalGeometryTypeFilter = QgsOgrUtils::ogrGeometryTypeToQgsWkbType(
|
||||
QgsOgrProviderUtils::ogrWkbGeometryTypeFromName( originalGeometryTypeString )
|
||||
);
|
||||
originalUriGeometryTypeWasSpecified = true;
|
||||
}
|
||||
|
||||
QString errCause;
|
||||
|
||||
QVariantMap firstLayerUriParts;
|
||||
@ -1226,6 +1237,13 @@ QList<QgsProviderSublayerDetails> QgsOgrProviderMetadata::querySublayers( const
|
||||
for ( int i = 0; i < res.count(); ++i )
|
||||
{
|
||||
QVariantMap parts = decodeUri( res.at( i ).uri() );
|
||||
if ( originalUriGeometryTypeWasSpecified && res.at( i ).wkbType() == QgsWkbTypes::Unknown )
|
||||
{
|
||||
res[ i ].setWkbType( originalGeometryTypeFilter );
|
||||
parts.insert( QStringLiteral( "geometryType" ), originalGeometryTypeString );
|
||||
res[i].setUri( encodeUri( parts ) );
|
||||
}
|
||||
|
||||
if ( !parts.value( QStringLiteral( "layerName" ) ).toString().isEmpty() ||
|
||||
!parts.value( QStringLiteral( "layerId" ) ).toString().isEmpty() )
|
||||
continue;
|
||||
@ -1260,13 +1278,22 @@ QList<QgsProviderSublayerDetails> QgsOgrProviderMetadata::querySublayers( const
|
||||
|
||||
if ( originalUriLayerIdWasSpecified )
|
||||
{
|
||||
// remove non-matching, unwanted layers
|
||||
// remove non-matching, unwanted layers by layer id
|
||||
res.erase( std::remove_if( res.begin(), res.end(), [ = ]( const QgsProviderSublayerDetails & sublayer )
|
||||
{
|
||||
return sublayer.layerNumber() != uriLayerId;
|
||||
} ), res.end() );
|
||||
}
|
||||
|
||||
if ( originalUriGeometryTypeWasSpecified )
|
||||
{
|
||||
// remove non-matching, unwanted layers by geometry type
|
||||
res.erase( std::remove_if( res.begin(), res.end(), [ = ]( const QgsProviderSublayerDetails & sublayer )
|
||||
{
|
||||
return sublayer.wkbType() != originalGeometryTypeFilter;
|
||||
} ), res.end() );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1856,6 +1856,107 @@ class PyQgsOGRProvider(unittest.TestCase):
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.Polygon)
|
||||
|
||||
# mixed types source, but with a URI which specifies a particular type. Only this type should be returned
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=Point"),
|
||||
Qgis.SublayerQueryFlag.ResolveGeometryType)
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=Point".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), 4)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Point)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.Point)
|
||||
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=LineString"),
|
||||
Qgis.SublayerQueryFlag.ResolveGeometryType)
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=LineString".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), 4)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.LineString)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.LineString)
|
||||
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=Polygon"),
|
||||
Qgis.SublayerQueryFlag.ResolveGeometryType)
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=Polygon".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), 3)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Polygon)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.Polygon)
|
||||
|
||||
# same as above, but without ResolveGeometryType flag
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=Point"))
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=Point".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), Qgis.FeatureCountState.Uncounted)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Point)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.Point)
|
||||
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=LineString"))
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=LineString".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), Qgis.FeatureCountState.Uncounted)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.LineString)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.LineString)
|
||||
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "mixed_types.TAB|geometrytype=Polygon"))
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertEqual(res[0].layerNumber(), 0)
|
||||
self.assertEqual(res[0].name(), "mixed_types")
|
||||
self.assertEqual(res[0].description(), "")
|
||||
self.assertEqual(res[0].uri(), "{}/mixed_types.TAB|geometrytype=Polygon".format(TEST_DATA_DIR))
|
||||
self.assertEqual(res[0].providerKey(), "ogr")
|
||||
self.assertEqual(res[0].type(), QgsMapLayerType.VectorLayer)
|
||||
self.assertEqual(res[0].featureCount(), Qgis.FeatureCountState.Uncounted)
|
||||
self.assertEqual(res[0].wkbType(), QgsWkbTypes.Polygon)
|
||||
self.assertEqual(res[0].geometryColumnName(), '')
|
||||
self.assertEqual(res[0].driverName(), 'MapInfo File')
|
||||
vl = res[0].toLayer(options)
|
||||
self.assertTrue(vl.isValid())
|
||||
self.assertEqual(vl.wkbType(), QgsWkbTypes.Polygon)
|
||||
|
||||
# spatialite
|
||||
res = metadata.querySublayers(os.path.join(TEST_DATA_DIR, "provider/spatialite.db"))
|
||||
self.assertCountEqual([{'name': r.name(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user