Remove composer from more code, port georeferencer reports to layouts

This commit is contained in:
Nyall Dawson 2018-01-17 18:36:40 +10:00
parent 5804745326
commit d8402acee8
15 changed files with 209 additions and 152 deletions

View File

@ -56,7 +56,6 @@ IF(WITH_APIDOC)
${CMAKE_SOURCE_DIR}/src/core/3d
${CMAKE_SOURCE_DIR}/src/core/annotations
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/diagram
${CMAKE_SOURCE_DIR}/src/core/dxf
${CMAKE_SOURCE_DIR}/src/core/effects

View File

@ -107,7 +107,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/expression
${CMAKE_SOURCE_DIR}/src/core/pal
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/diagram
${CMAKE_SOURCE_DIR}/src/core/effects
${CMAKE_SOURCE_DIR}/src/core/fieldformatter

View File

@ -576,7 +576,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core
${CMAKE_SOURCE_DIR}/src/core/annotations
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/expression
${CMAKE_SOURCE_DIR}/src/core/gps
${CMAKE_SOURCE_DIR}/src/core/dxf
@ -636,7 +635,6 @@ INCLUDE_DIRECTORIES(
../core
../core/annotations
../core/auth
../core/composer
../core/gps
../core/dxf
../core/geometry

View File

@ -23,7 +23,6 @@
#include "qgisapp.h"
#include "qgsstringutils.h"
#include "qgsmaplayermodel.h"
#include "qgscomposition.h"
#include "qgslayoutmanager.h"
#include "qgsmapcanvas.h"
#include <QToolButton>

View File

@ -16,7 +16,6 @@
***************************************************************************/
#include "qgslegendstyle.h"
#include "qgscomposition.h"
#include "qgsfontutils.h"
#include "qgssettings.h"

View File

@ -79,7 +79,8 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/core/metadata
${CMAKE_SOURCE_DIR}/src/core/raster
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/layout
${CMAKE_SOURCE_DIR}/src/core/symbology
${CMAKE_SOURCE_DIR}/src/gui
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets
${CMAKE_SOURCE_DIR}/src/gui/layertree

View File

@ -34,12 +34,13 @@
#include "qgisinterface.h"
#include "qgsapplication.h"
#include "qgscomposition.h"
#include "qgscomposerlabel.h"
#include "qgscomposermap.h"
#include "qgscomposertexttable.h"
#include "qgscomposertablecolumn.h"
#include "qgscomposerframe.h"
#include "qgslayout.h"
#include "qgslayoutitemlabel.h"
#include "qgslayoutitemmap.h"
#include "qgslayoutitemtexttable.h"
#include "qgslayouttablecolumn.h"
#include "qgslayoutframe.h"
#include "qgslayoutpagecollection.h"
#include "qgsmapcanvas.h"
#include "qgsmapcoordsdialog.h"
#include "qgsmaptoolzoom.h"
@ -1509,41 +1510,42 @@ bool QgsGeorefPluginGui::writePDFMapFile( const QString &fileName, const QgsGeor
}
double mapRatio = rlayer->extent().width() / rlayer->extent().height();
QPrinter printer;
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( fileName );
QgsSettings s;
double paperWidth = s.value( QStringLiteral( "/Plugin-GeoReferencer/Config/WidthPDFMap" ), "297" ).toDouble();
double paperHeight = s.value( QStringLiteral( "/Plugin-GeoReferencer/Config/HeightPDFMap" ), "420" ).toDouble();
//create composition
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
if ( mapRatio >= 1 )
{
composition->setPaperSize( paperHeight, paperWidth );
}
else
{
composition->setPaperSize( paperWidth, paperHeight );
}
composition->setPrintResolution( 300 );
printer.setPaperSize( QSizeF( composition->paperWidth(), composition->paperHeight() ), QPrinter::Millimeter );
//create layout
QgsLayout layout( QgsProject::instance() );
std::unique_ptr< QgsLayoutItemPage > page = qgis::make_unique< QgsLayoutItemPage >( &layout );
double leftMargin = 8;
double topMargin = 8;
double contentWidth = composition->paperWidth() - 2 * leftMargin;
double contentHeight = composition->paperHeight() - 2 * topMargin;
double contentWidth = 0.0;
double contentHeight = 0.0;
//composer map
QgsComposerMap *composerMap = new QgsComposerMap( composition, leftMargin, topMargin, contentWidth, contentHeight );
composerMap->setKeepLayerSet( true );
if ( mapRatio >= 1 )
{
page->setPageSize( QgsLayoutSize( paperHeight, paperWidth ) );
contentWidth = paperHeight - 2 * leftMargin;
contentHeight = paperWidth - 2 * topMargin;
}
else
{
page->setPageSize( QgsLayoutSize( paperWidth, paperHeight ) );
contentWidth = paperWidth - 2 * leftMargin;
contentHeight = paperHeight - 2 * topMargin;
}
layout.pageCollection()->addPage( page.release() );
//layout map
QgsLayoutItemMap *layoutMap = new QgsLayoutItemMap( &layout );
layoutMap->attemptSetSceneRect( QRectF( leftMargin, topMargin, contentWidth, contentHeight ) );
layoutMap->setKeepLayerSet( true );
QgsMapLayer *firstLayer = mCanvas->mapSettings().layers()[0];
composerMap->setLayers( QList<QgsMapLayer *>() << firstLayer );
composerMap->zoomToExtent( rlayer->extent() );
composition->addItem( composerMap );
printer.setFullPage( true );
printer.setColorMode( QPrinter::Color );
layoutMap->setLayers( QList<QgsMapLayer *>() << firstLayer );
layoutMap->setCrs( rlayer->crs() );
layoutMap->zoomToExtent( rlayer->extent() );
layout.addLayoutItem( layoutMap );
QString residualUnits;
if ( s.value( QStringLiteral( "/Plugin-GeoReferencer/Config/ResidualUnits" ) ) == "mapUnits" && mGeorefTransform.providesAccurateInverseTransformation() )
@ -1556,23 +1558,17 @@ bool QgsGeorefPluginGui::writePDFMapFile( const QString &fileName, const QgsGeor
}
//residual plot
QgsResidualPlotItem *resPlotItem = new QgsResidualPlotItem( composition );
composition->addItem( resPlotItem );
resPlotItem->setSceneRect( QRectF( leftMargin, topMargin, contentWidth, contentHeight ) );
resPlotItem->setExtent( composerMap->extent() );
QgsResidualPlotItem *resPlotItem = new QgsResidualPlotItem( &layout );
layout.addLayoutItem( resPlotItem );
resPlotItem->attemptSetSceneRect( QRectF( leftMargin, topMargin, contentWidth, contentHeight ) );
resPlotItem->setExtent( layoutMap->extent() );
resPlotItem->setGCPList( mPoints );
resPlotItem->setConvertScaleToMapUnits( residualUnits == tr( "map units" ) );
printer.setResolution( composition->printResolution() );
QPainter p( &printer );
composition->setPlotStyle( QgsComposition::Print );
QRectF paperRectMM = printer.pageRect( QPrinter::Millimeter );
QRectF paperRectPixel = printer.pageRect( QPrinter::DevicePixel );
composition->render( &p, paperRectPixel, paperRectMM );
delete resPlotItem;
delete composerMap;
delete composition;
QgsLayoutExporter exporter( &layout );
QgsLayoutExporter::PdfExportSettings settings;
settings.dpi = 300;
exporter.exportToPdf( fileName, settings );
return true;
}
@ -1584,11 +1580,15 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString &fileName, const QgsG
return false;
}
//create composition A4 with 300 dpi
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
composition->setPaperSize( 210, 297 ); //A4
composition->setPrintResolution( 300 );
composition->setNumPages( 2 );
//create layout A4 with 300 dpi
QgsLayout layout( QgsProject::instance() );
std::unique_ptr< QgsLayoutItemPage > page = qgis::make_unique< QgsLayoutItemPage >( &layout );
page->setPageSize( QgsLayoutSize( 210, 297 ) ); //A4
layout.pageCollection()->addPage( page.release() );
std::unique_ptr< QgsLayoutItemPage > page2 = qgis::make_unique< QgsLayoutItemPage >( &layout );
page2->setPageSize( QgsLayoutSize( 210, 297 ) ); //A4
layout.pageCollection()->addPage( page2.release() );
QFont titleFont;
titleFont.setPointSize( 9 );
@ -1606,14 +1606,14 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString &fileName, const QgsG
//title
QFileInfo rasterFi( mRasterFileName );
QgsComposerLabel *titleLabel = new QgsComposerLabel( composition );
QgsLayoutItemLabel *titleLabel = new QgsLayoutItemLabel( &layout );
titleLabel->setFont( titleFont );
titleLabel->setText( rasterFi.fileName() );
composition->addItem( titleLabel );
titleLabel->setSceneRect( QRectF( leftMargin, 5, contentWidth, 8 ) );
layout.addLayoutItem( titleLabel );
titleLabel->attemptSetSceneRect( QRectF( leftMargin, 5, contentWidth, 8 ) );
titleLabel->setFrameEnabled( false );
//composer map
//layout map
QgsRasterLayer *rLayer = ( QgsRasterLayer * ) mCanvas->layer( 0 );
if ( !rLayer )
{
@ -1636,16 +1636,18 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString &fileName, const QgsG
mapWidthMM = 70 / layerExtent.height() * layerExtent.width();
}
QgsComposerMap *composerMap = new QgsComposerMap( composition, leftMargin, titleLabel->rect().bottom() + titleLabel->pos().y(), mapWidthMM, mapHeightMM );
composerMap->setLayers( mCanvas->mapSettings().layers() );
composerMap->zoomToExtent( layerExtent );
composition->addItem( composerMap );
QgsLayoutItemMap *layoutMap = new QgsLayoutItemMap( &layout );
layoutMap->attemptSetSceneRect( QRectF( leftMargin, titleLabel->rect().bottom() + titleLabel->pos().y(), mapWidthMM, mapHeightMM ) );
layoutMap->setLayers( mCanvas->mapSettings().layers() );
layoutMap->setCrs( rLayer->crs() );
layoutMap->zoomToExtent( layerExtent );
layout.addLayoutItem( layoutMap );
QgsComposerTextTableV2 *parameterTable = nullptr;
QgsLayoutItemTextTable *parameterTable = nullptr;
double scaleX, scaleY, rotation;
QgsPointXY origin;
QgsComposerLabel *parameterLabel = nullptr;
QgsLayoutItemLabel *parameterLabel = nullptr;
//transformation that involves only scaling and rotation (linear or helmert) ?
bool wldTransform = transform.getOriginScaleRotation( origin, scaleX, scaleY, rotation );
@ -1659,84 +1661,84 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString &fileName, const QgsG
residualUnits = tr( "pixels" );
}
QGraphicsRectItem *previousItem = composerMap;
QGraphicsRectItem *previousItem = layoutMap;
if ( wldTransform )
{
QString parameterTitle = tr( "Transformation parameters" ) + QStringLiteral( " (" ) + convertTransformEnumToString( transform.transformParametrisation() ) + QStringLiteral( ")" );
parameterLabel = new QgsComposerLabel( composition );
parameterLabel = new QgsLayoutItemLabel( &layout );
parameterLabel->setFont( titleFont );
parameterLabel->setText( parameterTitle );
parameterLabel->adjustSizeToText();
composition->addItem( parameterLabel );
parameterLabel->setSceneRect( QRectF( leftMargin, composerMap->rect().bottom() + composerMap->pos().y() + 5, contentWidth, 8 ) );
layout.addLayoutItem( parameterLabel );
parameterLabel->attemptSetSceneRect( QRectF( leftMargin, layoutMap->rect().bottom() + layoutMap->pos().y() + 5, contentWidth, 8 ) );
parameterLabel->setFrameEnabled( false );
//calculate mean error
double meanError = 0;
calculateMeanError( meanError );
parameterTable = new QgsComposerTextTableV2( composition, false );
parameterTable = new QgsLayoutItemTextTable( &layout );
parameterTable->setHeaderFont( tableHeaderFont );
parameterTable->setContentFont( tableContentFont );
QgsComposerTableColumns columns;
columns << new QgsComposerTableColumn( tr( "Translation x" ) )
<< new QgsComposerTableColumn( tr( "Translation y" ) )
<< new QgsComposerTableColumn( tr( "Scale x" ) )
<< new QgsComposerTableColumn( tr( "Scale y" ) )
<< new QgsComposerTableColumn( tr( "Rotation [degrees]" ) )
<< new QgsComposerTableColumn( tr( "Mean error [%1]" ).arg( residualUnits ) );
QgsLayoutTableColumns columns;
columns << new QgsLayoutTableColumn( tr( "Translation x" ) )
<< new QgsLayoutTableColumn( tr( "Translation y" ) )
<< new QgsLayoutTableColumn( tr( "Scale x" ) )
<< new QgsLayoutTableColumn( tr( "Scale y" ) )
<< new QgsLayoutTableColumn( tr( "Rotation [degrees]" ) )
<< new QgsLayoutTableColumn( tr( "Mean error [%1]" ).arg( residualUnits ) );
parameterTable->setColumns( columns );
QStringList row;
row << QString::number( origin.x(), 'f', 3 ) << QString::number( origin.y(), 'f', 3 ) << QString::number( scaleX ) << QString::number( scaleY ) << QString::number( rotation * 180 / M_PI ) << QString::number( meanError );
parameterTable->addRow( row );
QgsComposerFrame *tableFrame = new QgsComposerFrame( composition, parameterTable, leftMargin, parameterLabel->rect().bottom() + parameterLabel->pos().y() + 5, contentWidth, 12 );
QgsLayoutFrame *tableFrame = new QgsLayoutFrame( &layout, parameterTable );
tableFrame->attemptSetSceneRect( QRectF( leftMargin, parameterLabel->rect().bottom() + parameterLabel->pos().y() + 5, contentWidth, 12 ) );
parameterTable->addFrame( tableFrame );
composition->addItem( tableFrame );
parameterTable->setGridStrokeWidth( 0.1 );
previousItem = tableFrame;
}
QgsComposerLabel *residualLabel = new QgsComposerLabel( composition );
QgsLayoutItemLabel *residualLabel = new QgsLayoutItemLabel( &layout );
residualLabel->setFont( titleFont );
residualLabel->setText( tr( "Residuals" ) );
composition->addItem( residualLabel );
residualLabel->setSceneRect( QRectF( leftMargin, previousItem->rect().bottom() + previousItem->pos().y() + 5, contentWidth, 6 ) );
layout.addLayoutItem( residualLabel );
residualLabel->attemptSetSceneRect( QRectF( leftMargin, previousItem->rect().bottom() + previousItem->pos().y() + 5, contentWidth, 6 ) );
residualLabel->setFrameEnabled( false );
//residual plot
QgsResidualPlotItem *resPlotItem = new QgsResidualPlotItem( composition );
composition->addItem( resPlotItem );
resPlotItem->setSceneRect( QRectF( leftMargin, residualLabel->rect().bottom() + residualLabel->pos().y() + 5, contentWidth, composerMap->rect().height() ) );
resPlotItem->setExtent( composerMap->extent() );
QgsResidualPlotItem *resPlotItem = new QgsResidualPlotItem( &layout );
layout.addLayoutItem( resPlotItem );
resPlotItem->attemptSetSceneRect( QRectF( leftMargin, residualLabel->rect().bottom() + residualLabel->pos().y() + 5, contentWidth, layoutMap->rect().height() ) );
resPlotItem->setExtent( layoutMap->extent() );
resPlotItem->setGCPList( mPoints );
//necessary for the correct scale bar unit label
resPlotItem->setConvertScaleToMapUnits( residualUnits == tr( "map units" ) );
QgsComposerTextTableV2 *gcpTable = new QgsComposerTextTableV2( composition, false );
QgsLayoutItemTextTable *gcpTable = new QgsLayoutItemTextTable( &layout );
gcpTable->setHeaderFont( tableHeaderFont );
gcpTable->setContentFont( tableContentFont );
gcpTable->setHeaderMode( QgsComposerTableV2::AllFrames );
QgsComposerTableColumns columns;
columns << new QgsComposerTableColumn( tr( "ID" ) )
<< new QgsComposerTableColumn( tr( "Enabled" ) )
<< new QgsComposerTableColumn( tr( "Pixel X" ) )
<< new QgsComposerTableColumn( tr( "Pixel Y" ) )
<< new QgsComposerTableColumn( tr( "Map X" ) )
<< new QgsComposerTableColumn( tr( "Map Y" ) )
<< new QgsComposerTableColumn( tr( "Res X (%1)" ).arg( residualUnits ) )
<< new QgsComposerTableColumn( tr( "Res Y (%1)" ).arg( residualUnits ) )
<< new QgsComposerTableColumn( tr( "Res Total (%1)" ).arg( residualUnits ) );
gcpTable->setHeaderMode( QgsLayoutTable::AllFrames );
QgsLayoutTableColumns columns;
columns << new QgsLayoutTableColumn( tr( "ID" ) )
<< new QgsLayoutTableColumn( tr( "Enabled" ) )
<< new QgsLayoutTableColumn( tr( "Pixel X" ) )
<< new QgsLayoutTableColumn( tr( "Pixel Y" ) )
<< new QgsLayoutTableColumn( tr( "Map X" ) )
<< new QgsLayoutTableColumn( tr( "Map Y" ) )
<< new QgsLayoutTableColumn( tr( "Res X (%1)" ).arg( residualUnits ) )
<< new QgsLayoutTableColumn( tr( "Res Y (%1)" ).arg( residualUnits ) )
<< new QgsLayoutTableColumn( tr( "Res Total (%1)" ).arg( residualUnits ) );
gcpTable->setColumns( columns );
QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
QList< QStringList > gcpTableContents;
QVector< QStringList > gcpTableContents;
for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
{
QStringList currentGCPStrings;
@ -1761,27 +1763,24 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString &fileName, const QgsG
double firstFrameY = resPlotItem->rect().bottom() + resPlotItem->pos().y() + 5;
double firstFrameHeight = 287 - firstFrameY;
QgsComposerFrame *gcpFirstFrame = new QgsComposerFrame( composition, gcpTable, leftMargin, firstFrameY, contentWidth, firstFrameHeight );
QgsLayoutFrame *gcpFirstFrame = new QgsLayoutFrame( &layout, gcpTable );
gcpFirstFrame->attemptSetSceneRect( QRectF( leftMargin, firstFrameY, contentWidth, firstFrameHeight ) );
gcpTable->addFrame( gcpFirstFrame );
composition->addItem( gcpFirstFrame );
QgsComposerFrame *gcpSecondFrame = new QgsComposerFrame( composition, gcpTable, leftMargin, 10, contentWidth, 277.0 );
gcpSecondFrame->setItemPosition( leftMargin, 10, QgsComposerItem::UpperLeft, 2 );
QgsLayoutFrame *gcpSecondFrame = new QgsLayoutFrame( &layout, gcpTable );
gcpSecondFrame->attemptSetSceneRect( QRectF( leftMargin, 10, contentWidth, 277.0 ) );
gcpSecondFrame->attemptMove( QgsLayoutPoint( leftMargin, 10 ), true, false, 1 );
gcpSecondFrame->setHidePageIfEmpty( true );
gcpTable->addFrame( gcpSecondFrame );
composition->addItem( gcpSecondFrame );
gcpTable->setGridStrokeWidth( 0.1 );
gcpTable->setResizeMode( QgsComposerMultiFrame::RepeatUntilFinished );
gcpTable->setResizeMode( QgsLayoutMultiFrame::RepeatUntilFinished );
composition->exportAsPDF( fileName );
QgsLayoutExporter exporter( &layout );
QgsLayoutExporter::PdfExportSettings settings;
settings.dpi = 300;
exporter.exportToPdf( fileName, settings );
delete titleLabel;
delete parameterLabel;
delete residualLabel;
delete resPlotItem;
delete composerMap;
delete composition;
return true;
}

