Skip to content

Commit

Permalink
Address PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Feb 6, 2025
1 parent a99adcd commit c90eb46
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 10 deletions.
63 changes: 56 additions & 7 deletions src/core/providers/ogr/qgsogrproviderutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2764,12 +2764,11 @@ QList< QgsProviderSublayerDetails > QgsOgrProviderUtils::querySubLayerList( int
OGRwkbGeometryType pointBaseType { wkbPoint };

// Last type in the list is the winner
const static QList<OGRwkbGeometryType> pointHyerarchy { wkbPoint, wkbMultiPoint };
// Note: compound curve takes precedence over multilinestring
const static QList<OGRwkbGeometryType> lineHyerarchy { wkbLineString, wkbCircularString, wkbMultiCurve, wkbMultiLineString, wkbCompoundCurve, wkbMultiCurve };
const static QList<OGRwkbGeometryType> polyHyerarchy { wkbPolyhedralSurface, wkbTIN, wkbPolygon, wkbCurvePolygon, wkbMultiSurface, wkbMultiPolygon };
const static QList<OGRwkbGeometryType> pointHierarchy { wkbPoint, wkbMultiPoint };
const static QList<OGRwkbGeometryType> lineHierarchy { wkbLineString, wkbCircularString, wkbMultiLineString, wkbCompoundCurve, wkbMultiCurve };
const static QList<OGRwkbGeometryType> polyHierarchy { wkbPolyhedralSurface, wkbTIN, wkbPolygon, wkbCurvePolygon, wkbMultiPolygon, wkbMultiSurface };

for ( const auto t : std::as_const( pointHyerarchy ) )
for ( const auto t : std::as_const( pointHierarchy ) )
{
if ( fCount.contains( t ) )
{
Expand All @@ -2779,7 +2778,39 @@ QList< QgsProviderSublayerDetails > QgsOgrProviderUtils::querySubLayerList( int
}
}

for ( const auto t : std::as_const( lineHyerarchy ) )
// For lines use a three-step approach
// 1. First collapse linestring and circularstring into compoundcurve
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCircularString ) )
{
baseTypeCount[Qgis::GeometryType::Line] += fCount.value( wkbLineString );
baseTypeCount[Qgis::GeometryType::Line] += fCount.value( wkbCircularString );
lineBaseType = wkbCompoundCurve;
if ( ! fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] = baseTypeCount[Qgis::GeometryType::Line];
baseTypeCount[Qgis::GeometryType::Line] = 0;
}
fCount.remove( wkbLineString );
fCount.remove( wkbCircularString );
}

// 2. Then collapse multilinestring and compoundcurve into multicurve
if ( fCount.contains( wkbMultiLineString ) && fCount.contains( wkbCompoundCurve ) )
{
baseTypeCount[Qgis::GeometryType::Line] += fCount.value( wkbMultiLineString );
baseTypeCount[Qgis::GeometryType::Line] += fCount.value( wkbCompoundCurve );
lineBaseType = wkbMultiCurve;
if ( ! fCount.contains( wkbMultiCurve ) )
{
fCount[wkbMultiCurve] = baseTypeCount[Qgis::GeometryType::Line];
baseTypeCount[Qgis::GeometryType::Line] = 0;
}
fCount.remove( wkbMultiLineString );
fCount.remove( wkbCompoundCurve );
}

// 3. Then follow the hierarchy
for ( const auto t : std::as_const( lineHierarchy ) )
{
if ( fCount.contains( t ) )
{
Expand All @@ -2789,7 +2820,25 @@ QList< QgsProviderSublayerDetails > QgsOgrProviderUtils::querySubLayerList( int
}
}

for ( const auto t : std::as_const( polyHyerarchy ) )

// For polygons use a two-step approach:
// 1. First collapse multipolygon and curvepolygon into multisurface
if ( fCount.contains( wkbMultiPolygon ) && fCount.contains( wkbCurvePolygon ) )
{
baseTypeCount[Qgis::GeometryType::Polygon] += fCount.value( wkbMultiPolygon );
baseTypeCount[Qgis::GeometryType::Polygon] += fCount.value( wkbMultiSurface );
polyBaseType = wkbMultiSurface;
if ( ! fCount.contains( wkbMultiSurface ) )
{
fCount[wkbMultiSurface] = baseTypeCount[Qgis::GeometryType::Polygon];
baseTypeCount[Qgis::GeometryType::Polygon] = 0;
}
fCount.remove( wkbMultiPolygon );
fCount.remove( wkbCurvePolygon );
}

// 2. Then collapse following the hierarchy
for ( const auto t : std::as_const( polyHierarchy ) )
{
if ( fCount.contains( t ) )
{
Expand Down
144 changes: 141 additions & 3 deletions tests/src/python/test_provider_ogr.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def testMixOfPolygonCurvePolygon(self):
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
["0", "testMixOfPolygonCurvePolygon", "4", "MultiPolygon", "", ""]
["0", "testMixOfPolygonCurvePolygon", "4", "MultiSurface", "", ""]
),
)

Expand All @@ -188,7 +188,6 @@ def testMixOfLineStringCompoundCurve(self):
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(f"{datasource}|layerid=0", "test", "ogr")
Expand All @@ -197,7 +196,146 @@ def testMixOfLineStringCompoundCurve(self):
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
["0", "testMixOfLineStringCompoundCurve", "5", "CompoundCurve", "", ""]
["0", "testMixOfLineStringCompoundCurve", "4", "MultiCurve", "", ""]
),
)

