64 mRect = mCanvas->rect();
67 prepareGeometryChange();
68 setPos( mRect.topLeft() );
71 mCachedImages.clear();
79 mCachedImages.clear();
84 bool redrawResults(
const QString &sourceId )
86 auto it = mCachedImages.find( sourceId );
87 if ( it == mCachedImages.end() )
90 mCachedImages.erase( it );
95 QRectF boundingRect()
const override
102 if ( !mPlotArea.isNull() )
107 if ( !scene()->views().isEmpty() )
108 context.
setScaleFactor( scene()->views().at( 0 )->logicalDpiX() / 25.4 );
117 const QRectF area = plotArea();
118 if ( !area.contains( point.x(), point.y() ) )
131 const QRectF area = plotArea();
140 mPlotArea = plotArea;
145 const QStringList sourceIds = mRenderer->sourceIds();
146 for (
const QString &source : sourceIds )
149 auto it = mCachedImages.constFind( source );
150 if ( it != mCachedImages.constEnd() )
156 plot = mRenderer->renderToImage( plotArea.width(), plotArea.height(), xMinimum(),
xMaximum(),
yMinimum(),
yMaximum(), source );
157 mCachedImages.insert( source, plot );
159 rc.
painter()->drawImage( plotArea.left(), plotArea.top(), plot );
163 void paint( QPainter *painter )
override
166 if ( !mImage.isNull() )
168 painter->drawImage( 0, 0, mImage );
172 mImage = QImage( mRect.width(), mRect.height(), QImage::Format_ARGB32_Premultiplied );
173 mImage.fill( Qt::transparent );
175 QPainter imagePainter( &mImage );
176 imagePainter.setRenderHint( QPainter::Antialiasing,
true );
186 painter->drawImage( 0, 0, mImage );
196 QMap< QString, QImage > mCachedImages;
209 , mPlotItem( plotItem )
215 mRect = mCanvas->rect();
217 prepareGeometryChange();
218 setPos( mRect.topLeft() );
228 QRectF boundingRect()
const override
233 void paint( QPainter *painter )
override
235 const QgsPointXY crossHairPlotPoint = mPlotItem->plotPointToCanvasPoint( mPoint );
236 if ( crossHairPlotPoint.
isEmpty() )
240 painter->setBrush( Qt::NoBrush );
242 crossHairPen.setCosmetic(
true );
243 crossHairPen.setWidthF( 1 );
244 crossHairPen.setStyle( Qt::DashLine );
245 crossHairPen.setCapStyle( Qt::FlatCap );
246 crossHairPen.setColor( QColor( 0, 0, 0, 150 ) );
247 painter->setPen( crossHairPen );
248 painter->drawLine( QPointF( mPlotItem->plotArea().left(), crossHairPlotPoint.
y() ), QPointF( mPlotItem->plotArea().right(), crossHairPlotPoint.
y() ) );
249 painter->drawLine( QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().top() ), QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().bottom() ) );
254 const QString xCoordinateText = mPlotItem->xAxis().numericFormat()->formatDouble( mPoint.distance(), numericContext );
255 const QString yCoordinateText = mPlotItem->yAxis().numericFormat()->formatDouble( mPoint.elevation(), numericContext );
258 const QFontMetrics fm( font );
259 const double height = fm.capHeight();
260 const double xWidth = fm.horizontalAdvance( xCoordinateText );
261 const double yWidth = fm.horizontalAdvance( yCoordinateText );
262 const double textAxisMargin = fm.horizontalAdvance(
' ' );
264 QPointF xCoordOrigin;
265 QPointF yCoordOrigin;
267 if ( mPoint.distance() < ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5 )
269 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
272 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
274 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
279 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
281 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
286 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
289 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
291 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
296 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
298 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
303 painter->setBrush( QBrush( QColor( 255, 255, 255, 220 ) ) );
304 painter->setPen( Qt::NoPen );
305 painter->drawRect( QRectF( xCoordOrigin.x() - textAxisMargin + 1, xCoordOrigin.y() - textAxisMargin - height + 1, xWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
306 painter->drawRect( QRectF( yCoordOrigin.x() - textAxisMargin + 1, yCoordOrigin.y() - textAxisMargin - height + 1, yWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
308 painter->setBrush( Qt::NoBrush );
309 painter->setPen( Qt::black );
311 painter->drawText( xCoordOrigin, xCoordinateText );
312 painter->drawText( yCoordOrigin, yCoordinateText );
320 QgsElevationProfilePlotItem *mPlotItem =
nullptr;
330 mPlotItem =
new QgsElevationProfilePlotItem(
this );
332 textFormat.
setColor( qApp->palette().color( QPalette::Text ) );
333 mPlotItem->xAxis().setTextFormat( textFormat );
334 mPlotItem->yAxis().setTextFormat( textFormat );
336 mCrossHairsItem =
new QgsElevationProfileCrossHairsItem(
this, mPlotItem );
337 mCrossHairsItem->setZValue( 100 );
338 mCrossHairsItem->hide();
341 mDeferredRegenerationTimer =
new QTimer(
this );
342 mDeferredRegenerationTimer->setSingleShot(
true );
343 mDeferredRegenerationTimer->stop();
344 connect( mDeferredRegenerationTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRegeneration );
346 mDeferredRedrawTimer =
new QTimer(
this );
347 mDeferredRedrawTimer->setSingleShot(
true );
348 mDeferredRedrawTimer->stop();
349 connect( mDeferredRedrawTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRedraw );
357 mPlotItem->setRenderer(
nullptr );
358 mCurrentJob->deleteLater();
359 mCurrentJob =
nullptr;
367 mPlotItem->setRenderer(
nullptr );
370 mCurrentJob->deleteLater();
371 mCurrentJob =
nullptr;
377 const double dxPercent = dx / mPlotItem->plotArea().width();
378 const double dyPercent = dy / mPlotItem->plotArea().height();
381 const double dxPlot = - dxPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
382 const double dyPlot = dyPercent * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
384 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
385 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
386 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
387 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
391 mPlotItem->updatePlot();
397 if ( !mPlotItem->plotArea().contains( x, y ) )
400 const double newCenterX = mPlotItem->xMinimum() + ( x - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
401 const double newCenterY = mPlotItem->yMinimum() + ( mPlotItem->plotArea().bottom() - y ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
403 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
404 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
406 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
407 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
408 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
409 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
413 mPlotItem->updatePlot();
425 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
426 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
427 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
435 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) );
442 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
443 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
444 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
452 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) );
459void QgsElevationProfileCanvas::setupLayerConnections(
QgsMapLayer *layer,
bool isDisconnect )
474 switch ( layer->
type() )
508 if ( !mCurrentJob || !mSnappingEnabled )
522 const double currentWidth = mPlotItem->xMaximum() - mPlotItem->xMinimum();
523 const double currentHeight = mPlotItem->yMaximum() - mPlotItem->yMinimum();
525 const double newWidth = currentWidth / xFactor;
526 const double newHeight = currentHeight / yFactor;
528 const double currentCenterX = ( mPlotItem->xMinimum() + mPlotItem->xMaximum() ) * 0.5;
529 const double currentCenterY = ( mPlotItem->yMinimum() + mPlotItem->yMaximum() ) * 0.5;
531 mPlotItem->setXMinimum( currentCenterX - newWidth * 0.5 );
532 mPlotItem->setXMaximum( currentCenterX + newWidth * 0.5 );
533 mPlotItem->setYMinimum( currentCenterY - newHeight * 0.5 );
534 mPlotItem->setYMaximum( currentCenterY + newHeight * 0.5 );
537 mPlotItem->updatePlot();
543 const QRectF intersected = rect.intersected( mPlotItem->plotArea() );
545 const double minX = ( intersected.left() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
546 const double maxX = ( intersected.right() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
547 const double minY = ( mPlotItem->plotArea().bottom() - intersected.bottom() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
548 const double maxY = ( mPlotItem->plotArea().bottom() - intersected.top() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
550 mPlotItem->setXMinimum( minX );
551 mPlotItem->setXMaximum( maxX );
552 mPlotItem->setYMinimum( minY );
553 mPlotItem->setYMaximum( maxY );
556 mPlotItem->updatePlot();
564 double zoomFactor = settings.
value( QStringLiteral(
"qgis/zoom_factor" ), 2 ).toDouble();
567 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs(
event->angleDelta().y() );
569 if (
event->modifiers() & Qt::ControlModifier )
572 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
576 bool zoomIn =
event->angleDelta().y() > 0;
577 double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
579 QRectF viewportRect = mPlotItem->plotArea();
581 if ( viewportRect.contains(
event->position() ) )
584 const double oldCenterX = 0.5 * ( mPlotItem->xMaximum() + mPlotItem->xMinimum() );
585 const double oldCenterY = 0.5 * ( mPlotItem->yMaximum() + mPlotItem->yMinimum() );
587 const double eventPosX = (
event->position().x() - viewportRect.left() ) / viewportRect.width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
588 const double eventPosY = ( viewportRect.bottom() -
event->position().y() ) / viewportRect.height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
590 const double newCenterX = eventPosX + ( ( oldCenterX - eventPosX ) * scaleFactor );
591 const double newCenterY = eventPosY + ( ( oldCenterY - eventPosY ) * scaleFactor );
593 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
594 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
596 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
597 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
598 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
599 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
617 if ( e->isAccepted() )
619 mCrossHairsItem->hide();
624 if ( mCurrentJob && mSnappingEnabled && !plotPoint.
isEmpty() )
633 mCrossHairsItem->hide();
637 mCrossHairsItem->setPoint( plotPoint );
638 mCrossHairsItem->show();
645 return mPlotItem->plotArea();
655 mPlotItem->setRenderer(
nullptr );
657 mCurrentJob->deleteLater();
658 mCurrentJob =
nullptr;
671 const QList< QgsMapLayer * > layersToGenerate =
layers();
672 QList< QgsAbstractProfileSource * > sources;
673 sources.reserve( layersToGenerate .size() );
677 sources.append( source );
685 generationContext.
setMaximumErrorMapUnits( MAX_ERROR_PIXELS * ( mProfileCurve->length() ) / mPlotItem->plotArea().width() );
690 mPlotItem->setRenderer( mCurrentJob );
697 mZoomFullWhenJobFinished =
true;
700void QgsElevationProfileCanvas::generationFinished()
707 if ( mZoomFullWhenJobFinished )
710 mZoomFullWhenJobFinished =
false;
719 mPlotItem->updatePlot();
722 if ( mForceRegenerationAfterCurrentJobCompletes )
724 mForceRegenerationAfterCurrentJobCompletes =
false;
726 scheduleDeferredRegeneration();
730void QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged()
733 if ( !mCurrentJob || mCurrentJob->
isActive() )
740 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
745 scheduleDeferredRegeneration();
750void QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged()
753 if ( !mCurrentJob || mCurrentJob->
isActive() )
760 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
766 if ( mPlotItem->redrawResults( layer->
id() ) )
767 scheduleDeferredRedraw();
771void QgsElevationProfileCanvas::regenerateResultsForLayer()
773 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( sender() ) )
778 scheduleDeferredRegeneration();
783void QgsElevationProfileCanvas::scheduleDeferredRegeneration()
785 if ( !mDeferredRegenerationScheduled )
787 mDeferredRegenerationTimer->start( 1 );
788 mDeferredRegenerationScheduled =
true;
792void QgsElevationProfileCanvas::scheduleDeferredRedraw()
794 if ( !mDeferredRedrawScheduled )
796 mDeferredRedrawTimer->start( 1 );
797 mDeferredRedrawScheduled =
true;
801void QgsElevationProfileCanvas::startDeferredRegeneration()
803 if ( mCurrentJob && !mCurrentJob->
isActive() )
808 else if ( mCurrentJob )
810 mForceRegenerationAfterCurrentJobCompletes =
true;
813 mDeferredRegenerationScheduled =
false;
816void QgsElevationProfileCanvas::startDeferredRedraw()
819 mDeferredRedrawScheduled =
false;
822void QgsElevationProfileCanvas::refineResults()
828 const double plotDistanceRange = mPlotItem->xMaximum() - mPlotItem->xMinimum();
829 const double plotElevationRange = mPlotItem->yMaximum() - mPlotItem->yMinimum();
830 const double plotDistanceUnitsPerPixel = plotDistanceRange / mPlotItem->plotArea().width();
834 const double targetMaxErrorInMapUnits = MAX_ERROR_PIXELS * plotDistanceUnitsPerPixel;
835 const double factor = std::pow( 10.0, 1 - std::ceil( std::log10( std::fabs( targetMaxErrorInMapUnits ) ) ) );
836 const double roundedErrorInMapUnits = std::floor( targetMaxErrorInMapUnits * factor ) / factor;
844 mPlotItem->xMaximum() + plotDistanceRange * 0.05 ) );
847 mPlotItem->yMaximum() + plotElevationRange * 0.05 ) );
850 scheduleDeferredRegeneration();
855 if ( !mPlotItem->plotArea().contains( point.x(), point.y() ) )
858 return mPlotItem->canvasPointToPlotPoint( point );
863 return mPlotItem->plotPointToCanvasPoint( point );
869 mPlotItem->mProject = project;
879 mProfileCurve.reset( curve );
884 return mProfileCurve.get();
899 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
901 setupLayerConnections( layer,
true );
905 auto filteredList =
layers;
906 filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
909 return !layer || !layer->isValid();
910 } ), filteredList.end() );
912 mLayers = _qgis_listRawToQPointer( filteredList );
913 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
915 setupLayerConnections( layer,
false );
921 return _qgis_listQPointerToRaw( mLayers );
927 mPlotItem->updateRect();
928 mCrossHairsItem->updateRect();
933 QgsPlotCanvas::paintEvent(
event );
935 if ( !mFirstDrawOccurred )
938 mFirstDrawOccurred =
true;
939 mPlotItem->updateRect();
940 mCrossHairsItem->updateRect();
946 if ( !mPlotItem->plotArea().contains( point.
x(), point.
y() ) )
949 if ( !mProfileCurve )
952 const double dx = point.
x() - mPlotItem->plotArea().left();
954 const double distanceAlongPlotPercent = dx / mPlotItem->plotArea().width();
955 double distanceAlongCurveLength = distanceAlongPlotPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
957 std::unique_ptr< QgsPoint > mapXyPoint( mProfileCurve->interpolatePoint( distanceAlongCurveLength ) );
961 const double mapZ = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * ( mPlotItem->plotArea().bottom() - point.
y() ) + mPlotItem->yMinimum();
963 return QgsPoint( mapXyPoint->x(), mapXyPoint->y(), mapZ );
968 if ( !mProfileCurve )
973 const double distanceAlongCurve =
geos.lineLocatePoint( point, &error );
975 const double distanceAlongCurveOnPlot = distanceAlongCurve - mPlotItem->xMinimum();
976 const double distanceAlongCurvePercent = distanceAlongCurveOnPlot / ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
977 const double distanceAlongPlotRect = distanceAlongCurvePercent * mPlotItem->plotArea().width();
979 const double canvasX = mPlotItem->plotArea().left() + distanceAlongPlotRect;
982 if ( std::isnan( point.
z() ) || point.
z() < mPlotItem->yMinimum() )
984 canvasY = mPlotItem->plotArea().top();
986 else if ( point.
z() > mPlotItem->yMaximum() )
988 canvasY = mPlotItem->plotArea().bottom();
992 const double yPercent = ( point.
z() - mPlotItem->yMinimum() ) / ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
993 canvasY = mPlotItem->plotArea().bottom() - mPlotItem->plotArea().height() * yPercent;
1009 mPlotItem->setYMinimum( 0 );
1010 mPlotItem->setYMaximum( 10 );
1015 mPlotItem->setYMinimum( zRange.
lower() - 5 );
1016 mPlotItem->setYMaximum( zRange.
lower() + 5 );
1021 const double margin = ( zRange.
upper() - zRange.
lower() ) * 0.05;
1022 mPlotItem->setYMinimum( zRange.
lower() - margin );
1023 mPlotItem->setYMaximum( zRange.
upper() + margin );
1027 mPlotItem->setXMinimum( 0 );
1029 mPlotItem->setXMaximum( profileLength * 1.02 );
1032 mPlotItem->updatePlot();
1038 mPlotItem->setYMinimum( minimumElevation );
1039 mPlotItem->setYMaximum( maximumElevation );
1040 mPlotItem->setXMinimum( minimumDistance );
1041 mPlotItem->setXMaximum( maximumDistance );
1043 mPlotItem->updatePlot();
1049 return QgsDoubleRange( mPlotItem->xMinimum(), mPlotItem->xMaximum() );
1054 return QgsDoubleRange( mPlotItem->yMinimum(), mPlotItem->yMaximum() );
1063class QgsElevationProfilePlot :
public Qgs2DPlot
1068 : mRenderer( renderer )
1077 rc.
painter()->translate( plotArea.left(), plotArea.top() );
1079 rc.
painter()->translate( -plotArea.left(), -plotArea.top() );
1096 QgsElevationProfilePlot profilePlot( mCurrentJob );
1100 QDomElement elem = doc.createElement( QStringLiteral(
"plot" ) );
1102 plotSettings.
writeXml( elem, doc, rwContext );
1103 profilePlot.readXml( elem, rwContext );
1105 profilePlot.setSize( QSizeF( width, height ) );
1106 profilePlot.render( context );
1116 return mCurrentJob->
identify( plotPoint, identifyContext() );
1127 double distance1 = topLeftPlotPoint.
distance();
1128 double distance2 = bottomRightPlotPoint.
distance();
1129 if ( distance2 < distance1 )
1130 std::swap( distance1, distance2 );
1132 double elevation1 = topLeftPlotPoint.
elevation();
1133 double elevation2 = bottomRightPlotPoint.
elevation();
1134 if ( elevation2 < elevation1 )
1135 std::swap( elevation1, elevation2 );
1143 mPlotItem->setRenderer(
nullptr );
1144 mPlotItem->updatePlot();
1149 mSnappingEnabled = enabled;
Base class for 2-dimensional plot/chart/graphs.
void calculateOptimisedIntervals(QgsRenderContext &context)
Automatically sets the grid and label intervals to optimal values for display in the given render con...
double yMaximum() const
Returns the maximum value of the y axis.
void setSize(QSizeF size)
Sets the overall size of the plot (including titles and over components which sit outside the plot ar...
double xMaximum() const
Returns the maximum value of the x axis.
void render(QgsRenderContext &context)
Renders the plot.
void setYMaximum(double maximum)
Sets the maximum value of the y axis.
double xMinimum() const
Returns the minimum value of the x axis.
double yMinimum() const
Returns the minimum value of the y axis.
QRectF interiorPlotArea(QgsRenderContext &context) const
Returns the area of the plot which corresponds to the actual plot content (excluding all titles and o...
void setYMinimum(double minimum)
Sets the minimum value of the y axis.
virtual void renderContent(QgsRenderContext &context, const QRectF &plotArea)
Renders the plot content.
bool writeXml(QDomElement &element, QDomDocument &document, QgsReadWriteContext &context) const override
Writes the plot's properties into an XML element.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
Interface for classes which can generate elevation profiles.
virtual QgsAbstractTerrainProvider * clone() const =0
Creates a clone of the provider and returns the new object.
This class represents a coordinate reference system (CRS).
Abstract base class for curved geometry type.
QgsRange which stores a range of double values.
A canvas for elevation profiles.
QgsDoubleRange visibleElevationRange() const
Returns the elevation range currently visible in the plot.
QgsCurve * profileCurve() const
Returns the profile curve.
void setTolerance(double tolerance)
Sets the profile tolerance (in crs() units).
void setProfileCurve(QgsCurve *curve)
Sets the profile curve.
void zoomToRect(const QRectF &rect) override
Zooms the plot to the specified rect in canvas units.
void activeJobCountChanged(int count)
Emitted when the number of active background jobs changes.
QgsElevationProfileCanvas(QWidget *parent=nullptr)
Constructor for QgsElevationProfileCanvas, with the specified parent widget.
void scalePlot(double factor) override
Scales the plot by a specified scale factor.
void paintEvent(QPaintEvent *event) override
QgsDoubleRange visibleDistanceRange() const
Returns the distance range currently visible in the plot.
void cancelJobs() override
Cancel any rendering job, in a blocking way.
QgsCoordinateReferenceSystem crs() const override
Returns the coordinate reference system (CRS) for map coordinates used by the canvas.
void clear()
Clears the current profile.
QgsProfilePoint canvasPointToPlotPoint(QPointF point) const
Converts a canvas point to the equivalent plot point.
QgsPointXY plotPointToCanvasPoint(const QgsProfilePoint &point) const
Converts a plot point to the equivalent canvas point.
QgsPoint toMapCoordinates(const QgsPointXY &point) const override
Converts a point on the canvas to the associated map coordinate.
void setVisiblePlotRange(double minimumDistance, double maximumDistance, double minimumElevation, double maximumElevation)
Sets the visible area of the plot.
void canvasPointHovered(const QgsPointXY &point, const QgsProfilePoint &profilePoint)
Emitted when the mouse hovers over the specified point (in canvas coordinates).
void render(QgsRenderContext &context, double width, double height, const Qgs2DPlot &plotSettings)
Renders a portion of the profile using the specified render context.
QgsPointXY snapToPlot(QPoint point) override
Snap a canvas point to the plot.
void setProject(QgsProject *project)
Sets the project associated with the profile.
QList< QgsMapLayer * > layers() const
Returns the list of layers included in the profile.
void resizeEvent(QResizeEvent *event) override
void centerPlotOn(double x, double y) override
Centers the plot on the plot point corresponding to x, y in canvas units.
const Qgs2DPlot & plot() const
Returns a reference to the 2D plot used by the widget.
void wheelZoom(QWheelEvent *event) override
Zoom plot from a mouse wheel event.
void refresh() override
Triggers a complete regeneration of the profile, causing the profile extraction to perform in the bac...
double tolerance() const
Returns the tolerance of the profile (in crs() units).
void mouseMoveEvent(QMouseEvent *e) override
void panContentsBy(double dx, double dy) override
Pans the plot contents by dx, dy in canvas units.
void invalidateCurrentPlotExtent()
Invalidates the current plot extent, which means that the visible plot area will be recalculated and ...
QgsPointXY toCanvasCoordinates(const QgsPoint &point) const override
Converts a point in map coordinates to the associated canvas point.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs associated with the canvas' map coordinates.
~QgsElevationProfileCanvas() override
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to include in the profile.
void zoomFull()
Zooms to the full extent of the profile.
void setSnappingEnabled(bool enabled)
Sets whether snapping of cursor points is enabled.
QVector< QgsProfileIdentifyResults > identify(QPointF point)
Identify results visible at the specified plot point.
QRectF plotArea() const
Returns the interior rectangle representing the surface of the plot, in canvas coordinates.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Does vector analysis using the geos library and handles import, export, exception handling*.
Base class for storage of map layer elevation properties.
void profileGenerationPropertyChanged()
Emitted when any of the elevation properties which relate solely to generation of elevation profiles ...
void profileRenderingPropertyChanged()
Emitted when any of the elevation properties which relate solely to presentation of elevation results...
Base class for all map layer types.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
void dataChanged()
Data of layer changed.
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
A context for numeric formats.
An abstract class for items that can be placed on a QgsPlotCanvas.
virtual void paint(QPainter *painter)=0
Paints the item.
Plot canvas is a class for displaying interactive 2d charts and plots.
bool event(QEvent *e) override
void plotAreaChanged()
Emitted whenever the visible area of the plot is changed.
void mouseMoveEvent(QMouseEvent *e) override
void resizeEvent(QResizeEvent *e) override
A class to represent a 2D point.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
Encapsulates the context in which an elevation profile is to be generated.
double maximumErrorMapUnits() const
Returns the maximum allowed error in the generated result, in profile curve map units.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the profie, to be used in size conversions.
void setMaximumErrorMapUnits(double error)
Sets the maximum allowed error in the generated result, in profile curve map units.
void setDistanceRange(const QgsDoubleRange &range)
Sets the range of distances to include in the generation.
void setElevationRange(const QgsDoubleRange &range)
Sets the range of elevations to include in the generation.
void setMapUnitsPerDistancePixel(double units)
Sets the number of map units per pixel in the distance dimension.
Encapsulates the context of identifying profile results.
double maximumPointElevationDelta
Maximum allowed snapping delta for the elevation values when identifying a point.
double maximumPointDistanceDelta
Maximum allowed snapping delta for the distance values when identifying a point.
QgsProject * project
Associated project.
double displayRatioElevationVsDistance
Display ratio of elevation vs distance units.
double maximumSurfaceDistanceDelta
Maximum allowed snapping delta for the distance values when identifying a continuous elevation surfac...
double maximumSurfaceElevationDelta
Maximum allowed snapping delta for the elevation values when identifying a continuous elevation surfa...
Generates and renders elevation profile plots.
QgsProfileSnapResult snapPoint(const QgsProfilePoint &point, const QgsProfileSnapContext &context)
Snap a point to the results.
void regenerateInvalidatedResults()
Starts a background regeneration of any invalidated results and immediately returns.
void invalidateAllRefinableSources()
Invalidates previous results from all refinable sources.
void cancelGeneration()
Stop the generation job - does not return until the job has terminated.
void startGeneration()
Start the generation job and immediately return.
QgsDoubleRange zRange() const
Returns the limits of the retrieved elevation values.
QVector< QgsProfileIdentifyResults > identify(const QgsProfilePoint &point, const QgsProfileIdentifyContext &context)
Identify results visible at the specified profile point.
bool isActive() const
Returns true if the generation job is currently running in background.
bool invalidateResults(QgsAbstractProfileSource *source)
Invalidates the profile results from the source with matching ID.
void replaceSource(QgsAbstractProfileSource *source)
Replaces the existing source with matching ID.
void setContext(const QgsProfileGenerationContext &context)
Sets the context in which the profile generation will occur.
void generationFinished()
Emitted when the profile generation is finished (or canceled).
Encapsulates a point on a distance-elevation profile.
double elevation() const
Returns the elevation of the point.
double distance() const
Returns the distance of the point.
bool isEmpty() const
Returns true if the point is empty.
Encapsulates properties and constraints relating to fetching elevation profiles from different source...
QgsProfileRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate expressions.
QgsProfileRequest & setTransformContext(const QgsCoordinateTransformContext &context)
Sets the transform context, for use when transforming coordinates from a source to the request's crs(...
QgsProfileRequest & setTerrainProvider(QgsAbstractTerrainProvider *provider)
Sets the terrain provider.
QgsProfileRequest & setTolerance(double tolerance)
Sets the tolerance of the request (in crs() units).
QgsProfileRequest & setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the desired Coordinate Reference System (crs) for the profile.
Encapsulates the context of snapping a profile point.
double maximumPointDistanceDelta
Maximum allowed snapping delta for the distance values when snapping to a point.
double maximumSurfaceElevationDelta
Maximum allowed snapping delta for the elevation values when snapping to a continuous elevation surfa...
double maximumPointElevationDelta
Maximum allowed snapping delta for the elevation values when snapping to a point.
double maximumSurfaceDistanceDelta
Maximum allowed snapping delta for the distance values when snapping to a continuous elevation surfac...
double displayRatioElevationVsDistance
Display ratio of elevation vs distance units.
Encapsulates results of snapping a profile point.
bool isValid() const
Returns true if the result is a valid point.
QgsProfilePoint snappedPoint
Snapped point.
QgsAbstractTerrainProvider * terrainProvider()
Returns the project's terrain provider.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
const QgsProjectElevationProperties * elevationProperties() const
Returns the project's elevation properties, which contains the project's elevation related settings.
QgsCoordinateTransformContext transformContext
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
A utility class for dynamic handling of changes to screen properties.
double screenDpi() const
Returns the current screen DPI for the screen that the parent widget appears on.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
Represents a vector layer which manages a vector based data sets.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geometry)
Emitted whenever a geometry change is done in the edit buffer.
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
Contains geos related utilities and functions.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const QgsCoordinateReferenceSystem & crs