Skip to content

Commit

Permalink
Add rendered callout details to QgsLabelingResults for retrieval afte…
Browse files Browse the repository at this point in the history
…r a map render completes
  • Loading branch information
nyalldawson committed Feb 23, 2021
1 parent 4f39cf6 commit d84da56
Show file tree
Hide file tree
Showing 17 changed files with 586 additions and 5 deletions.
21 changes: 21 additions & 0 deletions python/core/auto_generated/callouts/qgscallout.sip.in
Expand Up @@ -209,6 +209,27 @@ being rendered.
Returns the coordinate transform to convert from the original layer associated with
the callout to the destination map CRS.

.. versionadded:: 3.20
%End

void addCalloutPosition( const QgsCalloutPosition &position );
%Docstring
Adds a rendered callout position.

The position details such as the callout line origin and destination should be populated by the
callout subclass during rendering operations.

.. note::

the feature ID, layer ID and provider ID of the :py:class:`QgsCalloutPosition` will be automatically populated.

.. versionadded:: 3.20
%End

QList< QgsCalloutPosition > positions() const;
%Docstring
Returns the list of rendered callout positions.

.. versionadded:: 3.20
%End

Expand Down
98 changes: 98 additions & 0 deletions python/core/auto_generated/labeling/qgscalloutposition.sip.in
@@ -0,0 +1,98 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/labeling/qgscalloutposition.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsCalloutPosition
{
%Docstring
Represents the calculated placement of a map label callout line.

.. versionadded:: 3.20
%End

%TypeHeaderCode
#include "qgscalloutposition.h"
%End
public:

QgsCalloutPosition( QgsFeatureId id, const QString &layer, const QString &providerId = QString() );
%Docstring
Constructor for QgsCalloutPosition.

:param id: associated feature ID
:param layer: ID of associated map layer
:param providerId: ID of associated label provider
%End

QgsCalloutPosition();
%Docstring
Constructor for QgsCalloutPosition
%End

QgsFeatureId featureId;

QString layerID;

QString providerID;

QPointF origin() const;
%Docstring
Returns the origin of the callout line, in map coordinates.

The origin of the callout line is the line point associated with the label text.

.. seealso:: :py:func:`setOrigin`

.. seealso:: :py:func:`destination`
%End

void setOrigin( const QPointF &origin );
%Docstring
Sets the ``origin`` of the callout line, in map coordinates.

The origin of the callout line is the line point associated with the label text.

.. seealso:: :py:func:`origin`

.. seealso:: :py:func:`setDestination`
%End

QPointF destination() const;
%Docstring
Returns the destination of the callout line, in map coordinates.

The destination of the callout line is the line point associated with the feature's geometry.

.. seealso:: :py:func:`setDestination`

.. seealso:: :py:func:`origin`
%End

void setDestination( const QPointF &destination );
%Docstring
Sets the ``destination`` of the callout line, in map coordinates.

The destination of the callout line is the line point associated with the feature's geometry.

.. seealso:: :py:func:`destination`

.. seealso:: :py:func:`setOrigin`
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/labeling/qgscalloutposition.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
10 changes: 10 additions & 0 deletions python/core/auto_generated/labeling/qgslabelingresults.sip.in
Expand Up @@ -8,6 +8,7 @@




class QgsLabelingResults
{
%Docstring
Expand All @@ -32,6 +33,15 @@ Returns the details of any labels placed at the specifed point (in map coordinat
QList<QgsLabelPosition> labelsWithinRect( const QgsRectangle &r ) const;
%Docstring
Returns the details of any labels placed within the specifed rectangle (in map coordinates).
%End

QList<QgsCalloutPosition> calloutsWithinRectangle( const QgsRectangle &rectangle ) const;
%Docstring
Returns a list of callouts with origins or destinations inside the given ``rectangle``.

The ``rectangle`` is specified in map coordinates.

.. versionadded:: 3.20
%End

void setMapSettings( const QgsMapSettings &settings );
Expand Down
12 changes: 12 additions & 0 deletions python/core/auto_generated/labeling/qgslabelsearchtree.sip.in
Expand Up @@ -43,6 +43,18 @@ Removes and deletes all the entries.




QList<const QgsCalloutPosition *> calloutsInRectangle( const QgsRectangle &rectangle ) const;
%Docstring
Returns the list of callouts with origins or destinations inside the given ``rectangle``.

The ``rectangle`` is specified in map coordinates.

QgsLabelSearchTree keeps ownership, don't delete the returned objects.

.. versionadded:: 3.20
%End

void setMapSettings( const QgsMapSettings &settings );
%Docstring
Sets the map ``settings`` associated with the labeling run.
Expand Down
2 changes: 1 addition & 1 deletion python/core/core_auto.sip
Expand Up @@ -325,6 +325,7 @@
%Include auto_generated/gps/qgsgpsdconnection.sip
%Include auto_generated/gps/qgsgpsdetector.sip
%Include auto_generated/gps/qgsnmeaconnection.sip
%Include auto_generated/labeling/qgscalloutposition.sip
%Include auto_generated/labeling/qgslabeling.sip
%Include auto_generated/labeling/qgslabelingenginesettings.sip
%Include auto_generated/labeling/qgslabelingresults.sip
Expand Down Expand Up @@ -630,5 +631,4 @@
%Include auto_generated/gps/qgsqtlocationconnection.sip
%Include auto_generated/gps/qgsgpsconnectionregistry.sip
%Include auto_generated/symbology/qgsmasksymbollayer.sip
%Include auto_generated/labeling/qgslabelthinningsettings.sip
%Include auto_generated/qgsuserprofile.sip
1 change: 1 addition & 0 deletions src/app/labeling/qgsmaptoollabel.cpp
Expand Up @@ -34,6 +34,7 @@
#include "qgsmapmouseevent.h"
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsstatusbar.h"
#include "qgslabelingresults.h"

#include <QMouseEvent>

Expand Down
2 changes: 1 addition & 1 deletion src/app/labeling/qgsmaptoolshowhidelabels.cpp
Expand Up @@ -26,7 +26,7 @@
#include "qgsmaptoolselectutils.h"
#include "qgsrubberband.h"
#include "qgslogger.h"

#include "qgslabelingresults.h"

QgsMapToolShowHideLabels::QgsMapToolShowHideLabels( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDock )
: QgsMapToolLabel( canvas, cadDock )
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -1212,6 +1212,7 @@ set(QGIS_CORE_HDRS
gps/qgsgpsdetector.h
gps/qgsnmeaconnection.h

labeling/qgscalloutposition.h
labeling/qgslabelfeature.h
labeling/qgslabeling.h
labeling/qgslabelingengine.h
Expand Down
18 changes: 16 additions & 2 deletions src/core/callouts/qgscallout.cpp
Expand Up @@ -650,7 +650,14 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d
}
}

mLineSymbol->renderPolyline( line.asQPolygonF(), nullptr, context );
const QPolygonF points = line.asQPolygonF();

QgsCalloutPosition position;
position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() );
position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() );
calloutContext.addCalloutPosition( position );

