QGIS API Documentation 3.40.0-Bratislava (b56115d8743)
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 "qgsgui.h"
24#include "qgsmapcanvas.h"
25#include "qgsdatums.h"
26#include "qgsproviderregistry.h"
28#include "qgspointcloudlayer.h"
29#include "qgsmaplayerutils.h"
30#include "qgsvectorlayer.h"
31
33 : QDialog( parent, fl )
34 , mLayer( layer )
35 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
36{
37 if ( layer )
38 {
39 mSelectedCrs = layer->crs();
40 mLayerExtent = layer->extent();
41 }
42 setup();
43}
44
45void QgsPointCloudLayerSaveAsDialog::setup()
46{
47 setupUi( this );
49
50 connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
51 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged );
52 connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked );
53 connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked );
54 connect( mFilterGeometryLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged );
55 connect( mFilterGeometryGroupBox, &QgsCollapsibleGroupBox::toggled, this, &QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled );
56 connect( mMinimumZSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged );
57 connect( mMaximumZSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged );
58
59#ifdef Q_OS_WIN
60 mHelpButtonBox->setVisible( false );
61 mButtonBox->addButton( QDialogButtonBox::Help );
62 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
63#else
64 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsPointCloudLayerSaveAsDialog::showHelp );
65#endif
66 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsPointCloudLayerSaveAsDialog::accept );
67 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsPointCloudLayerSaveAsDialog::reject );
68
69 mFormatComboBox->blockSignals( true );
70 const QList< QgsPointCloudLayerExporter::ExportFormat > supportedFormats = QgsPointCloudLayerExporter::supportedFormats();
71 for ( const auto &format : supportedFormats )
72 mFormatComboBox->addItem( getTranslatedNameForFormat( format ), static_cast< int >( format ) );
73
74 QgsSettings settings;
75 const int defaultFormat = settings.value( QStringLiteral( "UI/lastPointCloudFormat" ), 0 ).toInt();
76 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( defaultFormat ) );
77 mFormatComboBox->blockSignals( false );
78 mFormatComboBox_currentIndexChanged( 0 );
79
80 mCrsSelector->setCrs( mSelectedCrs );
81 mCrsSelector->setLayerCrs( mSelectedCrs );
82 mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
83 "The data points will be transformed from the layer coordinate reference system." ) );
84
85
86 // attributes
87 if ( mLayer )
88 {
89 const auto attributes = mLayer->attributes();
90 QStringList availableAttributes;
91 for ( int i = 0; i < attributes.count(); ++i )
92 {
93 const QString attribute = attributes.at( i ).name();
94 if ( attribute.compare( QLatin1String( "X" ), Qt::CaseInsensitive ) &&
95 attribute.compare( QLatin1String( "Y" ), Qt::CaseInsensitive ) &&
96 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, [ = ]( const QString & filePath )
150 {
151 QgsSettings settings;
152 if ( !filePath.isEmpty() )
153 mLastUsedFilename = filePath;
154
155 const QFileInfo fileInfo( filePath );
156 settings.setValue( QStringLiteral( "UI/lastPointCloudFileFilterDir" ), fileInfo.absolutePath() );
157 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
158 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
159 {
160 leLayername->setDefaultValue( suggestedLayerName );
161 }
162
163 // if no layer name set, then automatically match the output layer name to the file name
164 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
165 {
166 leLayername->setText( suggestedLayerName );
167 }
168 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
169 } );
170
171 try
172 {
173 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
174 if ( ensemble.isValid() )
175 {
176 mCrsSelector->setSourceEnsemble( ensemble.name() );
177 }
178 }
179 catch ( QgsNotSupportedException & )
180 {
181 }
182
183 mCrsSelector->setShowAccuracyWarnings( true );
184
185 mAddToCanvas->setEnabled( exportFormat() != QgsPointCloudLayerExporter::ExportFormat::Memory );
186
187 if ( mLayer )
188 {
189 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( mLayer->name() );
190 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
191 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
192 if ( leLayername->isEnabled() )
193 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
194 }
195
196 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( exportFormat() == QgsPointCloudLayerExporter::ExportFormat::Memory ||
197 !mFilename->filePath().isEmpty() );
198}
199
200void QgsPointCloudLayerSaveAsDialog::accept()
201{
202 if ( QFile::exists( filename() ) )
203 {
207 layername() );
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 {
224 {
225 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
226 overwriteFileButton->setVisible( true );
227 overwriteLayerButton->setVisible( true );
228 }
230 {
231 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
232 overwriteFileButton->setVisible( true );
233 }
234 else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
236 {
237 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
238 appendToLayerButton->setVisible( true );
239 overwriteFileButton->setVisible( true );
240 overwriteLayerButton->setVisible( true );
241 }
242 else
243 {
244 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
245 appendToLayerButton->setVisible( true );
246 overwriteFileButton->setVisible( true );
247 }
248
249 int ret = msgBox.exec();
250 if ( ret == QMessageBox::Cancel )
251 return;
252 if ( msgBox.clickedButton() == overwriteFileButton )
253 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
254 else if ( msgBox.clickedButton() == overwriteLayerButton )
255 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
256 else if ( msgBox.clickedButton() == appendToLayerButton )
257 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
258 }
259 else // !layerExists
260 {
262 {
263 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
264 }
265 else
266 {
267 // should not reach here, layer does not exist and cannot add new layer
268 if ( QMessageBox::question( this,
269 tr( "Save Point Cloud Layer As" ),
270 tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
271 {
272 return;
273 }
274 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
275 }
276 }
277 }
278 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
279 {
280 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
281 QStringList layerList;
282 layerList.reserve( sublayers.size() );
283 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
284 {
285 layerList.append( sublayer.name() );
286 }
287 if ( layerList.length() > 1 )
288 {
289 layerList.sort( Qt::CaseInsensitive );
290 QMessageBox msgBox;
291 msgBox.setIcon( QMessageBox::Warning );
292 msgBox.setWindowTitle( tr( "Overwrite File" ) );
293 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
294 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
295 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
296 if ( msgBox.exec() == QMessageBox::Cancel )
297 return;
298 }
299 }
300
301 QgsSettings settings;
302 settings.setValue( QStringLiteral( "UI/lastPointCloudFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
303 settings.setValue( QStringLiteral( "UI/lastPointCloudFormat" ), static_cast< int >( exportFormat() ) );
304 QDialog::accept();
305}
306
307void QgsPointCloudLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
308{
309 Q_UNUSED( idx )
310
312
313 switch ( format )
314 {
319 mAttributesSelection->setEnabled( true );
320 break;
321
324 mAttributesSelection->setEnabled( false );
325 break;
326 }
327
328 switch ( format )
329 {
332 leLayername->setEnabled( true );
333 break;
334 \
339 leLayername->setEnabled( false );
340 break;
341 }
342
343 switch ( format )
344 {
346 mWasAddToCanvasForced = !mAddToCanvas->isChecked();
347 mAddToCanvas->setEnabled( false );
348 mAddToCanvas->setChecked( true );
349 mFilename->setEnabled( false );
350 break;
351
357 mAddToCanvas->setEnabled( true );
358 if ( mWasAddToCanvasForced )
359 {
360 mAddToCanvas->setChecked( !mAddToCanvas->isChecked() );
361 mWasAddToCanvasForced = false;
362 }
363 mFilename->setEnabled( true );
364 break;
365 }
366
367 if ( mFilename->isEnabled() )
368 {
369 mFilename->setFilter( getFilterForFormat( format ) );
370
371 // if output filename already defined we need to replace old suffix
372 // to avoid double extensions like .gpkg.shp
373 if ( !mLastUsedFilename.isEmpty() )
374 {
375 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
376 QString ext;
377 ext = rx.match( getFilterForFormat( format ) ).captured( 1 );
378 if ( !ext.isEmpty() )
379 {
380 QFileInfo fi( mLastUsedFilename );
381 mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
382 }
383 }
384 }
385
386 if ( !mFilename->isEnabled() )
387 mFilename->setFilePath( QString() );
388
389 if ( !leLayername->isEnabled() )
390 {
391 leLayername->setText( QString() );
392 }
393 else if ( leLayername->text().isEmpty() )
394 {
395 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
396 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
397 {
398 layerName = QFileInfo( mFilename->filePath() ).baseName();
399 leLayername->setDefaultValue( layerName );
400 }
401 if ( layerName.isEmpty() )
402 {
403 layerName = tr( "new_layer" );
404 }
405 leLayername->setText( layerName );
406 }
407
408 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( format == QgsPointCloudLayerExporter::ExportFormat::Memory ||
409 !mFilename->filePath().isEmpty() );
410}
411
412void QgsPointCloudLayerSaveAsDialog::mFilterGeometryGroupBoxCheckToggled( bool checked )
413{
414 if ( checked )
415 mFilterGeometryLayerChanged( mFilterGeometryLayerComboBox->currentLayer() );
416}
417
418void QgsPointCloudLayerSaveAsDialog::mFilterGeometryLayerChanged( QgsMapLayer *layer )
419{
420 QgsVectorLayer *vlayer = dynamic_cast< QgsVectorLayer * >( layer );
421 mSelectedFeaturesCheckBox->setChecked( false );
422 mSelectedFeaturesCheckBox->setEnabled( hasFilterLayer() && vlayer && vlayer->selectedFeatureCount() );
423}
424
425void QgsPointCloudLayerSaveAsDialog::mMinimumZSpinBoxValueChanged( const double value )
426{
427 mMaximumZSpinBox->setMinimum( value );
428}
429
430void QgsPointCloudLayerSaveAsDialog::mMaximumZSpinBoxValueChanged( const double value )
431{
432 mMinimumZSpinBox->setMaximum( value );
433}
434
435void QgsPointCloudLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
436{
437 mSelectedCrs = crs;
438 mExtentGroupBox->setOutputCrs( mSelectedCrs );
439}
440
442{
443 return mFilename->filePath();
444}
445
447{
448 return leLayername->text();
449}
450
452{
453 return static_cast< QgsPointCloudLayerExporter::ExportFormat >( mFormatComboBox->currentData().toInt() );
454}
455
460
462{
463 QStringList attributes;
464
465 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
466 {
467 if ( mAttributeTable->item( i, 0 )->checkState() == Qt::Checked )
468 {
469 attributes.append( mAttributeTable->item( i, 0 )->text() );
470 }
471 }
472
473 return attributes;
474}
475
477{
478 return mAddToCanvas->isChecked();
479}
480
482{
483 mAddToCanvas->setChecked( enabled );
484}
485
487{
488 mMapCanvas = canvas;
489 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
490}
491
493{
494 return mExtentGroupBox->isChecked();
495}
496
498{
499 return mExtentGroupBox->outputExtent();
500}
501
503{
504 return mFilterGeometryGroupBox->isChecked() && mFilterGeometryLayerComboBox->count() > 0;
505}
506
508{
509 return mFilterGeometryLayerComboBox->currentLayer();
510}
511
513{
514 return hasFilterLayer() && mSelectedFeaturesCheckBox->isChecked();
515}
516
518{
519 return mAttributesSelection->isChecked() && mAttributesSelection->isEnabled();
520}
521
523{
524 return mZRangeGroupBox->isChecked();
525}
526
528{
529 return QgsDoubleRange( mMinimumZSpinBox->value(), mMaximumZSpinBox->value() );
530}
531
533{
534 return mPointsLimitGroupBox->isChecked();
535}
536
538{
539 return mPointsLimitSpinBox->value();
540}
541
546
547void QgsPointCloudLayerSaveAsDialog::mSelectAllAttributes_clicked()
548{
549 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
550 {
551 mAttributeTable->item( i, 0 )->setCheckState( Qt::Checked );
552 }
553}
554
555void QgsPointCloudLayerSaveAsDialog::mDeselectAllAttributes_clicked()
556{
557 {
558 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
559 {
560 mAttributeTable->item( i, 0 )->setCheckState( Qt::Unchecked );
561 }
562 }
563}
564
565void QgsPointCloudLayerSaveAsDialog::showHelp()
566{
567 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
568}
569
570QString QgsPointCloudLayerSaveAsDialog::getFilterForFormat( QgsPointCloudLayerExporter::ExportFormat format )
571{
572 switch ( format )
573 {
575 return QStringLiteral( "LAZ point cloud (*.laz *.LAZ);;LAS point cloud (*.las *.LAS)" );
577 return QStringLiteral( "GeoPackage (*.gpkg *.GPKG)" );
579 return QStringLiteral( "AutoCAD DXF (*.dxf *.dxf)" );
581 return QStringLiteral( "ESRI Shapefile (*.shp *.SHP)" );
583 return QStringLiteral( "Comma separated values (*.csv *.CSV)" );
585 break;
586 }
587 return QString();
588}
589
590QString QgsPointCloudLayerSaveAsDialog::getTranslatedNameForFormat( QgsPointCloudLayerExporter::ExportFormat format )
591{
592 switch ( format )
593 {
595 return tr( "Temporary Scratch Layer" );
597 return tr( "GeoPackage" );
599 return tr( "AutoCAD DXF" );
601 return tr( "ESRI Shapefile" );
603 return tr( "LAS/LAZ point cloud" );
605 return tr( "Comma separated values" );
606 }
607 return QString();
608}
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:208
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