From b68a9c3b815f52d47c07065f31351b1c9d478ae9 Mon Sep 17 00:00:00 2001 From: nirvn Date: Tue, 30 Jul 2019 16:38:26 +0700 Subject: [PATCH] Add tests --- tests/src/core/testqgscallout.cpp | 128 ++++++++++++++++++ ...cted_callout_data_defined_anchor_point.png | Bin 0 -> 4335 bytes .../expected_callout_point_on_exterior.png | Bin 0 -> 3495 bytes 3 files changed, 128 insertions(+) create mode 100644 tests/testdata/control_images/callouts/expected_callout_data_defined_anchor_point/expected_callout_data_defined_anchor_point.png create mode 100644 tests/testdata/control_images/callouts/expected_callout_point_on_exterior/expected_callout_point_on_exterior.png diff --git a/tests/src/core/testqgscallout.cpp b/tests/src/core/testqgscallout.cpp index 66a02b514e4..0db20c95760 100644 --- a/tests/src/core/testqgscallout.cpp +++ b/tests/src/core/testqgscallout.cpp @@ -138,6 +138,8 @@ class TestQgsCallout: public QObject void calloutNoDrawToAllParts(); void calloutDrawToAllParts(); void calloutDataDefinedDrawToAllParts(); + void calloutPointOnExterior(); + void calloutDataDefinedAnchorPoint(); void manhattan(); void manhattanRotated(); void manhattanNoDrawToAllParts(); @@ -1255,6 +1257,132 @@ void TestQgsCallout::calloutDataDefinedDrawToAllParts() QVERIFY( imageCheck( "callout_data_defined_draw_to_all_parts_simple", img, 20 ) ); } +void TestQgsCallout::calloutPointOnExterior() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Polygon?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + QgsFillSymbol *fill = static_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ); + fill->setColor( QColor( 255, 0, 0 ) ); + vl2->setRenderer( new QgsSingleSymbolRenderer( fill ) ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 189950 << 5000000 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Polygon ((190000 4999900, 190100 5000100, 190100 5000100, 190000 5000100, 190000 4999900 ))" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 480 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( vl2->crs() ); + mapSettings.setExtent( QgsRectangle( 189900, 4999800, 190200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsSimpleLineCallout *callout = new QgsSimpleLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setAnchorPoint( QgsCallout::PointOnExterior ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "callout_point_on_exterior", img, 20 ) ); +} + +void TestQgsCallout::calloutDataDefinedAnchorPoint() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Polygon?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + QgsFillSymbol *fill = static_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ); + fill->setColor( QColor( 255, 0, 0 ) ); + vl2->setRenderer( new QgsSingleSymbolRenderer( fill ) ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 189950 << 5000000 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Polygon ((190000 4999900, 190100 5000100, 190100 5000100, 190000 5000100, 190000 4999900 ))" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 480 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( vl2->crs() ); + mapSettings.setExtent( QgsRectangle( 189900, 4999800, 190200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsSimpleLineCallout *callout = new QgsSimpleLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->dataDefinedProperties().setProperty( QgsCallout::AnchorPointPosition, QgsProperty::fromExpression( QStringLiteral( "'centroid'" ) ) ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "callout_data_defined_anchor_point", img, 20 ) ); +} + void TestQgsCallout::manhattan() { QSize size( 640, 480 ); diff --git a/tests/testdata/control_images/callouts/expected_callout_data_defined_anchor_point/expected_callout_data_defined_anchor_point.png b/tests/testdata/control_images/callouts/expected_callout_data_defined_anchor_point/expected_callout_data_defined_anchor_point.png new file mode 100644 index 0000000000000000000000000000000000000000..f699bf9e62084ccc6ba54c9e392d66bcbf604153 GIT binary patch literal 4335 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 adPQ;}+0=dNrZM~n1KG3N#V+55e&IiCIsCo= literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_callout_point_on_exterior/expected_callout_point_on_exterior.png b/tests/testdata/control_images/callouts/expected_callout_point_on_exterior/expected_callout_point_on_exterior.png new file mode 100644 index 0000000000000000000000000000000000000000..7e7003c4ca51de8baf8d0bafa72763d8ac93abec GIT binary patch literal 3495 zcmeH~i&s-u7RC=ZAc?sk)zOGl1>`Y^nu}oT1BG%KsDMI|8MWvHL{N(gA|S0of;2cj z5IcsK50FmLI#!@dsQAp42vm#^fvJvFL@5DLL=0d9*U-;3Yt0|g)vR?_R`NUF-e>Qe zvp?7$wldIa{Iv0e5Ub@M`-c-kDF`v^5K{Q&@`d0FcoQXlymluc);HfhW_j+`c38Z2 zx&KEIX(##~sw*C)Om7%y?(4gDNjasZ<%2D&O7G+-m_>hb$vJ-flW~%X(K{&1oE=Q2 zsL;zgt+S#u+lSkK3?(Cv-c8XF z&Af6tluHegR42~2PAi+bj|e7v%A?;0yu~X$0G$nzdcat~5+ca+kVo$U)bPsv2y11K zxHxjY7Ft=M3QB|xr)X^>uXGbKjJrW{+MeS=01p#^CzOjRIs`e-iWmktPrGoO3Q$P| ztFYTCfCy^~h_G=^9Cs5Cbxy*DP-jRzuM9$1TZ3e_1IL+bW#6LCNsPR7Hboyo6UIY1 z4-m>VfcZoa;~_8ol%ii~d1a%Bsq_SN`wk zC4$KL^3r91O}z3`C>H@bbDRs{aUwVl<#vjGh&sm!nMBk%4Rx;2$~I>c!H39c3m9ec zi!q;CbAwmbW6epUc*Vr1j>QJaF*MUnFZEif$P9<#1QF<^=0XO`6-1*eQrkFiOtN0; zFJ$OrMzI@3XT_QP4iHTukQ2wO!)g&jtBm5c6fKA~`Q;Oh4Uj9x`0J%NfestR+w3`J zpy(YTZPN)@(5O1ta7?jN(2dum{{nG+}^f9vf})I|sNI%2^yE1k54qSdm)i zN6~LLnf$~eX7B`*PMmHh;8DVs0HU+$*jqecK9nw;E)uYaus(oEP;NB&-3B}Yr7Ndn z0ZRz`7&%2(S}k><&lA3r4>sfmxrqZM*50X6oyK6fdT^k`XI|Ny_A51GcB3(GhR}nP z_FUVBf%dwcK1+5PwO#X9&lqWCN3UP5P$doh>s&&H;m+-Z_44`YG4JwDZr^))ieYzm zf&9ukeUNQlYiRNH%c<3>*TWMYU*~`73UBY=fCDg6!t?a6NWT3T7b;)?C zs~~?@-$3m-B^EvHw_os}x+>mS)&&yYcxLQvl`3hlA+X>3^Gze=88}pt=7nE88t7V* zKV!{yQFr^?vNU+u3OEnj+REOK71AC^3K>)zOHj$v3EpJ(a%d)2b5{+=DonhUL2%2Th}58E*TrTn{7-t z>`Lz|*Y`ieCAu7}5G_pUZM!X1pSb?iB|bjB%QQMRaLZMl@pfo%?z@|Q#k^2aU0rSH zZaz~{bEmdezHD?(`b~_29xqw#-g5M}bxssD{PNN6Utc{Loc!V1$Vm5@8EMUV?$6kI zT$X!xaso0Ai(>H_)Ov=>YK|=1xGvP2f7N_iQqR-?0$V5z40hG8ue+MiiY%pK~MbE{C)qr0?iTe`(SWMXG zg=)qe${16v4ZF}vq(Fx4gk;!I{aa=Iyi2MFs9=mlkzsa7Xs zekoEjz7+jA*b%}O8pRqX&L+-O%ZL~!pfwb|94Mc#hm2y@g|k7vBO+!aVkAaRjq^Ql9M0-%q zBrL_`U%|*TBZW*`6K}EIl?z*9kig;CYg$>q zSKx5$0zgM7u^~8I1jk#rICEiU1_>Na^Bv%LioO6P98PXV~ISKGE(F_89M$xUv z35N^0#aqN-)WSdEa2hYb06>I=!-Zf&aTwXy5FAdk5zWJpK8jM{a3RR~Z%2+nPB@&V z1`u<&6FK2GIc5qVMt>6^M(q;hgu}gnve%xg6aZ!sO)8)ZMgNSjaJa45Q12|R z5*vcUY4m`9qv+#M!r``}eZ4MRCH~NW!)eX~no;yc!zAz z+hL6dMc+IBvVEJ0%6TuU=B3oqx=`&4+Y54wO-V_qlBPz1Gkf1Z fp5J8;I>rLqZF7J5RuP8(yvXvutn@GUi`x4eCGKwP literal 0 HcmV?d00001