mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Use direct QPainterPaths when clipping map renders using a QPainter based clip
Allows correct clipping to multipolygons, polygons with holes, etc
This commit is contained in:
parent
205273e7cd
commit
040dd56b80
@ -772,11 +772,17 @@ QPainterPath QgsCurvePolygon::asQPainterPath() const
|
||||
{
|
||||
QPainterPath p;
|
||||
if ( mExteriorRing )
|
||||
mExteriorRing->addToPainterPath( p );
|
||||
{
|
||||
QPainterPath ring = mExteriorRing->asQPainterPath();
|
||||
ring.closeSubpath();
|
||||
p.addPath( ring );
|
||||
}
|
||||
|
||||
for ( const QgsCurve *ring : mInteriorRings )
|
||||
{
|
||||
p.addPath( ring->asQPainterPath() );
|
||||
QPainterPath ringPath = ring->asQPainterPath();
|
||||
ringPath.closeSubpath();
|
||||
p.addPath( ringPath );
|
||||
}
|
||||
|
||||
return p;
|
||||
|
@ -169,15 +169,10 @@ QPainterPath QgsMapClippingUtils::calculatePainterClipRegion( const QList<QgsMap
|
||||
if ( !shouldClip )
|
||||
return QPainterPath();
|
||||
|
||||
// filter out polygon parts from result only
|
||||
result.convertGeometryCollectionToSubclass( QgsWkbTypes::PolygonGeometry );
|
||||
|
||||
// transform to painter coordinates
|
||||
result.mapToPixel( context.mapToPixel() );
|
||||
|
||||
QPainterPath path;
|
||||
path.addPolygon( result.asQPolygonF() );
|
||||
return path;
|
||||
return result.constGet()->asQPainterPath();
|
||||
}
|
||||
|
||||
QgsGeometry QgsMapClippingUtils::calculateLabelIntersectionGeometry( const QList<QgsMapClippingRegion> ®ions, const QgsRenderContext &context, bool &shouldClip )
|
||||
|
@ -5902,7 +5902,6 @@ class TestQgsGeometry(unittest.TestCase):
|
||||
rendered_image = self.renderGeometry(geom, False, True)
|
||||
assert self.imageCheck(test['name'] + '_aspolygon', test['as_polygon_reference_image'], rendered_image)
|
||||
|
||||
|
||||
def testGeometryAsQPainterPath(self):
|
||||
'''Tests conversion of different geometries to QPainterPath, including bad/odd geometries.'''
|
||||
|
||||
@ -5980,6 +5979,9 @@ class TestQgsGeometry(unittest.TestCase):
|
||||
{'name': 'Collection Mixed',
|
||||
'wkt': 'GeometryCollection(Point(1 2), MultiPoint(3 3, 2 3), LineString (0 0,3 4,4 3), MultiLineString((3 1, 3 2, 4 2)), Polygon((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)), MultiPolygon(((4 0, 5 0, 5 1, 6 1, 6 2, 4 2, 4 0)),(( 1 4, 2 4, 1 5, 1 4))))',
|
||||
'reference_image': 'collection_mixed'},
|
||||
{'name': 'MultiCurvePolygon',
|
||||
'wkt': 'MultiSurface (CurvePolygon (CompoundCurve (CircularString (-12942312 4593500, -11871048 5481118, -11363838 5065730, -11551856 4038191, -12133399 4130014),(-12133399 4130014, -12942312 4593500)),(-12120281 5175043, -12456964 4694067, -11752991 4256817, -11569346 4943300, -12120281 5175043)),Polygon ((-10856627 5625411, -11083997 4995770, -10887235 4357384, -9684796 4851477, -10069576 5428648, -10856627 5625411)))',
|
||||
'reference_image': 'multicurvepolygon_with_rings'}
|
||||
]
|
||||
|
||||
for test in tests:
|
||||
|
@ -229,6 +229,46 @@ class TestQgsVectorLayerRenderer(unittest.TestCase):
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
def testRenderWithPainterClipRegionsMultiPolygon(self):
|
||||
poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp'))
|
||||
self.assertTrue(poly_layer.isValid())
|
||||
|
||||
sym1 = QgsFillSymbol.createSimple({'color': '#ff00ff', 'outline_color': '#000000', 'outline_width': '1'})
|
||||
renderer = QgsSingleSymbolRenderer(sym1)
|
||||
poly_layer.setRenderer(renderer)
|
||||
|
||||
mapsettings = QgsMapSettings()
|
||||
mapsettings.setOutputSize(QSize(400, 400))
|
||||
mapsettings.setOutputDpi(96)
|
||||
mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
|
||||
mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5))
|
||||
mapsettings.setLayers([poly_layer])
|
||||
|
||||
region = QgsMapClippingRegion(QgsGeometry.fromWkt(
|
||||
'MultiSurface (Polygon ((-10856627.66351187042891979 5625411.45629768911749125, -11083997.96136780828237534 4995770.63146586995571852, -10887235.20360786281526089 4357384.79517805296927691, -9684796.12840820662677288 4851477.9424419105052948, -10069576.63247209787368774 5428648.69853774644434452, -10856627.66351187042891979 5625411.45629768911749125)),Polygon ((-12045949.22152753174304962 5533588.83600971661508083, -12758667.65519132651388645 4868967.96535390708595514, -12478827.28859940730035305 4296169.71498607192188501, -11783598.87784760631620884 4077544.42858613422140479, -11223918.14466376602649689 4715930.26487395167350769, -11127723.01864779368042946 5673509.01930567622184753, -11359465.8222317285835743 5809056.69687363691627979, -12045949.22152753174304962 5533588.83600971661508083),(-11341975.79931973293423653 4790262.86224992945790291, -11722383.7976556234061718 4318032.24362606555223465, -12019714.18715953826904297 4606617.62167398259043694, -11757363.84347961470484734 4908320.51690589636564255, -11341975.79931973293423653 4790262.86224992945790291)))'))
|
||||
region.setFeatureClip(QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly)
|
||||
mapsettings.addClippingRegion(region)
|
||||
|
||||
renderchecker = QgsMultiRenderChecker()
|
||||
renderchecker.setMapSettings(mapsettings)
|
||||
renderchecker.setControlPathPrefix('vectorlayerrenderer')
|
||||
renderchecker.setControlName('expected_painterclip_region_multi')
|
||||
result = renderchecker.runTest('expected_painterclip_region_multi')
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
# also try with symbol levels
|
||||
renderer.setUsingSymbolLevels(True)
|
||||
poly_layer.setRenderer(renderer)
|
||||
|
||||
renderchecker = QgsMultiRenderChecker()
|
||||
renderchecker.setMapSettings(mapsettings)
|
||||
renderchecker.setControlPathPrefix('vectorlayerrenderer')
|
||||
renderchecker.setControlName('expected_painterclip_region_multi')
|
||||
result = renderchecker.runTest('expected_painterclip_region_multi')
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 460 KiB |
Loading…
x
Reference in New Issue
Block a user