Skip to content

Commit

Permalink
Merge pull request #47277 from rouault/fix_46245
Browse files Browse the repository at this point in the history
DXF export: fix crash on some MultiPolygon geometries when offset != 0 (fixes #46245)
  • Loading branch information
rouault committed Feb 11, 2022
2 parents d1c558f + 7890c08 commit 0a71331
Showing 1 changed file with 32 additions and 58 deletions.
90 changes: 32 additions & 58 deletions src/core/dxf/qgsdxfexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,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 @@ -1631,45 +1633,28 @@ 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 );
Q_ASSERT( gc );
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 );

break;
}

case QgsWkbTypes::CurvePolygon:
case QgsWkbTypes::Polygon:
case QgsWkbTypes::MultiSurface:
case QgsWkbTypes::MultiPolygon:
{
if ( !qgsDoubleNear( offset, 0.0 ) )
{
Expand All @@ -1682,39 +1667,28 @@ 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 );
Q_ASSERT( gc );
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 );
}
}
}

break;
Expand Down

0 comments on commit 0a71331

Please sign in to comment.