QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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(
88 "Select the coordinate reference system for the vector file. "
89 "The data points will be transformed from the layer coordinate reference system."
90 ) );
91
92
93 // attributes
94 if ( mLayer )
95 {
96 const auto attributes = mLayer->attributes();
97 QStringList availableAttributes;
98 for ( int i = 0; i < attributes.count(); ++i )
99 {
100 const QString attribute = attributes.at( i ).name();
101 if ( attribute.compare( 'X'_L1, Qt::CaseInsensitive ) && attribute.compare( 'Y'_L1, Qt::CaseInsensitive ) && attribute.compare( 'Z'_L1, Qt::CaseInsensitive ) )
102 {
103 availableAttributes.append( attribute );
104 }
105 }
106
107 mAttributeTable->setRowCount( availableAttributes.count() );
108 QStringList horizontalHeaders = QStringList() << tr( "Attribute" );
109 mAttributeTable->setColumnCount( horizontalHeaders.size() );
110 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
111
112 for ( int i = 0; i < availableAttributes.count(); ++i )
113 {
114 QTableWidgetItem *item = new QTableWidgetItem( availableAttributes.at( i ) );
115 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
116 item->setCheckState( Qt::Checked );
117 mAttributeTable->setItem( i, 0, item );
118 }
119 mAttributeTable->resizeColumnsToContents();
120 }
121
122 // extent group box
123 mExtentGroupBox->setOutputCrs( mSelectedCrs );
124 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
125 mExtentGroupBox->setOutputExtentFromOriginal();
126 mExtentGroupBox->setCheckable( true );
127 mExtentGroupBox->setChecked( false );
128 mExtentGroupBox->setCollapsed( true );
129
130 // polygon layer filter group box
131 mFilterGeometryLayerComboBox->setFilters( Qgis::LayerFilter::PolygonLayer );
132
133 // ZRange group box
134 mMinimumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
135 mMaximumZSpinBox->setRange( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() );
136 if ( mLayer )
137 {
138 mMinimumZSpinBox->setValue( mLayer->statistics().minimum( u"Z"_s ) );
139 mMinimumZSpinBox->setClearValue( mMinimumZSpinBox->value() );
140 mMaximumZSpinBox->setValue( mLayer->statistics().maximum( u"Z"_s ) );
141 mMaximumZSpinBox->setClearValue( mMaximumZSpinBox->value() );
142 }
143
144 // points limit group box
145 mPointsLimitSpinBox->setMinimum( 1 );
146 mPointsLimitSpinBox->setMaximum( std::numeric_limits<int>::max() );
147 mPointsLimitSpinBox->setValue( 1e6 );
148 mPointsLimitSpinBox->setClearValue( 1e6 );
149
150 mFilename->setStorageMode( QgsFileWidget::SaveFile );
151 mFilename->setDialogTitle( tr( "Save Layer As" ) );
152 mFilename->setDefaultRoot( settings.value( u"UI/lastPointCloudFileFilterDir"_s, QDir::homePath() ).toString() );
153 mFilename->setConfirmOverwrite( false );
154 connect( mFilename, &QgsFileWidget::fileChanged, this, [this]( const QString &filePath ) {
155 QgsSettings settings;
156 if ( !filePath.isEmpty() )
157 mLastUsedFilename = filePath;
158
159 const QFileInfo fileInfo( filePath );
160 settings.setValue( u"UI/lastPointCloudFileFilterDir"_s, fileInfo.absolutePath() );
161 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
162 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
163 {
164 leLayername->setDefaultValue( suggestedLayerName );
165 }
166
167 // if no layer name set, then automatically match the output layer name to the file name
168 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
169 {
170 leLayername->setText( suggestedLayerName );
171 }
172 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
173 } );
174
175 try
176 {
177 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
178 if ( ensemble.isValid() )
179 {
180 mCrsSelector->setSourceEnsemble( ensemble.name() );
181 }
182 }
183 catch ( QgsNotSupportedException & )
184 {}
185
186 mCrsSelector->setShowAccuracyWarnings( true );
187
188 mAddToCanvas->setEnabled( exportFormat() != QgsPointCloudLayerExporter::ExportFormat::Memory );
189
190 if ( mLayer )
191 {
192 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( mLayer->name() );
193 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
194 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
195 if ( leLayername->isEnabled() )
196 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
197 }
198
199 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( exportFormat() == QgsPointCloudLayerExporter::ExportFormat::Memory || !mFilename->filePath().isEmpty() );
200}
201
202void QgsPointCloudLayerSaveAsDialog::accept()
203{
204 if ( QFile::exists( filename() ) )
205 {
208 QMessageBox msgBox;
209 msgBox.setIcon( QMessageBox::Question );
210 msgBox.setWindowTitle( tr( "Save Point Cloud Layer As" ) );
211 QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
212 QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
213 QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
214 msgBox.setStandardButtons( QMessageBox::Cancel );
215 msgBox.setDefaultButton( QMessageBox::Cancel );
216 overwriteFileButton->hide();
217 overwriteLayerButton->hide();
218 appendToLayerButton->hide();
219 if ( layerExists )
220 {
222 {
223 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
224 overwriteFileButton->setVisible( true );
225 overwriteLayerButton->setVisible( true );
226 }
228 {
229 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
230 overwriteFileButton->setVisible( true );
231 }
233 {
234 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
235 appendToLayerButton->setVisible( true );
236 overwriteFileButton->setVisible( true );
237 overwriteLayerButton->setVisible( true );
238 }
239 else
240 {
241 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
242 appendToLayerButton->setVisible( true );
243 overwriteFileButton->setVisible( true );
244 }
245
246 int ret = msgBox.exec();
247 if ( ret == QMessageBox::Cancel )
248 return;
249 if ( msgBox.clickedButton() == overwriteFileButton )
250 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
251 else if ( msgBox.clickedButton() == overwriteLayerButton )
252 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
253 else if ( msgBox.clickedButton() == appendToLayerButton )
254 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
255 }
256 else // !layerExists
257 {
259 {
260 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
261 }
262 else
263 {
264 // should not reach here, layer does not exist and cannot add new layer
265 if ( QMessageBox::question( this, tr( "Save Point Cloud Layer As" ), tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
266 {
267 return;
268 }
269 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
270 }
271 }
272 }
273 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
274 {
275 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
276 QStringList layerList;
277 layerList.reserve( sublayers.size() );
278 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
279 {
280 layerList.append( sublayer.name() );
281 }
282 if ( layerList.length() > 1 )
283 {
284 layerList.sort( Qt::CaseInsensitive );
285 QMessageBox msgBox;
286 msgBox.setIcon( QMessageBox::Warning );
287 msgBox.setWindowTitle( tr( "Overwrite File" ) );
288 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
289 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
290 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
291 if ( msgBox.exec() == QMessageBox::Cancel )
292 return;
293 }
294 }
295
296 QgsSettings settings;
297 settings.setValue( u"UI/lastPointCloudFileFilterDir"_s, QFileInfo( filename() ).absolutePath() );
298 settings.setValue( u"UI/lastPointCloudFormat"_s, static_cast<int>( exportFormat() ) );
299 QDialog::accept();
300}
301
302void QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
303{
304 Q_UNUSED( idx )
305
307
308 switch ( format )
309 {
314 mAttributesSelection->setEnabled( true );
315 break;
316
319 mAttributesSelection->setEnabled( false );
320 break;
321 }
322
323 switch ( format )
324 {
327 leLayername->setEnabled( true );
328 break;
329
334 leLayername->setEnabled( false );
335 break;
336 }
337
338 switch ( format )
339 {
341 mWasAddToCanvasForced = !mAddToCanvas->isChecked();
342 mAddToCanvas->setEnabled( false );
343 mAddToCanvas->setChecked( true );
344 mFilename->setEnabled( false );
345 break;
346
352 mAddToCanvas->setEnabled( true );
353 if ( mWasAddToCanvasForced )
354 {
355 mAddToCanvas->setChecked( !mAddToCanvas->isChecked() );
356 mWasAddToCanvasForced = false;
357 }
358 mFilename->setEnabled( true );
359 break;
360 }
361
362 if ( mFilename->isEnabled() )
363 {
364 mFilename->setFilter( getFilterForFormat( format ) );
365
366 // if output filename already defined we need to replace old suffix
367 // to avoid double extensions like .gpkg.shp
368 if ( !mLastUsedFilename.isEmpty() )
369 {
370 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
371 QString ext;
372 ext = rx.match( getFilterForFormat( format ) ).captured( 1 );
373 if ( !ext.isEmpty() )
374 {
375 QFileInfo fi( mLastUsedFilename );
376 mFilename->setFilePath( u"%1/%2.%3"_s.arg( fi.path(), fi.baseName(), ext ) );
377 }
378 }
379 }
380
381 if ( !mFilename->isEnabled() )
382 mFilename->setFilePath( QString() );
383
384 if ( !leLayername->isEnabled() )
385 {
386 leLayername->setText( QString() );
387 }
388 else if ( leLayername->text().isEmpty() )
389 {
390 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
391 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
392 {
393 layerName = QFileInfo( mFilename->filePath() ).baseName();
394 leLayername->setDefaultValue( layerName );
395 }
396 if ( layerName.isEmpty() )
397 {
398 layerName = tr( "new_layer" );
399 }
400 leLayername->setText( layerName );
401 }
402
403 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( format == QgsPointCloudLayerExporter::ExportFormat::Memory || !mFilename->filePath().isEmpty() );
404}
405
406void QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled( bool checked )
407{
408 if ( checked )
409 mFilterGeometryLayerChanged( mFilterGeometryLayerComboBox->currentLayer() );
410}
411
412void QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged( QgsMapLayer *layer )
413{
414 QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
415 mSelectedFeaturesCheckBox->setChecked( false );
416 mSelectedFeaturesCheckBox->setEnabled( hasFilterLayer() && vlayer && vlayer->selectedFeatureCount() );
417}
418
419void QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged( const double value )
420{
421 mMaximumZSpinBox->setMinimum( value );
422}
423
424void QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged( const double value )
425{
426 mMinimumZSpinBox->setMaximum( value );
427}
428
429void QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
430{
431 mSelectedCrs = crs;
432 mExtentGroupBox->setOutputCrs( mSelectedCrs );
433}
434
436{
437 return mFilename->filePath();
438}
439
441{
442 return leLayername->text();
443}
444
446{
447 return static_cast<QgsPointCloudLayerExporter::ExportFormat>( mFormatComboBox->currentData().toInt() );
448}
449
454
456{
457 QStringList attributes;
458
459 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
460 {
461 if ( mAttributeTable->item( i, 0 )->checkState() == Qt::Checked )
462 {
463 attributes.append( mAttributeTable->item( i, 0 )->text() );
464 }
465 }
466
467 return attributes;
468}
469
471{
472 return mAddToCanvas->isChecked();
473}
474
476{
477 mAddToCanvas->setChecked( enabled );
478}
479
481{
482 mMapCanvas = canvas;
483 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
484}
485
487{
488 return mExtentGroupBox->isChecked();
489}
490
492{
493 return mExtentGroupBox->outputExtent();
494}
495
497{
498 return mFilterGeometryGroupBox->isChecked() && mFilterGeometryLayerComboBox->count() > 0;
499}
500
502{
503 return mFilterGeometryLayerComboBox->currentLayer();
504}
505
507{
508 return hasFilterLayer() && mSelectedFeaturesCheckBox->isChecked();
509}
510
512{
513 return mAttributesSelection->isChecked() && mAttributesSelection->isEnabled();
514}
515
517{
518 return mZRangeGroupBox->isChecked();
519}
520
522{
523 return QgsDoubleRange( mMinimumZSpinBox->value(), mMaximumZSpinBox->value() );
524}
525
527{
528 return mPointsLimitGroupBox->isChecked();
529}
530
532{
533 return mPointsLimitSpinBox->value();
534}
535
540
541void QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked()
542{
543 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
544 {
545 mAttributeTable->item( i, 0 )->setCheckState( Qt::Checked );
546 }
547}
548
549void QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked()
550{
551 {
552 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
553 {
554 mAttributeTable->item( i, 0 )->setCheckState( Qt::Unchecked );
555 }
556 }
557}
558
559void QgsPointCloudLayerSaveAsDialog::showHelp()
560{
561 QgsHelp::openHelp( u"managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer"_s );
562}
563
564QString QgsPointCloudLayerSaveAsDialog::getFilterForFormat( QgsPointCloudLayerExporter::ExportFormat format )
565{
566 switch ( format )
567 {
569 return u"LAZ point cloud (*.laz *.LAZ);;LAS point cloud (*.las *.LAS)"_s;
571 return u"GeoPackage (*.gpkg *.GPKG)"_s;
573 return u"AutoCAD DXF (*.dxf *.dxf)"_s;
575 return u"ESRI Shapefile (*.shp *.SHP)"_s;
577 return u"Comma separated values (*.csv *.CSV)"_s;
579 break;
580 }
581 return QString();
582}
583
584QString QgsPointCloudLayerSaveAsDialog::getTranslatedNameForFormat( QgsPointCloudLayerExporter::ExportFormat format )
585{
586 switch ( format )
587 {
589 return tr( "Temporary Scratch Layer" );
591 return tr( "GeoPackage" );
593 return tr( "AutoCAD DXF" );
595 return tr( "ESRI Shapefile" );
597 return tr( "LAS/LAZ point cloud" );
599 return tr( "Comma separated values" );
600 }
601 return QString();
602}
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:106
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:111
QgsRange which stores a range of double values.
Definition qgsrange.h:217
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.