mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Move class, method out of QgsPalLabeling to central location
This commit is contained in:
		
							parent
							
								
									f041077a36
								
							
						
					
					
						commit
						7670fbe362
					
				
							
								
								
									
										5
									
								
								python/PyQt6/core/auto_additions/qgslabelingengine.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								python/PyQt6/core/auto_additions/qgslabelingengine.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
# The following has been generated automatically from src/core/labeling/qgslabelingengine.h
 | 
			
		||||
try:
 | 
			
		||||
    QgsLabelCandidate.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
@ -521,7 +521,3 @@ try:
 | 
			
		||||
    QgsPalLabeling.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
try:
 | 
			
		||||
    QgsLabelCandidate.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,38 @@
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/labeling/qgslabelingengine.h                                *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
%Docstring(signature="appended")
 | 
			
		||||
Represents a label candidate.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
%TypeHeaderCode
 | 
			
		||||
#include "qgslabelingengine.h"
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c );
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/labeling/qgslabelingengine.h                                *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
@ -620,21 +620,6 @@ Sets the layer's unplaced label ``visibility``.
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
%Docstring(signature="appended")
 | 
			
		||||
Represents a label candidate.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
%TypeHeaderCode
 | 
			
		||||
#include "qgspallabeling.h"
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c );
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QgsPalLabeling
 | 
			
		||||
{
 | 
			
		||||
@ -652,7 +637,6 @@ PAL labeling utilities.
 | 
			
		||||
Called to find out whether a specified ``layer`` is used for labeling.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static QgsGeometry prepareGeometry( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry(), bool mergeLines = false ) /Factory/;
 | 
			
		||||
%Docstring
 | 
			
		||||
Prepares a geometry for registration with PAL. Handles reprojection, rotation, clipping, etc.
 | 
			
		||||
 | 
			
		||||
@ -384,6 +384,7 @@
 | 
			
		||||
%Include auto_generated/gps/qgsvectorlayergpslogger.sip
 | 
			
		||||
%Include auto_generated/labeling/qgscalloutposition.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabeling.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingengine.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingenginesettings.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingresults.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabellinesettings.sip
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								python/core/auto_additions/qgslabelingengine.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								python/core/auto_additions/qgslabelingengine.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
# The following has been generated automatically from src/core/labeling/qgslabelingengine.h
 | 
			
		||||
try:
 | 
			
		||||
    QgsLabelCandidate.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
@ -521,7 +521,3 @@ try:
 | 
			
		||||
    QgsPalLabeling.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
try:
 | 
			
		||||
    QgsLabelCandidate.__group__ = ['labeling']
 | 
			
		||||
except NameError:
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								python/core/auto_generated/labeling/qgslabelingengine.sip.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								python/core/auto_generated/labeling/qgslabelingengine.sip.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/labeling/qgslabelingengine.h                                *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
%Docstring(signature="appended")
 | 
			
		||||
Represents a label candidate.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
%TypeHeaderCode
 | 
			
		||||
#include "qgslabelingengine.h"
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c );
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/labeling/qgslabelingengine.h                                *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
@ -620,21 +620,6 @@ Sets the layer's unplaced label ``visibility``.
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
%Docstring(signature="appended")
 | 
			
		||||
Represents a label candidate.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
%TypeHeaderCode
 | 
			
		||||