View File

@ -15,16 +15,16 @@
#include "qgsresidualplotitem.h"
#include "qgsgeorefdatapoint.h"
#include "qgscomposerutils.h"
#include "qgslayoututils.h"
#include <QPainter>
#include <cfloat>
#include <cmath>
QgsResidualPlotItem::QgsResidualPlotItem( QgsComposition *c )
: QgsComposerItem( c )
QgsResidualPlotItem::QgsResidualPlotItem( QgsLayout *layout )
: QgsLayoutItem( layout )
, mConvertScaleToMapUnits( false )
{
setBackgroundEnabled( false );
}
void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
@ -68,7 +68,7 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt
painter->setBrush( disabledBrush );
}
painter->drawRect( QRectF( gcpItemMMX - 0.5, gcpItemMMY - 0.5, 1, 1 ) );
QgsComposerUtils::drawText( painter, QPointF( gcpItemMMX + 2, gcpItemMMY + 2 ), QString::number( ( *gcpIt )->id() ), QFont() );
QgsLayoutUtils::drawText( painter, QPointF( gcpItemMMX + 2, gcpItemMMY + 2 ), QString::number( ( *gcpIt )->id() ), QFont() );
mmPixelRatio = maxMMToPixelRatioForGCP( *gcpIt, gcpItemMMX, gcpItemMMY );
if ( mmPixelRatio < minMMPixelRatio )
@ -97,7 +97,7 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt
QPointF p2( gcpItemMMX + ( *gcpIt )->residual().x() * minMMPixelRatio, gcpItemMMY + ( *gcpIt )->residual().y() * minMMPixelRatio );
painter->drawLine( p1, p2 );
painter->setBrush( QBrush( painter->pen().color() ) );
QgsComposerUtils::drawArrowHead( painter, p2.x(), p2.y(), QgsComposerUtils::angle( p1, p2 ), 1 );
drawArrowHead( painter, p2.x(), p2.y(), angle( p1, p2 ), 1 );
}
//draw scale bar
@ -132,20 +132,29 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt
scaleBarFont.setPointSize( 9 );
if ( mConvertScaleToMapUnits )
{
QgsComposerUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsComposerUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 map units" ).arg( scaleBarWidthUnits ), QFont() );
QgsLayoutUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsLayoutUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 map units" ).arg( scaleBarWidthUnits ), QFont() );
}
else
{
QgsComposerUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsComposerUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 pixels" ).arg( scaleBarWidthUnits ), QFont() );
QgsLayoutUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsLayoutUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 pixels" ).arg( scaleBarWidthUnits ), QFont() );
}
drawFrame( painter );
if ( isSelected() )
if ( frameEnabled() )
{
drawSelectionBoxes( painter );
painter->save();
painter->setPen( pen() );
painter->setBrush( Qt::NoBrush );
painter->setRenderHint( QPainter::Antialiasing, true );
painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
painter->restore();
}
}
void QgsResidualPlotItem::draw( QgsRenderContext &, const QStyleOptionGraphicsItem * )
{
}
double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint *p, double pixelXMM, double pixelYMM )
{
if ( !p )
@ -207,23 +216,65 @@ double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint *p
}
}
bool QgsResidualPlotItem::writeXml( QDomElement &elem, QDomDocument &doc ) const
{
Q_UNUSED( elem );
Q_UNUSED( doc );
return false;
}
bool QgsResidualPlotItem::readXml( const QDomElement &itemElem, const QDomDocument &doc )
{
Q_UNUSED( itemElem );
Q_UNUSED( doc );
return false;
}
double QgsResidualPlotItem::dist( QPointF p1, QPointF p2 ) const
{
double dx = p2.x() - p1.x();
double dy = p2.y() - p1.y();
return std::sqrt( dx * dx + dy * dy );
}
void QgsResidualPlotItem::drawArrowHead( QPainter *p, const double x, const double y, const double angle, const double arrowHeadWidth )
{
if ( !p )
{
return;
}
double angleRad = angle / 180.0 * M_PI;
QPointF middlePoint( x, y );
//rotate both arrow points
QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
QPointF p1Rotated, p2Rotated;
p1Rotated.setX( p1.x() * std::cos( angleRad ) + p1.y() * -std::sin( angleRad ) );
p1Rotated.setY( p1.x() * std::sin( angleRad ) + p1.y() * std::cos( angleRad ) );
p2Rotated.setX( p2.x() * std::cos( angleRad ) + p2.y() * -std::sin( angleRad ) );
p2Rotated.setY( p2.x() * std::sin( angleRad ) + p2.y() * std::cos( angleRad ) );
QPolygonF arrowHeadPoly;
arrowHeadPoly << middlePoint;
arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
p->save();
QPen arrowPen = p->pen();
arrowPen.setJoinStyle( Qt::RoundJoin );
QBrush arrowBrush = p->brush();
arrowBrush.setStyle( Qt::SolidPattern );
p->setPen( arrowPen );
p->setBrush( arrowBrush );
arrowBrush.setStyle( Qt::SolidPattern );
p->drawPolygon( arrowHeadPoly );
p->restore();
}
double QgsResidualPlotItem::angle( QPointF p1, QPointF p2 )
{
double xDiff = p2.x() - p1.x();
double yDiff = p2.y() - p1.y();
double length = std::sqrt( xDiff * xDiff + yDiff * yDiff );
if ( length <= 0 )
{
return 0;
}
double angle = std::acos( ( -yDiff * length ) / ( length * length ) ) * 180 / M_PI;
if ( xDiff < 0 )
{
return ( 360 - angle );
}
return angle;
}

