Skip to content

Commit 4bcb1dd

Browse files
authored
Merge pull request #4104 from nyalldawson/area
Forward port curvepolygon area fixes to 2.18
2 parents 73e0811 + c0516a4 commit 4bcb1dd

7 files changed

Lines changed: 42 additions & 19 deletions

File tree

python/core/geometry/qgscurvev2.sip

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ class QgsCurveV2: public QgsAbstractGeometryV2
5454
*/
5555
virtual int numPoints() const = 0;
5656

57-
/** Calculates the area of the curve. Derived classes should override this
58-
* to return the correct area of the curve.
57+
/** Sums up the area of the curve by iterating over the vertices (shoelace formula).
5958
*/
6059
virtual void sumUpArea( double& sum ) const = 0;
6160

src/core/geometry/qgscurvepolygonv2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ double QgsCurvePolygonV2::area() const
371371

372372
double totalArea = 0.0;
373373

374-
if ( mExteriorRing->isClosed() )
374+
if ( mExteriorRing->isRing() )
375375
{
376376
double area = 0.0;
377377
mExteriorRing->sumUpArea( area );
@@ -382,7 +382,7 @@ double QgsCurvePolygonV2::area() const
382382
for ( ; ringIt != mInteriorRings.constEnd(); ++ringIt )
383383
{
384384
double area = 0.0;
385-
if (( *ringIt )->isClosed() )
385+
if (( *ringIt )->isRing() )
386386
{
387387
( *ringIt )->sumUpArea( area );
388388
totalArea -= qAbs( area );

src/core/geometry/qgscurvev2.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ class CORE_EXPORT QgsCurveV2: public QgsAbstractGeometryV2
8181
*/
8282
virtual int numPoints() const = 0;
8383

84-
/** Calculates the area of the curve. Derived classes should override this
85-
* to return the correct area of the curve.
84+
/** Sums up the area of the curve by iterating over the vertices (shoelace formula).
8685
*/
8786
virtual void sumUpArea( double& sum ) const = 0;
8887

src/core/geometry/qgslinestringv2.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -840,9 +840,6 @@ QgsPointV2 QgsLineStringV2::centroid() const
840840
void QgsLineStringV2::sumUpArea( double& sum ) const
841841
{
842842
int maxIndex = numPoints() - 1;
843-
if ( maxIndex == 1 )
844-
return; //no area, just a single line
845-
846843
for ( int i = 0; i < maxIndex; ++i )
847844
{
848845
sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );

tests/src/core/testqgsgeometry.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
//qgis includes...
2929
#include <qgsapplication.h>
30+
#include "qgscompoundcurvev2.h"
3031
#include <qgsgeometry.h>
3132
#include "qgsgeometryutils.h"
3233
#include <qgspoint.h>
@@ -67,6 +68,7 @@ class TestQgsGeometry : public QObject
6768
// geometry types
6869
void pointV2(); //test QgsPointV2
6970
void lineStringV2(); //test QgsLineStringV2
71+
void compoundCurveV2(); //test QgsCompoundCurveV2
7072
void polygonV2(); //test QgsPolygonV2
7173
void multiPoint();
7274
void multiLineString();
@@ -2077,13 +2079,13 @@ void TestQgsGeometry::lineStringV2()
20772079
QCOMPARE( area, 1.0 );
20782080
l36.setPoints( QgsPointSequenceV2() << QgsPointV2( 5, 10 ) << QgsPointV2( 10, 10 ) );
20792081
l36.sumUpArea( area );
2080-
QCOMPARE( area, 1.0 );
2082+
QVERIFY( qgsDoubleNear( area, -24 ) );
20812083
l36.setPoints( QgsPointSequenceV2() << QgsPointV2( 0, 0 ) << QgsPointV2( 2, 0 ) << QgsPointV2( 2, 2 ) );
20822084
l36.sumUpArea( area );
2083-
QVERIFY( qgsDoubleNear( area, 3.0 ) );
2085+
QVERIFY( qgsDoubleNear( area, -22 ) );
20842086
l36.setPoints( QgsPointSequenceV2() << QgsPointV2( 0, 0 ) << QgsPointV2( 2, 0 ) << QgsPointV2( 2, 2 ) << QgsPointV2( 0, 2 ) );
20852087
l36.sumUpArea( area );
2086-
QVERIFY( qgsDoubleNear( area, 7.0 ) );
2088+
QVERIFY( qgsDoubleNear( area, -18 ) );
20872089

20882090
//boundingBox - test that bounding box is updated after every modification to the line string
20892091
QgsLineStringV2 l37;
@@ -2200,6 +2202,31 @@ void TestQgsGeometry::lineStringV2()
22002202
QCOMPARE( static_cast< QgsPointV2*>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
22012203
}
22022204

2205+
void TestQgsGeometry::compoundCurveV2()
2206+
{
2207+
//test that area of a compound curve ring is equal to a closed linestring with the same vertices
2208+
QgsCompoundCurveV2 cc;
2209+
QgsLineStringV2* l1 = new QgsLineStringV2();
2210+
l1->setPoints( QgsPointSequenceV2() << QgsPointV2( 1, 1 ) << QgsPointV2( 0, 2 ) );
2211+
cc.addCurve( l1 );
2212+
QgsLineStringV2* l2 = new QgsLineStringV2();
2213+
l2->setPoints( QgsPointSequenceV2() << QgsPointV2( 0, 2 ) << QgsPointV2( -1, 0 ) << QgsPointV2( 0, -1 ) );
2214+
cc.addCurve( l2 );
2215+
QgsLineStringV2* l3 = new QgsLineStringV2();
2216+
l3->setPoints( QgsPointSequenceV2() << QgsPointV2( 0, -1 ) << QgsPointV2( 1, 1 ) );
2217+
cc.addCurve( l3 );
2218+
2219+
double ccArea = 0.0;
2220+
cc.sumUpArea( ccArea );
2221+
2222+
QgsLineStringV2 ls;
2223+
ls.setPoints( QgsPointSequenceV2() << QgsPointV2( 1, 1 ) << QgsPointV2( 0, 2 ) << QgsPointV2( -1, 0 ) << QgsPointV2( 0, -1 )
2224+
<< QgsPointV2( 1, 1 ) );
2225+
double lsArea = 0.0;
2226+
ls.sumUpArea( lsArea );
2227+
QVERIFY( qgsDoubleNear( ccArea, lsArea ) );
2228+
}
2229+
22032230
void TestQgsGeometry::polygonV2()
22042231
{
22052232
//test constructor

tests/src/python/test_qgsgeometry.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,31 +180,31 @@ def testReferenceGeometry(self):
180180
bbox = geom.geometry().boundingBox()
181181
exp = float(row['x_min'])
182182
result = bbox.xMinimum()
183-
assert doubleNear(result, exp), "Min X {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
183+
self.assertAlmostEqual(result, exp, 5, "Min X {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
184184
exp = float(row['y_min'])
185185
result = bbox.yMinimum()
186-
assert doubleNear(result, exp), "Min Y {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
186+
self.assertAlmostEqual(result, exp, 5, "Min Y {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
187187
exp = float(row['x_max'])
188188
result = bbox.xMaximum()
189-
assert doubleNear(result, exp), "Max X {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
189+
self.assertAlmostEqual(result, exp, 5, "Max X {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
190190
exp = float(row['y_max'])
191191
result = bbox.yMaximum()
192-
assert doubleNear(result, exp), "Max Y {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
192+
self.assertAlmostEqual(result, exp, 5, "Max Y {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
193193

194194
# test area calculation
195195
exp = float(row['area'])
196196
result = geom.geometry().area()
197-
assert doubleNear(result, exp), "Area {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
197+
self.assertAlmostEqual(result, exp, 5, "Area {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
198198

199199
# test length calculation
200200
exp = float(row['length'])
201201
result = geom.geometry().length()
202-
assert doubleNear(result, exp, 0.00001), "Length {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
202+
self.assertAlmostEqual(result, exp, 5, "Length {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
203203

204204
# test perimeter calculation
205205
exp = float(row['perimeter'])
206206
result = geom.geometry().perimeter()
207-
assert doubleNear(result, exp, 0.00001), "Perimeter {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result)
207+
self.assertAlmostEqual(result, exp, 5, "Perimeter {}: mismatch Expected:\n{}\nGot:\n{}\n".format(i + 1, exp, result))
208208

209209
def testIntersection(self):
210210
myLine = QgsGeometry.fromPolyline([

tests/testdata/geom_data.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,4 @@ Polygon,,,,,,,,,,,,,,Malformed WKT
120120
"PolygonM ((0 0 1, 10 0 1, 10 10 1, 0 10 1, 0 0 1),(5 5 1, 7 5 1, 7 7 1, 5 7 1, 5 5 1),(1 1 1,2 1 1, 2 2 1, 1 2 1, 1 1 1))","POLYGON M ((0 0 1,10 0 1,10 10 1,0 10 1,0 0 1),(5 5 1,7 5 1,7 7 1,5 7 1,5 5 1),(1 1 1,2 1 1,2 2 1,1 2 1,1 1 1))",15,0,95,52,1,2,0,POINT(4.99473684210526 4.99473684210526),0,0,10,10,
121121
"PolygonZ ((0 0 1 , 10 0 1, 10 10 1, 0 10 1, 0 0 1))","POLYGON Z ((0 0 1,10 0 1,10 10 1,0 10 1,0 0 1))",5,0,100,40,1,0,0,POINT(5 5),0,0,10,10,
122122
"PolygonZ ((0 0 1, 10 0 1, 10 10 1, 0 10 1, 0 0 1),(5 5 1, 7 5 1, 7 7 1 , 5 7 1, 5 5 1))","POLYGON Z ((0 0 1,10 0 1,10 10 1,0 10 1,0 0 1),(5 5 1,7 5 1,7 7 1,5 7 1,5 5 1))",10,0,96,48,1,1,0,POINT(4.95833333333333 4.95833333333333),0,0,10,10,
123+
"CurvePolygon (CompoundCurve ((2678124.57778842002153397 1225804.43286111624911427, 2678251.0684670670889318 1225964.66278979112394154, 2678201.75901959836483002 1226077.95337014575488865, 2678199.27904875669628382 1226083.94340024818666279, 2678198.13904719380661845 1226083.5034040967002511, 2678188.08903313148766756 1226079.56343783461488783, 2678164.688993189483881 1226068.85351158352568746, 2678152.65896565327420831 1226061.85354482522234321, 2678133.63892276119440794 1226050.92359781125560403),CircularString (2678133.63892276119440794 1226050.92359781125560403, 2678124.47892813989892602 1226045.71365369856357574, 2678115.92887723352760077 1226039.55364341707900167, 2678110.39902341179549694 1226025.70413719792850316, 2678113.52874504774808884 1226011.12356549175456166, 2678117.04747172351926565 1226004.70550769660621881, 2678121.17868330329656601 1225998.66349145700223744, 2678122.91810466628521681 1225991.71089569479227066, 2678120.73861891590058804 1225984.88345037144608796, 2678109.63862727722153068 1225981.37343537760898471, 2678097.99861149024218321 1225981.17354299034923315, 2678087.07146158767864108 1225984.57272616261616349, 2678076.13865283969789743 1225987.95366438734345138, 2678068.26173875294625759 1225987.17441278789192438, 2678060.82864314317703247 1225984.45372360944747925, 2678052.37183309439569712 1225977.24715672573074698, 2678045.5285750487819314 1225968.49374381266534328, 2678039.90821403311565518 1225957.94303491595201194, 2678035.46847799280658364 1225946.84372220188379288, 2678033.64745173417031765 1225940.12937669246457517, 2678032.40841578459367156 1225933.28369381325319409, 2678033.68931351415812969 1225925.84029478346928954, 2678036.55834634136408567 1225918.85362965753301978, 2678039.0693440935574472 1225913.78109931806102395, 2678040.70829536207020283 1225908.363577825948596),(2678040.70829536207020283 1225908.363577825948596, 2678124.57778842002153397 1225804.43286111624911427)))","CurvePolygon (CompoundCurve ((2678124.57778842002153397 1225804.43286111624911427, 2678251.0684670670889318 1225964.66278979112394154, 2678201.75901959836483002 1226077.95337014575488865, 2678199.27904875669628382 1226083.94340024818666279, 2678198.13904719380661845 1226083.5034040967002511, 2678188.08903313148766756 1226079.56343783461488783, 2678164.688993189483881 1226068.85351158352568746, 2678152.65896565327420831 1226061.85354482522234321, 2678133.63892276119440794 1226050.92359781125560403),CircularString (2678133.63892276119440794 1226050.92359781125560403, 2678124.47892813989892602 1226045.71365369856357574, 2678115.92887723352760077 1226039.55364341707900167, 2678110.39902341179549694 1226025.70413719792850316, 2678113.52874504774808884 1226011.12356549175456166, 2678117.04747172351926565 1226004.70550769660621881, 2678121.17868330329656601 1225998.66349145700223744, 2678122.91810466628521681 1225991.71089569479227066, 2678120.73861891590058804 1225984.88345037144608796, 2678109.63862727722153068 1225981.37343537760898471, 2678097.99861149024218321 1225981.17354299034923315, 2678087.07146158767864108 1225984.57272616261616349, 2678076.13865283969789743 1225987.95366438734345138, 2678068.26173875294625759 1225987.17441278789192438, 2678060.82864314317703247 1225984.45372360944747925, 2678052.37183309439569712 1225977.24715672573074698, 2678045.5285750487819314 1225968.49374381266534328, 2678039.90821403311565518 1225957.94303491595201194, 2678035.46847799280658364 1225946.84372220188379288, 2678033.64745173417031765 1225940.12937669246457517, 2678032.40841578459367156 1225933.28369381325319409, 2678033.68931351415812969 1225925.84029478346928954, 2678036.55834634136408567 1225918.85362965753301978, 2678039.0693440935574472 1225913.78109931806102395, 2678040.70829536207020283 1225908.363577825948596),(2678040.70829536207020283 1225908.363577825948596, 2678124.57778842002153397 1225804.43286111624911427)))",34,0,32087.8047511,770.542777805,1,1,0,Point (2678143.67776390677317977 1225948.36456208629533648),2678032.40842,1225804.43286112,2678251.06846707,1226083.94340025,

0 commit comments

Comments
 (0)