Skip to content

Commit b440939

Browse files
committedNov 14, 2016
Fix test failure, report distance from pole
1 parent d6f09c0 commit b440939

File tree

9 files changed

+41
-10
lines changed

9 files changed

+41
-10
lines changed
 

‎python/core/geometry/qgsgeometry.sip

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,11 +535,12 @@ class QgsGeometry
535535
* approach guaranteed to find the true pole of inaccessibility within a specified
536536
* tolerance. More precise tolerances require more iterations and will take longer
537537
* to calculate.
538+
* Optionally, the distance to the polygon boundary from the pole can be stored.
538539
* @see centroid()
539540
* @see pointOnSurface()
540541
* @note added in QGIS 3.0
541542
*/
542-
QgsGeometry poleOfInaccessibility( double precision ) const;
543+
QgsGeometry poleOfInaccessibility( double precision, double* distanceToBoundary /Out/ = nullptr ) const;
543544

544545
/** Returns the smallest convex polygon that contains all the points in the geometry. */
545546
QgsGeometry convexHull() const;

‎python/plugins/processing/algs/help/qgis.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ qgis:polarplot: >
340340
qgis:poleofinaccessibility: >
341341
This algorithm calculates the pole of inaccessibility for a polygon layer, which is the most distant internal point from the boundary of the surface. This algorithm uses the 'polylabel' algorithm (Vladimir Agafonkin, 2016), which is an iterative approach guaranteed to find the true pole of inaccessibility within a specified tolerance (in layer units). More precise tolerances require more iterations and will take longer to calculate.
342342

343+
The distance from the calculated pole to the polygon boundary will be stored as a new attribute in the output layer.
344+
343345
qgis:polygoncentroids: >
344346
This algorithm creates a new point layer, with points representing the centroid of polygons of an input layer.
345347

‎python/plugins/processing/algs/qgis/PoleOfInaccessibility.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727

2828
import os
2929

30-
from qgis.core import QgsGeometry, QgsWkbTypes
30+
from qgis.core import QgsGeometry, QgsWkbTypes, QgsField, NULL
3131

32+
from qgis.PyQt.QtCore import QVariant
3233
from qgis.PyQt.QtGui import QIcon
3334

3435
from processing.core.GeoAlgorithm import GeoAlgorithm
@@ -65,9 +66,12 @@ def processAlgorithm(self, progress):
6566
self.getParameterValue(self.INPUT_LAYER))
6667
tolerance = self.getParameterValue(self.TOLERANCE)
6768

69+
fields = layer.fields()
70+
fields.append(QgsField('dist_pole', QVariant.Double))
71+
6872
writer = self.getOutputFromName(
6973
self.OUTPUT_LAYER).getVectorWriter(
70-
layer.fields(),
74+
fields,
7175
QgsWkbTypes.Point,
7276
layer.crs())
7377

@@ -78,12 +82,19 @@ def processAlgorithm(self, progress):
7882
output_feature = input_feature
7983
input_geometry = input_feature.geometry()
8084
if input_geometry:
81-
output_geometry = input_geometry.poleOfInaccessibility(tolerance)
85+
output_geometry, distance = input_geometry.poleOfInaccessibility(tolerance)
8286
if not output_geometry:
8387
raise GeoAlgorithmExecutionException(
8488
self.tr('Error calculating pole of inaccessibility'))
89+
attrs = input_feature.attributes()
90+
attrs.append(distance)
91+
output_feature.setAttributes(attrs)
8592

8693
output_feature.setGeometry(output_geometry)
94+
else:
95+
attrs = input_feature.attributes()
96+
attrs.append(NULL)
97+
output_feature.setAttributes(attrs)
8798

8899
writer.addFeature(output_feature)
89100
progress.setPercentage(int(current * total))

‎python/plugins/processing/tests/testdata/expected/pole_inaccessibility_polys.gml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<ogr:name>aaaaa</ogr:name>
1818
<ogr:intval>33</ogr:intval>
1919
<ogr:floatval>44.123456</ogr:floatval>
20+
<ogr:dist_pole>1.5</ogr:dist_pole>
2021
</ogr:pole_inaccessibility_polys>
2122
</gml:featureMember>
2223
<gml:featureMember>
@@ -25,20 +26,23 @@
2526
<ogr:name>Aaaaa</ogr:name>
2627
<ogr:intval>-33</ogr:intval>
2728
<ogr:floatval>0</ogr:floatval>
29+
<ogr:dist_pole>0.414211273193359</ogr:dist_pole>
2830
</ogr:pole_inaccessibility_polys>
2931
</gml:featureMember>
3032
<gml:featureMember>
3133
<ogr:pole_inaccessibility_polys fid="polys.2">
3234
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2.5,5.5</gml:coordinates></gml:Point></ogr:geometryProperty>
3335
<ogr:name>bbaaa</ogr:name>
3436
<ogr:floatval>0.123</ogr:floatval>
37+
<ogr:dist_pole>0.5</ogr:dist_pole>
3538
</ogr:pole_inaccessibility_polys>
3639
</gml:featureMember>
3740
<gml:featureMember>
3841
<ogr:pole_inaccessibility_polys fid="polys.3">
3942
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>6.585784912109375,-2.414215087890625</gml:coordinates></gml:Point></ogr:geometryProperty>
4043
<ogr:name>ASDF</ogr:name>
4144
<ogr:intval>0</ogr:intval>
45+
<ogr:dist_pole>0.585784912109375</ogr:dist_pole>
4246
</ogr:pole_inaccessibility_polys>
4347
</gml:featureMember>
4448
<gml:featureMember>
@@ -53,6 +57,7 @@
5357
<ogr:name>elim</ogr:name>
5458
<ogr:intval>2</ogr:intval>
5559
<ogr:floatval>3.33</ogr:floatval>
60+
<ogr:dist_pole>1.71028189541736</ogr:dist_pole>
5661
</ogr:pole_inaccessibility_polys>
5762
</gml:featureMember>
5863
</ogr:FeatureCollection>

