Skip to content

Commit

Permalink
DXF export: fix crash on some MultiPolygon geometries when offset != 0 (
Browse files Browse the repository at this point in the history
fixes #46245)
  • Loading branch information
rouault authored and github-actions[bot] committed Feb 11, 2022
1 parent 4a37fe8 commit e48fea4
Showing 1 changed file with 36 additions and 58 deletions.
94 changes: 36 additions & 58 deletions src/core/dxf/qgsdxfexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,8 @@ void QgsDxfExport::addFeature( QgsSymbolRenderContext &ctx, const QgsCoordinateT
case QgsWkbTypes::CircularString:
case QgsWkbTypes::CompoundCurve:
case QgsWkbTypes::LineString:
case QgsWkbTypes::MultiCurve:
case QgsWkbTypes::MultiLineString:
{
if ( !qgsDoubleNear( offset, 0.0 ) )
{
Expand All @@ -1629,45 +1631,29 @@ void QgsDxfExport::addFeature( QgsSymbolRenderContext &ctx, const QgsCoordinateT
if ( curve )
{
writePolyline( *curve, layer, lineStyleName, penColor, width );
break;
}

// Offset with miter might have turned the simple to a multiline string
offset = 0.0;
}
FALLTHROUGH

case QgsWkbTypes::MultiCurve:
case QgsWkbTypes::MultiLineString:
{
if ( !qgsDoubleNear( offset, 0.0 ) )
{
QgsGeos geos( sourceGeom );
tempGeom.reset( geos.offsetCurve( offset, 0, Qgis::JoinStyle::Miter, 2.0 ) ); //#spellok
if ( tempGeom )
sourceGeom = tempGeom.get();
else
sourceGeom = geom.constGet();
}

const QgsGeometryCollection *gc = dynamic_cast<const QgsGeometryCollection *>( sourceGeom );
if ( gc )
else
{
for ( int i = 0; i < gc->numGeometries(); i++ )
const QgsGeometryCollection *gc = dynamic_cast<const QgsGeometryCollection *>( sourceGeom );
if ( gc )
{
const QgsCurve *curve = dynamic_cast<const QgsCurve *>( gc->geometryN( i ) );
Q_ASSERT( curve );
writePolyline( *curve, layer, lineStyleName, penColor, width );
for ( int i = 0; i < gc->numGeometries(); i++ )
{
const QgsCurve *curve = dynamic_cast<const QgsCurve *>( gc->geometryN( i ) );
Q_ASSERT( curve );
writePolyline( *curve, layer, lineStyleName, penColor, width );
}
}
else
Q_ASSERT( gc );
}
else
Q_ASSERT( gc );

break;
}

case QgsWkbTypes::CurvePolygon:
case QgsWkbTypes::Polygon:
case QgsWkbTypes::MultiSurface:
case QgsWkbTypes::MultiPolygon:
{
if ( !qgsDoubleNear( offset, 0.0 ) )
{
Expand All @@ -1680,39 +1666,31 @@ void QgsDxfExport::addFeature( QgsSymbolRenderContext &ctx, const QgsCoordinateT
}

const QgsCurvePolygon *polygon = dynamic_cast<const QgsCurvePolygon *>( sourceGeom );
Q_ASSERT( polygon );

writePolyline( *polygon->exteriorRing(), layer, lineStyleName, penColor, width );
for ( int i = 0; i < polygon->numInteriorRings(); i++ )
writePolyline( *polygon->interiorRing( i ), layer, lineStyleName, penColor, width );

break;
}

case QgsWkbTypes::MultiSurface:
case QgsWkbTypes::MultiPolygon:
{
if ( !qgsDoubleNear( offset, 0.0 ) )
if ( polygon )
{
QgsGeos geos( sourceGeom );
tempGeom.reset( geos.buffer( offset, 0, Qgis::EndCapStyle::Flat, Qgis::JoinStyle::Miter, 2.0 ) ); //#spellok
if ( tempGeom )
sourceGeom = tempGeom.get();
else
sourceGeom = geom.constGet();
writePolyline( *polygon->exteriorRing(), layer, lineStyleName, penColor, width );
for ( int i = 0; i < polygon->numInteriorRings(); i++ )
writePolyline( *polygon->interiorRing( i ), layer, lineStyleName, penColor, width );
}

const QgsGeometryCollection *gc = dynamic_cast<const QgsGeometryCollection *>( sourceGeom );
Q_ASSERT( gc );

for ( int i = 0; i < gc->numGeometries(); i++ )
else
{
const QgsCurvePolygon *polygon = dynamic_cast<const QgsCurvePolygon *>( gc->geometryN( i ) );
Q_ASSERT( polygon );
const QgsGeometryCollection *gc = dynamic_cast<const QgsGeometryCollection *>( sourceGeom );
if ( gc )
{
for ( int i = 0; i < gc->numGeometries(); i++ )
{
const QgsCurvePolygon *polygon = dynamic_cast<const QgsCurvePolygon *>( gc->geometryN( i ) );
Q_ASSERT( polygon );

writePolyline( *polygon->exteriorRing(), layer, lineStyleName, penColor, width );
for ( int j = 0; j < polygon->numInteriorRings(); j++ )
writePolyline( *polygon->interiorRing( j ), layer, lineStyleName, penColor, width );
writePolyline( *polygon->exteriorRing(), layer, lineStyleName, penColor, width );
for ( int j = 0; j < polygon->numInteriorRings(); j++ )
writePolyline( *polygon->interiorRing( j ), layer, lineStyleName, penColor, width );
}
}
else
{
Q_ASSERT( gc );
}
}

break;
Expand Down

0 comments on commit e48fea4

Please sign in to comment.