1 /***************************************************************************
2 testqgscurve.cpp
3 --------------------------------------
4 Date : 21 July 2017
5 Copyright : (C) 2017-2019 by Sandro Santilli
6 Email : strk @ kbt.io
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15 #include <QObject>
16 #include <QString>
17 #include <QApplication>
18 #include <memory> // for unique_ptr
19
20 //qgis includes...
21 #include "qgsabstractgeometry.h"
22 #include "qgscircularstring.h"
23 #include "qgsgeometry.h"
24 #include "qgsgeometryfactory.h"
25 #include "qgslinestring.h"
26 #include "qgspoint.h"
27 #include "qgstest.h"
28
29 /**
30 * \ingroup UnitTests
31 * This is a unit test for the operations on curve geometries
32 */
33 class TestQgsCurve : public QObject
34 {
35 Q_OBJECT
36
37 public:
38 TestQgsCurve() = default;
39
40 private slots:
41 //void initTestCase();// will be called before the first testfunction is executed.
42 //void cleanupTestCase();// will be called after the last testfunction was executed.
43 //void init();// will be called before each testfunction is executed.
44 //void cleanup();// will be called after every testfunction.
45
46 void curveToLine();
47 };
48
49
50 #define TEST_C2L(circularString, tol, toltype, exp, prec) { \
51 std::unique_ptr< QgsLineString > lineString( \
52 circularString->curveToLine(tol, toltype) \
53 ); \
54 QVERIFY( lineString.get() ); \
55 QString wkt_out = lineString->asWkt(prec); \
56 QCOMPARE( wkt_out, QString( exp ) ); \
57 /* Test reverse */ \
58 std::unique_ptr< QgsCircularString > reversed( \
59 circularString->reversed() \
60 ); \
61 lineString.reset( \
62 reversed->curveToLine(tol, toltype) \
63 ); \
64 wkt_out = lineString->asWkt(prec); \
65 lineString.reset( \
66 reversed->curveToLine(tol, toltype) \
67 ); \
68 std::unique_ptr< QgsLineString > expgeom( \
69 dynamic_cast<QgsLineString *>( \
70 QgsGeometryFactory::geomFromWkt( exp ).release() \
71 ) \
72 ); \
73 expgeom.reset( expgeom->reversed() ); \
74 QString exp_reversed = expgeom->asWkt(prec); \
75 QCOMPARE( wkt_out, exp_reversed ); \
76 }
77
curveToLine()78 void TestQgsCurve::curveToLine()
79 {
80 std::unique_ptr< QgsCircularString > circularString;
81
82 /* input: 2 quadrants arc (180 degrees, PI radians) */
83 circularString.reset( dynamic_cast< QgsCircularString *>(
84 QgsGeometryFactory::geomFromWkt( QStringLiteral(
85 "CIRCULARSTRING(0 0,100 100,200 0)"
86 )
87 ).release()
88 ) );
89 QVERIFY( circularString.get() );
90
91 /* op: Maximum of 10 units of difference, symmetric */
92 TEST_C2L( circularString, 10, QgsAbstractGeometry::MaximumDifference,
93 "LineString (0 0, 29.29 70.71, 100 100, 170.71 70.71, 200 0)", 2 );
94
95 /* op: Maximum of 300 units (higher than sagitta) of difference, symmetric */
96 /* See https://github.com/qgis/QGIS/issues/31832 */
97 TEST_C2L( circularString, 300, QgsAbstractGeometry::MaximumDifference,
98 "LineString (0 0, 200 0)", 2 );
99
100 /* op: Maximum of M_PI / 8 degrees of angle, (a)symmetric */
101 /* See https://github.com/qgis/QGIS/issues/24616 */
102 TEST_C2L( circularString, M_PI / 8, QgsAbstractGeometry::MaximumAngle,
103 "LineString (0 0, 7.61 38.27, 29.29 70.71, 61.73 92.39, 100 100, 138.27 92.39, 170.71 70.71, 192.39 38.27, 200 0)", 2 );
104
105 /* op: Maximum of 70 degrees of angle, symmetric */
106 /* See https://github.com/qgis/QGIS/issues/24621 */
107 TEST_C2L( circularString, 70 * M_PI / 180, QgsAbstractGeometry::MaximumAngle,
108 "LineString (0 0, 50 86.6, 150 86.6, 200 0)", 2 );
109
110 /* input: 2 arcs of 2 quadrants each (180 degrees + 180 degrees other direction) */
111 circularString.reset( dynamic_cast<QgsCircularString *>(
112 QgsGeometryFactory::geomFromWkt( QStringLiteral(
113 "CIRCULARSTRING(0 0,100 100,200 0,300 -100,400 0)"
114 ) ).release()
115 ) );
116 QVERIFY( circularString.get() );
117
118 /* op: Maximum of M_PI / 3 degrees of angle */
119 TEST_C2L( circularString, M_PI / 3, QgsAbstractGeometry::MaximumAngle,
120 "LineString (0 0, 50 86.6, 150 86.6, 200 0, 250 -86.6, 350 -86.6, 400 0)", 2 );
121 }
122
123
124 QGSTEST_MAIN( TestQgsCurve )
125 #include "testqgscurve.moc"
126