View File

@ -16,19 +16,19 @@
#ifndef QGSRESIDUALPLOTITEM_H
#define QGSRESIDUALPLOTITEM_H
#include "qgscomposeritem.h"
#include "qgslayoutitem.h"
#include "qgsgcplist.h"
#include "qgsrectangle.h"
/**
* A composer item to visualise the distribution of georeference residuals. For the visualisation,
the length of the residual arrows are scaled*/
class QgsResidualPlotItem: public QgsComposerItem
class QgsResidualPlotItem: public QgsLayoutItem
{
Q_OBJECT
public:
explicit QgsResidualPlotItem( QgsComposition *c );
explicit QgsResidualPlotItem( QgsLayout *layout );
//! \brief Reimplementation of QCanvasItem::paint
void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;
@ -42,9 +42,7 @@ class QgsResidualPlotItem: public QgsComposerItem
void setConvertScaleToMapUnits( bool convert ) { mConvertScaleToMapUnits = convert; }
bool convertScaleToMapUnits() const { return mConvertScaleToMapUnits; }
bool writeXml( QDomElement &elem, QDomDocument &doc ) const override;
bool readXml( const QDomElement &itemElem, const QDomDocument &doc ) override;
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
private:
//gcp list
QgsGCPList mGCPList;
@ -58,6 +56,26 @@ class QgsResidualPlotItem: public QgsComposerItem
//! Returns distance between two points
double dist( QPointF p1, QPointF p2 ) const;
/**
* Draws an arrow head on to a QPainter.
* \param p destination painter
* \param x x-coordinate of arrow center
* \param y y-coordinate of arrow center
* \param angle angle in degrees which arrow should point toward, measured
* clockwise from pointing vertical upward
* \param arrowHeadWidth size of arrow head
*/
static void drawArrowHead( QPainter *p, const double x, const double y, const double angle, const double arrowHeadWidth );
/**
* Calculates the angle of the line from p1 to p2 (counter clockwise,
* starting from a line from north to south)
* \param p1 start point of line
* \param p2 end point of line
* \returns angle in degrees, clockwise from south
*/
static double angle( QPointF p1, QPointF p2 );
};
#endif // QGSRESIDUALPLOTITEM_H

