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