#include "qgspallabeling.h"
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c );
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QgsPalLabeling
 | 
			
		||||
{
 | 
			
		||||
@ -652,7 +637,6 @@ PAL labeling utilities.
 | 
			
		||||
Called to find out whether a specified ``layer`` is used for labeling.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static QgsGeometry prepareGeometry( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry(), bool mergeLines = false ) /Factory/;
 | 
			
		||||
%Docstring
 | 
			
		||||
Prepares a geometry for registration with PAL. Handles reprojection, rotation, clipping, etc.
 | 
			
		||||
 | 
			
		||||
@ -384,6 +384,7 @@
 | 
			
		||||
%Include auto_generated/gps/qgsvectorlayergpslogger.sip
 | 
			
		||||
%Include auto_generated/labeling/qgscalloutposition.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabeling.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingengine.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingenginesettings.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabelingresults.sip
 | 
			
		||||
%Include auto_generated/labeling/qgslabellinesettings.sip
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,7 @@
 | 
			
		||||
#include "qgsfillsymbol.h"
 | 
			
		||||
#include "qgsruntimeprofiler.h"
 | 
			
		||||
#include "qgslabelingenginerule.h"
 | 
			
		||||
#include "qgstextlabelfeature.h"
 | 
			
		||||
 | 
			
		||||
#include <QUuid>
 | 
			
		||||
 | 
			
		||||
@ -439,7 +440,7 @@ void QgsLabelingEngine::solve( QgsRenderContext &context )
 | 
			
		||||
      {
 | 
			
		||||
        pal::LabelPosition *lp = mProblem->featureCandidate( i, j );
 | 
			
		||||
 | 
			
		||||
        QgsPalLabeling::drawLabelCandidateRect( lp, painter, &xform );
 | 
			
		||||
        drawLabelCandidateRect( lp, context, &xform );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -604,6 +605,141 @@ QgsLabelingResults *QgsLabelingEngine::takeResults()
 | 
			
		||||
  return mResults.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsLabelingEngine::drawLabelCandidateRect( pal::LabelPosition *lp, QgsRenderContext &context, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates )
 | 
			
		||||
{
 | 
			
		||||
  QPainter *painter = context.painter();
 | 
			
		||||
  if ( !painter )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  QgsPointXY outPt = xform->transform( lp->getX(), lp->getY() );
 | 
			
		||||
 | 
			
		||||
  painter->save();
 | 
			
		||||
 | 
			
		||||
  QgsPointXY outPt2 = xform->transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
 | 
			
		||||
  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
 | 
			
		||||
  painter->translate( QPointF( outPt.x(), outPt.y() ) );
 | 
			
		||||
  painter->rotate( -lp->getAlpha() * 180 / M_PI );
 | 
			
		||||
 | 
			
		||||
  if ( lp->conflictsWithObstacle() )
 | 
			
		||||
  {
 | 
			
		||||
    painter->setPen( QColor( 255, 0, 0, 64 ) );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    painter->setPen( QColor( 0, 0, 0, 64 ) );
 | 
			
		||||
  }
 | 
			
		||||
  painter->drawRect( rect );
 | 
			
		||||
  painter->restore();
 | 
			
		||||
 | 
			
		||||
  // save the rect
 | 
			
		||||
  rect.moveTo( outPt.x(), outPt.y() );
 | 
			
		||||
  if ( candidates )
 | 
			
		||||
    candidates->append( QgsLabelCandidate( rect, lp->cost() * 1000 ) );
 | 
			
		||||
 | 
			
		||||
  // show all parts of the multipart label
 | 
			
		||||
  if ( lp->nextPart() )
 | 
			
		||||
    drawLabelCandidateRect( lp->nextPart(), context, xform, candidates );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsLabelingEngine::drawLabelMetrics( pal::LabelPosition *label, QgsMapToPixel xform, QgsRenderContext &context, const QPointF &renderPoint )
 | 
			
		||||
{
 | 
			
		||||
  QPainter *painter = context.painter();
 | 
			
		||||
  if ( !painter )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
 | 
			
		||||
  QRectF rect( 0, 0, outPt2.x() - renderPoint.x(), outPt2.y() - renderPoint.y() );
 | 
			
		||||
  painter->save();
 | 
			
		||||
  painter->setRenderHint( QPainter::Antialiasing, false );
 | 
			
		||||
  painter->translate( QPointF( renderPoint.x(), renderPoint.y() ) );
 | 
			
		||||
  painter->rotate( -label->getAlpha() * 180 / M_PI );
 | 
			
		||||
 | 
			
		||||
  painter->setBrush( Qt::NoBrush );
 | 
			
		||||
  painter->setPen( QColor( 255, 0, 0, 220 ) );
 | 
			
		||||
 | 
			
		||||
  painter->drawRect( rect );
 | 
			
		||||
 | 
			
		||||
  painter->setPen( QColor( 0, 0, 0, 60 ) );
 | 
			
		||||
  const QgsMargins &margins = label->getFeaturePart()->feature()->visualMargin();
 | 
			
		||||
  if ( margins.top() > 0 )
 | 
			
		||||
  {
 | 
			
		||||
    const double topMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
 | 
			
		||||
    painter->drawLine( QPointF( rect.left(), rect.top() - topMargin ), QPointF( rect.right(), rect.top() - topMargin ) );
 | 
			
		||||
  }
 | 
			
		||||
  if ( margins.bottom() > 0 )
 | 
			
		||||
  {
 | 
			
		||||
    const double bottomMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
 | 
			
		||||
    painter->drawLine( QPointF( rect.left(), rect.bottom() + bottomMargin ), QPointF( rect.right(), rect.bottom() + bottomMargin ) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const QRectF outerBounds = label->getFeaturePart()->feature()->outerBounds();
 | 
			
		||||
  if ( !outerBounds.isNull() )
 | 
			
		||||
  {
 | 
			
		||||
    const QRectF mapOuterBounds = QRectF( label->getX() + outerBounds.left(),
 | 
			
		||||
                                          label->getY() + outerBounds.top(),
 | 
			
		||||
                                          outerBounds.width(), outerBounds.height() );
 | 
			
		||||
 | 
			
		||||
    QgsPointXY outerBoundsPt1 = xform.transform( mapOuterBounds.left(), mapOuterBounds.top() );
 | 
			
		||||
    QgsPointXY outerBoundsPt2 = xform.transform( mapOuterBounds.right(), mapOuterBounds.bottom() );
 | 
			
		||||
 | 
			
		||||
    const QRectF outerBoundsPixel( outerBoundsPt1.x() - renderPoint.x(),
 | 
			
		||||
                                   outerBoundsPt1.y() - renderPoint.y(),
 | 
			
		||||
                                   outerBoundsPt2.x() - outerBoundsPt1.x(),
 | 
			
		||||
                                   outerBoundsPt2.y() - outerBoundsPt1.y() );
 | 
			
		||||
 | 
			
		||||
    QPen pen( QColor( 255, 0, 255, 140 ) );
 | 
			
		||||
    pen.setCosmetic( true );
 | 
			
		||||
    pen.setWidth( 1 );
 | 
			
		||||
    painter->setPen( pen );
 | 
			
		||||
    painter->drawRect( outerBoundsPixel );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ( QgsTextLabelFeature *textFeature = dynamic_cast< QgsTextLabelFeature * >( label->getFeaturePart()->feature() ) )
 | 
			
		||||
  {
 | 
			
		||||
    const QgsTextDocumentMetrics &metrics = textFeature->documentMetrics();
 | 
			
		||||
    const QgsTextDocument &document = textFeature->document();
 | 
			
		||||
    const int blockCount = document.size();
 | 
			
		||||
 | 
			
		||||
    double prevBlockBaseline = rect.bottom() - rect.top();
 | 
			
		||||
    const double verticalAlignOffset = -metrics.blockVerticalMargin( document.size() - 1 );
 | 
			
		||||
 | 
			
		||||
    // draw block baselines
 | 
			
		||||
    for ( int blockIndex = 0; blockIndex < blockCount; ++blockIndex )
 | 
			
		||||
    {
 | 
			
		||||
      const double blockBaseLine = metrics.baselineOffset( blockIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
 | 
			
		||||
      const QgsTextBlock &block = document.at( blockIndex );
 | 
			
		||||
      const int fragmentCount = block.size();
 | 
			
		||||
      double left = metrics.blockLeftMargin( blockIndex );
 | 
			
		||||
      for ( int fragmentIndex = 0; fragmentIndex < fragmentCount; ++fragmentIndex )
 | 
			
		||||
      {
 | 
			
		||||
        const double fragmentVerticalOffset = metrics.fragmentVerticalOffset( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
        const double right = left + metrics.fragmentHorizontalAdvance( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
 | 
			
		||||
        if ( fragmentIndex > 0 )
 | 
			
		||||
        {
 | 
			
		||||
          QPen pen( QColor( 0, 0, 255, 220 ) );
 | 
			
		||||
          pen.setStyle( Qt::PenStyle::DashLine );
 | 
			
		||||
 | 
			
		||||
          painter->setPen( pen );
 | 
			
		||||
 | 
			
		||||
          painter->drawLine( QPointF( rect.left() + left, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
 | 
			
		||||
                             QPointF( rect.left() + left, rect.top() + prevBlockBaseline + verticalAlignOffset ) );
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        painter->setPen( QColor( 0, 0, 255, 220 ) );
 | 
			
		||||
        painter->drawLine( QPointF( rect.left() + left, rect.top()  + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
 | 
			
		||||
                           QPointF( rect.left() + right, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ) );
 | 
			
		||||
        left = right;
 | 
			
		||||
      }
 | 
			
		||||
      prevBlockBaseline = blockBaseLine;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  painter->restore();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  QgsDefaultLabelingEngine
 | 
			
		||||
 | 
			
		||||
@ -16,8 +16,6 @@
 | 
			
		||||
#ifndef QGSLABELINGENGINE_H
 | 
			
		||||
#define QGSLABELINGENGINE_H
 | 
			
		||||
 | 
			
		||||
#define SIP_NO_FILE
 | 
			
		||||
 | 
			
		||||
#include "qgis_core.h"
 | 
			
		||||
#include "qgsmapsettings.h"
 | 
			
		||||
 | 
			
		||||
@ -29,12 +27,30 @@ class QgsLabelingResults;
 | 
			
		||||
class QgsLabelFeature;
 | 
			
		||||
class QgsLabelingEngineSettings;
 | 
			
		||||
 | 
			
		||||
#ifndef SIP_RUN
 | 
			
		||||
namespace pal
 | 
			
		||||
{
 | 
			
		||||
  class Problem;
 | 
			
		||||
  class Pal;
 | 
			
		||||
  class LabelPosition;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup core
 | 
			
		||||
 * \brief Represents a label candidate.
 | 
			
		||||
 */
 | 
			
		||||
class CORE_EXPORT QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c ): rect( r ), cost( c ) {}
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef SIP_RUN
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup core
 | 
			
		||||
@ -411,6 +427,20 @@ class CORE_EXPORT QgsLabelingEngine
 | 
			
		||||
    //! For internal use by the providers
 | 
			
		||||
    QgsLabelingResults *results() const { return mResults.get(); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Draws label candidate rectangles.
 | 
			
		||||
     *
 | 
			
		||||
     * \see drawLabelMetrics()
 | 
			
		||||
     */
 | 
			
		||||
    static void drawLabelCandidateRect( pal::LabelPosition *lp, QgsRenderContext &context, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates = nullptr );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Draws label metrics.
 | 
			
		||||
     *
 | 
			
		||||
     * \see drawLabelCandidateRect()
 | 
			
		||||
     */
 | 
			
		||||
    static void drawLabelMetrics( pal::LabelPosition *label, QgsMapToPixel xform, QgsRenderContext &context, const QPointF &renderPoint );
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
    void processProvider( QgsAbstractLabelProvider *provider, QgsRenderContext &context, pal::Pal &p );
 | 
			
		||||
 | 
			
		||||
@ -576,4 +606,6 @@ class CORE_EXPORT QgsLabelingUtils
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // QGSLABELINGENGINE_H
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,6 @@
 | 
			
		||||
#include "qgstextrenderer.h"
 | 
			
		||||
#include "qgsscaleutils.h"
 | 
			
		||||
 | 
			
		||||
#include "pal/labelposition.h"
 | 
			
		||||
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
@ -4831,62 +4829,3 @@ void QgsPalLabeling::dataDefinedDropShadow( QgsPalLayerSettings &tmpLyr,
 | 
			
		||||
    tmpLyr.setFormat( format );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsPalLabeling::drawLabelCandidateRect( pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates )
 | 
			
		||||
{
 | 
			
		||||
  QgsPointXY outPt = xform->transform( lp->getX(), lp->getY() );
 | 
			
		||||
 | 
			
		||||
  painter->save();
 | 
			
		||||
 | 
			
		||||
#if 0 // TODO: generalize some of this
 | 
			
		||||
  double w = lp->getWidth();
 | 
			
		||||
  double h = lp->getHeight();
 | 
			
		||||
  double cx = lp->getX() + w / 2.0;
 | 
			
		||||
  double cy = lp->getY() + h / 2.0;
 | 
			
		||||
  double scale = 1.0 / xform->mapUnitsPerPixel();
 | 
			
		||||
  double rotation = xform->mapRotation();
 | 
			
		||||
  double sw = w * scale;
 | 
			
		||||
  double sh = h * scale;
 | 
			
		||||
  QRectF rect( -sw / 2, -sh / 2, sw, sh );
 | 
			
		||||
 | 
			
		||||
  painter->translate( xform->transform( QPointF( cx, cy ) ).toQPointF() );
 | 
			
		||||
  if ( rotation )
 | 
			
		||||
  {
 | 
			
		||||
    // Only if not horizontal
 | 
			
		||||
    if ( lp->getFeaturePart()->getLayer()->getArrangement() != P_POINT &&
 | 
			
		||||
         lp->getFeaturePart()->getLayer()->getArrangement() != P_POINT_OVER &&
 | 
			
		||||
         lp->getFeaturePart()->getLayer()->getArrangement() != P_HORIZ )
 | 
			
		||||
    {
 | 
			
		||||
      painter->rotate( rotation );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  painter->translate( rect.bottomLeft() );
 | 
			
		||||
  painter->rotate( -lp->getAlpha() * 180 / M_PI );
 | 
			
		||||
  painter->translate( -rect.bottomLeft() );
 | 
			
		||||
#else
 | 
			
		||||
  QgsPointXY outPt2 = xform->transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
 | 
			
		||||
  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
 | 
			
		||||
  painter->translate( QPointF( outPt.x(), outPt.y() ) );
 | 
			
		||||
  painter->rotate( -lp->getAlpha() * 180 / M_PI );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if ( lp->conflictsWithObstacle() )
 | 
			
		||||
  {
 | 
			
		||||
    painter->setPen( QColor( 255, 0, 0, 64 ) );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    painter->setPen( QColor( 0, 0, 0, 64 ) );
 | 
			
		||||
  }
 | 
			
		||||
  painter->drawRect( rect );
 | 
			
		||||
  painter->restore();
 | 
			
		||||
 | 
			
		||||
  // save the rect
 | 
			
		||||
  rect.moveTo( outPt.x(), outPt.y() );
 | 
			
		||||
  if ( candidates )
 | 
			
		||||
    candidates->append( QgsLabelCandidate( rect, lp->cost() * 1000 ) );
 | 
			
		||||
 | 
			
		||||
  // show all parts of the multipart label
 | 
			
		||||
  if ( lp->nextPart() )
 | 
			
		||||
    drawLabelCandidateRect( lp->nextPart(), painter, xform, candidates );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1026,18 +1026,6 @@ class CORE_EXPORT QgsPalLayerSettings
 | 
			
		||||
    static void initPropertyDefinitions();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup core
 | 
			
		||||
 * \brief Represents a label candidate.
 | 
			
		||||
 */
 | 
			
		||||
class CORE_EXPORT QgsLabelCandidate
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    QgsLabelCandidate( const QRectF &r, double c ): rect( r ), cost( c ) {}
 | 
			
		||||
 | 
			
		||||
    QRectF rect;
 | 
			
		||||
    double cost;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \ingroup core
 | 
			
		||||
@ -1053,9 +1041,6 @@ class CORE_EXPORT QgsPalLabeling
 | 
			
		||||
     */
 | 
			
		||||
    static bool staticWillUseLayer( const QgsMapLayer *layer );
 | 
			
		||||
 | 
			
		||||
    //! \note not available in Python bindings
 | 
			
		||||
    static void drawLabelCandidateRect( pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates = nullptr ) SIP_SKIP;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepares a geometry for registration with PAL. Handles reprojection, rotation, clipping, etc.
 | 
			
		||||
     * \param geometry geometry to prepare
 | 
			
		||||
 | 
			
		||||
@ -560,98 +560,7 @@ void QgsVectorLayerLabelProvider::drawLabelPrivate( pal::LabelPosition *label, Q
 | 
			
		||||
    if ( drawType != Qgis::TextComponent::Text )
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
 | 
			
		||||
    QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
 | 
			
		||||
    painter->save();
 | 
			
		||||
    painter->setRenderHint( QPainter::Antialiasing, false );
 | 
			
		||||
    painter->translate( QPointF( outPt.x(), outPt.y() ) );
 | 
			
		||||
    painter->rotate( -label->getAlpha() * 180 / M_PI );
 | 
			
		||||
 | 
			
		||||
    painter->setBrush( Qt::NoBrush );
 | 
			
		||||
    painter->setPen( QColor( 255, 0, 0, 220 ) );
 | 
			
		||||
 | 
			
		||||
    painter->drawRect( rect );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    painter->setPen( QColor( 0, 0, 0, 60 ) );
 | 
			
		||||
    const QgsMargins &margins = label->getFeaturePart()->feature()->visualMargin();
 | 
			
		||||
    if ( margins.top() > 0 )
 | 
			
		||||
    {
 | 
			
		||||
      const double topMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
 | 
			
		||||
      painter->drawLine( QPointF( rect.left(), rect.top() - topMargin ), QPointF( rect.right(), rect.top() - topMargin ) );
 | 
			
		||||
    }
 | 
			
		||||
    if ( margins.bottom() > 0 )
 | 
			
		||||
    {
 | 
			
		||||
      const double bottomMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
 | 
			
		||||
      painter->drawLine( QPointF( rect.left(), rect.bottom() + bottomMargin ), QPointF( rect.right(), rect.bottom() + bottomMargin ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const QRectF outerBounds = label->getFeaturePart()->feature()->outerBounds();
 | 
			
		||||
    if ( !outerBounds.isNull() )
 | 
			
		||||
    {
 | 
			
		||||
      const QRectF mapOuterBounds = QRectF( label->getX() + outerBounds.left(),
 | 
			
		||||
                                            label->getY() + outerBounds.top(),
 | 
			
		||||
                                            outerBounds.width(), outerBounds.height() );
 | 
			
		||||
 | 
			
		||||
      QgsPointXY outerBoundsPt1 = xform.transform( mapOuterBounds.left(), mapOuterBounds.top() );
 | 
			
		||||
      QgsPointXY outerBoundsPt2 = xform.transform( mapOuterBounds.right(), mapOuterBounds.bottom() );
 | 
			
		||||
 | 
			
		||||
      const QRectF outerBoundsPixel( outerBoundsPt1.x() - outPt.x(),
 | 
			
		||||
                                     outerBoundsPt1.y() - outPt.y(),
 | 
			
		||||
                                     outerBoundsPt2.x() - outerBoundsPt1.x(),
 | 
			
		||||
                                     outerBoundsPt2.y() - outerBoundsPt1.y() );
 | 
			
		||||
 | 
			
		||||
      QPen pen( QColor( 255, 0, 255, 140 ) );
 | 
			
		||||
      pen.setCosmetic( true );
 | 
			
		||||
      pen.setWidth( 1 );
 | 
			
		||||
      painter->setPen( pen );
 | 
			
		||||
      painter->drawRect( outerBoundsPixel );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( QgsTextLabelFeature *textFeature = dynamic_cast< QgsTextLabelFeature * >( label->getFeaturePart()->feature() ) )
 | 
			
		||||
    {
 | 
			
		||||
      const QgsTextDocumentMetrics &metrics = textFeature->documentMetrics();
 | 
			
		||||
      const QgsTextDocument &document = textFeature->document();
 | 
			
		||||
      const int blockCount = document.size();
 | 
			
		||||
 | 
			
		||||
      double prevBlockBaseline = rect.bottom() - rect.top();
 | 
			
		||||
      const double verticalAlignOffset = -metrics.blockVerticalMargin( document.size() - 1 );
 | 
			
		||||
 | 
			
		||||
      // draw block baselines
 | 
			
		||||
      for ( int blockIndex = 0; blockIndex < blockCount; ++blockIndex )
 | 
			
		||||
      {
 | 
			
		||||
        const double blockBaseLine = metrics.baselineOffset( blockIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
 | 
			
		||||
        const QgsTextBlock &block = document.at( blockIndex );
 | 
			
		||||
        const int fragmentCount = block.size();
 | 
			
		||||
        double left = metrics.blockLeftMargin( blockIndex );
 | 
			
		||||
        for ( int fragmentIndex = 0; fragmentIndex < fragmentCount; ++fragmentIndex )
 | 
			
		||||
        {
 | 
			
		||||
          const double fragmentVerticalOffset = metrics.fragmentVerticalOffset( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
          const double right = left + metrics.fragmentHorizontalAdvance( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
 | 
			
		||||
 | 
			
		||||
          if ( fragmentIndex > 0 )
 | 
			
		||||
          {
 | 
			
		||||
            QPen pen( QColor( 0, 0, 255, 220 ) );
 | 
			
		||||
            pen.setStyle( Qt::PenStyle::DashLine );
 | 
			
		||||
 | 
			
		||||
            painter->setPen( pen );
 | 
			
		||||
 | 
			
		||||
            painter->drawLine( QPointF( rect.left() + left, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
 | 
			
		||||
                               QPointF( rect.left() + left, rect.top() + prevBlockBaseline + verticalAlignOffset ) );
 | 
			
		||||
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          painter->setPen( QColor( 0, 0, 255, 220 ) );
 | 
			
		||||
          painter->drawLine( QPointF( rect.left() + left, rect.top()  + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
 | 
			
		||||
                             QPointF( rect.left() + right, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ) );
 | 
			
		||||
          left = right;
 | 
			
		||||
        }
 | 
			
		||||
        prevBlockBaseline = blockBaseLine;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    painter->restore();
 | 
			
		||||
    QgsLabelingEngine::drawLabelMetrics( label, xform, context, outPt );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QgsTextRenderer::Component component;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user