21#include "moc_qgselevationprofilecanvas.cpp"
68 mRect = mCanvas->rect();
71 prepareGeometryChange();
72 setPos( mRect.topLeft() );
75 mCachedImages.clear();
83 mCachedImages.clear();
88 bool redrawResults(
const QString &sourceId )
90 auto it = mCachedImages.find( sourceId );
91 if ( it == mCachedImages.end() )
94 mCachedImages.erase( it );
99 QRectF boundingRect()
const override
104 QString distanceSuffix()
const
106 switch ( mDistanceUnit )
159 return QObject::tr(
"°" );
168 mDistanceUnit = unit;
175 if ( !mPlotArea.isNull() )
180 if ( !scene()->views().isEmpty() )
181 context.
setScaleFactor( scene()->views().at( 0 )->logicalDpiX() / 25.4 );
190 const QRectF area = plotArea();
191 if ( !area.contains( point.x(), point.y() ) )
194 const double distance = ( point.x() - area.left() ) / area.width() * (
xMaximum() -
xMinimum() ) * mXScaleFactor +
xMinimum() * mXScaleFactor;
201 if ( point.
distance() < xMinimum() * mXScaleFactor || point.
distance() > xMaximum()* mXScaleFactor || point.
elevation() < yMinimum() || point.
elevation() > yMaximum() )
204 const QRectF area = plotArea();
213 mPlotArea = plotArea;
218 const double pixelRatio = !scene()->views().empty() ? scene()->views().at( 0 )->devicePixelRatioF() : 1;
220 const QStringList sourceIds = mRenderer->sourceIds();
221 for (
const QString &source : sourceIds )
224 auto it = mCachedImages.constFind( source );
225 if ( it != mCachedImages.constEnd() )
231 plot = mRenderer->renderToImage( plotArea.width() * pixelRatio,
232 plotArea.height() * pixelRatio, xMinimum() * mXScaleFactor,
xMaximum() * mXScaleFactor,
yMinimum(),
yMaximum(), source, pixelRatio );
233 plot.setDevicePixelRatio( pixelRatio );
234 mCachedImages.insert( source, plot );
236 rc.
painter()->drawImage( QPointF( plotArea.left(),
237 plotArea.top() ), plot );
241 void paint( QPainter *painter )
override
244 if ( !mImage.isNull() )
246 painter->drawImage( QPointF( 0, 0 ), mImage );
250 const double pixelRatio = !scene()->views().empty() ? scene()->views().at( 0 )->devicePixelRatioF() : 1;
251 mImage = QImage( mRect.width() * pixelRatio, mRect.height() * pixelRatio, QImage::Format_ARGB32_Premultiplied );
252 mImage.setDevicePixelRatio( pixelRatio );
253 mImage.fill( Qt::transparent );
255 QPainter imagePainter( &mImage );
256 imagePainter.setRenderHint( QPainter::Antialiasing,
true );
260 const double mapUnitsPerPixel = (
xMaximum() -
xMinimum() ) * mXScaleFactor / plotArea().width();
270 painter->drawImage( QPointF( 0, 0 ), mImage );
275 double mXScaleFactor = 1.0;
283 QMap< QString, QImage > mCachedImages;
296 , mPlotItem( plotItem )
302 mRect = mCanvas->rect();
304 prepareGeometryChange();
305 setPos( mRect.topLeft() );
315 QRectF boundingRect()
const override
320 void paint( QPainter *painter )
override
322 const QgsPointXY crossHairPlotPoint = mPlotItem->plotPointToCanvasPoint( mPoint );
323 if ( crossHairPlotPoint.
isEmpty() )
327 painter->setBrush( Qt::NoBrush );
329 crossHairPen.setCosmetic(
true );
330 crossHairPen.setWidthF( 1 );
331 crossHairPen.setStyle( Qt::DashLine );
332 crossHairPen.setCapStyle( Qt::FlatCap );
333 const QPalette scenePalette = mPlotItem->scene()->palette();
334 QColor penColor = scenePalette.color( QPalette::ColorGroup::Active, QPalette::Text );
335 penColor.setAlpha( 150 );
336 crossHairPen.setColor( penColor );
337 painter->setPen( crossHairPen );
338 painter->drawLine( QPointF( mPlotItem->plotArea().left(), crossHairPlotPoint.
y() ), QPointF( mPlotItem->plotArea().right(), crossHairPlotPoint.
y() ) );
339 painter->drawLine( QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().top() ), QPointF( crossHairPlotPoint.
x(), mPlotItem->plotArea().bottom() ) );
344 const QString xCoordinateText = mPlotItem->xAxis().numericFormat()->formatDouble( mPoint.distance() / mPlotItem->mXScaleFactor, numericContext )
345 + mPlotItem->distanceSuffix();
347 const QString yCoordinateText = mPlotItem->yAxis().numericFormat()->formatDouble( mPoint.elevation(), numericContext );
350 const QFontMetrics fm( font );
351 const double height = fm.capHeight();
352 const double xWidth = fm.horizontalAdvance( xCoordinateText );
353 const double yWidth = fm.horizontalAdvance( yCoordinateText );
354 const double textAxisMargin = fm.horizontalAdvance(
' ' );
356 QPointF xCoordOrigin;
357 QPointF yCoordOrigin;
359 if ( mPoint.distance() < ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5 * mPlotItem->mXScaleFactor )
361 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
364 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
366 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
371 xCoordOrigin = QPointF( crossHairPlotPoint.
x() + textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
373 yCoordOrigin = QPointF( mPlotItem->plotArea().right() - yWidth - textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
378 if ( mPoint.elevation() < ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5 )
381 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().top() + height + textAxisMargin );
383 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() - textAxisMargin );
388 xCoordOrigin = QPointF( crossHairPlotPoint.
x() - xWidth - textAxisMargin, mPlotItem->plotArea().bottom() - textAxisMargin );
390 yCoordOrigin = QPointF( mPlotItem->plotArea().left() + textAxisMargin, crossHairPlotPoint.
y() + height + textAxisMargin );
395 QColor backgroundColor = mPlotItem->chartBackgroundSymbol()->color();
396 backgroundColor.setAlpha( 220 );
397 painter->setBrush( QBrush( backgroundColor ) );
398 painter->setPen( Qt::NoPen );
399 painter->drawRect( QRectF( xCoordOrigin.x() - textAxisMargin + 1, xCoordOrigin.y() - textAxisMargin - height + 1, xWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
400 painter->drawRect( QRectF( yCoordOrigin.x() - textAxisMargin + 1, yCoordOrigin.y() - textAxisMargin - height + 1, yWidth + 2 * textAxisMargin - 2, height + 2 * textAxisMargin - 2 ) );
402 painter->setBrush( Qt::NoBrush );
403 painter->setPen( scenePalette.color( QPalette::ColorGroup::Active, QPalette::Text ) );
405 painter->drawText( xCoordOrigin, xCoordinateText );
406 painter->drawText( yCoordOrigin, yCoordinateText );
414 QgsElevationProfilePlotItem *mPlotItem =
nullptr;
424 mPlotItem =
new QgsElevationProfilePlotItem(
this );
429 mCrossHairsItem =
new QgsElevationProfileCrossHairsItem(
this, mPlotItem );
430 mCrossHairsItem->setZValue( 100 );
431 mCrossHairsItem->hide();
434 mDeferredRegenerationTimer =
new QTimer(
this );
435 mDeferredRegenerationTimer->setSingleShot(
true );
436 mDeferredRegenerationTimer->stop();
437 connect( mDeferredRegenerationTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRegeneration );
439 mDeferredRedrawTimer =
new QTimer(
this );
440 mDeferredRedrawTimer->setSingleShot(
true );
441 mDeferredRedrawTimer->stop();
442 connect( mDeferredRedrawTimer, &QTimer::timeout,
this, &QgsElevationProfileCanvas::startDeferredRedraw );
450 mPlotItem->setRenderer(
nullptr );
451 mCurrentJob->deleteLater();
452 mCurrentJob =
nullptr;
460 mPlotItem->setRenderer(
nullptr );
463 mCurrentJob->deleteLater();
464 mCurrentJob =
nullptr;
470 const double dxPercent = dx / mPlotItem->plotArea().width();
471 const double dyPercent = dy / mPlotItem->plotArea().height();
474 const double dxPlot = - dxPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
475 const double dyPlot = dyPercent * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
478 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
479 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
480 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
481 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
485 mPlotItem->updatePlot();
491 if ( !mPlotItem->plotArea().contains( x, y ) )
494 const double newCenterX = mPlotItem->xMinimum() + ( x - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() );
495 const double newCenterY = mPlotItem->yMinimum() + ( mPlotItem->plotArea().bottom() - y ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
497 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
498 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
501 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
502 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
503 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
504 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
508 mPlotItem->updatePlot();
520 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
521 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
522 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
530 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor / ( mPlotItem->plotArea().width() ) );
537 const double toleranceInPixels = QFontMetrics( font() ).horizontalAdvance(
' ' );
538 const double xToleranceInPlotUnits = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor / ( mPlotItem->plotArea().width() ) * toleranceInPixels;
539 const double yToleranceInPlotUnits = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * toleranceInPixels;
547 / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor / ( mPlotItem->plotArea().width() ) );
554void QgsElevationProfileCanvas::setupLayerConnections(
QgsMapLayer *layer,
bool isDisconnect )
569 switch ( layer->
type() )
602void QgsElevationProfileCanvas::adjustRangeForAxisScaleLock(
double &xMinimum,
double &xMaximum,
double &yMinimum,
double &yMaximum )
const
605 const double horizontalScale = ( xMaximum - xMinimum ) / mPlotItem->plotArea().width();
606 const double verticalScale = ( yMaximum - yMinimum ) / mPlotItem->plotArea().height();
607 if ( horizontalScale > verticalScale )
609 const double height = horizontalScale * mPlotItem->plotArea().height();
610 const double deltaHeight = ( yMaximum - yMinimum ) - height;
611 yMinimum += deltaHeight / 2;
612 yMaximum -= deltaHeight / 2;
616 const double width = verticalScale * mPlotItem->plotArea().width();
617 const double deltaWidth = ( ( xMaximum - xMinimum ) - width );
618 xMinimum += deltaWidth / 2;
619 xMaximum -= deltaWidth / 2;
625 return mDistanceUnit;
630 mDistanceUnit = unit;
631 const double oldMin = mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
632 const double oldMax = mPlotItem->xMaximum() * mPlotItem->mXScaleFactor;
634 mPlotItem->setXAxisUnits( mDistanceUnit );
635 mPlotItem->setXMinimum( oldMin / mPlotItem->mXScaleFactor );
636 mPlotItem->setXMaximum( oldMax / mPlotItem->mXScaleFactor );
637 mPlotItem->updatePlot();
642 if ( !color.isValid() )
644 QPalette customPalette = qApp->palette();
645 const QColor baseColor = qApp->palette().color( QPalette::ColorRole::Base );
646 const QColor windowColor = qApp->palette().color( QPalette::ColorRole::Window );
647 customPalette.setColor( QPalette::ColorRole::Base, windowColor );
648 customPalette.setColor( QPalette::ColorRole::Window, baseColor );
649 setPalette( customPalette );
650 scene()->setPalette( customPalette );
655 const bool isDarkTheme = color.lightnessF() < 0.5;
656 QPalette customPalette = qApp->palette();
657 customPalette.setColor( QPalette::ColorRole::Window, color );
660 customPalette.setColor( QPalette::ColorRole::Text, QColor( 255, 255, 255 ) );
661 customPalette.setColor( QPalette::ColorRole::Base, color.lighter( 120 ) );
665 customPalette.setColor( QPalette::ColorRole::Text, QColor( 0, 0, 0 ) );
666 customPalette.setColor( QPalette::ColorRole::Base, color.darker( 120 ) );
669 setPalette( customPalette );
670 scene()->setPalette( customPalette );
673 updateChartFromPalette();
678 return mLockAxisScales;
683 mLockAxisScales = lock;
684 if ( mLockAxisScales )
686 double xMinimum = mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
687 double xMaximum = mPlotItem->xMaximum() * mPlotItem->mXScaleFactor;
688 double yMinimum = mPlotItem->yMinimum();
689 double yMaximum = mPlotItem->yMaximum();
690 adjustRangeForAxisScaleLock( xMinimum, xMaximum, yMinimum, yMaximum );
691 mPlotItem->setXMinimum( xMinimum / mPlotItem->mXScaleFactor );
692 mPlotItem->setXMaximum( xMaximum / mPlotItem->mXScaleFactor );
693 mPlotItem->setYMinimum( yMinimum );
694 mPlotItem->setYMaximum( yMaximum );
697 mPlotItem->updatePlot();
704 if ( !mCurrentJob || !mSnappingEnabled )
718 if ( mLockAxisScales )
721 const double currentWidth = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor;
722 const double currentHeight = mPlotItem->yMaximum() - mPlotItem->yMinimum();
724 const double newWidth = currentWidth / xFactor;
725 const double newHeight = currentHeight / yFactor;
727 const double currentCenterX = ( mPlotItem->xMinimum() + mPlotItem->xMaximum() ) * 0.5 * mPlotItem->mXScaleFactor;
728 const double currentCenterY = ( mPlotItem->yMinimum() + mPlotItem->yMaximum() ) * 0.5;
730 double xMinimum = currentCenterX - newWidth * 0.5;
731 double xMaximum = currentCenterX + newWidth * 0.5;
732 double yMinimum = currentCenterY - newHeight * 0.5;
733 double yMaximum = currentCenterY + newHeight * 0.5;
734 if ( mLockAxisScales )
736 adjustRangeForAxisScaleLock( xMinimum, xMaximum, yMinimum, yMaximum );
739 mPlotItem->setXMinimum( xMinimum / mPlotItem->mXScaleFactor );
740 mPlotItem->setXMaximum( xMaximum / mPlotItem->mXScaleFactor );
741 mPlotItem->setYMinimum( yMinimum );
742 mPlotItem->setYMaximum( yMaximum );
745 mPlotItem->updatePlot();
751 const QRectF intersected = rect.intersected( mPlotItem->plotArea() );
753 double minX = ( intersected.left() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor + mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
754 double maxX = ( intersected.right() - mPlotItem->plotArea().left() ) / mPlotItem->plotArea().width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor + mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
755 double minY = ( mPlotItem->plotArea().bottom() - intersected.bottom() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
756 double maxY = ( mPlotItem->plotArea().bottom() - intersected.top() ) / mPlotItem->plotArea().height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
758 if ( mLockAxisScales )
760 adjustRangeForAxisScaleLock( minX, maxX, minY, maxY );
763 mPlotItem->setXMinimum( minX / mPlotItem->mXScaleFactor );
764 mPlotItem->setXMaximum( maxX / mPlotItem->mXScaleFactor );
765 mPlotItem->setYMinimum( minY );
766 mPlotItem->setYMaximum( maxY );
769 mPlotItem->updatePlot();
777 double zoomFactor = settings.
value( QStringLiteral(
"qgis/zoom_factor" ), 2 ).toDouble();
778 bool reverseZoom = settings.
value( QStringLiteral(
"qgis/reverse_wheel_zoom" ),
false ).toBool();
779 bool zoomIn = reverseZoom ?
event->angleDelta().y() < 0 :
event->angleDelta().y() > 0;
782 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs(
event->angleDelta().y() );
784 if (
event->modifiers() & Qt::ControlModifier )
787 zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
791 double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
793 QRectF viewportRect = mPlotItem->plotArea();
795 if ( viewportRect.contains(
event->position() ) )
798 const double oldCenterX = 0.5 * ( mPlotItem->xMaximum() + mPlotItem->xMinimum() );
799 const double oldCenterY = 0.5 * ( mPlotItem->yMaximum() + mPlotItem->yMinimum() );
801 const double eventPosX = (
event->position().x() - viewportRect.left() ) / viewportRect.width() * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) + mPlotItem->xMinimum();
802 const double eventPosY = ( viewportRect.bottom() -
event->position().y() ) / viewportRect.height() * ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) + mPlotItem->yMinimum();
804 const double newCenterX = eventPosX + ( ( oldCenterX - eventPosX ) * scaleFactor );
805 const double newCenterY = eventPosY + ( ( oldCenterY - eventPosY ) * scaleFactor );
807 const double dxPlot = newCenterX - ( mPlotItem->xMaximum() + mPlotItem->xMinimum() ) * 0.5;
808 const double dyPlot = newCenterY - ( mPlotItem->yMaximum() + mPlotItem->yMinimum() ) * 0.5;
811 mPlotItem->setXMinimum( mPlotItem->xMinimum() + dxPlot );
812 mPlotItem->setXMaximum( mPlotItem->xMaximum() + dxPlot );
813 mPlotItem->setYMinimum( mPlotItem->yMinimum() + dyPlot );
814 mPlotItem->setYMaximum( mPlotItem->yMaximum() + dyPlot );
832 if ( e->isAccepted() )
834 mCrossHairsItem->hide();
839 if ( mCurrentJob && mSnappingEnabled && !plotPoint.
isEmpty() )
848 mCrossHairsItem->hide();
852 mCrossHairsItem->setPoint( plotPoint );
853 mCrossHairsItem->show();
860 return mPlotItem->plotArea();
880 const QList< QgsMapLayer * > layersToGenerate =
layers();
881 QList< QgsAbstractProfileSource * > sources;
883 sources.reserve( layersToGenerate.size() + registrySources.size() );
885 sources << registrySources;
889 sources.append( source );
897 generationContext.
setMaximumErrorMapUnits( MAX_ERROR_PIXELS * ( mProfileCurve->length() ) / mPlotItem->plotArea().width() );
902 mPlotItem->setRenderer( mCurrentJob );
909 mZoomFullWhenJobFinished =
true;
912void QgsElevationProfileCanvas::generationFinished()
919 if ( mZoomFullWhenJobFinished )
922 mZoomFullWhenJobFinished =
false;
931 mPlotItem->updatePlot();
934 if ( mForceRegenerationAfterCurrentJobCompletes )
936 mForceRegenerationAfterCurrentJobCompletes =
false;
938 scheduleDeferredRegeneration();
942void QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged()
945 if ( !mCurrentJob || mCurrentJob->
isActive() )
952 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
957 scheduleDeferredRegeneration();
962void QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged()
965 if ( !mCurrentJob || mCurrentJob->
isActive() )
972 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
978 if ( mPlotItem->redrawResults( layer->
id() ) )
979 scheduleDeferredRedraw();
983void QgsElevationProfileCanvas::regenerateResultsForLayer()
985 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( sender() ) )
990 scheduleDeferredRegeneration();
995void QgsElevationProfileCanvas::scheduleDeferredRegeneration()
997 if ( !mDeferredRegenerationScheduled )
999 mDeferredRegenerationTimer->start( 1 );
1000 mDeferredRegenerationScheduled =
true;
1004void QgsElevationProfileCanvas::scheduleDeferredRedraw()
1006 if ( !mDeferredRedrawScheduled )
1008 mDeferredRedrawTimer->start( 1 );
1009 mDeferredRedrawScheduled =
true;
1013void QgsElevationProfileCanvas::startDeferredRegeneration()
1015 if ( mCurrentJob && !mCurrentJob->
isActive() )
1020 else if ( mCurrentJob )
1022 mForceRegenerationAfterCurrentJobCompletes =
true;
1025 mDeferredRegenerationScheduled =
false;
1028void QgsElevationProfileCanvas::startDeferredRedraw()
1030 mPlotItem->update();
1031 mDeferredRedrawScheduled =
false;
1034void QgsElevationProfileCanvas::refineResults()
1040 const double plotDistanceRange = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor;
1041 const double plotElevationRange = mPlotItem->yMaximum() - mPlotItem->yMinimum();
1042 const double plotDistanceUnitsPerPixel = plotDistanceRange / mPlotItem->plotArea().width();
1046 const double targetMaxErrorInMapUnits = MAX_ERROR_PIXELS * plotDistanceUnitsPerPixel;
1047 const double factor = std::pow( 10.0, 1 - std::ceil( std::log10( std::fabs( targetMaxErrorInMapUnits ) ) ) );
1048 const double roundedErrorInMapUnits = std::floor( targetMaxErrorInMapUnits * factor ) / factor;
1056 mPlotItem->xMaximum() * mPlotItem->mXScaleFactor + plotDistanceRange * 0.05 ) );
1059 mPlotItem->yMaximum() + plotElevationRange * 0.05 ) );
1062 scheduleDeferredRegeneration();
1065void QgsElevationProfileCanvas::updateChartFromPalette()
1067 const QPalette chartPalette = palette();
1068 setBackgroundBrush( QBrush( chartPalette.color( QPalette::ColorRole::Base ) ) );
1071 textFormat.
setColor( chartPalette.color( QPalette::ColorGroup::Active, QPalette::Text ) );
1072 mPlotItem->xAxis().setTextFormat( textFormat );
1073 mPlotItem->yAxis().setTextFormat( textFormat );
1076 std::unique_ptr< QgsFillSymbol > chartFill( mPlotItem->chartBackgroundSymbol()->clone() );
1077 chartFill->setColor( chartPalette.color( QPalette::ColorGroup::Active, QPalette::ColorRole::Window ) );
1078 mPlotItem->setChartBackgroundSymbol( chartFill.release() );
1081 std::unique_ptr< QgsFillSymbol > chartBorder( mPlotItem->chartBorderSymbol()->clone() );
1082 chartBorder->setColor( chartPalette.color( QPalette::ColorGroup::Active, QPalette::ColorRole::Text ) );
1083 mPlotItem->setChartBorderSymbol( chartBorder.release() );
1086 std::unique_ptr< QgsLineSymbol > chartMajorSymbol( mPlotItem->xAxis().gridMajorSymbol()->clone() );
1087 QColor
c = chartPalette.color( QPalette::ColorGroup::Active, QPalette::ColorRole::Text );
1089 chartMajorSymbol->setColor(
c );
1090 mPlotItem->xAxis().setGridMajorSymbol( chartMajorSymbol->clone() );
1091 mPlotItem->yAxis().setGridMajorSymbol( chartMajorSymbol.release() );
1094 std::unique_ptr< QgsLineSymbol > chartMinorSymbol( mPlotItem->xAxis().gridMinorSymbol()->clone() );
1095 QColor
c = chartPalette.color( QPalette::ColorGroup::Active, QPalette::ColorRole::Text );
1097 chartMinorSymbol->setColor(
c );
1098 mPlotItem->xAxis().setGridMinorSymbol( chartMinorSymbol->clone() );
1099 mPlotItem->yAxis().setGridMinorSymbol( chartMinorSymbol.release() );
1101 mPlotItem->updatePlot();
1106 if ( !mPlotItem->plotArea().contains( point.x(), point.y() ) )
1109 return mPlotItem->canvasPointToPlotPoint( point );
1114 return mPlotItem->plotPointToCanvasPoint( point );
1120 mPlotItem->mProject = project;
1130 mProfileCurve.reset( curve );
1135 return mProfileCurve.get();
1150 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
1152 setupLayerConnections( layer,
true );
1156 auto filteredList =
layers;
1157 filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
1160 return !layer || !layer->isValid();
1161 } ), filteredList.end() );
1163 mLayers = _qgis_listRawToQPointer( filteredList );
1164 for (
QgsMapLayer *layer : std::as_const( mLayers ) )
1166 setupLayerConnections( layer,
false );
1172 return _qgis_listQPointerToRaw( mLayers );
1179 if ( mLockAxisScales )
1181 double xMinimum = mPlotItem->xMinimum();
1182 double xMaximum = mPlotItem->xMaximum();
1183 double yMinimum = mPlotItem->yMinimum();
1184 double yMaximum = mPlotItem->yMaximum();
1185 adjustRangeForAxisScaleLock( xMinimum, xMaximum, yMinimum, yMaximum );
1186 mPlotItem->setXMinimum( xMinimum );
1187 mPlotItem->setXMaximum( xMaximum );
1188 mPlotItem->setYMinimum( yMinimum );
1189 mPlotItem->setYMaximum( yMaximum );
1192 mPlotItem->updateRect();
1193 mCrossHairsItem->updateRect();
1198 QgsPlotCanvas::paintEvent(
event );
1200 if ( !mFirstDrawOccurred )
1203 mFirstDrawOccurred =
true;
1204 mPlotItem->updateRect();
1205 mCrossHairsItem->updateRect();
1211 if ( !mPlotItem->plotArea().contains( point.
x(), point.
y() ) )
1214 if ( !mProfileCurve )
1217 const double dx = point.
x() - mPlotItem->plotArea().left();
1219 const double distanceAlongPlotPercent = dx / mPlotItem->plotArea().width();
1220 double distanceAlongCurveLength = distanceAlongPlotPercent * ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor + mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
1222 std::unique_ptr< QgsPoint > mapXyPoint( mProfileCurve->interpolatePoint( distanceAlongCurveLength ) );
1226 const double mapZ = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / ( mPlotItem->plotArea().height() ) * ( mPlotItem->plotArea().bottom() - point.
y() ) + mPlotItem->yMinimum();
1228 return QgsPoint( mapXyPoint->x(), mapXyPoint->y(), mapZ );
1233 if ( !mProfileCurve )
1238 const double distanceAlongCurve =
geos.lineLocatePoint( point, &error );
1240 const double distanceAlongCurveOnPlot = distanceAlongCurve - mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
1241 const double distanceAlongCurvePercent = distanceAlongCurveOnPlot / ( ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor );
1242 const double distanceAlongPlotRect = distanceAlongCurvePercent * mPlotItem->plotArea().width();
1244 const double canvasX = mPlotItem->plotArea().left() + distanceAlongPlotRect;
1247 if ( std::isnan( point.
z() ) || point.
z() < mPlotItem->yMinimum() )
1249 canvasY = mPlotItem->plotArea().top();
1251 else if ( point.
z() > mPlotItem->yMaximum() )
1253 canvasY = mPlotItem->plotArea().bottom();
1257 const double yPercent = ( point.
z() - mPlotItem->yMinimum() ) / ( mPlotItem->yMaximum() - mPlotItem->yMinimum() );
1258 canvasY = mPlotItem->plotArea().bottom() - mPlotItem->plotArea().height() * yPercent;
1271 double yMinimum = 0;
1272 double yMaximum = 0;
1283 yMinimum = zRange.
lower() - 5;
1284 yMaximum = zRange.
lower() + 5;
1289 const double margin = ( zRange.
upper() - zRange.
lower() ) * 0.05;
1290 yMinimum = zRange.
lower() - margin;
1291 yMaximum = zRange.
upper() + margin;
1295 double xMinimum = 0;
1297 double xMaximum = profileLength * 1.02;
1299 if ( mLockAxisScales )
1301 adjustRangeForAxisScaleLock( xMinimum, xMaximum, yMinimum, yMaximum );
1304 mPlotItem->setXMinimum( xMinimum / mPlotItem->mXScaleFactor );
1305 mPlotItem->setXMaximum( xMaximum / mPlotItem->mXScaleFactor );
1306 mPlotItem->setYMinimum( yMinimum );
1307 mPlotItem->setYMaximum( yMaximum );
1310 mPlotItem->updatePlot();
1316 if ( mLockAxisScales )
1318 adjustRangeForAxisScaleLock( minimumDistance, maximumDistance, minimumElevation, maximumElevation );
1321 mPlotItem->setYMinimum( minimumElevation );
1322 mPlotItem->setYMaximum( maximumElevation );
1323 mPlotItem->setXMinimum( minimumDistance / mPlotItem->mXScaleFactor );
1324 mPlotItem->setXMaximum( maximumDistance / mPlotItem->mXScaleFactor );
1326 mPlotItem->updatePlot();
1332 return QgsDoubleRange( mPlotItem->xMinimum() * mPlotItem->mXScaleFactor, mPlotItem->xMaximum() * mPlotItem->mXScaleFactor );
1337 return QgsDoubleRange( mPlotItem->yMinimum(), mPlotItem->yMaximum() );
1346class QgsElevationProfilePlot :
public Qgs2DPlot
1351 : mRenderer( renderer )
1360 rc.
painter()->translate( plotArea.left(), plotArea.top() );
1361 mRenderer->render( rc, plotArea.width(), plotArea.height(), xMinimum() * mXScale,
xMaximum() * mXScale,
yMinimum(),
yMaximum() );
1362 rc.
painter()->translate( -plotArea.left(), -plotArea.top() );
1381 QgsElevationProfilePlot profilePlot( mCurrentJob );
1385 QDomElement elem = doc.createElement( QStringLiteral(
"plot" ) );
1387 plotSettings.
writeXml( elem, doc, rwContext );
1388 profilePlot.readXml( elem, rwContext );
1390 profilePlot.mXScale = mPlotItem->mXScaleFactor;
1391 profilePlot.xAxis().setLabelSuffix( mPlotItem->xAxis().labelSuffix() );
1392 profilePlot.xAxis().setLabelSuffixPlacement( mPlotItem->xAxis().labelSuffixPlacement() );
1394 profilePlot.setSize( QSizeF( width, height ) );
1395 profilePlot.render( context );
1405 return mCurrentJob->
identify( plotPoint, identifyContext() );
1416 double distance1 = topLeftPlotPoint.
distance();
1417 double distance2 = bottomRightPlotPoint.
distance();
1418 if ( distance2 < distance1 )
1419 std::swap( distance1, distance2 );
1421 double elevation1 = topLeftPlotPoint.
elevation();
1422 double elevation2 = bottomRightPlotPoint.
elevation();
1423 if ( elevation2 < elevation1 )
1424 std::swap( elevation1, elevation2 );
1433 mPlotItem->updatePlot();
1438 mSnappingEnabled = enabled;
@ FirstAndLastLabels
Place suffix after the first and last label values only.
DistanceUnit
Units of distance.
@ YardsBritishSears1922Truncated
British yards (Sears 1922 truncated)
@ MilesUSSurvey
US Survey miles.
@ LinksBritishSears1922
British links (Sears 1922)
@ YardsBritishBenoit1895A
British yards (Benoit 1895 A)
@ LinksBritishBenoit1895A
British links (Benoit 1895 A)
@ Centimeters
Centimeters.
@ YardsIndian1975
Indian yards (1975)
@ FeetUSSurvey
US Survey feet.
@ Millimeters
Millimeters.
@ FeetBritishSears1922
British feet (Sears 1922)
@ YardsClarkes
Clarke's yards.
@ YardsIndian
Indian yards.
@ FeetBritishBenoit1895B
British feet (Benoit 1895 B)
@ Miles
Terrestrial miles.
@ LinksUSSurvey
US Survey links.
@ ChainsUSSurvey
US Survey chains.
@ FeetClarkes
Clarke's feet.
@ Unknown
Unknown distance unit.
@ FeetBritish1936
British feet (1936)
@ FeetIndian1962
Indian feet (1962)
@ YardsBritishSears1922
British yards (Sears 1922)
@ FeetIndian1937
Indian feet (1937)
@ YardsIndian1937
Indian yards (1937)
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ ChainsBritishBenoit1895B
British chains (Benoit 1895 B)
@ LinksBritishSears1922Truncated
British links (Sears 1922 truncated)
@ ChainsBritishBenoit1895A
British chains (Benoit 1895 A)
@ YardsBritishBenoit1895B
British yards (Benoit 1895 B)
@ FeetBritish1865
British feet (1865)
@ YardsIndian1962
Indian yards (1962)
@ FeetBritishSears1922Truncated
British feet (Sears 1922 truncated)
@ MetersGermanLegal
German legal meter.
@ LinksBritishBenoit1895B
British links (Benoit 1895 B)
@ ChainsInternational
International chains.
@ LinksInternational
International links.
@ ChainsBritishSears1922Truncated
British chains (Sears 1922 truncated)
@ FeetIndian
Indian (geodetic) feet.
@ NauticalMiles
Nautical miles.
@ ChainsClarkes
Clarke's chains.
@ LinksClarkes
Clarke's links.
@ ChainsBritishSears1922
British chains (Sears 1922)
@ FeetIndian1975
Indian feet (1975)
@ FeetGoldCoast
Gold Coast feet.
@ FeetBritishBenoit1895A
British feet (Benoit 1895 A)
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
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.
QgsPlotAxis & xAxis()
Returns a reference to the plot's x 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.
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.
static QgsProfileSourceRegistry * profileSourceRegistry()
Returns registry of available profile source implementations.
This class represents a coordinate reference system (CRS).
Qgis::DistanceUnit mapUnits
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 setLockAxisScales(bool lock)
Sets whether the distance and elevation scales are locked to each other.
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.
void setDistanceUnit(Qgis::DistanceUnit unit)
Sets the distance unit used by the canvas.
QgsProfilePoint canvasPointToPlotPoint(QPointF point) const
Converts a canvas point to the equivalent plot point.
void setBackgroundColor(const QColor &color)
Sets the background color to use for the profile canvas.
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.
bool lockAxisScales() const
Returns true if the distance and elevation scales are locked to each other.
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...
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit used by the canvas.
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.
void dataChanged()
Data of layer changed.
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
Perform transforms between map coordinates and device coordinates.
A context for numeric formats.
void setLabelSuffixPlacement(Qgis::PlotAxisSuffixPlacement placement)
Sets the placement for the axis label suffixes.
void setLabelSuffix(const QString &suffix)
Sets the axis label suffix.
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.
QList< QgsAbstractProfileSource * > profileSources() const
Returns a list of registered profile sources.
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.
void setDevicePixelRatio(float ratio)
Sets the device pixel ratio.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
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.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static Q_INVOKABLE QString toAbbreviatedString(Qgis::DistanceUnit unit)
Returns a translated abbreviation representing a distance unit.
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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define BUILTIN_UNREACHABLE
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const QgsCoordinateReferenceSystem & crs