‎src/core/geometry/qgsgeometry.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,11 +1480,11 @@ QgsGeometry QgsGeometry::pointOnSurface() const
14801480
return QgsGeometry( pt.clone() );
14811481
}
14821482

1483-
QgsGeometry QgsGeometry::poleOfInaccessibility( double precision ) const
1483+
QgsGeometry QgsGeometry::poleOfInaccessibility( double precision, double* distanceToBoundary ) const
14841484
{
14851485
QgsInternalGeometryEngine engine( *this );
14861486

1487-
return engine.poleOfInaccessibility( precision );
1487+
return engine.poleOfInaccessibility( precision, distanceToBoundary );
14881488
}
14891489

14901490
QgsGeometry QgsGeometry::convexHull() const

‎src/core/geometry/qgsgeometry.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,12 @@ class CORE_EXPORT QgsGeometry
588588
* approach guaranteed to find the true pole of inaccessibility within a specified
589589
* tolerance. More precise tolerances require more iterations and will take longer
590590
* to calculate.
591+
* Optionally, the distance to the polygon boundary from the pole can be stored.
591592
* @see centroid()
592593
* @see pointOnSurface()
593594
* @note added in QGIS 3.0
594595
*/
595-
QgsGeometry poleOfInaccessibility( double precision ) const;
596+
QgsGeometry poleOfInaccessibility( double precision, double* distanceToBoundary = nullptr ) const;
596597

597598
//! Returns the smallest convex polygon that contains all the points in the geometry.
598599
QgsGeometry convexHull() const;

‎src/core/geometry/qgsinternalgeometryengine.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ QgsGeometry QgsInternalGeometryEngine::extrude( double x, double y ) const
9797
// ported from the original Javascript implementation developed by Vladimir Agafonkin
9898
// originally licensed under the ISC License
9999

100+
/// @cond PRIVATE
100101
class Cell
101102
{
102103
public:
@@ -153,9 +154,13 @@ Cell* getCentroidCell( const QgsPolygonV2* polygon )
153154
return new Cell( x / area, y / area, 0.0, polygon );
154155
}
155156

157+
///@endcond
156158

157-
QgsGeometry QgsInternalGeometryEngine::poleOfInaccessibility( double precision ) const
159+
QgsGeometry QgsInternalGeometryEngine::poleOfInaccessibility( double precision , double* distanceFromBoundary ) const
158160
{
161+
if ( distanceFromBoundary )
162+
*distanceFromBoundary = DBL_MAX;
163+
159164
if ( !mGeometry || mGeometry->isEmpty() )
160165
return QgsGeometry();
161166

@@ -232,5 +237,8 @@ QgsGeometry QgsInternalGeometryEngine::poleOfInaccessibility( double precision )
232237
cellQueue.push( new Cell( currentCell->x + h, currentCell->y + h, h, polygon ) );
233238
}
234239

240+
if ( distanceFromBoundary )
241+
*distanceFromBoundary = bestCell->d;
242+
235243
return QgsGeometry( new QgsPointV2( bestCell->x, bestCell->y ) );
236244
}

‎src/core/geometry/qgsinternalgeometryengine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class QgsInternalGeometryEngine
5757
* approach guaranteed to find the true pole of inaccessibility within a specified
5858
* tolerance. More precise tolerances require more iterations and will take longer
5959
* to calculate.
60+
* Optionally, the distance to the polygon boundary from the pole can be stored.
6061
*/
61-
QgsGeometry poleOfInaccessibility( double precision ) const;
62+
QgsGeometry poleOfInaccessibility( double precision, double* distanceFromBoundary = nullptr ) const;
6263

6364
private:
6465
const QgsAbstractGeometry* mGeometry;

‎tests/src/core/testqgsgeometry.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3960,9 +3960,11 @@ void TestQgsGeometry::poleOfInaccessibility()
39603960
QgsGeometry poly1 = QgsGeometry::fromWkt( poly1Wkt );
39613961
QgsGeometry poly2 = QgsGeometry::fromWkt( poly2Wkt );
39623962

3963-
QgsPoint point = poly1.poleOfInaccessibility( 1 ).asPoint();
3963+
double distance;
3964+
QgsPoint point = poly1.poleOfInaccessibility( 1 , &distance ).asPoint();
39643965
QGSCOMPARENEAR( point.x(), 3867.37, 0.01 );
39653966
QGSCOMPARENEAR( point.y(), 2126.45, 0.01 );
3967+
QGSCOMPARENEAR( distance, 289.51, 0.01 );
39663968

39673969
point = poly1.poleOfInaccessibility( 50 ).asPoint();
39683970
QGSCOMPARENEAR( point.x(), 3855.33, 0.01 );

0 commit comments

Comments
 (0)
Please sign in to comment.