mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[symbology] Fix broken centroid fill's force point inside polygon
This commit is contained in:
parent
7d3d9247c7
commit
0e4f0c8555
@ -661,9 +661,9 @@ Determines an SVG symbol's name from its ``path``.
|
||||
Calculate the centroid point of a QPolygonF
|
||||
%End
|
||||
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points );
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings = 0 );
|
||||
%Docstring
|
||||
Calculate a point within of a QPolygonF
|
||||
Calculate a point on the surface of a QPolygonF
|
||||
%End
|
||||
|
||||
static bool pointInPolygon( const QPolygonF &points, QPointF point );
|
||||
|
@ -3509,8 +3509,6 @@ void QgsCentroidFillSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
|
||||
void QgsCentroidFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
Q_UNUSED( rings )
|
||||
|
||||
if ( !mPointOnAllParts )
|
||||
{
|
||||
const QgsFeature *feature = context.feature();
|
||||
@ -3544,7 +3542,7 @@ void QgsCentroidFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<Q
|
||||
|
||||
if ( mPointOnAllParts || ( context.geometryPartNum() == mBiggestPartIndex ) )
|
||||
{
|
||||
QPointF centroid = mPointOnSurface ? QgsSymbolLayerUtils::polygonPointOnSurface( points ) : QgsSymbolLayerUtils::polygonCentroid( points );
|
||||
QPointF centroid = mPointOnSurface ? QgsSymbolLayerUtils::polygonPointOnSurface( points, rings ) : QgsSymbolLayerUtils::polygonCentroid( points );
|
||||
mMarker->renderPoint( centroid, context.feature(), context.renderContext(), -1, context.selected() );
|
||||
}
|
||||
}
|
||||
|
@ -3885,32 +3885,41 @@ QPointF QgsSymbolLayerUtils::polygonCentroid( const QPolygonF &points )
|
||||
return QPointF( cx, cy );
|
||||
}
|
||||
|
||||
QPointF QgsSymbolLayerUtils::polygonPointOnSurface( const QPolygonF &points )
|
||||
QPointF QgsSymbolLayerUtils::polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings )
|
||||
{
|
||||
QPointF centroid = QgsSymbolLayerUtils::polygonCentroid( points );
|
||||
|
||||
// check if centroid inside in polygon
|
||||
if ( !QgsSymbolLayerUtils::pointInPolygon( points, centroid ) )
|
||||
if ( ( rings && rings->count() > 0 ) || !pointInPolygon( points, centroid ) )
|
||||
{
|
||||
unsigned int i, pointCount = points.count();
|
||||
|
||||
QgsPolylineXY polyline( pointCount );
|
||||
for ( i = 0; i < pointCount; ++i ) polyline[i] = QgsPointXY( points[i].x(), points[i].y() );
|
||||
|
||||
QgsGeometry geom = QgsGeometry::fromPolygonXY( QgsPolygonXY() << polyline );
|
||||
if ( !geom.isNull() )
|
||||
{
|
||||
QgsGeometry pointOnSurfaceGeom = geom.pointOnSurface();
|
||||
if ( rings )
|
||||
{
|
||||
QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
|
||||
for ( ; ringIt != rings->constEnd(); ++ringIt )
|
||||
{
|
||||
pointCount = ( *ringIt ).count();
|
||||
QgsPolylineXY polyline( pointCount );
|
||||
for ( i = 0; i < pointCount; ++i ) polyline[i] = QgsPointXY( ( *ringIt )[i].x(), ( *ringIt )[i].y() );
|
||||
geom.addRing( polyline );
|
||||
}
|
||||
}
|
||||
|
||||
QgsGeometry pointOnSurfaceGeom = geom.pointOnSurface();
|
||||
if ( !pointOnSurfaceGeom.isNull() )
|
||||
{
|
||||
QgsPointXY point = pointOnSurfaceGeom.asPoint();
|
||||
|
||||
return QPointF( point.x(), point.y() );
|
||||
centroid.setX( point.x() );
|
||||
centroid.setY( point.y() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return centroid;
|
||||
|
||||
return QPointF( centroid.x(), centroid.y() );
|
||||
}
|
||||
|
||||
bool QgsSymbolLayerUtils::pointInPolygon( const QPolygonF &points, QPointF point )
|
||||
|
@ -605,8 +605,8 @@ class CORE_EXPORT QgsSymbolLayerUtils
|
||||
//! Calculate the centroid point of a QPolygonF
|
||||
static QPointF polygonCentroid( const QPolygonF &points );
|
||||
|
||||
//! Calculate a point within of a QPolygonF
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points );
|
||||
//! Calculate a point on the surface of a QPolygonF
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings = nullptr );
|
||||
|
||||
//! Calculate whether a point is within of a QPolygonF
|
||||
static bool pointInPolygon( const QPolygonF &points, QPointF point );
|
||||
|
@ -53,6 +53,7 @@ class TestQgsCentroidFillSymbol : public QObject
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
|
||||
void centroidFillSymbol();
|
||||
void centroidFillSymbolPointOnSurface();
|
||||
void centroidFillSymbolPartBiggest();
|
||||
|
||||
private:
|
||||
@ -132,11 +133,18 @@ void TestQgsCentroidFillSymbol::centroidFillSymbol()
|
||||
QVERIFY( imageCheck( "symbol_centroidfill" ) );
|
||||
}
|
||||
|
||||
void TestQgsCentroidFillSymbol::centroidFillSymbolPointOnSurface()
|
||||
{
|
||||
mCentroidFill->setPointOnSurface( true );
|
||||
QVERIFY( imageCheck( "symbol_centroidfill_point_on_surface" ) );
|
||||
mCentroidFill->setPointOnSurface( false );
|
||||
}
|
||||
|
||||
void TestQgsCentroidFillSymbol::centroidFillSymbolPartBiggest()
|
||||
{
|
||||
mCentroidFill->setPointOnAllParts( false );
|
||||
|
||||
QVERIFY( imageCheck( "symbol_centroidfill_part_biggest" ) );
|
||||
mCentroidFill->setPointOnAllParts( true );
|
||||
}
|
||||
|
||||
//
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 626 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Loading…
x
Reference in New Issue
Block a user