mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-30 00:29:39 -05:00
Improve results when using path stroking
Use GEOS to do the path stroking
This commit is contained in:
parent
4eb35e466d
commit
3ace4676fa
@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeometryPaintDevice: QPaintDevice
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeometryPaintDevice: QPaintDevice
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
|
||||
@ -48,8 +48,12 @@ QPaintEngine::Type QgsGeometryPaintEngine::type() const
|
||||
return QPaintEngine::User;
|
||||
}
|
||||
|
||||
void QgsGeometryPaintEngine::updateState( const QPaintEngineState & )
|
||||
void QgsGeometryPaintEngine::updateState( const QPaintEngineState &state )
|
||||
{
|
||||
if ( mUsePathStroker && state.state().testFlag( QPaintEngine::DirtyFlag::DirtyPen ) )
|
||||
{
|
||||
mPen = state.pen();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeometryPaintEngine::drawImage( const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags )
|
||||
@ -320,12 +324,76 @@ void QgsGeometryPaintEngine::drawPolygon( const QPointF *points, int pointCount,
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeometryPaintEngine::addStrokedLine( const QgsLineString *line, double penWidth, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, const QTransform *matrix )
|
||||
{
|
||||
QgsGeos geos( line );
|
||||
|
||||
std::unique_ptr< QgsAbstractGeometry > buffered( geos.buffer( penWidth / 2, mStrokedPathsSegments, endCapStyle, joinStyle, miterLimit ) );
|
||||
if ( !buffered )
|
||||
return;
|
||||
|
||||
if ( matrix )
|
||||
buffered->transform( *matrix );
|
||||
|
||||
if ( QgsGeometryCollection *bufferedCollection = qgsgeometry_cast< QgsGeometryCollection * >( buffered.get() ) )
|
||||
{
|
||||
mGeometry.addGeometries( bufferedCollection->takeGeometries() );
|
||||
}
|
||||
else if ( buffered )
|
||||
{
|
||||
mGeometry.addGeometry( buffered.release() );
|
||||
}
|
||||
}
|
||||
|
||||
Qgis::EndCapStyle QgsGeometryPaintEngine::penStyleToCapStyle( Qt::PenCapStyle style )
|
||||
{
|
||||
switch ( style )
|
||||
{
|
||||
case Qt::FlatCap:
|
||||
return Qgis::EndCapStyle::Flat;
|
||||
case Qt::SquareCap:
|
||||
return Qgis::EndCapStyle::Square;
|
||||
case Qt::RoundCap:
|
||||
return Qgis::EndCapStyle::Round;
|
||||
case Qt::MPenCapStyle:
|
||||
// undocumented?
|
||||
break;
|
||||
}
|
||||
|
||||
return Qgis::EndCapStyle::Round;
|
||||
}
|
||||
|
||||
Qgis::JoinStyle QgsGeometryPaintEngine::penStyleToJoinStyle( Qt::PenJoinStyle style )
|
||||
{
|
||||
switch ( style )
|
||||
{
|
||||
case Qt::MiterJoin:
|
||||
case Qt::SvgMiterJoin:
|
||||
return Qgis::JoinStyle::Miter;
|
||||
case Qt::BevelJoin:
|
||||
return Qgis::JoinStyle::Bevel;
|
||||
case Qt::RoundJoin:
|
||||
return Qgis::JoinStyle::Round;
|
||||
case Qt::MPenJoinStyle:
|
||||
// undocumented?
|
||||
break;
|
||||
}
|
||||
return Qgis::JoinStyle::Round;
|
||||
}
|
||||
|
||||
// based on QPainterPath::toSubpathPolygons()
|
||||
void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath &path, const QTransform &matrix )
|
||||
void QgsGeometryPaintEngine::addSubpathGeometries( const QPainterPath &path, const QTransform &matrix )
|
||||
{
|
||||
if ( path.isEmpty() )
|
||||
return;
|
||||
|
||||
const bool transformIsIdentity = matrix.isIdentity();
|
||||
|
||||
const Qgis::EndCapStyle endCapStyle = penStyleToCapStyle( mPen.capStyle() );
|
||||
const Qgis::JoinStyle joinStyle = penStyleToJoinStyle( mPen.joinStyle() );
|
||||
const double penWidth = mPen.widthF() <= 0 ? 1 : mPen.widthF();
|
||||
const double miterLimit = mPen.miterLimit();
|
||||
|
||||
QVector< double > currentX;
|
||||
QVector< double > currentY;
|
||||
const int count = path.elementCount();
|
||||
@ -343,13 +411,21 @@ void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath
|
||||
if ( currentX.size() > 1 )
|
||||
{
|
||||
std::unique_ptr< QgsLineString > line = std::make_unique< QgsLineString >( currentX, currentY );
|
||||
if ( line->isClosed() )
|
||||
if ( mUsePathStroker )
|
||||
{
|
||||
addStrokedLine( line.get(), penWidth, endCapStyle, joinStyle, miterLimit, transformIsIdentity ? nullptr : &matrix );
|
||||
}
|
||||
else if ( line->isClosed() )
|
||||
{
|
||||
if ( !transformIsIdentity )
|
||||
line->transform( matrix );
|
||||
queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line.release() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.addGeometry( line.release() );
|
||||
if ( !transformIsIdentity )
|
||||
line->transform( matrix );
|
||||
mGeometry.addGeometry( line.release() );
|
||||
}
|
||||
}
|
||||
currentX.resize( 0 );
|
||||
@ -357,19 +433,15 @@ void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath
|
||||
|
||||
currentX.reserve( 16 );
|
||||
currentY.reserve( 16 );
|
||||
double tx, ty;
|
||||
matrix.map( e.x, e.y, &tx, &ty );
|
||||
currentX << tx;
|
||||
currentY << ty;
|
||||
currentX << e.x;
|
||||
currentY << e.y;
|
||||
break;
|
||||
}
|
||||
|
||||
case QPainterPath::LineToElement:
|
||||
{
|
||||
double tx, ty;
|
||||
matrix.map( e.x, e.y, &tx, &ty );
|
||||
currentX << tx;
|
||||
currentY << ty;
|
||||
currentX << e.x;
|
||||
currentY << e.y;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -381,30 +453,18 @@ void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath
|
||||
const double x1 = path.elementAt( i - 1 ).x;
|
||||
const double y1 = path.elementAt( i - 1 ).y;
|
||||
|
||||
double tx1, ty1;
|
||||
matrix.map( x1, y1, &tx1, &ty1 );
|
||||
|
||||
double tx2, ty2;
|
||||
matrix.map( e.x, e.y, &tx2, &ty2 );
|
||||
|
||||
const double x3 = path.elementAt( i + 1 ).x;
|
||||
const double y3 = path.elementAt( i + 1 ).y;
|
||||
|
||||
double tx3, ty3;
|
||||
matrix.map( x3, y3, &tx3, &ty3 );
|
||||
|
||||
const double x4 = path.elementAt( i + 2 ).x;
|
||||
const double y4 = path.elementAt( i + 2 ).y;
|
||||
|
||||
double tx4, ty4;
|
||||
matrix.map( x4, y4, &tx4, &ty4 );
|
||||
|
||||
// TODO -- we could likely reduce the number of segmented points here!
|
||||
std::unique_ptr< QgsLineString> bezier( QgsLineString::fromBezierCurve(
|
||||
QgsPoint( tx1, ty1 ),
|
||||
QgsPoint( tx2, ty2 ),
|
||||
QgsPoint( tx3, ty3 ),
|
||||
QgsPoint( tx4, ty4 ) ) );
|
||||
QgsPoint( x1, y1 ),
|
||||
QgsPoint( e.x, e.y ),
|
||||
QgsPoint( x3, y3 ),
|
||||
QgsPoint( x4, y4 ) ) );
|
||||
|
||||
currentX << bezier->xVector();
|
||||
currentY << bezier->yVector();
|
||||
@ -421,20 +481,28 @@ void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath
|
||||
if ( currentX.size() > 1 )
|
||||
{
|
||||
std::unique_ptr< QgsLineString > line = std::make_unique< QgsLineString >( currentX, currentY );
|
||||
if ( line->isClosed() )
|
||||
if ( mUsePathStroker )
|
||||
{
|
||||
addStrokedLine( line.get(), penWidth, endCapStyle, joinStyle, miterLimit, transformIsIdentity ? nullptr : &matrix );
|
||||
}
|
||||
else if ( line->isClosed() )
|
||||
{
|
||||
if ( !transformIsIdentity )
|
||||
line->transform( matrix );
|
||||
queuedPolygons.emplace_back( std::make_unique< QgsPolygon >( line.release() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.addGeometry( line.release() );
|
||||
if ( !transformIsIdentity )
|
||||
line->transform( matrix );
|
||||
mGeometry.addGeometry( line.release() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( queuedPolygons.empty() )
|
||||
return;
|
||||
|
||||
collection.reserve( collection.numGeometries() + queuedPolygons.size() );
|
||||
mGeometry.reserve( mGeometry.numGeometries() + queuedPolygons.size() );
|
||||
|
||||
QgsMultiPolygon tempMultiPolygon;
|
||||
tempMultiPolygon.reserve( queuedPolygons.size() );
|
||||
@ -451,24 +519,14 @@ void addSubpathGeometries( QgsGeometryCollection &collection, const QPainterPath
|
||||
|
||||
for ( auto it = g->const_parts_begin(); it != g->const_parts_end(); ++it )
|
||||
{
|
||||
collection.addGeometry( ( *it )->clone() );
|
||||
mGeometry.addGeometry( ( *it )->clone() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeometryPaintEngine::drawPath( const QPainterPath &path )
|
||||
{
|
||||
QPainterPath realPath = path;
|
||||
if ( mUsePathStroker )
|
||||
{
|
||||
QPen pen = painter()->pen();
|
||||
QPainterPathStroker stroker( pen );
|
||||
QPainterPath strokedPath = stroker.createStroke( path );
|
||||
realPath = strokedPath;
|
||||
}
|
||||
|
||||
QTransform transform = painter()->combinedTransform();
|
||||
|
||||
addSubpathGeometries( mGeometry, realPath, transform );
|
||||
const QTransform transform = painter()->combinedTransform();
|
||||
addSubpathGeometries( path, transform );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
#include <QPaintEngine>
|
||||
#include <memory>
|
||||
|
||||
class QgsLineString;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
@ -82,8 +84,15 @@ class QgsGeometryPaintEngine: public QPaintEngine
|
||||
|
||||
private:
|
||||
|
||||
void addSubpathGeometries( const QPainterPath &path, const QTransform &matrix );
|
||||
void addStrokedLine( const QgsLineString *line, double penWidth, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, const QTransform *matrix );
|
||||
static Qgis::EndCapStyle penStyleToCapStyle( Qt::PenCapStyle style );
|
||||
static Qgis::JoinStyle penStyleToJoinStyle( Qt::PenJoinStyle style );
|
||||
|
||||
bool mUsePathStroker = false;
|
||||
QPen mPen;
|
||||
QgsGeometryCollection mGeometry;
|
||||
int mStrokedPathsSegments = 8;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -75,8 +75,10 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
)
|
||||
painter.end()
|
||||
|
||||
self.assertEqual(device.geometry().asWkt(2),
|
||||
'GeometryCollection (LineString (5.5 10.7, 6.8 12.9),LineString (15.5 12.7, 3.8 42.9),LineString (-4 -1, 2 3))')
|
||||
result = device.geometry()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (LineString (15.5 12.7, 3.8 42.9),LineString (5.5 10.7, 6.8 12.9),LineString (-4 -1, 2 3))')
|
||||
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
@ -104,8 +106,10 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
|
||||
painter.end()
|
||||
|
||||
self.assertEqual(device.geometry().asWkt(2),
|
||||
'GeometryCollection (LineString (11 32.1, 13.6 38.7),LineString (31 38.1, 7.6 128.7),LineString (-8 -3, 4 9))')
|
||||
result = device.geometry()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (LineString (31 38.1, 7.6 128.7),LineString (11 32.1, 13.6 38.7),LineString (-8 -3, 4 9))')
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
39)
|
||||
@ -134,8 +138,10 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
|
||||
painter.end()
|
||||
|
||||
self.assertEqual(device.geometry().asWkt(2),
|
||||
'GeometryCollection (Polygon ((6.15 10.32, 7.45 12.52, 6.15 13.28, 4.85 11.08, 6.15 10.32)),Polygon ((16.2 12.97, 4.5 43.17, 3.1 42.63, 14.8 12.43, 16.2 12.97)),Polygon ((-3.58 -1.62, 2.42 2.38, 1.58 3.62, -4.42 -0.38, -3.58 -1.62)))')
|
||||
result = device.geometry()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (Polygon ((4.85 11.08, 6.15 13.28, 7.45 12.52, 6.15 10.32, 4.85 11.08)),Polygon ((3.1 42.63, 4.5 43.17, 16.2 12.97, 14.8 12.43, 3.1 42.63)),Polygon ((-4.42 -0.38, 1.58 3.62, 2.42 2.38, -3.58 -1.62, -4.42 -0.38)))')
|
||||
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
@ -378,7 +384,7 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
result = device.geometry().clone()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (Polygon ((4.85 11.08, 6.15 13.28, 6.82 13.65, 15.52 13.45, 15.65 11.96, 5.65 9.96, 4.85 11.08),(8.71 12.11, 15.48 11.95, 15.5 12.7, 15.35 13.44, 8.71 12.11),(6.78 12.15, 7.22 12.14, 7.45 12.52, 6.8 12.9, 6.78 12.15),(5.35 11.44, 5.5 10.7, 6.15 10.32, 7 11.76, 5.35 11.44),(7 11.76, 8.71 12.11, 7.22 12.14, 7 11.76)),Polygon ((13.29 11.24, 21.29 35.24, 22.71 34.76, 14.71 10.76, 13.29 11.24)),Polygon ((-4.42 -0.38, 1.58 3.62, 2.42 2.38, -3.58 -1.62, -4.42 -0.38)))')
|
||||
'GeometryCollection (Polygon ((4.85 11.08, 6.15 13.28, 6.82 13.65, 15.52 13.45, 15.65 11.96, 5.65 9.96, 4.85 11.08),(7 11.76, 8.71 12.11, 7.22 12.14, 7 11.76)),Polygon ((13.29 11.24, 21.29 35.24, 22.71 34.76, 14.71 10.76, 13.29 11.24)),Polygon ((-4.42 -0.38, 1.58 3.62, 2.42 2.38, -3.58 -1.62, -4.42 -0.38)))')
|
||||
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
@ -409,7 +415,7 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
result = device.geometry().clone()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (Polygon ((9.71 33.24, 12.31 39.84, 13.63 40.95, 31.03 40.35, 31.29 35.89, 11.29 29.89, 9.71 33.24),(17.41 36.32, 30.97 35.85, 31 38.1, 30.71 40.31, 17.41 36.32),(13.57 36.45, 14.44 36.42, 14.89 37.56, 13.6 38.7, 13.57 36.45),(10.71 34.31, 11 32.1, 12.29 30.96, 14 35.29, 10.71 34.31),(14 35.29, 17.41 36.32, 14.44 36.42, 14 35.29)),Polygon ((26.58 33.71, 42.58 105.71, 45.42 104.29, 29.42 32.29, 26.58 33.71)),Polygon ((-8.83 -1.13, 3.17 10.87, 4.83 7.13, -7.17 -4.87, -8.83 -1.13)))')
|
||||
'GeometryCollection (Polygon ((9.71 33.24, 12.31 39.84, 13.63 40.95, 31.03 40.35, 31.29 35.89, 11.29 29.89, 9.71 33.24),(14 35.29, 17.41 36.32, 14.44 36.42, 14 35.29)),Polygon ((26.58 33.71, 42.58 105.71, 45.42 104.29, 29.42 32.29, 26.58 33.71)),Polygon ((-8.83 -1.13, 3.17 10.87, 4.83 7.13, -7.17 -4.87, -8.83 -1.13)))')
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
54)
|
||||
@ -489,7 +495,7 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
result = device.geometry().clone()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (Polygon ((4.82 10.39, 5.35 11.44, 15.35 13.44, 16.23 12.51, 13.8 3.2, 13.7 2.98, 13.61 2.85, 13.52 2.72, 13.43 2.6, 13.34 2.47, 13.25 2.35, 13.16 2.23, 13.07 2.11, 12.97 1.99, 12.87 1.87, 12.78 1.76, 12.68 1.64, 12.58 1.53, 12.48 1.42, 12.38 1.31, 12.28 1.2, 12.18 1.09, 12.07 0.99, 11.97 0.88, 11.86 0.78, 11.76 0.68, 11.65 0.58, 11.54 0.49, 11.43 0.39, 11.32 0.3, 11.21 0.21, 11.1 0.12, 10.99 0.03, 10.88 -0.05, 10.77 -0.13, 10.66 -0.21, 9.55 0.09, 4.82 10.39),(6.58 10.15, 10.51 1.58, 10.57 1.62, 10.66 1.71, 10.75 1.79, 10.85 1.88, 10.94 1.96, 11.03 2.05, 11.12 2.14, 11.2 2.23, 11.29 2.33, 11.38 2.42, 11.46 2.52, 11.55 2.62, 11.63 2.72, 11.72 2.82, 11.8 2.92, 11.88 3.03, 11.97 3.13, 12.05 3.24, 12.13 3.35, 12.21 3.46, 12.29 3.58, 12.37 3.69, 12.38 3.71, 14.47 11.73, 6.58 10.15),(9.8 1.02, 10.23 0.4, 10.91 0.72, 10.51 1.58, 10.48 1.54, 10.38 1.46, 10.29 1.39, 10.19 1.31, 10.09 1.23, 10 1.16, 9.9 1.09, 9.8 1.02),(14.47 11.73, 15.65 11.96, 15.5 12.7, 14.77 12.89, 14.47 11.73),(12.35 3.58, 13.07 3.39, 12.45 3.81, 12.38 3.71, 12.35 3.58),(5.5 10.7, 5.65 9.96, 6.58 10.15, 6.18 11.01, 5.5 10.7)))')
|
||||
'GeometryCollection (Polygon ((4.82 10.39, 5.35 11.44, 15.35 13.44, 16.23 12.51, 13.8 3.2, 13.69 2.97, 13.61 2.85, 13.61 2.85, 13.52 2.72, 13.52 2.72, 13.43 2.6, 13.43 2.59, 13.34 2.47, 13.34 2.47, 13.25 2.35, 13.25 2.34, 13.16 2.23, 13.16 2.22, 13.07 2.11, 13.06 2.1, 12.97 1.99, 12.97 1.98, 12.88 1.87, 12.87 1.87, 12.78 1.76, 12.78 1.75, 12.69 1.64, 12.68 1.64, 12.59 1.53, 12.58 1.52, 12.49 1.42, 12.48 1.41, 12.39 1.31, 12.38 1.3, 12.29 1.2, 12.28 1.2, 12.19 1.1, 12.18 1.09, 12.08 0.99, 12.08 0.99, 11.98 0.89, 11.97 0.88, 11.87 0.79, 11.87 0.78, 11.77 0.69, 11.76 0.68, 11.66 0.59, 11.66 0.59, 11.56 0.5, 11.55 0.49, 11.45 0.4, 11.44 0.4, 11.34 0.31, 11.33 0.3, 11.23 0.22, 11.22 0.21, 11.12 0.13, 11.11 0.12, 11 0.04, 11 0.04, 10.89 -0.04, 10.88 -0.05, 10.78 -0.13, 10.77 -0.13, 10.66 -0.21, 9.55 0.09, 4.82 10.39),(6.58 10.15, 10.51 1.58, 10.56 1.62, 10.65 1.7, 10.75 1.79, 10.84 1.87, 10.93 1.96, 11.02 2.05, 11.11 2.14, 11.2 2.23, 11.29 2.33, 11.37 2.42, 11.46 2.52, 11.55 2.62, 11.63 2.72, 11.72 2.82, 11.8 2.93, 11.88 3.03, 11.97 3.14, 12.05 3.25, 12.13 3.36, 12.21 3.47, 12.29 3.58, 12.37 3.69, 12.38 3.71, 14.47 11.73, 6.58 10.15)))')
|
||||
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
@ -512,7 +518,7 @@ class TestQgsGeometryPaintDevice(QgisTestCase):
|
||||
result = device.geometry().clone()
|
||||
result.normalize()
|
||||
self.assertEqual(result.asWkt(2),
|
||||
'GeometryCollection (Polygon ((9.64 31.16, 10.71 34.31, 30.71 40.31, 32.45 37.53, 27.59 9.61, 27.39 8.93, 27.22 8.55, 27.04 8.17, 26.87 7.79, 26.69 7.42, 26.5 7.05, 26.32 6.69, 26.13 6.33, 25.94 5.97, 25.75 5.62, 25.56 5.27, 25.36 4.92, 25.16 4.58, 24.96 4.25, 24.76 3.92, 24.56 3.59, 24.35 3.27, 24.14 2.96, 23.93 2.65, 23.72 2.34, 23.51 2.04, 23.3 1.75, 23.08 1.46, 22.87 1.18, 22.65 0.9, 22.43 0.63, 22.21 0.36, 21.99 0.1, 21.77 -0.15, 21.54 -0.39, 21.32 -0.63, 19.09 0.27, 9.64 31.16),(13.16 30.45, 21.03 4.73, 21.14 4.87, 21.33 5.12, 21.51 5.37, 21.69 5.63, 21.87 5.89, 22.05 6.16, 22.23 6.43, 22.41 6.7, 22.58 6.99, 22.76 7.27, 22.93 7.56, 23.1 7.86, 23.27 8.16, 23.44 8.46, 23.6 8.77, 23.77 9.08, 23.93 9.4, 24.1 9.73, 24.26 10.06, 24.42 10.39, 24.58 10.73, 24.74 11.08, 24.76 11.12, 28.94 35.19, 13.16 30.45),(19.6 3.05, 20.46 1.21, 21.82 2.15, 21.03 4.73, 20.95 4.63, 20.76 4.39, 20.57 4.16, 20.38 3.93, 20.19 3.7, 19.99 3.48, 19.79 3.26, 19.6 3.05),(28.94 35.19, 31.29 35.89, 31 38.1, 29.55 38.67, 28.94 35.19),(24.69 10.75, 26.14 10.18, 24.89 11.43, 24.76 11.12, 24.69 10.75),(11 32.1, 11.29 29.89, 13.16 30.45, 12.36 33.04, 11 32.1)))')
|
||||
'GeometryCollection (Polygon ((9.64 31.16, 10.71 34.31, 30.71 40.31, 32.45 37.53, 27.59 9.61, 27.39 8.92, 27.22 8.56, 27.21 8.54, 27.05 8.17, 27.04 8.15, 26.87 7.8, 26.86 7.78, 26.69 7.42, 26.68 7.4, 26.51 7.05, 26.5 7.03, 26.32 6.69, 26.31 6.67, 26.14 6.33, 26.12 6.31, 25.95 5.97, 25.94 5.95, 25.76 5.62, 25.75 5.6, 25.57 5.27, 25.55 5.25, 25.37 4.93, 25.36 4.91, 25.18 4.59, 25.16 4.57, 24.98 4.26, 24.97 4.24, 24.78 3.93, 24.77 3.91, 24.58 3.61, 24.56 3.59, 24.37 3.29, 24.36 3.27, 24.17 2.98, 24.15 2.96, 23.96 2.67, 23.95 2.65, 23.75 2.37, 23.74 2.35, 23.54 2.07, 23.52 2.05, 23.33 1.78, 23.31 1.76, 23.11 1.49, 23.1 1.47, 22.89 1.2, 22.88 1.19, 22.67 0.93, 22.66 0.91, 22.45 0.66, 22.44 0.64, 22.23 0.39, 22.22 0.37, 22.01 0.13, 21.99 0.11, 21.78 -0.13, 21.77 -0.15, 21.56 -0.38, 21.54 -0.4, 21.33 -0.62, 19.09 0.27, 9.64 31.16),(13.16 30.45, 21.03 4.73, 21.12 4.85, 21.31 5.1, 21.49 5.36, 21.67 5.62, 21.86 5.88, 22.04 6.15, 22.22 6.42, 22.39 6.7, 22.57 6.98, 22.75 7.27, 22.92 7.56, 23.09 7.86, 23.26 8.16, 23.43 8.47, 23.6 8.78, 23.77 9.09, 23.93 9.41, 24.1 9.74, 24.26 10.07, 24.42 10.4, 24.58 10.74, 24.74 11.08, 24.76 11.12, 28.94 35.19, 13.16 30.45)))')
|
||||
self.assertEqual(
|
||||
device.metric(QPaintDevice.PaintDeviceMetric.PdmWidth),
|
||||
22)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user