Skip to content

Commit

Permalink
[OGR provider] Fix issue when writing a multi-part multipolygon in a …
Browse files Browse the repository at this point in the history
…shapefile with GDAL >= 3.7 (fixes #54537)
  • Loading branch information
rouault authored and github-actions[bot] committed Sep 29, 2023
1 parent 5786239 commit 7246983
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -1364,6 +1364,15 @@ OGRGeometryH QgsOgrProvider::ConvertGeometryIfNecessary( OGRGeometryH hGeom )
return OGR_G_ForceToMultiLineString( hGeom );
}

if ( flattenLayerGeomType == wkbPolygon && flattenGeomType == wkbMultiPolygon &&
mGDALDriverName == QLatin1String( "ESRI Shapefile" ) )
{
// Do not force multipolygon to polygon for shapefiles, otherwise it will
// cause issues with GDAL 3.7 that does honour the topological intent of
// multipolygon
return hGeom;
}

return OGR_G_ForceTo( hGeom, layerGeomType, nullptr );
}

Expand Down
18 changes: 18 additions & 0 deletions tests/src/python/test_provider_shapefile.py
Expand Up @@ -1111,6 +1111,24 @@ def testLayersOnSameOGRLayerWithAndWithoutFilter(self):
assert QgsGeometry.compare(vl3_extent.asPolygon()[0], reference.asPolygon()[0],
0.00001), f'Expected {reference.asWkt()}, got {vl3_extent.asWkt()}'

def testWritingMultiPolygon(self):
"""Test that a MultiPolygon written to a Shape Polygon layer doesn't get converted to Polygon"""

tmpfile = os.path.join(self.basetestpath, 'testWritingMultiPolygon.shp')
ds = osgeo.ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(tmpfile)
ds.CreateLayer('testWritingMultiPolygon', geom_type=osgeo.ogr.wkbPolygon)
ds = None

vl = QgsVectorLayer(tmpfile, 'test')
f = QgsFeature()
f.setAttributes([200])
wkt = "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((10 0, 10 1, 11 1, 10 0)))"
f.setGeometry(QgsGeometry.fromWkt(wkt))
vl.dataProvider().addFeatures([f])

f = next(vl.getFeatures())
self.assertEqual(f.geometry().constGet().asWkt(), wkt)


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

0 comments on commit 7246983

Please sign in to comment.