mLineSymbol->renderPolyline( points, nullptr, context );
};

bool toAllParts = mDrawCalloutToAllParts;
Expand Down Expand Up @@ -762,7 +769,14 @@ void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, cons
}
}

lineSymbol()->renderPolyline( line.asQPolygonF(), nullptr, context );
const QPolygonF points = line.asQPolygonF();

QgsCalloutPosition position;
position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() );
position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() );
calloutContext.addCalloutPosition( position );

lineSymbol()->renderPolyline( points, nullptr, context );
};

bool toAllParts = drawCalloutToAllParts();
Expand Down
22 changes: 22 additions & 0 deletions src/core/callouts/qgscallout.h
Expand Up @@ -23,6 +23,7 @@
#include "qgsreadwritecontext.h"
#include "qgspropertycollection.h"
#include "qgsmapunitscale.h"
#include "qgscalloutposition.h"
#include <QString>
#include <QRectF>
#include <memory>
Expand Down Expand Up @@ -236,9 +237,30 @@ class CORE_EXPORT QgsCallout
*/
QgsCoordinateTransform originalFeatureToMapTransform( const QgsRenderContext &renderContext ) const;

/**
* Adds a rendered callout position.
*
* The position details such as the callout line origin and destination should be populated by the
* callout subclass during rendering operations.
*
* \note the feature ID, layer ID and provider ID of the QgsCalloutPosition will be automatically populated.
*
* \since QGIS 3.20
*/
void addCalloutPosition( const QgsCalloutPosition &position ) { return mPositions.push_back( position ); }

/**
* Returns the list of rendered callout positions.
*
* \since QGIS 3.20
*/
QList< QgsCalloutPosition > positions() const { return mPositions; }

private:
//! Lazy initialized coordinate transform from original feature CRS to map CRS
mutable QgsCoordinateTransform mOriginalFeatureToMapTransform;

QList< QgsCalloutPosition > mPositions;
};

/**
Expand Down
113 changes: 113 additions & 0 deletions src/core/labeling/qgscalloutposition.h
@@ -0,0 +1,113 @@
/***************************************************************************
qgscalloutposition.h
-------------------
begin : February 2021
copyright : (C) 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. *
* *
***************************************************************************/

#ifndef QGSCALLOUTPOSITION_H
#define QGSCALLOUTPOSITION_H

#include "qgis_core.h"
#include "qgis_sip.h"

#include "qgsfeatureid.h"

#include <QPointF>

/**
* \ingroup core
* \class QgsCalloutPosition
* \brief Represents the calculated placement of a map label callout line.
* \since QGIS 3.20
*/
class CORE_EXPORT QgsCalloutPosition
{
public:

/**
* Constructor for QgsCalloutPosition.
* \param id associated feature ID
* \param layer ID of associated map layer
* \param providerId ID of associated label provider
*/
QgsCalloutPosition( QgsFeatureId id, const QString &layer, const QString &providerId = QString() )
: featureId( id )
, layerID( layer )
, providerID( providerId )
{}

//! Constructor for QgsCalloutPosition
QgsCalloutPosition() = default;

/**
* ID of feature associated with this callout.
*/
QgsFeatureId featureId = FID_NULL;

/**
* ID of associated map layer.
*/
QString layerID;

/**
* ID of the associated label provider.
*/
QString providerID;

/**
* Returns the origin of the callout line, in map coordinates.
*
* The origin of the callout line is the line point associated with the label text.
*
* \see setOrigin()
* \see destination()
*/
QPointF origin() const { return mOrigin; }

/**
* Sets the \a origin of the callout line, in map coordinates.
*
* The origin of the callout line is the line point associated with the label text.
*
* \see origin()
* \see setDestination()
*/
void setOrigin( const QPointF &origin ) { mOrigin = origin; }

/**
* Returns the destination of the callout line, in map coordinates.
*
* The destination of the callout line is the line point associated with the feature's geometry.
*
* \see setDestination()
* \see origin()
*/
QPointF destination() const { return mDestination; }

/**
* Sets the \a destination of the callout line, in map coordinates.
*
* The destination of the callout line is the line point associated with the feature's geometry.
*
* \see destination()
* \see setOrigin()
*/
void setDestination( const QPointF &destination ) { mDestination = destination; }

private:

QPointF mOrigin;

QPointF mDestination;
};

#endif // QGSCALLOUTPOSITION_H

0 comments on commit d84da56

Please sign in to comment.