QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
Loading...
Searching...
No Matches
qgspointcloudlayersaveasdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudlayersaveasdialog.h
3 Dialog to select destination, type and crs to save as pointcloud layers
4 -------------------
5 begin : July 2022
6 copyright : (C) 2022 by Stefanos Natsis
7 email : uclaros at gmail dot com
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include <QMessageBox>
20#include <QRegularExpression>
21
23#include "moc_qgspointcloudlayersaveasdialog.cpp"
24#include "qgsgui.h"
25#include "qgsmapcanvas.h"
26#include "qgsdatums.h"
27#include "qgsproviderregistry.h"
29#include "qgspointcloudlayer.h"
30#include "qgsmaplayerutils.h"
31#include "qgsvectorlayer.h"
32
34 : QDialog( parent, fl )
35 , mLayer( layer )
36 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
37{
38 if ( layer )
39 {
40 mSelectedCrs = layer->crs();
41 mLayerExtent = layer->extent();
42 }
43 setup();
44}
45
46void QgsPointCloudLayerSaveAsDialog::setup()
47{
48 setupUi( this );
50
51 connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
52 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged );
53 connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked );
54 connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked );
55 connect( mFilterGeometryLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged );
56 connect( mFilterGeometryGroupBox, &QgsCollapsibleGroupBox::toggled, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled );
57 connect( mMinimumZSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged );
58 connect( mMaximumZSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged );
59
60#ifdef Q_OS_WIN
61 mHelpButtonBox->setVisible( false );
62 mButtonBox->addButton( QDialogButtonBox::Help );
63 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
64#else
65 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
66#endif
67 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsPointCloudLayerSaveAsDialog::accept );
68 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsPointCloudLayerSaveAsDialog::reject );
69
70 mFormatComboBox->blockSignals( true );
71 const QList< QgsPointCloudLayerExporter::ExportFormat > supportedFormats = QgsPointCloudLayerExporter::supportedFormats();
72 for ( const auto &format : supportedFormats )
73 mFormatComboBox->addItem( getTranslatedNameForFormat( format ), static_cast< int >( format ) );
74
75 QgsSettings settings;
76 const int defaultFormat = settings.value( QStringLiteral( "UI/lastPointCloudFormat" ), 0 ).toInt();
77 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( defaultFormat ) );
78 mFormatComboBox->blockSignals( false );
79 mFormatComboBox_currentIndexChanged( 0 );
80
81 mCrsSelector->setCrs( mSelectedCrs );
82 mCrsSelector->setLayerCrs( mSelectedCrs );
83 mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
84 "The data points will be transformed from the layer coordinate reference system." ) );
85
86
87 // attributes
88 if ( mLayer )
89 {
90 const auto attributes = mLayer->attributes();
91 QStringList availableAttributes;
92 for ( int i = 0; i < attributes.count(); ++i )
93 {
94 const QString attribute = attributes.at( i ).name();
95 if ( attribute.compare( QLatin1String( "X" ), Qt::CaseInsensitive ) &&
96 attribute.compare( QLatin1String( "Y" ), Qt::CaseInsensitive ) &&
97 attribute.compare( QLatin1String( "Z" ), Qt::CaseInsensitive ) )
98 {
99 availableAttributes.append( attribute );
100 }
101 }
102
103 mAttributeTable->setRowCount( availableAttributes.count() );
104 QStringList horizontalHeaders = QStringList() << tr( "Attribute" );
105 mAttributeTable->setColumnCount( horizontalHeaders.size() );
106 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
107
108 for ( int i = 0; i < availableAttributes.count(); ++i )
109 {
110 QTableWidgetItem *item = new QTableWidgetItem( availableAttributes.at( i ) );
111 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
112 item->setCheckState( Qt::Checked );
113 mAttributeTable->setItem( i, 0, item );
114 }
115 mAttributeTable->resizeColumnsToContents();
116 }
117
118 // extent group box
119 mExtentGroupBox->setOutputCrs( mSelectedCrs );
120 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
121 mExtentGroupBox->setOutputExtentFromOriginal();
122 mExtentGroupBox->setCheckable( true );
123 mExtentGroupBox->setChecked( false );
124 mExtentGroupBox->setCollapsed( true );
125
126 // polygon layer filter group box
127 mFilterGeometryLayerComboBox->setFilters( Qgis::LayerFilter::PolygonLayer );
128
129 // ZRange group box
130 mMinimumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
131 mMaximumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
132 if ( mLayer )
133 {
134 mMinimumZSpinBox->setValue( mLayer->statistics().minimum( QStringLiteral( "Z" ) ) );
135 mMinimumZSpinBox->setClearValue( mMinimumZSpinBox->value() );
136 mMaximumZSpinBox->setValue( mLayer->statistics().maximum( QStringLiteral( "Z" ) ) );
137 mMaximumZSpinBox->setClearValue( mMaximumZSpinBox->value() );
138 }
139
140 // points limit group box
141 mPointsLimitSpinBox->setMinimum( 1 );
142 mPointsLimitSpinBox->setMaximum( std::numeric_limits<int>::max() );
143 mPointsLimitSpinBox->setValue( 1e6 );
144 mPointsLimitSpinBox->setClearValue( 1e6 );
145
146 mFilename->setStorageMode( QgsFileWidget::SaveFile );
147 mFilename->setDialogTitle( tr( "Save Layer As" ) );
148 mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastPointCloudFileFilterDir" ), QDir::homePath() ).toString() );
149 mFilename->setConfirmOverwrite( false );
150 connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
151 {
152 QgsSettings settings;
153 if ( !filePath.isEmpty() )
154 mLastUsedFilename = filePath;
155
156 const QFileInfo fileInfo( filePath );
157 settings.setValue( QStringLiteral( "UI/lastPointCloudFileFilterDir" ), fileInfo.absolutePath() );
158 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
159 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
160 {
161 leLayername->setDefaultValue( suggestedLayerName );
162 }
163
164 // if no layer name set, then automatically match the output layer name to the file name
165 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
166 {
167 leLayername->setText( suggestedLayerName );
168 }
169 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
170 } );
171
172 try
173 {
174 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
175 if ( ensemble.isValid() )
176 {
177 mCrsSelector->setSourceEnsemble( ensemble.name() );
178 }
179 }
180 catch ( QgsNotSupportedException & )
181 {
182 }
183
184 mCrsSelector->setShowAccuracyWarnings( true );
185
186 mAddToCanvas->setEnabled( exportFormat() != QgsPointCloudLayerExporter::ExportFormat::Memory );
187
188 if ( mLayer )
189 {
190 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( mLayer->name() );
191 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
192 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
193 if ( leLayername->isEnabled() )
194 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
195 }
196
197 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( exportFormat() == QgsPointCloudLayerExporter::ExportFormat::Memory ||
198 !mFilename->filePath().isEmpty() );
199}
200
201void QgsPointCloudLayerSaveAsDialog::accept()
202{
203 if ( QFile::exists( filename() ) )
204 {
208 layername() );
209 QMessageBox msgBox;
210 msgBox.setIcon( QMessageBox::Question );
211 msgBox.setWindowTitle( tr( "Save Point Cloud Layer As" ) );
212 QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
213 QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
214 QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
215 msgBox.setStandardButtons( QMessageBox::Cancel );
216 msgBox.setDefaultButton( QMessageBox::Cancel );
217 overwriteFileButton->hide();
218 overwriteLayerButton->hide();
219 appendToLayerButton->hide();
220 if ( layerExists )
221 {
225 {
226 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
227 overwriteFileButton->setVisible( true );
228 overwriteLayerButton->setVisible( true );
229 }
231 {
232 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
233 overwriteFileButton->setVisible( true );
234 }
235 else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
237 {
238 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
239 appendToLayerButton->setVisible( true );
240 overwriteFileButton->setVisible( true );
241 overwriteLayerButton->setVisible( true );
242 }
243 else
244 {
245 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
246 appendToLayerButton->setVisible( true );
247 overwriteFileButton->setVisible( true );
248 }
249
250 int ret = msgBox.exec();
251 if ( ret == QMessageBox::Cancel )
252 return;
253 if ( msgBox.clickedButton() == overwriteFileButton )
254 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
255 else if ( msgBox.clickedButton() == overwriteLayerButton )
256 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
257 else if ( msgBox.clickedButton() == appendToLayerButton )
258 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
259 }
260 else // !layerExists
261 {
263 {
264 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
265 }
266 else
267 {
268 // should not reach here, layer does not exist and cannot add new layer
269 if ( QMessageBox::question( this,
270 tr( "Save Point Cloud Layer As" ),
271 tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
272 {
273 return;
274 }
275 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
276 }
277 }
278 }
279 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
280 {
281 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
282 QStringList layerList;
283 layerList.reserve( sublayers.size() );
284 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
285 {
286 layerList.append( sublayer.name() );
287 }
288 if ( layerList.length() > 1 )
289 {
290 layerList.sort( Qt::CaseInsensitive );
291 QMessageBox msgBox;
292 msgBox.setIcon( QMessageBox::Warning );
293 msgBox.setWindowTitle( tr( "Overwrite File" ) );
294 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
295 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
296 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
297 if ( msgBox.exec() == QMessageBox::Cancel )
298 return;
299 }
300 }
301
302 QgsSettings settings;
303 settings.setValue( QStringLiteral( "UI/lastPointCloudFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
304 settings.setValue( QStringLiteral( "UI/lastPointCloudFormat" ), static_cast< int >( exportFormat() ) );
305 QDialog::accept();
306}
307
308void QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
309{
310 Q_UNUSED( idx )
311
313
314 switch ( format )
315 {
320 mAttributesSelection->setEnabled( true );
321 break;
322
325 mAttributesSelection->setEnabled( false );
326 break;
327 }
328
329 switch ( format )
330 {
333 leLayername->setEnabled( true );
334 break;
335 \
340 leLayername->setEnabled( false );
341 break;
342 }
343
344 switch ( format )
345 {
347 mWasAddToCanvasForced = !mAddToCanvas->isChecked();
348 mAddToCanvas->setEnabled( false );
349 mAddToCanvas->setChecked( true );
350 mFilename->setEnabled( false );
351 break;
352
358 mAddToCanvas->setEnabled( true );
359 if ( mWasAddToCanvasForced )
360 {
361 mAddToCanvas->setChecked( !mAddToCanvas->isChecked() );
362 mWasAddToCanvasForced = false;
363 }
364 mFilename->setEnabled( true );
365 break;
366 }
367
368 if ( mFilename->isEnabled() )
369 {
370 mFilename->setFilter( getFilterForFormat( format ) );
371
372 // if output filename already defined we need to replace old suffix
373 // to avoid double extensions like .gpkg.shp
374 if ( !mLastUsedFilename.isEmpty() )
375 {
376 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
377 QString ext;
378 ext = rx.match( getFilterForFormat( format ) ).captured( 1 );
379 if ( !ext.isEmpty() )
380 {
381 QFileInfo fi( mLastUsedFilename );
382 mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
383 }
384 }
385 }
386
387 if ( !mFilename->isEnabled() )
388 mFilename->setFilePath( QString() );
389
390 if ( !leLayername->isEnabled() )
391 {
392 leLayername->setText( QString() );
393 }
394 else if ( leLayername->text().isEmpty() )
395 {
396 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
397 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
398 {
399 layerName = QFileInfo( mFilename->filePath() ).baseName();
400 leLayername->setDefaultValue( layerName );
401 }
402 if ( layerName.isEmpty() )
403 {
404 layerName = tr( "new_layer" );
405 }
406 leLayername->setText( layerName );
407 }
408
409 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( format == QgsPointCloudLayerExporter::ExportFormat::Memory ||
410 !mFilename->filePath().isEmpty() );
411}
412
413void QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled( bool checked )
414{
415 if ( checked )
416 mFilterGeometryLayerChanged( mFilterGeometryLayerComboBox->currentLayer() );
417}
418
419void QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged( QgsMapLayer *layer )
420{
421 QgsVectorLayer *vlayer = dynamic_cast< QgsVectorLayer * >( layer );
422 mSelectedFeaturesCheckBox->setChecked( false );
423 mSelectedFeaturesCheckBox->setEnabled( hasFilterLayer() && vlayer && vlayer->selectedFeatureCount() );
424}
425
426void QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged( const double value )
427{
428 mMaximumZSpinBox->setMinimum( value );
429}
430
431void QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged( const double value )
432{
433 mMinimumZSpinBox->setMaximum( value );
434}
435
436void QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
437{
438 mSelectedCrs = crs;
439 mExtentGroupBox->setOutputCrs( mSelectedCrs );
440}
441
443{
444 return mFilename->filePath();
445}
446
448{
449 return leLayername->text();
450}
451
453{
454 return static_cast< QgsPointCloudLayerExporter::ExportFormat >( mFormatComboBox->currentData().toInt() );
455}
456
461
463{
464 QStringList attributes;
465
466 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
467 {
468 if ( mAttributeTable->item( i, 0 )->checkState() == Qt::Checked )
469 {
470 attributes.append( mAttributeTable->item( i, 0 )->text() );
471 }
472 }
473
474 return attributes;
475}
476
478{
479 return mAddToCanvas->isChecked();
480}
481
483{
484 mAddToCanvas->setChecked( enabled );
485}
486
488{
489 mMapCanvas = canvas;
490 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
491}
492
494{
495 return mExtentGroupBox->isChecked();
496}
497
499{
500 return mExtentGroupBox->outputExtent();
501}
502
504{
505 return mFilterGeometryGroupBox->isChecked() && mFilterGeometryLayerComboBox->count() > 0;
506}
507
509{
510 return mFilterGeometryLayerComboBox->currentLayer();
511}
512
514{
515 return hasFilterLayer() && mSelectedFeaturesCheckBox->isChecked();
516}
517
519{
520 return mAttributesSelection->isChecked() && mAttributesSelection->isEnabled();
521}
522
524{
525 return mZRangeGroupBox->isChecked();
526}
527
529{
530 return QgsDoubleRange( mMinimumZSpinBox->value(), mMaximumZSpinBox->value() );
531}
532
534{
535 return mPointsLimitGroupBox->isChecked();
536}
537
539{
540 return mPointsLimitSpinBox->value();
541}
542
547
548void QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked()
549{
550 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
551 {
552 mAttributeTable->item( i, 0 )->setCheckState( Qt::Checked );
553 }
554}
555
556void QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked()
557{
558 {
559 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
560 {
561 mAttributeTable->item( i, 0 )->setCheckState( Qt::Unchecked );
562 }
563 }
564}
565
566void QgsPointCloudLayerSaveAsDialog::showHelp()
567{
568 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
569}
570
571QString QgsPointCloudLayerSaveAsDialog::getFilterForFormat( QgsPointCloudLayerExporter::ExportFormat format )
572{
573 switch ( format )
574 {
576 return QStringLiteral( "LAZ point cloud (*.laz *.LAZ);;LAS point cloud (*.las *.LAS)" );
578 return QStringLiteral( "GeoPackage (*.gpkg *.GPKG)" );
580 return QStringLiteral( "AutoCAD DXF (*.dxf *.dxf)" );
582 return QStringLiteral( "ESRI Shapefile (*.shp *.SHP)" );
584 return QStringLiteral( "Comma separated values (*.csv *.CSV)" );
586 break;
587 }
588 return QString();
589}
590
591QString QgsPointCloudLayerSaveAsDialog::getTranslatedNameForFormat( QgsPointCloudLayerExporter::ExportFormat format )
592{
593 switch ( format )
594 {
596 return tr( "Temporary Scratch Layer" );
598 return tr( "GeoPackage" );
600 return tr( "AutoCAD DXF" );
602 return tr( "ESRI Shapefile" );
604 return tr( "LAS/LAZ point cloud" );
606 return tr( "Comma separated values" );
607 }
608 return QString();
609}
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const
Attempts to retrieve datum ensemble details from the CRS.
Contains information about a datum ensemble.
Definition qgsdatums.h:95
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:107
QgsRange which stores a range of double values.
Definition qgsrange.h:231
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
@ SaveFile
Select a single new or pre-existing file.
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
@ ClearToDefault
Reset value to default value (see defaultValue() )
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:209
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:39
Map canvas is a class for displaying all GIS data types on a canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
static QString launderLayerName(const QString &name)
Launders a layer's name, converting it into a format which is general suitable for file names or data...
Base class for all map layer types.
Definition qgsmaplayer.h:76
QString name
Definition qgsmaplayer.h:80
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:83
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Custom exception class which is raised when an operation is not supported.
const QgsPointCloudAttribute & at(int index) const
Returns the attribute at the specified index.
QString name() const
Returns name of the attribute.
ExportFormat
Supported export formats for point clouds.
static QList< ExportFormat > supportedFormats()
Gets a list of the supported export formats.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the dialog.
QgsPointCloudLayerSaveAsDialog(QgsPointCloudLayer *layer, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Construct a new QgsPointCloudLayerSaveAsDialog.
QString filename() const
Returns the target filename.
bool hasPointsLimit() const
Determines if limiting the number of exported points is enabled.
bool hasFilterLayer() const
Determines if points will be spatially filtered by a layer's features.
QgsRectangle filterExtent() const
Determines the extent to be exported.
bool hasZRange() const
Determines if filtering by Z values is activated.
QgsCoordinateReferenceSystem crsObject() const
Returns the CRS chosen for export.
bool hasAttributes() const
Determines if attributes will be exported as fields.
QgsDoubleRange zRange() const
Determines the Z range of points to be exported.
QgsPointCloudLayerExporter::ExportFormat exportFormat() const
The format in which the export should be written.
bool hasFilterExtent() const
Determines if filtering the export by an extent is activated.
int pointsLimit() const
Determines the limit to the total number of points.
bool filterLayerSelectedOnly() const
Determines if only the selected features from the filterLayer will be used for spatial filtering.
QString layername() const
Returns the target layer name.
void setAddToCanvas(bool checked)
Sets whether the "add to canvas" checkbox should be checked.
bool addToCanvas() const
Returns true if the "add to canvas" checkbox is checked.
QgsMapLayer * filterLayer() const
Returns the layer responsible for spatially filtering points.
QStringList attributes() const
Returns a list of attributes which are selected for saving.
QgsVectorFileWriter::ActionOnExistingFile creationActionOnExistingFile() const
Returns creation action.
Represents a map layer supporting display of point clouds.
QgsRectangle extent() const override
Returns the extent of the layer.
const QgsPointCloudStatistics statistics() const
Returns the object containing statistics.
QgsPointCloudAttributeCollection attributes() const
Returns the attributes available from the layer.
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
void crsChanged(const QgsCoordinateReferenceSystem &crs)
Emitted when the selected CRS is changed.
QList< QgsProviderSublayerDetails > querySublayers(const QString &uri, Qgis::SublayerQueryFlags flags=Qgis::SublayerQueryFlags(), QgsFeedback *feedback=nullptr) const
Queries the specified uri and returns a list of any valid sublayers found in the dataset which can be...
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Contains details about a sub layer available from a dataset.
A rectangle specified with double values.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A convenience class for writing vector layers to disk based formats (e.g.
@ CanAppendToExistingLayer
Flag to indicate that new features can be added to an existing layer.
@ CanAddNewLayer
Flag to indicate that a new layer can be added to the dataset.
@ CanDeleteLayer
Flag to indicate that an existing layer can be deleted.
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name.
QFlags< EditionCapability > EditionCapabilities
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
ActionOnExistingFile
Enumeration to describe how to handle existing files.
@ CreateOrOverwriteLayer
Create or overwrite layer.
@ CreateOrOverwriteFile
Create or overwrite file.
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
Represents a vector layer which manages a vector based data sets.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
const QgsCoordinateReferenceSystem & crs