QGIS API Documentation 4.3.0-Master (0cfde48c85b)
Loading...
Searching...
No Matches
qgslayoutelevationprofilewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutelevationprofilewidget.cpp
3 ----------------------
4 begin : January 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgscurve.h"
23#include "qgsfillsymbol.h"
24#include "qgsgui.h"
25#include "qgslayertree.h"
27#include "qgslayout.h"
28#include "qgslayoutatlas.h"
31#include "qgslayoutitemwidget.h"
33#include "qgslinesymbol.h"
35#include "qgsplot.h"
36#include "qgsprofilerenderer.h"
38#include "qgsvectorlayer.h"
39
40#include <QMenu>
41#include <QString>
42
43#include "moc_qgslayoutelevationprofilewidget.cpp"
44
45using namespace Qt::StringLiterals;
46
48
50 : QgsLayoutItemBaseWidget( nullptr, profile )
51 , mProfile( profile )
52 , mLayerTree( new QgsLayerTree() )
53 , mLayerTreeBridge( new QgsLayerTreeRegistryBridge( mLayerTree.get(), mProfile->layout() ? mProfile->layout()->project() : QgsProject::instance(), this ) )
54{
55 Q_ASSERT( mProfile );
56
57 setupUi( this );
58 setPanelTitle( tr( "Elevation Profile Properties" ) );
59
60 mCopyFromDockMenu = new QMenu( this );
61 connect( mCopyFromDockMenu, &QMenu::aboutToShow, this, [this] { sBuildCopyMenuFunction( this, mCopyFromDockMenu ); } );
62
63 connect( mActionRefresh, &QAction::triggered, this, [this] {
64 if ( !mProfile )
65 {
66 return;
67 }
68 mProfile->invalidateCache();
69 mProfile->refresh();
70 } );
71
72 QToolButton *copyFromDockButton = new QToolButton();
73 copyFromDockButton->setAutoRaise( true );
74 copyFromDockButton->setToolTip( tr( "Copy From Profile" ) );
75 copyFromDockButton->setMenu( mCopyFromDockMenu );
76 copyFromDockButton->setPopupMode( QToolButton::InstantPopup );
77 copyFromDockButton->setIcon( QgsApplication::getThemeIcon( u"/mActionCopyProfileSettings.svg"_s ) );
78
79 mDockToolbar->addWidget( copyFromDockButton );
80
81 //add widget for general composer item properties
82 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, profile );
83 mainLayout->addWidget( mItemPropertiesWidget );
84
85 connect( mLayerTree.get(), &QgsLayerTree::layerOrderChanged, this, &QgsLayoutElevationProfileWidget::updateItemSources );
86 connect( mLayerTree.get(), &QgsLayerTreeGroup::visibilityChanged, this, &QgsLayoutElevationProfileWidget::updateItemSources );
87
88 mRangeMethodCombo->addItem( tr( "Manual Ranges" ), QVariant::fromValue( Qgis::ElevationProfileRangeMethod::ManualRange ) );
89 mRangeMethodCombo->addItem( tr( "Fixed Scales" ), QVariant::fromValue( Qgis::ElevationProfileRangeMethod::FixedScale ) );
90 mRangesStackedWidget->setSizeMode( QgsStackedWidget::SizeMode::CurrentPageOnly );
91 connect( mRangeMethodCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
92 if ( !mProfile || mBlockChanges )
93 return;
94
95 const Qgis::ElevationProfileRangeMethod method = mRangeMethodCombo->currentData().value< Qgis::ElevationProfileRangeMethod >();
96 switch ( method )
97 {
99 mRangesStackedWidget->setCurrentWidget( mPageManualRanges );
100 break;
101
103 mRangesStackedWidget->setCurrentWidget( mPageFixedScales );
104 break;
105 }
106
107 mProfile->beginCommand( tr( "Change Profile Range Method" ) );
108 mProfile->setRangeMethod( method );
109 mProfile->invalidateCache();
110 mProfile->update();
111 mProfile->endCommand();
112 } );
113
114 connect( mDistanceScaleWidget, &QgsScaleWidget::scaleChanged, this, [this]( double ) {
115 if ( !mProfile || mBlockChanges )
116 return;
117
118 mProfile->beginCommand( tr( "Change Distance Scale" ) );
119 mProfile->setDistanceScale( mDistanceScaleWidget->scale() );
120 mProfile->invalidateCache();
121 mProfile->update();
122 mProfile->endCommand();
123 } );
124
125 // the standard distance scales aren't so useful for elevation ranges!
126 mElevationScaleWidget->setPredefinedScales( { 5000, 2500, 1000, 500, 250, 100, 50, 10 } );
127 connect( mElevationScaleWidget, &QgsScaleWidget::scaleChanged, this, [this]( double ) {
128 if ( !mProfile || mBlockChanges )
129 return;
130
131 mProfile->beginCommand( tr( "Change Elevation Scale" ) );
132 mProfile->setElevationScale( mElevationScaleWidget->scale() );
133 mProfile->invalidateCache();
134 mProfile->update();
135 mProfile->endCommand();
136 } );
137
138 mSpinTolerance->setClearValue( 0 );
139 connect( mSpinTolerance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
140 if ( !mProfile || mBlockChanges )
141 return;
142
143 mProfile->beginCommand( tr( "Change Profile Tolerance Distance" ), QgsLayoutItem::UndoElevationProfileTolerance );
144 mProfile->setTolerance( value );
145 mProfile->invalidateCache();
146 mProfile->update();
147 mProfile->endCommand();
148 } );
149
150 connect( mCheckControlledByAtlas, &QCheckBox::toggled, this, [this] {
151 if ( !mProfile || mBlockChanges )
152 return;
153
154 mProfile->beginCommand( tr( "Change Profile Atlas Control" ) );
155 mProfile->setAtlasDriven( mCheckControlledByAtlas->isChecked() );
156 mProfile->invalidateCache();
157 mProfile->update();
158 mProfile->endCommand();
159 } );
160
161 // subsections indicator
162 mSubsectionsSymbolButton->setSymbolType( Qgis::SymbolType::Line );
163 connect( mSubsectionsSymbolButton, &QgsSymbolButton::changed, this, [this] {
164 if ( !mProfile || mBlockChanges )
165 return;
166
167 mProfile->beginCommand( tr( "Change Profile Subsection Indicator" ), QgsLayoutItem::UndoElevationProfileSubsectionLines );
168 mProfile->setSubsectionsSymbol( mSubsectionsSymbolButton->clonedSymbol<QgsLineSymbol>() );
169 mProfile->invalidateCache();
170 mProfile->update();
171 mProfile->endCommand();
172 } );
173 mSubsectionsSymbolButton->setDefaultSymbol( QgsProfilePlotRenderer::defaultSubSectionsSymbol().release() );
174
175 connect( mSubsectionsActivateCheck, &QGroupBox::toggled, this, [this] {
176 if ( !mProfile || mBlockChanges )
177 return;
178
179 const bool subsectionsActivated = mSubsectionsActivateCheck->isChecked();
180 mProfile->beginCommand( tr( "Change Profile Subsection Indicator" ), QgsLayoutItem::UndoElevationProfileSubsectionLines );
181 std::unique_ptr<QgsLineSymbol> subSectionsSymbol( subsectionsActivated ? mSubsectionsSymbolButton->clonedSymbol<QgsLineSymbol>() : nullptr );
182 mProfile->setSubsectionsSymbol( subSectionsSymbol.release() );
183
184 mProfile->invalidateCache();
185 mProfile->update();
186 mProfile->endCommand();
187 } );
188
189 mSpinMinDistance->setClearValue( 0 );
190 connect( mSpinMinDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
191 if ( !mProfile || mBlockChanges )
192 return;
193
194 mProfile->beginCommand( tr( "Change Profile Chart Minimum Distance" ), QgsLayoutItem::UndoElevationProfileMinimumDistance );
195 mProfile->plot()->setXMinimum( value );
196 mProfile->invalidateCache();
197 mProfile->update();
198 mProfile->endCommand();
199 } );
200
201 connect( mSpinMaxDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
202 if ( !mProfile || mBlockChanges )
203 return;
204
205 mProfile->beginCommand( tr( "Change Profile Chart Maximum Distance" ), QgsLayoutItem::UndoElevationProfileMaximumDistance );
206 mProfile->plot()->setXMaximum( value );
207 mProfile->invalidateCache();
208 mProfile->update();
209 mProfile->endCommand();
210 } );
211
212 mSpinMinElevation->setClearValue( 0 );
213 mSpinMinElevation2->setClearValue( 0 );
214 // we have two minimum elevation spins (on different pages of the range type stacked widget), keep these in sync
215 connect( mSpinMinElevation, qOverload<double>( &QDoubleSpinBox::valueChanged ), mSpinMinElevation2, &QDoubleSpinBox::setValue );
216 connect( mSpinMinElevation2, qOverload<double>( &QDoubleSpinBox::valueChanged ), mSpinMinElevation, &QDoubleSpinBox::setValue );
217
218 connect( mSpinMinElevation, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
219 if ( !mProfile || mBlockChanges )
220 return;
221
222 mProfile->beginCommand( tr( "Change Profile Chart Minimum Elevation" ), QgsLayoutItem::UndoElevationProfileMinimumElevation );
223 mProfile->plot()->setYMinimum( value );
224 mProfile->invalidateCache();
225 mProfile->update();
226 mProfile->endCommand();
227 } );
228
229 connect( mSpinMaxElevation, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
230 if ( !mProfile || mBlockChanges )
231 return;
232
233 mProfile->beginCommand( tr( "Change Profile Chart Maximum Elevation" ), QgsLayoutItem::UndoElevationProfileMaximumElevation );
234 mProfile->plot()->setYMaximum( value );
235 mProfile->invalidateCache();
236 mProfile->update();
237 mProfile->endCommand();
238 } );
239
240 mDistanceAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
241 connect( mDistanceAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
242 if ( !mProfile || mBlockChanges )
243 return;
244
245 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
246 mProfile->plot()->xAxis().setGridMajorSymbol( mDistanceAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
247 mProfile->invalidateCache();
248 mProfile->update();
249 mProfile->endCommand();
250 } );
251 mDistanceAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
252
253 mDistanceAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
254 connect( mDistanceAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
255 if ( !mProfile || mBlockChanges )
256 return;
257
258 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
259 mProfile->plot()->xAxis().setGridMinorSymbol( mDistanceAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
260 mProfile->invalidateCache();
261 mProfile->update();
262 mProfile->endCommand();
263 } );
264 mDistanceAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
265
266 connect( mDistanceAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
267 if ( !mProfile || mBlockChanges )
268 return;
269
270 mProfile->beginCommand( tr( "Change Profile Chart Distance Major Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMajorGridlines );
271 mProfile->plot()->xAxis().setGridIntervalMajor( value );
272 mProfile->invalidateCache();
273 mProfile->update();
274 mProfile->endCommand();
275 } );
276
277 connect( mDistanceAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
278 if ( !mProfile || mBlockChanges )
279 return;
280
281 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileDistanceMinorGridlines );
282 mProfile->plot()->xAxis().setGridIntervalMinor( value );
283 mProfile->invalidateCache();
284 mProfile->update();
285 mProfile->endCommand();
286 } );
287
288 connect( mDistanceAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
289 if ( !mProfile || mBlockChanges )
290 return;
291
292 mProfile->beginCommand( tr( "Change Profile Chart Distance Label" ), QgsLayoutItem::UndoElevationProfileDistanceLabels );
293 mProfile->plot()->xAxis().setLabelInterval( value );
294 mProfile->invalidateCache();
295 mProfile->update();
296 mProfile->endCommand();
297 } );
298
299 mElevationAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
300 connect( mElevationAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
301 if ( !mProfile || mBlockChanges )
302 return;
303
304 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
305 mProfile->plot()->yAxis().setGridMajorSymbol( mElevationAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
306 mProfile->invalidateCache();
307 mProfile->update();
308 mProfile->endCommand();
309 } );
310 mElevationAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
311
312 mElevationAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
313 connect( mElevationAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
314 if ( !mProfile || mBlockChanges )
315 return;
316
317 mProfile->beginCommand( tr( "Change Profile Chart Elevation Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
318 mProfile->plot()->yAxis().setGridMinorSymbol( mElevationAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
319 mProfile->invalidateCache();
320 mProfile->update();
321 mProfile->endCommand();
322 } );
323 mElevationAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
324
325 connect( mElevationAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
326 if ( !mProfile || mBlockChanges )
327 return;
328
329 mProfile->beginCommand( tr( "Change Profile Chart Elevation Label" ), QgsLayoutItem::UndoElevationProfileElevationLabels );
330 mProfile->plot()->yAxis().setLabelInterval( value );
331 mProfile->invalidateCache();
332 mProfile->update();
333 mProfile->endCommand();
334 } );
335
336 connect( mElevationAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
337 if ( !mProfile || mBlockChanges )
338 return;
339
340 mProfile->beginCommand( tr( "Change Profile Chart Elevation Major Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMajorGridlines );
341 mProfile->plot()->yAxis().setGridIntervalMajor( value );
342 mProfile->invalidateCache();
343 mProfile->update();
344 mProfile->endCommand();
345 } );
346
347 connect( mElevationAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
348 if ( !mProfile || mBlockChanges )
349 return;
350
351 mProfile->beginCommand( tr( "Change Profile Chart Distance Minor Gridlines" ), QgsLayoutItem::UndoElevationProfileElevationMinorGridlines );
352 mProfile->plot()->yAxis().setGridIntervalMinor( value );
353 mProfile->invalidateCache();
354 mProfile->update();
355 mProfile->endCommand();
356 } );
357
358 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
359 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [this] {
360 if ( !mProfile || mBlockChanges )
361 return;
362
363 mProfile->beginCommand( tr( "Change Profile Chart Background" ), QgsLayoutItem::UndoElevationProfileChartBackground );
364 mProfile->plot()->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
365 mProfile->invalidateCache();
366 mProfile->update();
367 mProfile->endCommand();
368 } );
369 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
370
371 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
372 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [this] {
373 if ( !mProfile || mBlockChanges )
374 return;
375
376 mProfile->beginCommand( tr( "Change Profile Chart Border" ), QgsLayoutItem::UndoElevationProfileChartBorder );
377 mProfile->plot()->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
378 mProfile->invalidateCache();
379 mProfile->update();
380 mProfile->endCommand();
381 } );
382 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
383
384 connect( mDistanceAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
385 if ( !mProfile || mBlockChanges )
386 return;
387
389 widget->setPanelTitle( tr( "Distance Number Format" ) );
390 widget->setFormat( mProfile->plot()->xAxis().numericFormat() );
391 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
392 mProfile->beginCommand( tr( "Change Profile Chart Distance Format" ), QgsLayoutItem::UndoElevationProfileDistanceFormat );
393 mProfile->plot()->xAxis().setNumericFormat( widget->format() );
394 mProfile->invalidateCache();
395 mProfile->endCommand();
396 mProfile->update();
397 } );
398 openPanel( widget );
399 } );
400
401 connect( mElevationAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
402 if ( !mProfile || mBlockChanges )
403 return;
404
406 widget->setPanelTitle( tr( "Elevation Number Format" ) );
407 widget->setFormat( mProfile->plot()->yAxis().numericFormat() );
408 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
409 mProfile->beginCommand( tr( "Change Profile Chart Elevation Format" ), QgsLayoutItem::UndoElevationProfileElevationFormat );
410 mProfile->plot()->yAxis().setNumericFormat( widget->format() );
411 mProfile->invalidateCache();
412 mProfile->endCommand();
413 mProfile->update();
414 } );
415 openPanel( widget );
416 } );
417
418 mDistanceAxisLabelFontButton->setDialogTitle( tr( "Distance Label Font" ) );
419 mElevationAxisLabelFontButton->setDialogTitle( tr( "Elevation Label Font" ) );
420 mDistanceAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
421 mElevationAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
422
423 connect( mDistanceAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
424 if ( !mProfile || mBlockChanges )
425 return;
426
427 mProfile->beginCommand( tr( "Change Profile Chart Distance Font" ), QgsLayoutItem::UndoElevationProfileDistanceFont );
428 mProfile->plot()->xAxis().setTextFormat( mDistanceAxisLabelFontButton->textFormat() );
429 mProfile->invalidateCache();
430 mProfile->endCommand();
431 mProfile->update();
432 } );
433
434 connect( mElevationAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
435 if ( !mProfile || mBlockChanges )
436 return;
437
438 mProfile->beginCommand( tr( "Change Profile Chart Elevation Font" ), QgsLayoutItem::UndoElevationProfileElevationFont );
439 mProfile->plot()->yAxis().setTextFormat( mElevationAxisLabelFontButton->textFormat() );
440 mProfile->invalidateCache();
441 mProfile->endCommand();
442 mProfile->update();
443 } );
444
445 mSpinLeftMargin->setClearValue( 0 );
446 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
447 if ( !mProfile || mBlockChanges )
448 return;
449
450 mProfile->beginCommand( tr( "Change Profile Chart Left Margin" ), QgsLayoutItem::UndoMarginLeft );
451 QgsMargins margins = mProfile->plot()->margins();
452 margins.setLeft( value );
453 mProfile->plot()->setMargins( margins );
454 mProfile->invalidateCache();
455 mProfile->update();
456 mProfile->endCommand();
457 } );
458
459 mSpinRightMargin->setClearValue( 0 );
460 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
461 if ( !mProfile || mBlockChanges )
462 return;
463
464 mProfile->beginCommand( tr( "Change Profile Chart Right Margin" ), QgsLayoutItem::UndoMarginRight );
465 QgsMargins margins = mProfile->plot()->margins();
466 margins.setRight( value );
467 mProfile->plot()->setMargins( margins );
468 mProfile->invalidateCache();
469 mProfile->update();
470 mProfile->endCommand();
471 } );
472
473 mSpinTopMargin->setClearValue( 0 );
474 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
475 if ( !mProfile || mBlockChanges )
476 return;
477
478 mProfile->beginCommand( tr( "Change Profile Chart Top Margin" ), QgsLayoutItem::UndoMarginTop );
479 QgsMargins margins = mProfile->plot()->margins();
480 margins.setTop( value );
481 mProfile->plot()->setMargins( margins );
482 mProfile->invalidateCache();
483 mProfile->update();
484 mProfile->endCommand();
485 } );
486
487 mSpinBottomMargin->setClearValue( 0 );
488 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
489 if ( !mProfile || mBlockChanges )
490 return;
491
492 mProfile->beginCommand( tr( "Change Profile Chart Bottom Margin" ), QgsLayoutItem::UndoMarginBottom );
493 QgsMargins margins = mProfile->plot()->margins();
494 margins.setBottom( value );
495 mProfile->plot()->setMargins( margins );
496 mProfile->invalidateCache();
497 mProfile->update();
498 mProfile->endCommand();
499 } );
500
501 for ( Qgis::DistanceUnit unit : {
512 } )
513 {
514 QString title;
516 {
518 }
519 else
520 {
521 title = QgsUnitTypes::toString( unit );
522 }
523 mDistanceUnitCombo->addItem( title, QVariant::fromValue( unit ) );
524 }
525
526 connect( mDistanceUnitCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
527 if ( !mProfile || mBlockChanges )
528 return;
529
530 mProfile->beginCommand( tr( "Change Profile Chart Units" ) );
531 mProfile->setDistanceUnit( mDistanceUnitCombo->currentData().value<Qgis::DistanceUnit>() );
532 mProfile->invalidateCache();
533 mProfile->update();
534 mProfile->endCommand();
535 } );
536
537 mDistanceLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
538 mDistanceLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
539 mDistanceLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
540 mDistanceLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
541 mDistanceLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
542 connect( mDistanceLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
543 if ( !mProfile || mBlockChanges )
544 return;
545
546 mProfile->beginCommand( tr( "Change Profile Chart Label Placement" ) );
547 mProfile->plot()->xAxis().setLabelSuffixPlacement( mDistanceLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
548 mProfile->invalidateCache();
549 mProfile->update();
550 mProfile->endCommand();
551 } );
552
553
569
570 mLayerTreeView = new QgsElevationProfileLayerTreeView( mLayerTree.get() );
571
572 QVBoxLayout *vl = new QVBoxLayout();
573 vl->setContentsMargins( 0, 0, 0, 0 );
574 vl->addWidget( mLayerTreeView );
575 mTreeViewContainer->setLayout( vl );
576
577 mBlockChanges++;
578 mLayerTreeView->populateInitialSources( mProfile->layout() && mProfile->layout()->project() ? mProfile->layout()->project() : QgsProject::instance() );
579 mBlockChanges--;
580
581 setGuiElementValues();
582 connect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
583
584 mSubsectionsSymbolButton->registerExpressionContextGenerator( mProfile );
585 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
586 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
587 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
588 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
589 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
590 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
591 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
592 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
593
594 mSubsectionsSymbolButton->setLayer( coverageLayer() );
595 mDistanceAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
596 mDistanceAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
597 mElevationAxisMajorLinesSymbolButton->setLayer( coverageLayer() );
598 mElevationAxisMinorLinesSymbolButton->setLayer( coverageLayer() );
599 mDistanceAxisLabelFontButton->setLayer( coverageLayer() );
600 mElevationAxisLabelFontButton->setLayer( coverageLayer() );
601 mChartBackgroundSymbolButton->setLayer( coverageLayer() );
602 mChartBorderSymbolButton->setLayer( coverageLayer() );
603
604 if ( mProfile->layout() )
605 {
606 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, this, [this]( QgsVectorLayer *layer ) {
607 mSubsectionsSymbolButton->setLayer( layer );
608 mDistanceAxisMajorLinesSymbolButton->setLayer( layer );
609 mDistanceAxisMinorLinesSymbolButton->setLayer( layer );
610 mElevationAxisMajorLinesSymbolButton->setLayer( layer );
611 mElevationAxisMinorLinesSymbolButton->setLayer( layer );
612 mDistanceAxisLabelFontButton->setLayer( layer );
613 mElevationAxisLabelFontButton->setLayer( layer );
614 mChartBackgroundSymbolButton->setLayer( layer );
615 mChartBorderSymbolButton->setLayer( layer );
616 } );
617
618 connect( &mProfile->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, this, &QgsLayoutElevationProfileWidget::atlasLayerChanged );
619 }
620
621 if ( QgsLayoutAtlas *atlas = layoutAtlas() )
622 {
623 connect( atlas, &QgsLayoutAtlas::toggled, this, &QgsLayoutElevationProfileWidget::layoutAtlasToggled );
624 layoutAtlasToggled( atlas->enabled() );
625 }
626}
627
629
631{
632 if ( mItemPropertiesWidget )
633 mItemPropertiesWidget->setMasterLayout( masterLayout );
634}
635
637{
638 QgsExpressionContext context = mProfile->createExpressionContext();
639
640 auto plotScope = std::make_unique<QgsExpressionContextScope>( u"plot"_s );
641 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( u"plot_axis"_s, QString(), true ) );
642 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( u"plot_axis_value"_s, 0.0, true ) );
643 context.appendScope( plotScope.release() );
644
645 return context;
646}
647
653
655{
656 mCheckControlledByAtlas->setText( tr( "Controlled by %1" ).arg( string == tr( "atlas" ) ? tr( "Atlas" ) : tr( "Report" ) ) );
657}
658
660{
661 mBlockChanges++;
662
663 mProfile->setCrs( canvas->crs() );
664
665 mSpinTolerance->setValue( canvas->tolerance() );
666 mProfile->setTolerance( canvas->tolerance() );
667
668 mProfile->setDistanceUnit( canvas->distanceUnit() );
669 mDistanceUnitCombo->setCurrentIndex( mDistanceUnitCombo->findData( QVariant::fromValue( canvas->distanceUnit() ) ) );
670
671 mProfile->plot()->xAxis().setLabelSuffixPlacement( canvas->plot().xAxis().labelSuffixPlacement() );
672 mDistanceLabelsCombo->setCurrentIndex( mDistanceLabelsCombo->findData( QVariant::fromValue( canvas->plot().xAxis().labelSuffixPlacement() ) ) );
673
674 if ( const QgsCurve *curve = canvas->profileCurve() )
675 mProfile->setProfileCurve( curve->clone() );
676
677 mSpinMinDistance->setValue( canvas->plot().xMinimum() );
678 mSpinMinDistance->setClearValue( canvas->plot().xMinimum() );
679 mProfile->plot()->setXMinimum( canvas->plot().xMinimum() );
680
681 mSpinMaxDistance->setValue( canvas->plot().xMaximum() );
682 mSpinMaxDistance->setClearValue( canvas->plot().xMaximum() );
683 mProfile->plot()->setXMaximum( canvas->plot().xMaximum() );
684
685 mDistanceAxisMajorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMajor() );
686 mDistanceAxisMajorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMajor() );
687 mProfile->plot()->xAxis().setGridIntervalMajor( canvas->plot().xAxis().gridIntervalMajor() );
688
689 mDistanceAxisMinorIntervalSpin->setValue( canvas->plot().xAxis().gridIntervalMinor() );
690 mDistanceAxisMinorIntervalSpin->setClearValue( canvas->plot().xAxis().gridIntervalMinor() );
691 mProfile->plot()->xAxis().setGridIntervalMinor( canvas->plot().xAxis().gridIntervalMinor() );
692
693 mDistanceAxisLabelIntervalSpin->setValue( canvas->plot().xAxis().labelInterval() );
694 mDistanceAxisLabelIntervalSpin->setClearValue( canvas->plot().xAxis().labelInterval() );
695 mProfile->plot()->xAxis().setLabelInterval( canvas->plot().xAxis().labelInterval() );
696
697 mSpinMinElevation->setValue( canvas->plot().yMinimum() );
698 mSpinMinElevation->setClearValue( canvas->plot().yMinimum() );
699 mProfile->plot()->setYMinimum( canvas->plot().yMinimum() );
700
701 mSpinMaxElevation->setValue( canvas->plot().yMaximum() );
702 mSpinMaxElevation->setClearValue( canvas->plot().yMaximum() );
703 mProfile->plot()->setYMaximum( canvas->plot().yMaximum() );
704
705 mElevationAxisMajorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMajor() );
706 mElevationAxisMajorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMajor() );
707 mProfile->plot()->yAxis().setGridIntervalMajor( canvas->plot().yAxis().gridIntervalMajor() );
708
709 mElevationAxisMinorIntervalSpin->setValue( canvas->plot().yAxis().gridIntervalMinor() );
710 mElevationAxisMinorIntervalSpin->setClearValue( canvas->plot().yAxis().gridIntervalMinor() );
711 mProfile->plot()->yAxis().setGridIntervalMinor( canvas->plot().yAxis().gridIntervalMinor() );
712
713 mElevationAxisLabelIntervalSpin->setValue( canvas->plot().yAxis().labelInterval() );
714 mElevationAxisLabelIntervalSpin->setClearValue( canvas->plot().yAxis().labelInterval() );
715 mProfile->plot()->yAxis().setLabelInterval( canvas->plot().yAxis().labelInterval() );
716
717 const QgsLineSymbol *subSectionsSymbol = canvas->subsectionsSymbol() ? canvas->subsectionsSymbol() : nullptr;
718 const bool subSectionsEnabled = static_cast< bool >( subSectionsSymbol );
719 mSubsectionsActivateCheck->setChecked( subSectionsEnabled );
720 if ( subSectionsSymbol )
721 {
722 mSubsectionsSymbolButton->setSymbol( subSectionsSymbol->clone() );
723 mProfile->setSubsectionsSymbol( subSectionsSymbol->clone() );
724 }
725
726 QList<QgsMapLayer *> canvasLayers = canvas->layers();
727 mProfile->setLayers( canvasLayers );
728
729 QList<QgsAbstractProfileSource *> canvasSources = canvas->sources();
730 mProfile->setSources( canvasSources );
731
732 syncLayerTreeAndProfileItemSources();
733
734 mProfile->invalidateCache();
735 mProfile->update();
736 mBlockChanges--;
737}
738
739void QgsLayoutElevationProfileWidget::syncLayerTreeAndProfileItemSources()
740{
741 // Update layer tree node visibility, based on layout item profile
742 const QList<QgsLayerTreeNode *> nodes = mLayerTree->findLayersAndCustomNodes();
743 for ( QgsLayerTreeNode *node : nodes )
744 {
745 QgsAbstractProfileSource *source = nullptr;
746 if ( QgsLayerTree::isLayer( node ) )
747 {
748 QgsLayerTreeLayer *layerNode = QgsLayerTree::toLayer( node );
749 QgsMapLayer *layer = layerNode->layer();
750 if ( !layer )
751 continue;
752
753 source = layer->profileSource();
754 }
755 else if ( QgsLayerTree::isCustomNode( node ) && node->customProperty( u"source"_s ) == QgsElevationProfileLayerTreeView::CUSTOM_NODE_ELEVATION_PROFILE_SOURCE )
756 {
757 QgsLayerTreeCustomNode *customNode = QgsLayerTree::toCustomNode( node );
758 source = QgsApplication::profileSourceRegistry()->findSourceById( customNode->id() );
759 }
760
761 if ( !source )
762 {
763 node->setItemVisibilityChecked( false );
764 }
765 else
766 {
767 node->setItemVisibilityChecked( mProfile->sources().contains( source ) );
768 }
769 }
770
771 // Update layer tree node ordering, based on layout item profile
772 QList< QgsLayerTreeNode * > orderedNodes;
773 const QList<QgsAbstractProfileSource *> profileSources = mProfile->sources();
774 for ( const QgsAbstractProfileSource *source : profileSources )
775 {
776 if ( QgsLayerTreeLayer *layerNode = mLayerTree->findLayer( source->profileSourceId() ) )
777 {
778 orderedNodes << layerNode;
779 }
780 else if ( QgsLayerTreeCustomNode *customNode = mLayerTree->findCustomNode( source->profileSourceId() ) )
781 {
782 orderedNodes << customNode;
783 }
784 }
785 mLayerTree->reorderGroupLayersAndCustomNodes( orderedNodes );
786}
787
789{
791 return false;
792
793 if ( mProfile )
794 {
795 disconnect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
796 }
797
798 mProfile = qobject_cast<QgsLayoutItemElevationProfile *>( item );
799 mItemPropertiesWidget->setItem( mProfile );
800
801 if ( mProfile )
802 {
803 connect( mProfile, &QgsLayoutObject::changed, this, &QgsLayoutElevationProfileWidget::setGuiElementValues );
804 mSubsectionsSymbolButton->registerExpressionContextGenerator( mProfile );
805 mDistanceAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
806 mDistanceAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
807 mElevationAxisMajorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
808 mElevationAxisMinorLinesSymbolButton->registerExpressionContextGenerator( mProfile );
809 mDistanceAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
810 mElevationAxisLabelFontButton->registerExpressionContextGenerator( mProfile );
811 mChartBackgroundSymbolButton->registerExpressionContextGenerator( mProfile );
812 mChartBorderSymbolButton->registerExpressionContextGenerator( mProfile );
813 }
814
815 setGuiElementValues();
816
817 return true;
818}
819
820void QgsLayoutElevationProfileWidget::setGuiElementValues()
821{
822 mBlockChanges++;
823
824 mSpinTolerance->setValue( mProfile->tolerance() );
825 mCheckControlledByAtlas->setChecked( mProfile->atlasDriven() );
826
827 mRangeMethodCombo->setCurrentIndex( mRangeMethodCombo->findData( QVariant::fromValue( mProfile->rangeMethod() ) ) );
828 switch ( mProfile->rangeMethod() )
829 {
831 mRangesStackedWidget->setCurrentWidget( mPageManualRanges );
832 break;
833
835 mRangesStackedWidget->setCurrentWidget( mPageFixedScales );
836 break;
837 }
838
839 mDistanceScaleWidget->setScale( mProfile->distanceScale() );
840 mElevationScaleWidget->setScale( mProfile->elevationScale() );
841
842 mSpinMinDistance->setValue( mProfile->plot()->xMinimum() );
843 mSpinMaxDistance->setValue( mProfile->plot()->xMaximum() );
844 mSpinMinElevation->setValue( mProfile->plot()->yMinimum() );
845 mSpinMaxElevation->setValue( mProfile->plot()->yMaximum() );
846
847 mSubsectionsActivateCheck->setChecked( mProfile->subsectionsSymbol() );
848 if ( mProfile->subsectionsSymbol() )
849 {
850 mSubsectionsSymbolButton->setSymbol( mProfile->subsectionsSymbol()->clone() );
851 }
852
853 if ( mProfile->plot()->xAxis().gridMajorSymbol() )
854 mDistanceAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMajorSymbol()->clone() );
855 if ( mProfile->plot()->xAxis().gridMinorSymbol() )
856 mDistanceAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMinorSymbol()->clone() );
857 if ( mProfile->plot()->yAxis().gridMajorSymbol() )
858 mElevationAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMajorSymbol()->clone() );
859 if ( mProfile->plot()->yAxis().gridMinorSymbol() )
860 mElevationAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMinorSymbol()->clone() );
861
862 mDistanceAxisLabelFontButton->setTextFormat( mProfile->plot()->xAxis().textFormat() );
863 mElevationAxisLabelFontButton->setTextFormat( mProfile->plot()->yAxis().textFormat() );
864
865 mDistanceUnitCombo->setCurrentIndex( mDistanceUnitCombo->findData( QVariant::fromValue( mProfile->distanceUnit() ) ) );
866 mDistanceLabelsCombo->setCurrentIndex( mDistanceLabelsCombo->findData( QVariant::fromValue( mProfile->plot()->xAxis().labelSuffixPlacement() ) ) );
867
868 mDistanceAxisMajorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMajor() );
869 mDistanceAxisMinorIntervalSpin->setValue( mProfile->plot()->xAxis().gridIntervalMinor() );
870 mDistanceAxisLabelIntervalSpin->setValue( mProfile->plot()->xAxis().labelInterval() );
871
872 mElevationAxisMajorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMajor() );
873 mElevationAxisMinorIntervalSpin->setValue( mProfile->plot()->yAxis().gridIntervalMinor() );
874 mElevationAxisLabelIntervalSpin->setValue( mProfile->plot()->yAxis().labelInterval() );
875
876 if ( mProfile->plot()->chartBackgroundSymbol() )
877 mChartBackgroundSymbolButton->setSymbol( mProfile->plot()->chartBackgroundSymbol()->clone() );
878 if ( mProfile->plot()->chartBorderSymbol() )
879 mChartBorderSymbolButton->setSymbol( mProfile->plot()->chartBorderSymbol()->clone() );
880
881 mSpinLeftMargin->setValue( mProfile->plot()->margins().left() );
882 mSpinRightMargin->setValue( mProfile->plot()->margins().right() );
883 mSpinTopMargin->setValue( mProfile->plot()->margins().top() );
884 mSpinBottomMargin->setValue( mProfile->plot()->margins().bottom() );
885
886 syncLayerTreeAndProfileItemSources();
887
888 updateDataDefinedButton( mDDBtnTolerance );
889 updateDataDefinedButton( mDDBtnMinDistance );
890 updateDataDefinedButton( mDDBtnMaxDistance );
891 updateDataDefinedButton( mDDBtnMinElevation );
892 updateDataDefinedButton( mDDBtnMaxElevation );
893 updateDataDefinedButton( mDDBtnDistanceMajorInterval );
894 updateDataDefinedButton( mDDBtnDistanceMinorInterval );
895 updateDataDefinedButton( mDDBtnDistanceLabelInterval );
896 updateDataDefinedButton( mDDBtnElevationMajorInterval );
897 updateDataDefinedButton( mDDBtnElevationMinorInterval );
898 updateDataDefinedButton( mDDBtnElevationLabelInterval );
899 updateDataDefinedButton( mDDBtnLeftMargin );
900 updateDataDefinedButton( mDDBtnRightMargin );
901 updateDataDefinedButton( mDDBtnTopMargin );
902 updateDataDefinedButton( mDDBtnBottomMargin );
903
904 mBlockChanges--;
905}
906
907void QgsLayoutElevationProfileWidget::updateItemSources()
908{
909 if ( mBlockChanges )
910 return;
911
912 QList<QgsMapLayer *> layers;
913 QList<QgsAbstractProfileSource *> sources;
914 const QList<QgsLayerTreeNode *> layerAndCustomNodeOrder = mLayerTree->layerAndCustomNodeOrder();
915 for ( QgsLayerTreeNode *node : layerAndCustomNodeOrder )
916 {
917 if ( QgsLayerTree::isLayer( node ) )
918 {
919 QgsMapLayer *layer = QgsLayerTree::toLayer( node )->layer();
920 if ( mLayerTree->findLayer( layer )->isVisible() )
921 {
922 layers << layer;
923 sources << layer->profileSource();
924 }
925 }
926 else if ( QgsLayerTree::isCustomNode( node ) && node->customProperty( u"source"_s ) == QgsElevationProfileLayerTreeView::CUSTOM_NODE_ELEVATION_PROFILE_SOURCE )
927 {
928 QgsLayerTreeCustomNode *customNode = QgsLayerTree::toCustomNode( node );
929 if ( mLayerTree->findCustomNode( customNode->id() )->isVisible() )
930 {
931 if ( QgsAbstractProfileSource *customSource = QgsApplication::profileSourceRegistry()->findSourceById( customNode->id() ) )
932 {
933 sources << customSource;
934 }
935 }
936 }
937 }
938
939 // Legacy: layer tree layers are in opposite direction to what the elevation profile requires
940 std::reverse( layers.begin(), layers.end() );
941 mProfile->setLayers( layers );
942
943 mProfile->setSources( sources );
944 mProfile->update();
945}
946
947void QgsLayoutElevationProfileWidget::layoutAtlasToggled( bool atlasEnabled )
948{
949 if ( atlasEnabled && mProfile && mProfile->layout() && mProfile->layout()->reportContext().layer() && mProfile->layout()->reportContext().layer()->geometryType() == Qgis::GeometryType::Line )
950 {
951 mCheckControlledByAtlas->setEnabled( true );
952 }
953 else
954 {
955 mCheckControlledByAtlas->setEnabled( false );
956 mCheckControlledByAtlas->setChecked( false );
957 }
958}
959
960void QgsLayoutElevationProfileWidget::atlasLayerChanged( QgsVectorLayer *layer )
961{
962 if ( !layer || layer->geometryType() != Qgis::GeometryType::Line )
963 {
964 //non-line layer, disable atlas control
965 mCheckControlledByAtlas->setChecked( false );
966 mCheckControlledByAtlas->setEnabled( false );
967 return;
968 }
969 else
970 {
971 mCheckControlledByAtlas->setEnabled( true );
972 }
973}
PlotAxisSuffixPlacement
Placement options for suffixes in the labels for axis of plots.
Definition qgis.h:3556
@ FirstAndLastLabels
Place suffix after the first and last label values only.
Definition qgis.h:3561
@ EveryLabel
Place suffix after every value label.
Definition qgis.h:3558
@ FirstLabel
Place suffix after the first label value only.
Definition qgis.h:3559
@ LastLabel
Place suffix after the last label value only.
Definition qgis.h:3560
@ NoLabels
Do not place suffixes.
Definition qgis.h:3557
DistanceUnit
Units of distance.
Definition qgis.h:5568
@ Feet
Imperial feet.
Definition qgis.h:5571
@ Centimeters
Centimeters.
Definition qgis.h:5576
@ Millimeters
Millimeters.
Definition qgis.h:5577
@ Miles
Terrestrial miles.
Definition qgis.h:5574
@ Meters
Meters.
Definition qgis.h:5569
@ Yards
Imperial yards.
Definition qgis.h:5573
@ Degrees
Degrees, for planar geographic CRS distance measurements.
Definition qgis.h:5575
@ Inches
Inches.
Definition qgis.h:5578
@ NauticalMiles
Nautical miles.
Definition qgis.h:5572
@ Kilometers
Kilometers.
Definition qgis.h:5570
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
Definition qgis.h:3633
@ Line
Lines.
Definition qgis.h:401
@ Line
Line symbol.
Definition qgis.h:673
@ Fill
Fill symbol.
Definition qgis.h:674
ElevationProfileRangeMethod
Elevation profile range calculation methods.
Definition qgis.h:6165
@ ManualRange
Distance/elevation ranges are manually set.
Definition qgis.h:6166
@ FixedScale
Distance and elevation ranges are calculated from fixed scales.
Definition qgis.h:6167
double yMaximum() const
Returns the maximum value of the y axis.
Definition qgsplot.h:769
double xMinimum() const
Returns the minimum value of the x axis.
Definition qgsplot.h:727
QgsPlotAxis & yAxis()
Returns a reference to the plot's y axis.
Definition qgsplot.h:797
QgsPlotAxis & xAxis()
Returns a reference to the plot's x axis.
Definition qgsplot.h:783
double yMinimum() const
Returns the minimum value of the y axis.
Definition qgsplot.h:741
double xMaximum() const
Returns the maximum value of the x axis.
Definition qgsplot.h:755
Interface for classes which can generate elevation profiles.
virtual QString profileSourceId() const
Returns a unique identifier for this profile source.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsProfileSourceRegistry * profileSourceRegistry()
Returns registry of available profile source implementations.
Abstract base class for curved geometry type.
Definition qgscurve.h:36
A canvas for elevation profiles.
QgsCurve * profileCurve() const
Returns the profile curve.
QgsCoordinateReferenceSystem crs() const override
Returns the coordinate reference system (CRS) for map coordinates used by the canvas.
const Qgs2DXyPlot & plot() const
Returns a reference to the 2D plot used by the widget.
QList< QgsMapLayer * > layers() const
Returns the list of layers included in the profile.
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit used by the canvas.
double tolerance() const
Returns the tolerance of the profile (in crs() units).
QList< QgsAbstractProfileSource * > sources() const
Returns the list of sources included in the profile.
QgsLineSymbol * subsectionsSymbol()
Returns the symbol used to draw the subsections.
A layer tree view for elevation profiles.
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.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
void changed()
Emitted when the widget's text format settings are changed.
@ HigDialogTitleIsTitleCase
Dialog titles should be title case.
Definition qgsgui.h:284
static QgsGui::HigFlags higFlags()
Returns the platform's HIG flags.
Definition qgsgui.cpp:254
QString id() const override
Returns the node's unique identifier.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Base class for nodes in a layer tree.
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
Listens to layer changes from a QgsProject and applies changes to a QgsLayerTree.
Namespace with helper functions for layer tree operations.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
void layerOrderChanged()
Emitted when the layer order has changed.
static bool isCustomNode(const QgsLayerTreeNode *node)
Check whether the node is a valid custom node.
static QgsLayerTreeCustomNode * toCustomNode(QgsLayerTreeNode *node)
Cast node to a custom node.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
void toggled(bool enabled)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
A widget for layout elevation profile item settings.
void setReportTypeString(const QString &string) override
Sets the string to use to describe the current report type (e.g.
void copySettingsFromProfileCanvas(QgsElevationProfileCanvas *canvas)
Copies selected settings from a elevation profile canvas.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
static std::function< void(QgsLayoutElevationProfileWidget *, QMenu *)> sBuildCopyMenuFunction
QgsLayoutElevationProfileWidget(QgsLayoutItemElevationProfile *profile)
constructor
void setDesignerInterface(QgsLayoutDesignerInterface *iface) override
Sets the the layout designer interface in which the widget is being shown.
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Updates a previously registered data defined button to reflect the item's current properties.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsLayoutObject::DataDefinedProperty property)
Registers a data defined button, setting up its initial value, connections and description.
virtual void setDesignerInterface(QgsLayoutDesignerInterface *iface)
Sets the the layout designer interface in which the widget is being shown.
QgsLayoutAtlas * layoutAtlas() const
Returns the atlas for the layout (if available).
QgsLayoutItemBaseWidget(QWidget *parent SIP_TRANSFERTHIS, QgsLayoutObject *layoutObject)
Constructor for QgsLayoutItemBaseWidget, linked with the specified layoutObject.
A layout item subclass for elevation profile plots.
A widget for controlling the common properties of layout items (e.g.
@ LayoutElevationProfile
Elevation profile item.
Base class for graphical items within a QgsLayout.
@ UndoElevationProfileElevationMajorGridlines
Change elevation profile elevation axis major gridlines.
@ UndoElevationProfileMaximumDistance
Change elevation profile maximum distance.
@ UndoElevationProfileChartBackground
Change elevation profile chart background.
@ UndoElevationProfileDistanceMinorGridlines
Change elevation profile distance axis minor gridlines.
@ UndoMarginTop
Top margin.
@ UndoElevationProfileChartBorder
Change elevation profile chart border.
@ UndoElevationProfileMaximumElevation
Change elevation profile maximum elevation.
@ UndoMarginLeft
Left margin.
@ UndoMarginRight
Right margin.
@ UndoElevationProfileTolerance
Change elevation profile distance tolerance.
@ UndoElevationProfileElevationFormat
Change elevation profile elevation axis number format.
@ UndoElevationProfileMinimumElevation
Change elevation profile minimum elevation.
@ UndoElevationProfileDistanceLabels
Change elevation profile distance axis label interval.
@ UndoMarginBottom
Bottom margin.
@ UndoElevationProfileElevationFont
Change elevation profile elevation axis number font.
@ UndoElevationProfileDistanceFormat
Change elevation profile distance axis number format.
@ UndoElevationProfileElevationMinorGridlines
Change elevation profile elevation axis minor gridlines.
@ UndoElevationProfileDistanceFont
Change elevation profile distance axis number font.
@ UndoElevationProfileElevationLabels
Change elevation profile elevation axis label interval.
@ UndoElevationProfileDistanceMajorGridlines
Change elevation profile distance axis major gridlines.
@ UndoElevationProfileMinimumDistance
Change elevation profile minimum distance.
@ UndoElevationProfileSubsectionLines
Change elevation profile subsection indicator symbol.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
@ ElevationProfileMaximumDistance
Maximum distance value for elevation profile.
@ ElevationProfileElevationMinorInterval
Minor grid line interval for elevation profile elevation axis.
@ ElevationProfileDistanceMinorInterval
Minor grid line interval for elevation profile distance axis.
@ ElevationProfileMinimumDistance
Minimum distance value for elevation profile.
@ ElevationProfileMaximumElevation
Maximum elevation value for elevation profile.
@ ElevationProfileDistanceLabelInterval
Label interval for elevation profile distance axis.
@ ElevationProfileTolerance
Tolerance distance for elevation profiles.
@ ElevationProfileMinimumElevation
Minimum elevation value for elevation profile.
@ ElevationProfileElevationLabelInterval
Label interval for elevation profile elevation axis.
@ ElevationProfileDistanceMajorInterval
Major grid line interval for elevation profile distance axis.
@ ElevationProfileElevationMajorInterval
Major grid line interval for elevation profile elevation axis.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Base class for all map layer types.
Definition qgsmaplayer.h:83
virtual QgsAbstractProfileSource * profileSource()
Returns the layer's profile source if it has profile capabilities.
Defines the four margins of a rectangle.
Definition qgsmargins.h:40
void setBottom(double bottom)
Sets the bottom margin to bottom.
Definition qgsmargins.h:112
void setLeft(double left)
Sets the left margin to left.
Definition qgsmargins.h:94
void setRight(double right)
Sets the right margin to right.
Definition qgsmargins.h:106
void setTop(double top)
Sets the top margin to top.
Definition qgsmargins.h:100
Interface for master layout type objects, such as print layouts and reports.
A widget which allows choice of numeric formats and the properties of them.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
void changed()
Emitted whenever the format configured55 in the widget is changed.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
double gridIntervalMinor() const
Returns the interval of minor grid lines for the axis.
Definition qgsplot.h:389
double gridIntervalMajor() const
Returns the interval of major grid lines for the axis.
Definition qgsplot.h:403
double labelInterval() const
Returns the interval of labels for the axis.
Definition qgsplot.h:417
Qgis::PlotAxisSuffixPlacement labelSuffixPlacement() const
Returns the placement for the axis label suffixes.
Definition qgsplot.cpp:205
static QgsFillSymbol * chartBorderSymbol()
Returns the default fill symbol to use for the chart area border.
Definition qgsplot.cpp:1407
static QgsLineSymbol * axisGridMinorSymbol()
Returns the default line symbol to use for axis minor grid lines.
Definition qgsplot.cpp:1394
static QgsFillSymbol * chartBackgroundSymbol()
Returns the default fill symbol to use for the chart area background fill.
Definition qgsplot.cpp:1401
static QgsLineSymbol * axisGridMajorSymbol()
Returns the default line symbol to use for axis major grid lines.
Definition qgsplot.cpp:1387
static std::unique_ptr< QgsLineSymbol > defaultSubSectionsSymbol()
Returns the default line symbol to use for subsections lines.
QgsAbstractProfileSource * findSourceById(const QString &sourceId) const
Finds a registered profile source by id.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:114
static QgsProject * instance()
Returns the QgsProject singleton instance.
void scaleChanged(double scale)
Emitted when user has finished editing/selecting a new scale.
@ CurrentPageOnly
Only the size of the current page is considered when calculating the stacked widget size.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
void changed()
Emitted when the symbol's settings are changed.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Single variable definition for use within a QgsExpressionContextScope.