60 mRect = mCanvas->rect();
63 prepareGeometryChange();
64 setPos( mRect.topLeft() );
67 mCachedImages.clear();
75 mCachedImages.clear();
80 bool redrawResults(
const QString &sourceId )
82 auto it = mCachedImages.find( sourceId );
83 if ( it == mCachedImages.end() )
86 mCachedImages.erase( it );
91 QRectF boundingRect()
const override
98 if ( !mPlotArea.isNull() )
103 if ( !scene()->views().isEmpty() )
104 context.
setScaleFactor( scene()->views().at( 0 )->logicalDpiX() / 25.4 );
113 const QRectF area = plotArea();
114 if ( !area.contains( point.x(), point.y() ) )
127 const QRectF area = plotArea();
136 mPlotArea = plotArea;
141 const QStringList sourceIds = mRenderer->sourceIds();
142 for (
const QString &source : sourceIds )
145 auto it = mCachedImages.constFind( source );
146 if ( it != mCachedImages.constEnd() )
152 plot = mRenderer->renderToImage( plotArea.width(), plotArea.height(), xMinimum(),
xMaximum(),
yMinimum(),
yMaximum(), source );
153 mCachedImages.insert( source, plot );
155 rc.
painter()->drawImage( plotArea.left(), plotArea.top(), plot );
159 void paint( QPainter *painter )
override
162 if ( !mImage.isNull() )
164 painter->drawImage( 0, 0, mImage );
168 mImage = QImage( mRect.width(), mRect.height(), QImage::Format_ARGB32_Premultiplied );
169 mImage.fill( Qt::transparent );
171 QPainter imagePainter( &mImage );
172 imagePainter.setRenderHint( QPainter::Antialiasing,
true );
182 painter->drawImage( 0, 0, mImage );
192 QMap< QString, QImage > mCachedImages;
205 , mPlotItem( plotItem )
211 mRect = mCanvas->rect();
213 prepareGeometryChange();
214 setPos( mRect.topLeft() );
224 QRectF boundingRect()
const override
229 void paint( QPainter *painter )
override
231 const QgsPointXY crossHairPlotPoint = mPlotItem->plotPointToCanvasPoint( mPoint );
232 if ( crossHairPlotPoint.
isEmpty() )
236 painter->setBrush( Qt::NoBrush );
238 crossHairPen.setCosmetic(
true );
239 crossHairPen.setWidthF( 1 );
240 crossHairPen.setStyle( Qt::DashLine );
241 crossHairPen.setCapStyle( Qt::FlatCap );
242 crossHairPen.setColor( QColor( 0, 0, 0, 150 ) );
243 painter->setPen( crossHairPen );
244 painter->drawLine( QPointF( mPlotItem->plotArea().left(), crossHairPlotPoint.
y() ), QPointF( mPlotItem->plotArea().right(), crossHairPlotPoint.
y() ) );
245 painter->drawLine( QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().top() ), QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().bottom() ) );
250 const QString xCoordinateText = mPlotItem->xAxis().numericFormat()->formatDouble( mPoint.distance(), numericContext );
251 const QString yCoordinateText = mPlotItem->yAxis().numericFormat()->formatDouble( mPoint.elevation(), numericContext );
254 const QFontMetrics fm( font );
255 const double height = fm.capHeight();
256 const double xWidth = fm.horizontalAdvance( xCoordinateText );
257 const double yWidth = fm.horizontalAdvance( yCoordinateText );
258 const double textAxisMargin = fm.horizontalAdvance(
' ' );
260 QPointF xCoordOrigin;
261 QPointF yCoordOrigin;
263 if ( mPoint.distance() < ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5 )
265 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
268 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
270 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
275 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
277 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
282 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
285 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
287 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
292 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
294 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
299 painter->setBrush( QBrush( QColor( 255, 255, 255, 220 ) ) );
300 painter->setPen( Qt::NoPen );
301 painter->drawRect( QRectF( xCoordOrigin.x() - textAxisMargin + 1, xCoordOrigin.y() - textAxisMargin - height + 1, xWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
302 painter->drawRect( QRectF( yCoordOrigin.x() - textAxisMargin + 1, yCoordOrigin.y() - textAxisMargin - height + 1, yWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
304 painter->setBrush( Qt::NoBrush );
305 painter->setPen( Qt::black );
307 painter->drawText( xCoordOrigin, xCoordinateText );
308 painter->drawText( yCoordOrigin, yCoordinateText );
316 QgsElevationProfilePlotItem *mPlotItem =
nullptr;
326 mPlotItem =
new QgsElevationProfilePlotItem(
this );
327 mCrossHairsItem =
new QgsElevationProfileCrossHairsItem(
this, mPlotItem );
328 mCrossHairsItem->setZValue( 100 );
329 mCrossHairsItem->hide();
332 mDeferredRegenerationTimer =
new QTimer(
this );
333 mDeferredRegenerationTimer->setSingleShot(
true );
334 mDeferredRegenerationTimer->stop();
335 connect( mDeferredRegenerationTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRegeneration );
337 mDeferredRedrawTimer =
new QTimer(
this );
338 mDeferredRedrawTimer->setSingleShot(
true );
339 mDeferredRedrawTimer->stop();
340 connect( mDeferredRedrawTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRedraw );
348 mPlotItem->setRenderer(
nullptr );
349 mCurrentJob->deleteLater();
350 mCurrentJob =
nullptr;
358 mPlotItem->setRenderer(
nullptr );
361 mCurrentJob->deleteLater();
362 mCurrentJob =
nullptr;
368 const double dxPercent = dx / mPlotItem->plotArea().width();
369 const double dyPercent = dy / mPlotItem->plotArea().height();
372 const double dxPlot = - dxPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
373 const double dyPlot = dyPercent * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
375 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
376 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
377 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
378 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
382 mPlotItem->updatePlot();
388 if ( !mPlotItem->plotArea().contains( x, y ) )
391 const double newCenterX = mPlotItem->xMinimum() + ( x - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
392 const double newCenterY = mPlotItem->yMinimum() + ( mPlotItem->plotArea().bottom() - y ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
394 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
395 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
397 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
398 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
399 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
400 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
404 mPlotItem->updatePlot();
416 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
417 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
418 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
426 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) );
433 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
434 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
435 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
443 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) / ( mPlotItem->plotArea().width() ) );
450void QgsElevationProfileCanvas::setupLayerConnections(
QgsMapLayer *layer,
bool isDisconnect )
465 switch ( layer->
type() )
467 case Qgis::LayerType::Vector:
486 case Qgis::LayerType::Raster:
487 case Qgis::LayerType::Plugin:
488 case Qgis::LayerType::Mesh:
489 case Qgis::LayerType::VectorTile:
490 case Qgis::LayerType::Annotation:
491 case Qgis::LayerType::PointCloud:
492 case Qgis::LayerType::Group:
499 if ( !mCurrentJob || !mSnappingEnabled )
513 const double currentWidth = mPlotItem->xMaximum() - mPlotItem->xMinimum();
514 const double currentHeight = mPlotItem->yMaximum() - mPlotItem->yMinimum();
516 const double newWidth = currentWidth / xFactor;
517 const double newHeight = currentHeight / yFactor;
519 const double currentCenterX = ( mPlotItem->xMinimum() + mPlotItem->xMaximum() ) * 0.5;
520 const double currentCenterY = ( mPlotItem->yMinimum() + mPlotItem->yMaximum() ) * 0.5;
522 mPlotItem->setXMinimum( currentCenterX - newWidth * 0.5 );
523 mPlotItem->setXMaximum( currentCenterX + newWidth * 0.5 );
524 mPlotItem->setYMinimum( currentCenterY - newHeight * 0.5 );
525 mPlotItem->setYMaximum( currentCenterY + newHeight * 0.5 );
528 mPlotItem->updatePlot();
534 const QRectF intersected = rect.intersected( mPlotItem->plotArea() );
536 const double minX = ( intersected.left() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
537 const double maxX = ( intersected.right() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
538 const double minY = ( mPlotItem->plotArea().bottom() - intersected.bottom() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
539 const double maxY = ( mPlotItem->plotArea().bottom() - intersected.top() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
541 mPlotItem->setXMinimum( minX );
542 mPlotItem->setXMaximum( maxX );
543 mPlotItem->setYMinimum( minY );
544 mPlotItem->setYMaximum( maxY );
547 mPlotItem->updatePlot();
555 double zoomFactor = settings.
value( QStringLiteral(
"qgis/zoom_factor" ), 2 ).toDouble();
558 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs(
event->angleDelta().y() );
560 if (
event->modifiers() & Qt::ControlModifier )
563 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
567 bool zoomIn =
event->angleDelta().y() > 0;
568 double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
570 QRectF viewportRect = mPlotItem->plotArea();
572 if ( viewportRect.contains(
event->position() ) )
575 const double oldCenterX = 0.5 * ( mPlotItem->xMaximum() + mPlotItem->xMinimum() );
576 const double oldCenterY = 0.5 * ( mPlotItem->yMaximum() + mPlotItem->yMinimum() );
578 const double eventPosX = (
event->position().x() - viewportRect.left() ) / viewportRect.width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
579 const double eventPosY = ( viewportRect.bottom() -
event->position().y() ) / viewportRect.height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
581 const double newCenterX = eventPosX + ( ( oldCenterX - eventPosX ) * scaleFactor );
582 const double newCenterY = eventPosY + ( ( oldCenterY - eventPosY ) * scaleFactor );
584 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
585 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
587 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
588 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
589 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
590 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
608 if ( e->isAccepted() )
610 mCrossHairsItem->hide();
615 if ( mCurrentJob && mSnappingEnabled && !plotPoint.
isEmpty() )
624 mCrossHairsItem->hide();
628 mCrossHairsItem->setPoint( plotPoint );
629 mCrossHairsItem->show();
636 return mPlotItem->plotArea();
646 mPlotItem->setRenderer(
nullptr );
648 mCurrentJob->deleteLater();
649 mCurrentJob =
nullptr;
662 const QList< QgsMapLayer * > layersToGenerate =
layers();
663 QList< QgsAbstractProfileSource * > sources;
664 sources.reserve( layersToGenerate .size() );
668 sources.append( source );
676 generationContext.
setMaximumErrorMapUnits( MAX_ERROR_PIXELS * ( mProfileCurve->length() ) / mPlotItem->plotArea().width() );
681 mPlotItem->setRenderer( mCurrentJob );
688 mZoomFullWhenJobFinished =
true;
691void QgsElevationProfileCanvas::generationFinished()
698 if ( mZoomFullWhenJobFinished )
701 mZoomFullWhenJobFinished =
false;
710 mPlotItem->updatePlot();
713 if ( mForceRegenerationAfterCurrentJobCompletes )
715 mForceRegenerationAfterCurrentJobCompletes =
false;
717 scheduleDeferredRegeneration();
721void QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged()
724 if ( !mCurrentJob || mCurrentJob->
isActive() )
731 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
736 scheduleDeferredRegeneration();
741void QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged()
744 if ( !mCurrentJob || mCurrentJob->
isActive() )
751 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
757 if ( mPlotItem->redrawResults( layer->
id() ) )
758 scheduleDeferredRedraw();
762void QgsElevationProfileCanvas::regenerateResultsForLayer()
764 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( sender() ) )
769 scheduleDeferredRegeneration();
774void QgsElevationProfileCanvas::scheduleDeferredRegeneration()
776 if ( !mDeferredRegenerationScheduled )
778 mDeferredRegenerationTimer->start( 1 );
779 mDeferredRegenerationScheduled =
true;
783void QgsElevationProfileCanvas::scheduleDeferredRedraw()
785 if ( !mDeferredRedrawScheduled )
787 mDeferredRedrawTimer->start( 1 );
788 mDeferredRedrawScheduled =
true;
792void QgsElevationProfileCanvas::startDeferredRegeneration()
794 if ( mCurrentJob && !mCurrentJob->
isActive() )
799 else if ( mCurrentJob )
801 mForceRegenerationAfterCurrentJobCompletes =
true;
804 mDeferredRegenerationScheduled =
false;
807void QgsElevationProfileCanvas::startDeferredRedraw()
810 mDeferredRedrawScheduled =
false;
813void QgsElevationProfileCanvas::refineResults()
819 const double plotDistanceRange = mPlotItem->xMaximum() - mPlotItem->xMinimum();
820 const double plotElevationRange = mPlotItem->yMaximum() - mPlotItem->yMinimum();
821 const double plotDistanceUnitsPerPixel = plotDistanceRange / mPlotItem->plotArea().width();
825 const double targetMaxErrorInMapUnits = MAX_ERROR_PIXELS * plotDistanceUnitsPerPixel;
826 const double factor = std::pow( 10.0, 1 - std::ceil( std::log10( std::fabs( targetMaxErrorInMapUnits ) ) ) );
827 const double roundedErrorInMapUnits = std::floor( targetMaxErrorInMapUnits * factor ) / factor;
835 mPlotItem->xMaximum() + plotDistanceRange * 0.05 ) );
838 mPlotItem->yMaximum() + plotElevationRange * 0.05 ) );
841 scheduleDeferredRegeneration();
846 if ( !mPlotItem->plotArea().contains( point.x(), point.y() ) )
849 return mPlotItem->canvasPointToPlotPoint( point );
854 return mPlotItem->plotPointToCanvasPoint( point );
860 mPlotItem->mProject = project;
870 mProfileCurve.reset( curve );
875 return mProfileCurve.get();
890 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
892 setupLayerConnections( layer,
true );
896 auto filteredList =
layers;
897 filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
900 return !layer || !layer->isValid();
901 } ), filteredList.end() );
903 mLayers = _qgis_listRawToQPointer( filteredList );
904 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
906 setupLayerConnections( layer,
false );
912 return _qgis_listQPointerToRaw( mLayers );
918 mPlotItem->updateRect();
919 mCrossHairsItem->updateRect();
924 QgsPlotCanvas::paintEvent(
event );
926 if ( !mFirstDrawOccurred )
929 mFirstDrawOccurred =
true;
930 mPlotItem->updateRect();
931 mCrossHairsItem->updateRect();
937 if ( !mPlotItem->plotArea().contains( point.
x(), point.
y() ) )
940 if ( !mProfileCurve )
943 const double dx = point.
x() - mPlotItem->plotArea().left();
945 const double distanceAlongPlotPercent = dx / mPlotItem->plotArea().width();
946 double distanceAlongCurveLength = distanceAlongPlotPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
948 std::unique_ptr< QgsPoint > mapXyPoint( mProfileCurve->interpolatePoint( distanceAlongCurveLength ) );
952 const double mapZ = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * ( mPlotItem->plotArea().bottom() - point.
y() ) + mPlotItem->yMinimum();
954 return QgsPoint( mapXyPoint->x(), mapXyPoint->y(), mapZ );
959 if ( !mProfileCurve )
964 const double distanceAlongCurve =
geos.lineLocatePoint( point, &error );
966 const double distanceAlongCurveOnPlot = distanceAlongCurve - mPlotItem->xMinimum();
967 const double distanceAlongCurvePercent = distanceAlongCurveOnPlot / ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
968 const double distanceAlongPlotRect = distanceAlongCurvePercent * mPlotItem->plotArea().width();
970 const double canvasX = mPlotItem->plotArea().left() + distanceAlongPlotRect;
973 if ( std::isnan( point.
z() ) || point.
z() < mPlotItem->yMinimum() )
975 canvasY = mPlotItem->plotArea().top();
977 else if ( point.
z() > mPlotItem->yMaximum() )
979 canvasY = mPlotItem->plotArea().bottom();
983 const double yPercent = ( point.
z() - mPlotItem->yMinimum() ) / ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
984 canvasY = mPlotItem->plotArea().bottom() - mPlotItem->plotArea().height() * yPercent;
1000 mPlotItem->setYMinimum( 0 );
1001 mPlotItem->setYMaximum( 10 );
1006 mPlotItem->setYMinimum( zRange.
lower() - 5 );
1007 mPlotItem->setYMaximum( zRange.
lower() + 5 );
1012 const double margin = ( zRange.
upper() - zRange.
lower() ) * 0.05;
1013 mPlotItem->setYMinimum( zRange.
lower() - margin );
1014 mPlotItem->setYMaximum( zRange.
upper() + margin );
1018 mPlotItem->setXMinimum( 0 );
1020 mPlotItem->setXMaximum( profileLength * 1.02 );
1023 mPlotItem->updatePlot();
1029 mPlotItem->setYMinimum( minimumElevation );
1030 mPlotItem->setYMaximum( maximumElevation );
1031 mPlotItem->setXMinimum( minimumDistance );
1032 mPlotItem->setXMaximum( maximumDistance );
1034 mPlotItem->updatePlot();
1040 return QgsDoubleRange( mPlotItem->xMinimum(), mPlotItem->xMaximum() );
1045 return QgsDoubleRange( mPlotItem->yMinimum(), mPlotItem->yMaximum() );
1054class QgsElevationProfilePlot :
public Qgs2DPlot
1059 : mRenderer( renderer )
1068 rc.
painter()->translate( plotArea.left(), plotArea.top() );
1070 rc.
painter()->translate( -plotArea.left(), -plotArea.top() );
1087 QgsElevationProfilePlot profilePlot( mCurrentJob );
1091 QDomElement elem = doc.createElement( QStringLiteral(
"plot" ) );
1093 plotSettings.
writeXml( elem, doc, rwContext );
1094 profilePlot.readXml( elem, rwContext );
1096 profilePlot.setSize( QSizeF( width, height ) );
1097 profilePlot.render( context );
1107 return mCurrentJob->
identify( plotPoint, identifyContext() );
1118 double distance1 = topLeftPlotPoint.
distance();
1119 double distance2 = bottomRightPlotPoint.
distance();
1120 if ( distance2 < distance1 )
1121 std::swap( distance1, distance2 );
1123 double elevation1 = topLeftPlotPoint.
elevation();
1124 double elevation2 = bottomRightPlotPoint.
elevation();
1125 if ( elevation2 < elevation1 )
1126 std::swap( elevation1, elevation2 );
1134 mPlotItem->setRenderer(
nullptr );
1135 mPlotItem->updatePlot();
1140 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.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the plot's properties into an XML element.
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.
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 SIP_HOLDGIL
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 SIP_HOLDGIL
Returns the elevation of the point.
bool isEmpty() const SIP_HOLDGIL
Returns true if the point is empty.
double distance() const SIP_HOLDGIL
Returns the distance of the point.
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.
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.
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