diff --git a/src/core/symbology-ng/qgslinesymbollayerv2.cpp b/src/core/symbology-ng/qgslinesymbollayerv2.cpp index 9bb68a4be2e..9c3f2b4825a 100644 --- a/src/core/symbology-ng/qgslinesymbollayerv2.cpp +++ b/src/core/symbology-ng/qgslinesymbollayerv2.cpp @@ -273,7 +273,7 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym else { double scaledOffset = offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale ); - QList mline = ::offsetLine( points, scaledOffset ); + QList mline = ::offsetLine( points, scaledOffset, context.feature() ? context.feature()->geometry()->type() : QGis::Line ); for ( int part = 0; part < mline.count(); ++part ) p->drawPolyline( mline[ part ] ); } @@ -779,7 +779,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym } else { - QList mline = ::offsetLine( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale ) ); + QList mline = ::offsetLine( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit, mOffsetMapUnitScale ), context.feature() ? context.feature()->geometry()->type() : QGis::Line ); for ( int part = 0; part < mline.count(); ++part ) { diff --git a/src/core/symbology-ng/qgssymbollayerv2utils.cpp b/src/core/symbology-ng/qgssymbollayerv2utils.cpp index 58c73d6bb90..58e8c1652ae 100644 --- a/src/core/symbology-ng/qgssymbollayerv2utils.cpp +++ b/src/core/symbology-ng/qgssymbollayerv2utils.cpp @@ -659,10 +659,30 @@ static QPointF linesIntersection( QPointF p1, double t1, QPointF p2, double t2 ) y = p1.y() + t1 * ( x - p1.x() ); return QPointF( x, y ); } +#else +static QPolygonF makeOffsetGeometry( const QgsPolyline& polyline ) +{ + int i, pointCount = polyline.count(); + + QPolygonF resultLine; + resultLine.resize( pointCount ); + + const QgsPoint* tempPtr = polyline.data(); + + for ( i = 0; i < pointCount; ++i, tempPtr++ ) + resultLine[i] = QPointF( tempPtr->x(), tempPtr->y() ); + + return resultLine; +} +static QList makeOffsetGeometry( const QgsPolygon& polygon ) +{ + QList resultGeom; + for ( int ring = 0; ring < polygon.size(); ++ring ) resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) ); + return resultGeom; +} #endif - -QList offsetLine( QPolygonF polyline, double dist ) +QList offsetLine( QPolygonF polyline, double dist, QGis::GeometryType geometryType ) { QList resultLine; @@ -685,11 +705,11 @@ QList offsetLine( QPolygonF polyline, double dist ) for ( i = 0; i < pointCount; ++i, tempPtr++ ) tempPolyline[i] = QgsPoint( tempPtr->rx(), tempPtr->ry() ); - QgsGeometry* tempGeometry = QgsGeometry::fromPolyline( tempPolyline ); + QgsGeometry * tempGeometry = ( geometryType == QGis::Polygon ) ? QgsGeometry::fromPolygon( QgsPolygon() << tempPolyline ) : QgsGeometry::fromPolyline( tempPolyline ); if ( tempGeometry ) { const GEOSGeometry* geosGeom = tempGeometry->asGeos(); - GEOSGeometry* offsetGeom = GEOSOffsetCurve( geosGeom, dist, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ); + GEOSGeometry* offsetGeom = ( geometryType == QGis::Polygon ) ? GEOSBuffer( geosGeom, -dist, 8 /*quadSegments*/ ) : GEOSOffsetCurve( geosGeom, dist, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ); if ( offsetGeom ) { @@ -697,16 +717,13 @@ QList offsetLine( QPolygonF polyline, double dist ) if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBLineString ) { - tempPolyline = tempGeometry->asPolyline(); - - pointCount = tempPolyline.count(); - newLine.resize( pointCount ); - - QgsPoint* tempPtr2 = tempPolyline.data(); - for ( i = 0; i < pointCount; ++i, tempPtr2++ ) - newLine[i] = QPointF( tempPtr2->x(), tempPtr2->y() ); - resultLine.append( newLine ); - + resultLine.append( makeOffsetGeometry( tempGeometry->asPolyline() ) ); + delete tempGeometry; + return resultLine; + } + else if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBPolygon ) + { + resultLine.append( makeOffsetGeometry( tempGeometry->asPolygon() ) ); delete tempGeometry; return resultLine; } @@ -716,17 +733,18 @@ QList offsetLine( QPolygonF polyline, double dist ) for ( int part = 0; part < tempMPolyline.count(); ++part ) { - tempPolyline = tempMPolyline[ part ]; + resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) ); + } + delete tempGeometry; + return resultLine; + } + else if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBMultiPolygon ) + { + QgsMultiPolygon tempMPolygon = tempGeometry->asMultiPolygon(); - pointCount = tempPolyline.count(); - newLine.resize( pointCount ); - - QgsPoint* tempPtr2 = tempPolyline.data(); - for ( i = 0; i < pointCount; ++i, tempPtr2++ ) - newLine[i] = QPointF( tempPtr2->x(), tempPtr2->y() ); - resultLine.append( newLine ); - - newLine = QPolygonF(); + for ( int part = 0; part < tempMPolygon.count(); ++part ) + { + resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) ); } delete tempGeometry; return resultLine; @@ -781,6 +799,21 @@ QList offsetLine( QPolygonF polyline, double dist ) #endif } +QList offsetLine( QPolygonF polyline, double dist ) +{ + QGis::GeometryType geometryType = QGis::Point; + int pointCount = polyline.count(); + + if ( pointCount > 3 && polyline[ 0 ].x() == polyline[ pointCount - 1 ].x() && polyline[ 0 ].y() == polyline[ pointCount - 1 ].y() ) + { + geometryType = QGis::Polygon; + } + else if ( pointCount > 1 ) + { + geometryType = QGis::Line; + } + return offsetLine( polyline, dist, geometryType ); +} ///// diff --git a/src/core/symbology-ng/qgssymbollayerv2utils.h b/src/core/symbology-ng/qgssymbollayerv2utils.h index 1d10e8f1296..f178486e5ef 100644 --- a/src/core/symbology-ng/qgssymbollayerv2utils.h +++ b/src/core/symbology-ng/qgssymbollayerv2utils.h @@ -312,9 +312,10 @@ class CORE_EXPORT QgsSymbolLayerV2Utils class QPolygonF; -//! calculate line shifted by a specified distance +//! @deprecated since 2.4 - calculate line shifted by a specified distance QList offsetLine( QPolygonF polyline, double dist ); - +//! calculate geometry shifted by a specified distance +QList offsetLine( QPolygonF polyline, double dist, QGis::GeometryType geometryType ); #endif