mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-06 00:05:16 -04:00
326 lines
12 KiB
C++
326 lines
12 KiB
C++
/***************************************************************************
|
|
testqgslayoututils.cpp
|
|
---------------------
|
|
begin : July 2017
|
|
copyright : (C) 2017 by Nyall Dawson
|
|
email : nyall dot dawson at gmail dot com
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgslayout.h"
|
|
#include "qgstest.h"
|
|
#include "qgslayoututils.h"
|
|
#include "qgsproject.h"
|
|
#include "qgslayoutitemmap.h"
|
|
|
|
class TestQgsLayoutUtils: public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
private slots:
|
|
void initTestCase();// will be called before the first testfunction is executed.
|
|
void cleanupTestCase();// will be called after the last testfunction was executed.
|
|
void init();// will be called before each testfunction is executed.
|
|
void cleanup();// will be called after every testfunction.
|
|
void normalizedAngle(); //test normalised angle function
|
|
void createRenderContextFromLayout();
|
|
void createRenderContextFromMap();
|
|
void relativePosition();
|
|
void relativeResizeRect();
|
|
|
|
private:
|
|
QString mReport;
|
|
|
|
};
|
|
|
|
void TestQgsLayoutUtils::initTestCase()
|
|
{
|
|
mReport = QStringLiteral( "<h1>Layout Utils Tests</h1>\n" );
|
|
}
|
|
|
|
void TestQgsLayoutUtils::cleanupTestCase()
|
|
{
|
|
QString myReportFile = QDir::tempPath() + QDir::separator() + "qgistest.html";
|
|
QFile myFile( myReportFile );
|
|
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
|
|
{
|
|
QTextStream myQTextStream( &myFile );
|
|
myQTextStream << mReport;
|
|
myFile.close();
|
|
}
|
|
}
|
|
|
|
void TestQgsLayoutUtils::init()
|
|
{
|
|
|
|
}
|
|
|
|
void TestQgsLayoutUtils::cleanup()
|
|
{
|
|
|
|
}
|
|
|
|
void TestQgsLayoutUtils::normalizedAngle()
|
|
{
|
|
QList< QPair< double, double > > testVals;
|
|
testVals << qMakePair( 0.0, 0.0 );
|
|
testVals << qMakePair( 90.0, 90.0 );
|
|
testVals << qMakePair( 180.0, 180.0 );
|
|
testVals << qMakePair( 270.0, 270.0 );
|
|
testVals << qMakePair( 360.0, 0.0 );
|
|
testVals << qMakePair( 390.0, 30.0 );
|
|
testVals << qMakePair( 720.0, 0.0 );
|
|
testVals << qMakePair( 730.0, 10.0 );
|
|
testVals << qMakePair( -10.0, 350.0 );
|
|
testVals << qMakePair( -360.0, 0.0 );
|
|
testVals << qMakePair( -370.0, 350.0 );
|
|
testVals << qMakePair( -760.0, 320.0 );
|
|
|
|
//test normalized angle helper function
|
|
QList< QPair< double, double > >::const_iterator it = testVals.constBegin();
|
|
for ( ; it != testVals.constEnd(); ++it )
|
|
|
|
{
|
|
double result = QgsLayoutUtils::normalizedAngle( ( *it ).first );
|
|
qDebug() << QStringLiteral( "actual: %1 expected: %2" ).arg( result ).arg( ( *it ).second );
|
|
QGSCOMPARENEAR( result, ( *it ).second, 4 * DBL_EPSILON );
|
|
|
|
}
|
|
|
|
//test with allowing negative angles
|
|
QList< QPair< double, double > > negativeTestVals;
|
|
negativeTestVals << qMakePair( 0.0, 0.0 );
|
|
negativeTestVals << qMakePair( 90.0, 90.0 );
|
|
negativeTestVals << qMakePair( 360.0, 0.0 );
|
|
negativeTestVals << qMakePair( -10.0, -10.0 );
|
|
negativeTestVals << qMakePair( -359.0, -359.0 );
|
|
negativeTestVals << qMakePair( -360.0, 0.0 );
|
|
negativeTestVals << qMakePair( -361.0, -1.0 );
|
|
negativeTestVals << qMakePair( -370.0, -10.0 );
|
|
negativeTestVals << qMakePair( -760.0, -40.0 );
|
|
it = negativeTestVals.constBegin();
|
|
for ( ; it != negativeTestVals.constEnd(); ++it )
|
|
|
|
{
|
|
double result = QgsLayoutUtils::normalizedAngle( ( *it ).first, true );
|
|
qDebug() << QStringLiteral( "actual: %1 expected: %2" ).arg( result ).arg( ( *it ).second );
|
|
QGSCOMPARENEAR( result, ( *it ).second, 4 * DBL_EPSILON );
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void TestQgsLayoutUtils::createRenderContextFromLayout()
|
|
{
|
|
QImage testImage = QImage( 250, 250, QImage::Format_RGB32 );
|
|
testImage.setDotsPerMeterX( 150 / 25.4 * 1000 );
|
|
testImage.setDotsPerMeterY( 150 / 25.4 * 1000 );
|
|
QPainter p( &testImage );
|
|
|
|
// no layout
|
|
QgsRenderContext rc = QgsLayoutUtils::createRenderContextForLayout( nullptr, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QCOMPARE( rc.painter(), &p );
|
|
|
|
// no layout, no painter
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( nullptr, nullptr );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
|
|
QVERIFY( !rc.painter() );
|
|
|
|
//create layout with no reference map
|
|
QgsRectangle extent( 2000, 2800, 2500, 2900 );
|
|
QgsProject project;
|
|
QgsLayout l( &project );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QCOMPARE( rc.painter(), &p );
|
|
|
|
// layout, no map, no painter
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
|
|
QVERIFY( !rc.painter() );
|
|
|
|
// add a reference map
|
|
QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
|
|
#if 0 // TODO
|
|
map->setNewExtent( extent );
|
|
map->setSceneRect( QRectF( 30, 60, 200, 100 ) );
|
|
composition->addComposerMap( map );
|
|
#endif
|
|
l.setReferenceMap( map );
|
|
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QGSCOMPARENEAR( rc.rendererScale(), map->scale(), 1000000 );
|
|
QCOMPARE( rc.painter(), &p );
|
|
|
|
// layout, reference map, no painter
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
|
|
QGSCOMPARENEAR( rc.rendererScale(), map->scale(), 1000000 );
|
|
QVERIFY( !rc.painter() );
|
|
|
|
// check render context flags are correctly set
|
|
l.context().setFlags( 0 );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
|
|
l.context().setFlag( QgsLayoutContext::FlagAntialiasing );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
|
|
l.context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
|
|
p.end();
|
|
}
|
|
|
|
void TestQgsLayoutUtils::createRenderContextFromMap()
|
|
{
|
|
QImage testImage = QImage( 250, 250, QImage::Format_RGB32 );
|
|
testImage.setDotsPerMeterX( 150 / 25.4 * 1000 );
|
|
testImage.setDotsPerMeterY( 150 / 25.4 * 1000 );
|
|
QPainter p( &testImage );
|
|
|
|
// no map
|
|
QgsRenderContext rc = QgsLayoutUtils::createRenderContextForMap( nullptr, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QCOMPARE( rc.painter(), &p );
|
|
|
|
// no map, no painter
|
|
rc = QgsLayoutUtils::createRenderContextForMap( nullptr, nullptr );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
|
|
QVERIFY( !rc.painter() );
|
|
|
|
//create composition with no reference map
|
|
QgsRectangle extent( 2000, 2800, 2500, 2900 );
|
|
QgsProject project;
|
|
QgsLayout l( &project );
|
|
|
|
#if 0 // TODO
|
|
// add a map
|
|
QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
|
|
|
|
map->setNewExtent( extent );
|
|
map->setSceneRect( QRectF( 30, 60, 200, 100 ) );
|
|
l.addComposerMap( map );
|
|
#endif
|
|
|
|
#if 0 //TODO
|
|
rc = QgsLayoutUtils::createRenderContextForMap( map, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QGSCOMPARENEAR( rc.rendererScale(), map->scale(), 1000000 );
|
|
QCOMPARE( rc.painter(), &p );
|
|
|
|
// map, no painter
|
|
rc = QgsLayoutUtils::createRenderContextForMap( map, nullptr );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
|
|
QGSCOMPARENEAR( rc.rendererScale(), map->scale(), 1000000 );
|
|
QVERIFY( !rc.painter() );
|
|
|
|
// secondary map
|
|
QgsLayoutItemMap *map2 = new QgsLayoutItemMap( &l );
|
|
|
|
map2->setNewExtent( extent );
|
|
map2->setSceneRect( QRectF( 30, 60, 100, 50 ) );
|
|
composition->addComposerMap( map2 );
|
|
|
|
rc = QgsLayoutUtils::createRenderContextForMap( map2, &p );
|
|
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
|
|
QGSCOMPARENEAR( rc.rendererScale(), map2->scale(), 1000000 );
|
|
QVERIFY( rc.painter() );
|
|
|
|
// check render context flags are correctly set
|
|
l.context().setFlags( 0 );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
|
|
l.context().setFlag( QgsLayoutContext::FlagAntialiasing );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
|
|
l.context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects );
|
|
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
|
|
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
|
|
#endif
|
|
p.end();
|
|
}
|
|
|
|
|
|
void TestQgsLayoutUtils::relativePosition()
|
|
{
|
|
//+ve gradient
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 1, 0, 2, 0, 4 ), 2, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 0, 0, 2, 0, 4 ), 0, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 2, 0, 2, 0, 4 ), 4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 4, 0, 2, 0, 4 ), 8, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( -2, 0, 2, 0, 4 ), -4, 0.001 );
|
|
//-ve gradient
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 1, 0, 2, 4, 0 ), 2, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 0, 0, 2, 4, 0 ), 4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 2, 0, 2, 4, 0 ), 0, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 4, 0, 2, 4, 0 ), -4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( -2, 0, 2, 4, 0 ), 8, 0.001 );
|
|
//-ve domain
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 1, 2, 0, 0, 4 ), 2, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 0, 2, 0, 0, 4 ), 4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 2, 2, 0, 0, 4 ), 0, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 4, 2, 0, 0, 4 ), -4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( -2, 2, 0, 0, 4 ), 8, 0.001 );
|
|
//-ve domain and gradient
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 1, 2, 0, 4, 0 ), 2, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 0, 2, 0, 4, 0 ), 0, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 2, 2, 0, 4, 0 ), 4, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( 4, 2, 0, 4, 0 ), 8, 0.001 );
|
|
QGSCOMPARENEAR( QgsLayoutUtils::relativePosition( -2, 2, 0, 4, 0 ), -4, 0.001 );
|
|
}
|
|
|
|
void TestQgsLayoutUtils::relativeResizeRect()
|
|
{
|
|
//test rectangle which fills bounds
|
|
QRectF testRect = QRectF( 0, 0, 1, 1 );
|
|
QRectF boundsBefore = QRectF( 0, 0, 1, 1 );
|
|
QRectF boundsAfter = QRectF( 0, 0, 1, 1 );
|
|
QgsLayoutUtils::relativeResizeRect( testRect, boundsBefore, boundsAfter );
|
|
QCOMPARE( testRect, QRectF( 0, 0, 1, 1 ) );
|
|
testRect = QRectF( 0, 0, 1, 1 );
|
|
boundsAfter = QRectF( 0, 0, 2, 2 );
|
|
QgsLayoutUtils::relativeResizeRect( testRect, boundsBefore, boundsAfter );
|
|
QCOMPARE( testRect, QRectF( 0, 0, 2, 2 ) );
|
|
testRect = QRectF( 0, 0, 1, 1 );
|
|
boundsAfter = QRectF( 0, 0, 0.5, 4 );
|
|
QgsLayoutUtils::relativeResizeRect( testRect, boundsBefore, boundsAfter );
|
|
QCOMPARE( testRect, QRectF( 0, 0, 0.5, 4 ) );
|
|
|
|
//test rectangle which doesn't fill bounds
|
|
testRect = QRectF( 1, 2, 1, 2 );
|
|
boundsBefore = QRectF( 0, 0, 4, 8 );
|
|
boundsAfter = QRectF( 0, 0, 2, 4 );
|
|
QgsLayoutUtils::relativeResizeRect( testRect, boundsBefore, boundsAfter );
|
|
QCOMPARE( testRect, QRectF( 0.5, 1, 0.5, 1 ) );
|
|
}
|
|
|
|
QGSTEST_MAIN( TestQgsLayoutUtils )
|
|
#include "testqgslayoututils.moc"
|