View File

@ -110,7 +110,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/metadata
${CMAKE_SOURCE_DIR}/src/core/raster
${CMAKE_SOURCE_DIR}/src/core/symbology
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/layout
${CMAKE_SOURCE_DIR}/src/core/layertree
${CMAKE_SOURCE_DIR}/src/analysis/interpolation

View File

@ -36,7 +36,6 @@ INCLUDE_DIRECTORIES(
../../../core/metadata
../../../core/raster
../../../core/symbology
../../../core/composer
../../../core/layertree
../..
..

View File

@ -46,7 +46,6 @@ INCLUDE_DIRECTORIES(
../../../core/metadata
../../../core/raster
../../../core/symbology
../../../core/composer
../../../core/layertree
../..
..

View File

@ -51,7 +51,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/metadata
${CMAKE_SOURCE_DIR}/src/core/raster
${CMAKE_SOURCE_DIR}/src/core/symbology
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/layertree
${CMAKE_SOURCE_DIR}/src/core/layout
${CMAKE_SOURCE_DIR}/src/gui

View File

@ -13,7 +13,6 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core
${CMAKE_SOURCE_DIR}/src/core/expression
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/core/layout
${CMAKE_SOURCE_DIR}/src/core/metadata

View File

@ -5,7 +5,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/core/composer
${CMAKE_SOURCE_DIR}/src/core/expression
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/core/layout