def testMixOfCurvePolygonAndMultiPolygon(self):

datasource = os.path.join(
self.basetestpath, "testMixOfCurvePolygonAndMultiPolygon.csv"
)
with open(datasource, "w") as f:
f.write("id,WKT\n")
f.write('1,"CURVEPOLYGON((0 0,0 1,1 1,0 0))"\n')
f.write('2,"MULTIPOLYGON(((0 0,0 1,1 1,0 0)))"\n')

vl = QgsVectorLayer(f"{datasource}|layerid=0", "test", "ogr")
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
[
"0",
"testMixOfCurvePolygonAndMultiPolygon",
"2",
"MultiSurface",
"",
"",
]
),
)

def testMixOfLineStringAndCircularString(self):

datasource = os.path.join(
self.basetestpath, "testMixOfLineStringAndCircularString.csv"
)
with open(datasource, "w") as f:
f.write("id,WKT\n")
f.write('1,"LINESTRING(0 0,0 1)"\n')
f.write('2,"CIRCULARSTRING(0 0,1 1,2 0)"\n')

vl = QgsVectorLayer(f"{datasource}|layerid=0", "test", "ogr")
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
[
"0",
"testMixOfLineStringAndCircularString",
"2",
"CompoundCurve",
"",
"",
]
),
)

def testMixOfLineStringAndCircularStringAndCompoundCurve(self):

datasource = os.path.join(
self.basetestpath,
"testMixOfLineStringAndCircularStringAndCompoundCurve.csv",
)
with open(datasource, "w") as f:
f.write("id,WKT\n")
f.write('1,"LINESTRING(0 0,0 1)"\n')
f.write('2,"CIRCULARSTRING(0 0,1 1,2 0)"\n')
f.write('3,"COMPOUNDCURVE((0 0,0 1))"\n')

vl = QgsVectorLayer(f"{datasource}|layerid=0", "test", "ogr")
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
[
"0",
"testMixOfLineStringAndCircularStringAndCompoundCurve",
"3",
"CompoundCurve",
"",
"",
]
),
)

def testMixOfMultiLineStringAndCompoundCurve(self):

datasource = os.path.join(
self.basetestpath, "testMixOfMultiLineStringAndCompoundCurve.csv"
)
with open(datasource, "w") as f:
f.write("id,WKT\n")
f.write('1,"MULTILINESTRING((0 0,0 1))"\n')
f.write('2,"COMPOUNDCURVE((0 0,0 1))"\n')

vl = QgsVectorLayer(f"{datasource}|layerid=0", "test", "ogr")
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
[
"0",
"testMixOfMultiLineStringAndCompoundCurve",
"2",
"MultiCurve",
"",
"",
]
),
)

def testMixOfMultiLineStringAndCompoundCurveAndMultiCurve(self):

datasource = os.path.join(
self.basetestpath,
"testMixOfMultiLineStringAndCompoundCurveAndMultiCurve.csv",
)
with open(datasource, "w") as f:
f.write("id,WKT\n")
f.write('1,"MULTILINESTRING((0 0,0 1))"\n')
f.write('2,"COMPOUNDCURVE((0 0,0 1))"\n')
f.write('3,"MULTICURVE((0 0,0 1))"\n')

vl = QgsVectorLayer(f"{datasource}|layerid=0", "test", "ogr")
self.assertTrue(vl.isValid())
self.assertEqual(len(vl.dataProvider().subLayers()), 1)
self.assertEqual(
vl.dataProvider().subLayers()[0],
QgsDataProvider.SUBLAYER_SEPARATOR.join(
[
"0",
"testMixOfMultiLineStringAndCompoundCurveAndMultiCurve",
"3",
"MultiCurve",
"",
"",
]
),
)

Expand Down

0 comments on commit c90eb46

Please sign in to comment.