QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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
20
21#include "qgsdatums.h"
22#include "qgsgui.h"
23#include "qgsmapcanvas.h"
24#include "qgsmaplayerutils.h"
25#include "qgspointcloudlayer.h"
26#include "qgsproviderregistry.h"
28#include "qgsvectorlayer.h"
29
30#include <QMessageBox>
31#include <QRegularExpression>
32#include <QString>
33
34#include "moc_qgspointcloudlayersaveasdialog.cpp"
35
36using namespace Qt::StringLiterals;
37
39 : QDialog( parent, fl )
40 , mLayer( layer )
41{
42 if ( layer )
43 {
44 mSelectedCrs = layer->crs();
45 mLayerExtent = layer->extent();
46 }
47 setup();
48}
49
50void QgsPointCloudLayerSaveAsDialog::setup()
51{
52 setupUi( this );
54
55 connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
56 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged );
57 connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked );
58 connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked );
59 connect( mFilterGeometryLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged );
60 connect( mFilterGeometryGroupBox, &QgsCollapsibleGroupBox::toggled, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled );
61 connect( mMinimumZSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged );
62 connect( mMaximumZSpinBox, static_cast<void ( QgsDoubleSpinBox::* )( double )>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged );
63
64#ifdef Q_OS_WIN
65 mHelpButtonBox->setVisible( false );
66 mButtonBox->addButton( QDialogButtonBox::Help );
67 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
68#else
69 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
70#endif
71 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsPointCloudLayerSaveAsDialog::accept );
72 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsPointCloudLayerSaveAsDialog::reject );
73
74 mFormatComboBox->blockSignals( true );
75 const QList<QgsPointCloudLayerExporter::ExportFormat> supportedFormats = QgsPointCloudLayerExporter::supportedFormats();
76 for ( const auto &format : supportedFormats )
77 mFormatComboBox->addItem( getTranslatedNameForFormat( format ), static_cast<int>( format ) );
78
79 QgsSettings settings;
80 const int defaultFormat = settings.value( u"UI/lastPointCloudFormat"_s, 0 ).toInt();
81 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( defaultFormat ) );
82 mFormatComboBox->blockSignals( false );
83 mFormatComboBox_currentIndexChanged( 0 );
84
85 mCrsSelector->setCrs( mSelectedCrs );
86 mCrsSelector->setLayerCrs( mSelectedCrs );
87 mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
88 "The data points will be transformed from the layer coordinate reference system." ) );
89
90
91 // attributes
92 if ( mLayer )
93 {
94 const auto attributes = mLayer->attributes();
95 QStringList availableAttributes;
96 for ( int i = 0; i < attributes.count(); ++i )
97 {
98 const QString attribute = attributes.at( i ).name();
99 if ( attribute.compare( 'X'_L1, Qt::CaseInsensitive ) && attribute.compare( 'Y'_L1, Qt::CaseInsensitive ) && attribute.compare( 'Z'_L1, Qt::CaseInsensitive ) )
100 {
101 availableAttributes.append( attribute );
102 }
103 }
104
105 mAttributeTable->setRowCount( availableAttributes.count() );
106 QStringList horizontalHeaders = QStringList() << tr( "Attribute" );
107 mAttributeTable->setColumnCount( horizontalHeaders.size() );
108 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
109
110 for ( int i = 0; i < availableAttributes.count(); ++i )
111 {
112 QTableWidgetItem *item = new QTableWidgetItem( availableAttributes.at( i ) );
113 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
114 item->setCheckState( Qt::Checked );
115 mAttributeTable->setItem( i, 0, item );
116 }
117 mAttributeTable->resizeColumnsToContents();
118 }
119
120 // extent group box
121 mExtentGroupBox->setOutputCrs( mSelectedCrs );
122 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
123 mExtentGroupBox->setOutputExtentFromOriginal();
124 mExtentGroupBox->setCheckable( true );
125 mExtentGroupBox->setChecked( false );
126 mExtentGroupBox->setCollapsed( true );
127
128 // polygon layer filter group box
129 mFilterGeometryLayerComboBox->setFilters( Qgis::LayerFilter::PolygonLayer );
130
131 // ZRange group box
132 mMinimumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
133 mMaximumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
134 if ( mLayer )
135 {
136 mMinimumZSpinBox->setValue( mLayer->statistics().minimum( u"Z"_s ) );
137 mMinimumZSpinBox->setClearValue( mMinimumZSpinBox->value() );
138 mMaximumZSpinBox->setValue( mLayer->statistics().maximum( u"Z"_s ) );
139 mMaximumZSpinBox->setClearValue( mMaximumZSpinBox->value() );
140 }
141
142 // points limit group box
143 mPointsLimitSpinBox->setMinimum( 1 );
144 mPointsLimitSpinBox->setMaximum( std::numeric_limits<int>::max() );
145 mPointsLimitSpinBox->setValue( 1e6 );
146 mPointsLimitSpinBox->setClearValue( 1e6 );
147
148 mFilename->setStorageMode( QgsFileWidget::SaveFile );
149 mFilename->setDialogTitle( tr( "Save Layer As" ) );
150 mFilename->setDefaultRoot( settings.value( u"UI/lastPointCloudFileFilterDir"_s, QDir::homePath() ).toString() );
151 mFilename->setConfirmOverwrite( false );
152 connect( mFilename, &QgsFileWidget::fileChanged, this, [this]( const QString &filePath ) {
153 QgsSettings settings;
154 if ( !filePath.isEmpty() )
155 mLastUsedFilename = filePath;
156
157 const QFileInfo fileInfo( filePath );
158 settings.setValue( u"UI/lastPointCloudFileFilterDir"_s, fileInfo.absolutePath() );
159 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
160 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
161 {
162 leLayername->setDefaultValue( suggestedLayerName );
163 }
164
165 // if no layer name set, then automatically match the output layer name to the file name
166 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
167 {
168 leLayername->setText( suggestedLayerName );
169 }
170 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
171 } );
172
173 try
174 {
175 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
176 if ( ensemble.isValid() )
177 {
178 mCrsSelector->setSourceEnsemble( ensemble.name() );
179 }
180 }
181 catch ( QgsNotSupportedException & )
182 {
183 }
184
185 mCrsSelector->setShowAccuracyWarnings( true );
186
187 mAddToCanvas->setEnabled( exportFormat() != QgsPointCloudLayerExporter::ExportFormat::Memory );
188
189 if ( mLayer )
190 {
191 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( mLayer->name() );
192 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
193 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
194 if ( leLayername->isEnabled() )
195 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
196 }
197
198 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( exportFormat() == QgsPointCloudLayerExporter::ExportFormat::Memory || !mFilename->filePath().isEmpty() );
199}
200
201void QgsPointCloudLayerSaveAsDialog::accept()
202{
203 if ( QFile::exists( filename() ) )
204 {
207 QMessageBox msgBox;
208 msgBox.setIcon( QMessageBox::Question );
209 msgBox.setWindowTitle( tr( "Save Point Cloud Layer As" ) );
210 QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
211 QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
212 QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
213 msgBox.setStandardButtons( QMessageBox::Cancel );
214 msgBox.setDefaultButton( QMessageBox::Cancel );
215 overwriteFileButton->hide();
216 overwriteLayerButton->hide();
217 appendToLayerButton->hide();
218 if ( layerExists )
219 {
221 {
222 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
223 overwriteFileButton->setVisible( true );
224 overwriteLayerButton->setVisible( true );
225 }
227 {
228 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
229 overwriteFileButton->setVisible( true );
230 }
232 {
233 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
234 appendToLayerButton->setVisible( true );
235 overwriteFileButton->setVisible( true );
236 overwriteLayerButton->setVisible( true );
237 }
238 else
239 {
240 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
241 appendToLayerButton->setVisible( true );
242 overwriteFileButton->setVisible( true );
243 }
244
245 int ret = msgBox.exec();
246 if ( ret == QMessageBox::Cancel )
247 return;
248 if ( msgBox.clickedButton() == overwriteFileButton )
249 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
250 else if ( msgBox.clickedButton() == overwriteLayerButton )
251 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
252 else if ( msgBox.clickedButton() == appendToLayerButton )
253 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
254 }
255 else // !layerExists
256 {
258 {
259 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
260 }
261 else
262 {
263 // should not reach here, layer does not exist and cannot add new layer
264 if ( QMessageBox::question( this, tr( "Save Point Cloud Layer As" ), tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
265 {
266 return;
267 }
268 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
269 }
270 }
271 }
272 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
273 {
274 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
275 QStringList layerList;
276 layerList.reserve( sublayers.size() );
277 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
278 {
279 layerList.append( sublayer.name() );
280 }
281 if ( layerList.length() > 1 )
282 {
283 layerList.sort( Qt::CaseInsensitive );
284 QMessageBox msgBox;
285 msgBox.setIcon( QMessageBox::Warning );
286 msgBox.setWindowTitle( tr( "Overwrite File" ) );
287 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
288 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
289 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
290 if ( msgBox.exec() == QMessageBox::Cancel )
291 return;
292 }
293 }
294
295 QgsSettings settings;
296 settings.setValue( u"UI/lastPointCloudFileFilterDir"_s, QFileInfo( filename() ).absolutePath() );
297 settings.setValue( u"UI/lastPointCloudFormat"_s, static_cast<int>( exportFormat() ) );
298 QDialog::accept();
299}
300
301void QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
302{
303 Q_UNUSED( idx )
304
306
307 switch ( format )
308 {
313 mAttributesSelection->setEnabled( true );
314 break;
315
318 mAttributesSelection->setEnabled( false );
319 break;
320 }
321
322 switch ( format )
323 {
326 leLayername->setEnabled( true );
327 break;
328
333 leLayername->setEnabled( false );
334 break;
335 }
336
337 switch ( format )
338 {
340 mWasAddToCanvasForced = !mAddToCanvas->isChecked();
341 mAddToCanvas->setEnabled( false );
342 mAddToCanvas->setChecked( true );
343 mFilename->setEnabled( false );
344 break;
345
351 mAddToCanvas->setEnabled( true );
352 if ( mWasAddToCanvasForced )
353 {
354 mAddToCanvas->setChecked( !mAddToCanvas->isChecked() );
355 mWasAddToCanvasForced = false;
356 }
357 mFilename->setEnabled( true );
358 break;
359 }
360
361 if ( mFilename->isEnabled() )
362 {
363 mFilename->setFilter( getFilterForFormat( format ) );
364
365 // if output filename already defined we need to replace old suffix
366 // to avoid double extensions like .gpkg.shp
367 if ( !mLastUsedFilename.isEmpty() )
368 {
369 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
370 QString ext;
371 ext = rx.match( getFilterForFormat( format ) ).captured( 1 );
372 if ( !ext.isEmpty() )
373 {
374 QFileInfo fi( mLastUsedFilename );
375 mFilename->setFilePath( u"%1/%2.%3"_s.arg( fi.path(), fi.baseName(), ext ) );
376 }
377 }
378 }
379
380 if ( !mFilename->isEnabled() )
381 mFilename->setFilePath( QString() );
382
383 if ( !leLayername->isEnabled() )
384 {
385 leLayername->setText( QString() );
386 }
387 else if ( leLayername->text().isEmpty() )
388 {
389 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
390 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
391 {
392 layerName = QFileInfo( mFilename->filePath() ).baseName();
393 leLayername->setDefaultValue( layerName );
394 }
395 if ( layerName.isEmpty() )
396 {
397 layerName = tr( "new_layer" );
398 }
399 leLayername->setText( layerName );
400 }
401
402 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( format == QgsPointCloudLayerExporter::ExportFormat::Memory || !mFilename->filePath().isEmpty() );
403}
404
405void QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled( bool checked )
406{
407 if ( checked )
408 mFilterGeometryLayerChanged( mFilterGeometryLayerComboBox->currentLayer() );
409}
410
411void QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged( QgsMapLayer *layer )
412{
413 QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
414 mSelectedFeaturesCheckBox->setChecked( false );
415 mSelectedFeaturesCheckBox->setEnabled( hasFilterLayer() && vlayer && vlayer->selectedFeatureCount() );
416}
417
418void QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged( const double value )
419{
420 mMaximumZSpinBox->setMinimum( value );
421}
422
423void QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged( const double value )
424{
425 mMinimumZSpinBox->setMaximum( value );
426}
427
428void QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
429{
430 mSelectedCrs = crs;
431 mExtentGroupBox->setOutputCrs( mSelectedCrs );
432}
433
435{
436 return mFilename->filePath();
437}
438
440{
441 return leLayername->text();
442}
443
445{
446 return static_cast<QgsPointCloudLayerExporter::ExportFormat>( mFormatComboBox->currentData().toInt() );
447}
448
453
455{
456 QStringList attributes;
457
458 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
459 {
460 if ( mAttributeTable->item( i, 0 )->checkState() == Qt::Checked )
461 {
462 attributes.append( mAttributeTable->item( i, 0 )->text() );
463 }
464 }
465
466 return attributes;
467}
468
470{
471 return mAddToCanvas->isChecked();
472}
473
475{
476 mAddToCanvas->setChecked( enabled );
477}
478
480{
481 mMapCanvas = canvas;
482 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
483}
484
486{
487 return mExtentGroupBox->isChecked();
488}
489
491{
492 return mExtentGroupBox->outputExtent();
493}
494
496{
497 return mFilterGeometryGroupBox->isChecked() && mFilterGeometryLayerComboBox->count() > 0;
498}
499
501{
502 return mFilterGeometryLayerComboBox->currentLayer();
503}
504
506{
507 return hasFilterLayer() && mSelectedFeaturesCheckBox->isChecked();
508}
509
511{
512 return mAttributesSelection->isChecked() && mAttributesSelection->isEnabled();
513}
514
516{
517 return mZRangeGroupBox->isChecked();
518}
519
521{
522 return QgsDoubleRange( mMinimumZSpinBox->value(), mMaximumZSpinBox->value() );
523}
524
526{
527 return mPointsLimitGroupBox->isChecked();
528}
529
531{
532 return mPointsLimitSpinBox->value();
533}
534
539
540void QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked()
541{
542 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
543 {
544 mAttributeTable->item( i, 0 )->setCheckState( Qt::Checked );
545 }
546}
547
548void QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked()
549{
550 {
551 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
552 {
553 mAttributeTable->item( i, 0 )->setCheckState( Qt::Unchecked );
554 }
555 }
556}
557
558void QgsPointCloudLayerSaveAsDialog::showHelp()
559{
560 QgsHelp::openHelp( u"managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer"_s );
561}
562
563QString QgsPointCloudLayerSaveAsDialog::getFilterForFormat( QgsPointCloudLayerExporter::ExportFormat format )
564{
565 switch ( format )
566 {
568 return u"LAZ point cloud (*.laz *.LAZ);;LAS point cloud (*.las *.LAS)"_s;
570 return u"GeoPackage (*.gpkg *.GPKG)"_s;
572 return u"AutoCAD DXF (*.dxf *.dxf)"_s;
574 return u"ESRI Shapefile (*.shp *.SHP)"_s;
576 return u"Comma separated values (*.csv *.CSV)"_s;
578 break;
579 }
580 return QString();
581}
582
583QString QgsPointCloudLayerSaveAsDialog::getTranslatedNameForFormat( QgsPointCloudLayerExporter::ExportFormat format )
584{
585 switch ( format )
586 {
588 return tr( "Temporary Scratch Layer" );
590 return tr( "GeoPackage" );
592 return tr( "AutoCAD DXF" );
594 return tr( "ESRI Shapefile" );
596 return tr( "LAS/LAZ point cloud" );
598 return tr( "Comma separated values" );
599 }
600 return QString();
601}
Represents a coordinate reference system (CRS).
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:104
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:109
QgsRange which stores a range of double values.
Definition qgsrange.h:236
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:224
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
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:83
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:90
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.
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.
QgsPointCloudAttributeCollection attributes() const
Returns the attributes available from the layer.
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.
A rectangle specified with double values.
Stores settings for use within QGIS.
Definition qgssettings.h:68
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.
@ 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.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.