Skip to content

Commit a8150d1

Browse files
committedJun 13, 2014
Merge pull request #1437 from ahuarte47/Issue_10195
Fix bug #10195: Offset line symbology added to polygon layer leads to crash
2 parents c49e38c + 17a8e38 commit a8150d1

File tree

3 files changed

+62
-28
lines changed

3 files changed

+62
-28
lines changed
 

‎src/core/symbology-ng/qgslinesymbollayerv2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
273273
else
274274
{
275275
double scaledOffset = offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale );
276-
QList<QPolygonF> mline = ::offsetLine( points, scaledOffset );
276+
QList<QPolygonF> mline = ::offsetLine( points, scaledOffset, context.feature() ? context.feature()->geometry()->type() : QGis::Line );
277277
for ( int part = 0; part < mline.count(); ++part )
278278
p->drawPolyline( mline[ part ] );
279279
}
@@ -779,7 +779,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
779779
}
780780
else
781781
{
782-
QList<QPolygonF> mline = ::offsetLine( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale ) );
782+
QList<QPolygonF> mline = ::offsetLine( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale ), context.feature() ? context.feature()->geometry()->type() : QGis::Line );
783783

784784
for ( int part = 0; part < mline.count(); ++part )
785785
{

‎src/core/symbology-ng/qgssymbollayerv2utils.cpp

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,30 @@ static QPointF linesIntersection( QPointF p1, double t1, QPointF p2, double t2 )
659659
y = p1.y() + t1 * ( x - p1.x() );
660660
return QPointF( x, y );
661661
}
662-
#endif
662+
#else
663+
static QPolygonF makeOffsetGeometry( const QgsPolyline& polyline )
664+
{
665+
int i, pointCount = polyline.count();
663666

667+
QPolygonF resultLine;
668+
resultLine.resize( pointCount );
664669

665-
QList<QPolygonF> offsetLine( QPolygonF polyline, double dist )
670+
const QgsPoint* tempPtr = polyline.data();
671+
672+
for ( i = 0; i < pointCount; ++i, tempPtr++ )
673+
resultLine[i] = QPointF( tempPtr->x(), tempPtr->y() );
674+
675+
return resultLine;
676+
}
677+
static QList<QPolygonF> makeOffsetGeometry( const QgsPolygon& polygon )
678+
{
679+
QList<QPolygonF> resultGeom;
680+
for ( int ring = 0; ring < polygon.size(); ++ring ) resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
681+
return resultGeom;
682+
}
683+
#endif
684+
685+
QList<QPolygonF> offsetLine( QPolygonF polyline, double dist, QGis::GeometryType geometryType )
666686
{
667687
QList<QPolygonF> resultLine;
668688

@@ -685,28 +705,25 @@ QList<QPolygonF> offsetLine( QPolygonF polyline, double dist )
685705
for ( i = 0; i < pointCount; ++i, tempPtr++ )
686706
tempPolyline[i] = QgsPoint( tempPtr->rx(), tempPtr->ry() );
687707

688-
QgsGeometry* tempGeometry = QgsGeometry::fromPolyline( tempPolyline );
708+
QgsGeometry * tempGeometry = ( geometryType == QGis::Polygon ) ? QgsGeometry::fromPolygon( QgsPolygon() << tempPolyline ) : QgsGeometry::fromPolyline( tempPolyline );
689709
if ( tempGeometry )
690710
{
691711
const GEOSGeometry* geosGeom = tempGeometry->asGeos();
692-
GEOSGeometry* offsetGeom = GEOSOffsetCurve( geosGeom, dist, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ );
712+
GEOSGeometry* offsetGeom = ( geometryType == QGis::Polygon ) ? GEOSBuffer( geosGeom, -dist, 8 /*quadSegments*/ ) : GEOSOffsetCurve( geosGeom, dist, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ );
693713

694714
if ( offsetGeom )
695715
{
696716
tempGeometry->fromGeos( offsetGeom );
697717

698718
if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBLineString )
699719
{
700-
tempPolyline = tempGeometry->asPolyline();
701-
702-
pointCount = tempPolyline.count();
703-
newLine.resize( pointCount );
704-
705-
QgsPoint* tempPtr2 = tempPolyline.data();
706-
for ( i = 0; i < pointCount; ++i, tempPtr2++ )
707-
newLine[i] = QPointF( tempPtr2->x(), tempPtr2->y() );
708-
resultLine.append( newLine );
709-
720+
resultLine.append( makeOffsetGeometry( tempGeometry->asPolyline() ) );
721+
delete tempGeometry;
722+
return resultLine;
723+
}
724+
else if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBPolygon )
725+
{
726+
resultLine.append( makeOffsetGeometry( tempGeometry->asPolygon() ) );
710727
delete tempGeometry;
711728
return resultLine;
712729
}
@@ -716,17 +733,18 @@ QList<QPolygonF> offsetLine( QPolygonF polyline, double dist )
716733

717734
for ( int part = 0; part < tempMPolyline.count(); ++part )
718735
{
719-
tempPolyline = tempMPolyline[ part ];
720-
721-
pointCount = tempPolyline.count();
722-
newLine.resize( pointCount );
723-
724-
QgsPoint* tempPtr2 = tempPolyline.data();
725-
for ( i = 0; i < pointCount; ++i, tempPtr2++ )
726-
newLine[i] = QPointF( tempPtr2->x(), tempPtr2->y() );
727-
resultLine.append( newLine );
736+
resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
737+
}
738+
delete tempGeometry;
739+
return resultLine;
740+
}
741+
else if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBMultiPolygon )
742+
{
743+
QgsMultiPolygon tempMPolygon = tempGeometry->asMultiPolygon();
728744

729-
newLine = QPolygonF();
745+
for ( int part = 0; part < tempMPolygon.count(); ++part )
746+
{
747+
resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
730748
}
731749
delete tempGeometry;
732750
return resultLine;
@@ -781,6 +799,21 @@ QList<QPolygonF> offsetLine( QPolygonF polyline, double dist )
781799

782800
#endif
783801
}
802+
QList<QPolygonF> offsetLine( QPolygonF polyline, double dist )
803+
{
804+
QGis::GeometryType geometryType = QGis::Point;
805+
int pointCount = polyline.count();
806+
807+
if ( pointCount > 3 && polyline[ 0 ].x() == polyline[ pointCount - 1 ].x() && polyline[ 0 ].y() == polyline[ pointCount - 1 ].y() )
808+
{
809+
geometryType = QGis::Polygon;
810+
}
811+
else if ( pointCount > 1 )
812+
{
813+
geometryType = QGis::Line;
814+
}
815+
return offsetLine( polyline, dist, geometryType );
816+
}
784817

785818
/////
786819

‎src/core/symbology-ng/qgssymbollayerv2utils.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,10 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
312312

313313
class QPolygonF;
314314

315-
//! calculate line shifted by a specified distance
315+
//! @deprecated since 2.4 - calculate line shifted by a specified distance
316316
QList<QPolygonF> offsetLine( QPolygonF polyline, double dist );
317-
317+
//! calculate geometry shifted by a specified distance
318+
QList<QPolygonF> offsetLine( QPolygonF polyline, double dist, QGis::GeometryType geometryType );
318319

319320
#endif
320321

0 commit comments

Comments
 (0)
Please sign in to comment.