diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 26a3683260d..5d85e2444e6 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -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 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 5605244f1a1..123361fac62 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -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 diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 409954d13a9..ef9501b72b6 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -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 diff --git a/src/app/locator/qgsinbuiltlocatorfilters.cpp b/src/app/locator/qgsinbuiltlocatorfilters.cpp index f600a21703f..1423c85a5c4 100644 --- a/src/app/locator/qgsinbuiltlocatorfilters.cpp +++ b/src/app/locator/qgsinbuiltlocatorfilters.cpp @@ -23,7 +23,6 @@ #include "qgisapp.h" #include "qgsstringutils.h" #include "qgsmaplayermodel.h" -#include "qgscomposition.h" #include "qgslayoutmanager.h" #include "qgsmapcanvas.h" #include diff --git a/src/core/qgslegendstyle.cpp b/src/core/qgslegendstyle.cpp index bbc45161a61..b018cf109e8 100644 --- a/src/core/qgslegendstyle.cpp +++ b/src/core/qgslegendstyle.cpp @@ -16,7 +16,6 @@ ***************************************************************************/ #include "qgslegendstyle.h" -#include "qgscomposition.h" #include "qgsfontutils.h" #include "qgssettings.h" diff --git a/src/plugins/georeferencer/CMakeLists.txt b/src/plugins/georeferencer/CMakeLists.txt index b13f7069ff5..3e4a3288a1d 100644 --- a/src/plugins/georeferencer/CMakeLists.txt +++ b/src/plugins/georeferencer/CMakeLists.txt @@ -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 diff --git a/src/plugins/georeferencer/qgsgeorefplugingui.cpp b/src/plugins/georeferencer/qgsgeorefplugingui.cpp index 10db91d17c1..918c000f376 100644 --- a/src/plugins/georeferencer/qgsgeorefplugingui.cpp +++ b/src/plugins/georeferencer/qgsgeorefplugingui.cpp @@ -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() << firstLayer ); - composerMap->zoomToExtent( rlayer->extent() ); - composition->addItem( composerMap ); - printer.setFullPage( true ); - printer.setColorMode( QPrinter::Color ); + layoutMap->setLayers( QList() << 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; } diff --git a/src/plugins/georeferencer/qgsresidualplotitem.cpp b/src/plugins/georeferencer/qgsresidualplotitem.cpp index 19e78c8f53d..13daab1ec33 100644 --- a/src/plugins/georeferencer/qgsresidualplotitem.cpp +++ b/src/plugins/georeferencer/qgsresidualplotitem.cpp @@ -15,16 +15,16 @@ #include "qgsresidualplotitem.h" #include "qgsgeorefdatapoint.h" -#include "qgscomposerutils.h" +#include "qgslayoututils.h" #include #include #include -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; +} diff --git a/src/plugins/georeferencer/qgsresidualplotitem.h b/src/plugins/georeferencer/qgsresidualplotitem.h index a661b51e409..c0b41e619d0 100644 --- a/src/plugins/georeferencer/qgsresidualplotitem.h +++ b/src/plugins/georeferencer/qgsresidualplotitem.h @@ -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 diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 7af8f3b09a5..e63687d7584 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -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 diff --git a/src/server/services/wcs/CMakeLists.txt b/src/server/services/wcs/CMakeLists.txt index ebb92a8f01f..65497b40a29 100644 --- a/src/server/services/wcs/CMakeLists.txt +++ b/src/server/services/wcs/CMakeLists.txt @@ -36,7 +36,6 @@ INCLUDE_DIRECTORIES( ../../../core/metadata ../../../core/raster ../../../core/symbology - ../../../core/composer ../../../core/layertree ../.. .. diff --git a/src/server/services/wfs/CMakeLists.txt b/src/server/services/wfs/CMakeLists.txt index 53db84e882c..e5dfbb4692c 100644 --- a/src/server/services/wfs/CMakeLists.txt +++ b/src/server/services/wfs/CMakeLists.txt @@ -46,7 +46,6 @@ INCLUDE_DIRECTORIES( ../../../core/metadata ../../../core/raster ../../../core/symbology - ../../../core/composer ../../../core/layertree ../.. .. diff --git a/src/server/services/wms/CMakeLists.txt b/src/server/services/wms/CMakeLists.txt index 8c50dae97e9..7b5f9896e09 100644 --- a/src/server/services/wms/CMakeLists.txt +++ b/src/server/services/wms/CMakeLists.txt @@ -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 diff --git a/tests/src/3d/CMakeLists.txt b/tests/src/3d/CMakeLists.txt index 09708f517ea..bb07af2e5ef 100644 --- a/tests/src/3d/CMakeLists.txt +++ b/tests/src/3d/CMakeLists.txt @@ -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 diff --git a/tests/src/app/CMakeLists.txt b/tests/src/app/CMakeLists.txt index 68a25b67d52..550fc7bb0b6 100644 --- a/tests/src/app/CMakeLists.txt +++ b/tests/src/app/CMakeLists.txt @@ -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