34#include "moc_qgsmapcanvasannotationitem.cpp"
40 setFlag( QGraphicsItem::ItemIsSelectable,
true );
46 connect( mAnnotation, &
QgsAnnotation::moved,
this, &QgsMapCanvasAnnotationItem::setFeatureForMapPosition );
55 connect( mAnnotation, &QgsAnnotation::destroyed,
this, &QgsMapCanvasAnnotationItem::annotationDeleted );
58 setFeatureForMapPosition();
66 if ( mAnnotation->hasFixedMapPosition() )
82 const double x = mAnnotation->relativePosition().x() *
mMapCanvas->width();
83 const double y = mAnnotation->relativePosition().y() *
mMapCanvas->height();
94void QgsMapCanvasAnnotationItem::updateBoundingRect()
96 prepareGeometryChange();
101 const double mmToPixelScale =
mMapCanvas->physicalDpiX() / 25.4;
105 mBoundingRect = QRectF( -fillSymbolBleed, -fillSymbolBleed, mmToPixelScale * mAnnotation->
frameSizeMm().width() + fillSymbolBleed * 2, mmToPixelScale * mAnnotation->
frameSizeMm().height() + fillSymbolBleed * 2 );
109 double halfSymbolSize = 0.0;
110 if ( mAnnotation && mAnnotation->markerSymbol() )
112 halfSymbolSize = scaledSymbolSize() / 2.0;
115 const QPointF offset = mAnnotation ? QPointF( mAnnotation->frameOffsetFromReferencePointMm().x() * mmToPixelScale, mAnnotation->frameOffsetFromReferencePointMm().y() * mmToPixelScale ) : QPointF( 0, 0 );
117 const QSizeF frameSize = mAnnotation ? QSizeF( mAnnotation->frameSizeMm().width() * mmToPixelScale, mAnnotation->frameSizeMm().height() * mmToPixelScale ) : QSizeF( 0.0, 0.0 );
119 const double xMinPos = std::min( -halfSymbolSize, offset.x() - fillSymbolBleed );
120 const double xMaxPos = std::max( halfSymbolSize, offset.x() + frameSize.width() + fillSymbolBleed );
121 const double yMinPos = std::min( -halfSymbolSize, offset.y() - fillSymbolBleed );
122 const double yMaxPos = std::max( halfSymbolSize, offset.y() + frameSize.height() + fillSymbolBleed );
123 mBoundingRect = QRectF( xMinPos, yMinPos, xMaxPos - xMinPos, yMaxPos - yMinPos );
127void QgsMapCanvasAnnotationItem::onCanvasLayersChanged()
135 else if ( !mAnnotation->mapLayer() )
141 setVisible(
mMapCanvas->mapSettings().layers(
true ).contains( mAnnotation->mapLayer() ) );
145void QgsMapCanvasAnnotationItem::setFeatureForMapPosition()
147 if ( !mAnnotation || !mAnnotation->hasFixedMapPosition() )
150 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( mAnnotation->mapLayer() );
155 QgsPointXY mapPosition = mAnnotation->mapPosition();
161 mapPosition = ct.transform( mapPosition );
163 catch ( QgsCsException & )
167 QgsRectangle searchRect( mapPosition.
x() - halfIdentifyWidth, mapPosition.
y() - halfIdentifyWidth, mapPosition.
x() + halfIdentifyWidth, mapPosition.
y() + halfIdentifyWidth );
169 searchRect =
mMapCanvas->mapSettings().mapToLayerCoordinates( vectorLayer, searchRect );
173 QgsFeature currentFeature;
175 mAnnotation->setAssociatedFeature( currentFeature );
178void QgsMapCanvasAnnotationItem::annotationDeleted()
180 mAnnotation =
nullptr;
184void QgsMapCanvasAnnotationItem::drawSelectionBoxes( QPainter *p )
const
191 const double handlerSize = 10;
192 p->setPen( Qt::NoPen );
193 p->setBrush( QColor( 200, 200, 210, 120 ) );
194 p->drawRect( QRectF( mBoundingRect.left(), mBoundingRect.top(), handlerSize, handlerSize ) );
195 p->drawRect( QRectF( mBoundingRect.right() - handlerSize, mBoundingRect.top(), handlerSize, handlerSize ) );
196 p->drawRect( QRectF( mBoundingRect.right() - handlerSize, mBoundingRect.bottom() - handlerSize, handlerSize, handlerSize ) );
197 p->drawRect( QRectF( mBoundingRect.left(), mBoundingRect.bottom() - handlerSize, handlerSize, handlerSize ) );
202 const QPointF itemPos = mapFromScene( pos );
204 const int cursorSensitivity = 7;
206 if ( mAnnotation && mAnnotation->hasFixedMapPosition() && std::fabs( itemPos.x() ) < cursorSensitivity && std::fabs( itemPos.y() ) < cursorSensitivity )
211 const double mmToPixelScale =
mMapCanvas->logicalDpiX() / 25.4;
213 const QPointF offset = mAnnotation && mAnnotation->hasFixedMapPosition() ? mAnnotation->frameOffsetFromReferencePointMm() * mmToPixelScale : QPointF( 0, 0 );
214 const QSizeF frameSize = mAnnotation ? mAnnotation->frameSizeMm() * mmToPixelScale : QSizeF( 0, 0 );
216 bool left, right, up, down, inframe;
217 left = std::fabs( itemPos.x() - offset.x() ) < cursorSensitivity;
218 right = std::fabs( itemPos.x() - ( offset.x() + frameSize.width() ) ) < cursorSensitivity;
219 up = std::fabs( itemPos.y() - offset.y() ) < cursorSensitivity;
220 down = std::fabs( itemPos.y() - ( offset.y() + frameSize.height() ) ) < cursorSensitivity;
221 inframe = ( itemPos.x() + cursorSensitivity >= offset.x() && itemPos.x() - cursorSensitivity <= ( offset.x() + frameSize.width() ) && itemPos.y() + cursorSensitivity >= offset.y() && itemPos.y() - cursorSensitivity <= ( offset.y() + frameSize.height() ) );
231 else if ( right && up )
235 else if ( left && down )
239 else if ( right && down )
243 if ( left && inframe )
247 if ( right && inframe )
255 if ( down && inframe )
271 switch ( moveAction )
274 return Qt::ArrowCursor;
277 return Qt::SizeAllCursor;
280 return Qt::SizeVerCursor;
283 return Qt::SizeHorCursor;
286 return Qt::SizeFDiagCursor;
289 return Qt::SizeBDiagCursor;
291 return Qt::ArrowCursor;
295double QgsMapCanvasAnnotationItem::scaledSymbolSize()
const
304 return mAnnotation->markerSymbol()->size();
307 const double dpmm =
mMapCanvas->logicalDpiX() / 25.4;
308 return dpmm * mAnnotation->markerSymbol()->size();
313 if ( !mAnnotation || !mAnnotation->isVisible() )
320 mAnnotation->render( rc );
324 drawSelectionBoxes( painter );
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ Antialiasing
Use antialiasing while drawing.
Abstract base class for annotation items which are drawn over a map.
void appearanceChanged()
Emitted whenever the annotation's appearance changes.
QgsMarkerSymbol * markerSymbol() const
Returns the symbol that is drawn at the annotation's map position.
void moved()
Emitted when the annotation's position has changed and items need to be moved to reflect this.
QgsFillSymbol * fillSymbol() const
Returns the symbol that is used for rendering the annotation frame.
QSizeF frameSizeMm() const
Returns the size (in millimeters) of the annotation's frame (the main area in which the annotation's ...
void mapLayerChanged()
Emitted when the map layer associated with the annotation changes.
Custom exception class for Coordinate Reference System related exceptions.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
const QgsAnnotation * annotation() const
Returns the item's annotation.
QgsMapCanvasAnnotationItem(QgsAnnotation *annotation, QgsMapCanvas *mapCanvas)
Constructor for QgsMapCanvasAnnotationItem.
MouseMoveAction moveActionForPosition(QPointF pos) const
Returns the mouse move behavior for a given position in scene coordinates.
Qt::CursorShape cursorShapeForAction(MouseMoveAction moveAction) const
Returns matching cursor shape for a mouse move action.
void paint(QPainter *painter) override
function to be implemented by derived classes
QRectF boundingRect() const override
void updatePosition() override
called on changed extent or resize event to update position of the item
MouseMoveAction
Mouse actions for interacting with item.
@ ResizeFrameRight
Resize frame right.
@ ResizeFrameRightUp
Resize frame right up.
@ MoveFramePosition
Moving position of frame relative to annotation.
@ ResizeFrameUp
Resize frame up.
@ ResizeFrameRightDown
Resize frame right down.
@ MoveMapPosition
Moving annotation map position.
@ ResizeFrameDown
Resize frame down.
@ ResizeFrameLeftUp
Resize frame left up.
@ ResizeFrameLeft
Resize frame left.
@ ResizeFrameLeftDown
Resize frame left down.
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
QgsMapCanvas * mMapCanvas
pointer to map canvas
QgsMapCanvasItem(QgsMapCanvas *mapCanvas)
protected constructor: cannot be constructed directly
Map canvas is a class for displaying all GIS data types on a canvas.
void destinationCrsChanged()
Emitted when map CRS has changed.
void layersChanged()
Emitted when a new set of layers has been received.
bool annotationsVisible() const
Returns true if annotations are visible within the map canvas.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Contains information about the context of a rendering operation.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.