Skip to content

Commit

Permalink
Merge pull request #42648 from roya0045/fix_mainangle
Browse files Browse the repository at this point in the history
[Bugfix] geometry engine::main_angle : promote longer box in case of tie
  • Loading branch information
lbartoletti committed Oct 11, 2021
2 parents 7a0fb2a + 6a717fc commit 1666afe
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 2 deletions.
2 changes: 1 addition & 1 deletion resources/function_help/json/main_angle
Expand Up @@ -2,7 +2,7 @@
"name": "main_angle",
"type": "function",
"groups": ["GeometryGroup"],
"description":"Returns the main angle of a geometry (clockwise, in degrees from North), which represents the angle of the oriented minimal bounding rectangle which completely covers the geometry.",
"description":"Returns the angle of the long axis (clockwise, in degrees from North) of the oriented minimal bounding rectangle, which completely covers the geometry.",
"arguments": [ {"arg":"geometry","description":"a geometry"} ],
"examples": [ { "expression":"main_angle(geom_from_wkt('Polygon ((321577 129614, 321581 129618, 321585 129615, 321581 129610, 321577 129614))'))", "returns":"38.66"}]
}
Expand Down
7 changes: 7 additions & 0 deletions src/core/geometry/qgsinternalgeometryengine.cpp
Expand Up @@ -1629,6 +1629,13 @@ QgsGeometry QgsInternalGeometryEngine::orientedMinimumBoundingBox( double &area,
pt1 = hull->vertexAt( vertexId );
}

if ( width > height )
{
width = minRect.height();
height = minRect.width();
angle = angle + 90.0;
}

QgsGeometry minBounds = QgsGeometry::fromRect( minRect );
minBounds.rotate( angle, QgsPointXY( pt0.x(), pt0.y() ) );

Expand Down
3 changes: 2 additions & 1 deletion src/core/geometry/qgsinternalgeometryengine.h
Expand Up @@ -213,7 +213,8 @@ class QgsInternalGeometryEngine

/**
* Returns the oriented minimum bounding box for the geometry, which is the smallest (by area)
* rotated rectangle which fully encompasses the geometry. The area, angle (clockwise in degrees from North),
* rotated rectangle which fully encompasses the geometry.
* The area, angle of the long axis (clockwise in degrees from North),
* width and height of the rotated bounding box will also be returned.
*
* If an error was encountered while creating the result, more information can be retrieved
Expand Down
1 change: 1 addition & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -1358,6 +1358,7 @@ class TestQgsExpression: public QObject
QTest::newRow( "m_min line M NaN" ) << "m_min(make_line(geom_from_wkt('PointZM (0 0 0 nan)'),geom_from_wkt('PointZM (1 1 1 2)')))" << false << QVariant( );
QTest::newRow( "m_min line" ) << "m_min(make_line(make_point_m(0,0,1),make_point_m(-1,-1,2),make_point_m(-2,-2,0)))" << false << QVariant( 0.0 );
QTest::newRow( "main angle polygon" ) << "round(main_angle( geom_from_wkt('POLYGON((0 0,2 9,9 2,0 0))')))" << false << QVariant( 77 );
QTest::newRow( "main angle polygon edge case" ) << "round(main_angle( geom_from_wkt('POLYGON((353542.63843526 378974.92373469, 353544.95808017 378975.73690545, 353545.27173175 378974.84218528, 353542.95208684 378974.02901451, 353542.63843526 378974.92373469))')))" << false << QVariant( 71 );
QTest::newRow( "main angle multi polygon" ) << "round(main_angle( geom_from_wkt('MULTIPOLYGON(((0 0,3 10,1 10,1 6,0 0)))')))" << false << QVariant( 17 );
QTest::newRow( "main angle point" ) << "main_angle( geom_from_wkt('POINT (1.5 0.5)') )" << true << QVariant();
QTest::newRow( "main angle line" ) << "round(main_angle( geom_from_wkt('LINESTRING (-1 2, 9 12)') ))" << false << QVariant( 45 );
Expand Down

0 comments on commit 1666afe

Please sign in to comment.