diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp
index d085a5e6c76f..230fca2c2e40 100644
--- a/src/core/geometry/qgsgeometryutils.cpp
+++ b/src/core/geometry/qgsgeometryutils.cpp
@@ -922,7 +922,8 @@ void QgsGeometryUtils::segmentizeArc( const QgsPoint &p1, const QgsPoint &p2, co
if ( symmetric )
{
double angle = a3 - a1;
- if ( angle < 0 ) angle += M_PI * 2;
+ // angle == 0 when full circle
+ if ( angle <= 0 ) angle += M_PI * 2;
/* Number of segments in output */
int segs = ceil( angle / increment );
@@ -931,7 +932,8 @@ void QgsGeometryUtils::segmentizeArc( const QgsPoint &p1, const QgsPoint &p2, co
}
/* Adjust a3 up so we can increment from a1 to a3 cleanly */
- if ( a3 < a1 )
+ // a3 == a1 when full circle
+ if ( a3 <= a1 )
a3 += 2.0 * M_PI;
if ( a2 < a1 )
a2 += 2.0 * M_PI;
diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp
index c9bc707d8f66..736002800f8c 100644
--- a/tests/src/core/testqgsgeometry.cpp
+++ b/tests/src/core/testqgsgeometry.cpp
@@ -13927,66 +13927,64 @@ void TestQgsGeometry::multiSurface()
//as JSON
QgsMultiSurface exportC;
- ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
+ QgsLineString lineRing;
+ lineRing.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 7, 13 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
part.clear();
- part.setExteriorRing( ring.clone() );
+ part.setExteriorRing( lineRing.clone() );
exportC.addGeometry( part.clone() );
- ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
+ lineRing.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 27, 43 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
part.clear();
- part.setExteriorRing( ring.clone() );
+ part.setExteriorRing( lineRing.clone() );
exportC.addGeometry( part.clone() );
// GML document for compare
QDomDocument doc( "gml" );
// as GML2
- QString expectedSimpleGML2( QStringLiteral( "7,17 7,1727,37 27,37" ) );
+ QString expectedSimpleGML2( QStringLiteral( "7,17 7,13 3,13 7,1727,37 27,43 43,43 27,37" ) );
QString res = elemToString( exportC.asGml2( doc, 1 ) );
QGSCOMPAREGML( res, expectedSimpleGML2 );
QString expectedGML2empty( QStringLiteral( "" ) );
QGSCOMPAREGML( elemToString( QgsMultiSurface().asGml2( doc ) ), expectedGML2empty );
//as GML3
- QString expectedSimpleGML3( QStringLiteral( "7 17 3 13 7 1727 37 43 43 27 37" ) );
+
+ QString expectedSimpleGML3( QStringLiteral( "7 17 7 13 3 13 7 1727 37 27 43 43 43 27 37" ) );
res = elemToString( exportC.asGml3( doc ) );
QCOMPARE( res, expectedSimpleGML3 );
QString expectedGML3empty( QStringLiteral( "" ) );
QGSCOMPAREGML( elemToString( QgsMultiSurface().asGml3( doc ) ), expectedGML3empty );
// as JSON
- QString expectedSimpleJson( "{\"coordinates\":[[[7.0,17.0],[7.0,17.0]],[[27.0,37.0],[27.0,37.0]]],\"type\":\"MultiPolygon\"}" );
+ QString expectedSimpleJson( "{\"coordinates\":[[[7.0,17.0],[7.0,13.0],[3.0,13.0],[7.0,17.0]],[[27.0,37.0],[27.0,43.0],[43.0,43.0],[27.0,37.0]]],\"type\":\"MultiPolygon\"}" );
res = exportC.asJson( 1 );
QCOMPARE( res, expectedSimpleJson );
- ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 17, 27 ) << QgsPoint( QgsWkbTypes::Point, 18, 28 ) << QgsPoint( QgsWkbTypes::Point, 17, 27 ) ) ;
- part.addInteriorRing( ring.clone() );
+ lineRing.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 17, 27 ) << QgsPoint( QgsWkbTypes::Point, 17, 28 ) << QgsPoint( QgsWkbTypes::Point, 18, 28 ) << QgsPoint( QgsWkbTypes::Point, 17, 27 ) ) ;
+ part.addInteriorRing( lineRing.clone() );
exportC.addGeometry( part.clone() );
- QString expectedJsonWithRings( "{\"coordinates\":[[[7.0,17.0],[7.0,17.0]],[[27.0,37.0],[27.0,37.0]],[[27.0,37.0],[27.0,37.0]],[[17.0,27.0],[17.0,27.0]]],\"type\":\"MultiPolygon\"}" );
+ QString expectedJsonWithRings( "{\"coordinates\":[[[7.0,17.0],[7.0,13.0],[3.0,13.0],[7.0,17.0]],[[27.0,37.0],[27.0,43.0],[43.0,43.0],[27.0,37.0]],[[27.0,37.0],[27.0,43.0],[43.0,43.0],[27.0,37.0]],[[17.0,27.0],[17.0,28.0],[18.0,28.0],[17.0,27.0]]],\"type\":\"MultiPolygon\"}" );
res = exportC.asJson( 1 );
QCOMPARE( res, expectedJsonWithRings );
QgsMultiSurface exportFloat;
- ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 3 / 5.0, 13 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) ) ;
+ lineRing.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 0.1234, 0.1234 ) << QgsPoint( QgsWkbTypes::Point, 0.1234, 1.2344 ) << QgsPoint( QgsWkbTypes::Point, 1.2344, 1.2344 ) << QgsPoint( QgsWkbTypes::Point, 0.1234, 0.1234 ) ) ;
part.clear();
- part.setExteriorRing( ring.clone() );
- exportFloat.addGeometry( part.clone() );
- ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 43 / 41.0, 43 / 42.0 ) << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) ) ;
- part.clear();
- part.setExteriorRing( ring.clone() );
+ part.setExteriorRing( lineRing.clone() );
exportFloat.addGeometry( part.clone() );
- QString expectedJsonPrec3( QStringLiteral( "{\"coordinates\":[[[2.333,5.667],[2.333,5.667]],[[9.0,4.111],[9.0,4.111]]],\"type\":\"MultiPolygon\"}" ) );
+ QString expectedJsonPrec3( QStringLiteral( "{\"coordinates\":[[[0.123,0.123],[0.123,1.234],[1.234,1.234],[0.123,0.123]]],\"type\":\"MultiPolygon\"}" ) );
res = exportFloat.asJson( 3 );
QCOMPARE( res, expectedJsonPrec3 );
// as GML2
- QString expectedGML2prec3( QStringLiteral( "2.333,5.667 2.333,5.6679,4.111 9,4.111" ) );
+ QString expectedGML2prec3( QStringLiteral( "0.123,0.123 0.123,1.234 1.234,1.234 0.123,0.123" ) );
res = elemToString( exportFloat.asGml2( doc, 3 ) );
QGSCOMPAREGML( res, expectedGML2prec3 );
//as GML3
- QString expectedGML3prec3( QStringLiteral( "2.333 5.667 0.6 4.333 2.333 5.6679 4.111 1.049 1.024 9 4.111" ) );
+ QString expectedGML3prec3( QStringLiteral( "0.123 0.123 0.123 1.234 1.234 1.234 0.123 0.123" ) );
res = elemToString( exportFloat.asGml3( doc, 3 ) );
QCOMPARE( res, expectedGML3prec3 );
diff --git a/tests/src/core/testqgsgeometryutils.cpp b/tests/src/core/testqgsgeometryutils.cpp
index be107e23aec5..a79f14519f31 100644
--- a/tests/src/core/testqgsgeometryutils.cpp
+++ b/tests/src/core/testqgsgeometryutils.cpp
@@ -13,6 +13,8 @@
* *
***************************************************************************/
+#include
+
#include "qgstest.h"
#include
#include "qgsgeometryutils.h"
@@ -71,6 +73,9 @@ class TestQgsGeometryUtils: public QObject
void testInterpolatePointOnLineByValue();
void testPointOnLineWithDistance();
void interpolatePointOnArc();
+ void testSegmentizeArcHalfCircle();
+ void testSegmentizeArcHalfCircleOtherDirection();
+ void testSegmentizeArcFullCircle();
};
@@ -1271,5 +1276,74 @@ void TestQgsGeometryUtils::interpolatePointOnArc()
QGSCOMPARENEAR( p.y(), -2.0, 0.00001 );
}
+void TestQgsGeometryUtils::testSegmentizeArcHalfCircle()
+{
+ QgsPointSequence points;
+ const double xoff = 1;
+ const double yoff = 100;
+ QgsGeometryUtils::segmentizeArc( QgsPoint( xoff + 0, yoff + 0 ),
+ QgsPoint( xoff + 1, yoff + 1 ),
+ QgsPoint( xoff + 2, yoff + 0 ),
+ points, 0.1,
+ QgsAbstractGeometry::MaximumDifference, false, false );
+ QCOMPARE( points.size(), 5 );
+ QGSCOMPARENEAR( points[0].x(), xoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[0].y(), yoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[1].x(), xoff + 1 - sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[1].y(), yoff + sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[2].x(), xoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[2].y(), yoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[3].x(), xoff + 1 + sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[3].y(), yoff + sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[4].x(), xoff + 2.0, 0.00001 );
+ QGSCOMPARENEAR( points[4].y(), yoff + 0.0, 0.00001 );
+}
+
+void TestQgsGeometryUtils::testSegmentizeArcHalfCircleOtherDirection()
+{
+ QgsPointSequence points;
+ const double xoff = 1;
+ const double yoff = 100;
+ QgsGeometryUtils::segmentizeArc( QgsPoint( xoff + 0, yoff + 0 ),
+ QgsPoint( xoff + 1, yoff - 1 ),
+ QgsPoint( xoff + 2, yoff + 0 ),
+ points, 0.1,
+ QgsAbstractGeometry::MaximumDifference, false, false );
+ QCOMPARE( points.size(), 5 );
+ QGSCOMPARENEAR( points[0].x(), xoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[0].y(), yoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[1].x(), xoff + 1 - sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[1].y(), yoff + -sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[2].x(), xoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[2].y(), yoff + -1.0, 0.00001 );
+ QGSCOMPARENEAR( points[3].x(), xoff + 1 + sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[3].y(), yoff + -sqrt( 2 ) / 2, 0.00001 );
+ QGSCOMPARENEAR( points[4].x(), xoff + 2.0, 0.00001 );
+ QGSCOMPARENEAR( points[4].y(), yoff + 0.0, 0.00001 );
+}
+
+void TestQgsGeometryUtils::testSegmentizeArcFullCircle()
+{
+ QgsPointSequence points;
+ const double xoff = 1;
+ const double yoff = 100;
+ QgsGeometryUtils::segmentizeArc( QgsPoint( xoff + 0, yoff + 0 ),
+ QgsPoint( xoff + 2, yoff + 0 ),
+ QgsPoint( xoff + 0, yoff + 0 ),
+ points, 0.4,
+ QgsAbstractGeometry::MaximumDifference, false, false );
+ QCOMPARE( points.size(), 5 );
+ QGSCOMPARENEAR( points[0].x(), xoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[0].y(), yoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[1].x(), xoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[1].y(), yoff + -1.0, 0.00001 );
+ QGSCOMPARENEAR( points[2].x(), xoff + 2.0, 0.00001 );
+ QGSCOMPARENEAR( points[2].y(), yoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[3].x(), xoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[3].y(), yoff + 1.0, 0.00001 );
+ QGSCOMPARENEAR( points[4].x(), xoff + 0.0, 0.00001 );
+ QGSCOMPARENEAR( points[4].y(), yoff + 0.0, 0.00001 );
+}
+
QGSTEST_MAIN( TestQgsGeometryUtils )
#include "testqgsgeometryutils.moc"