33 #include <QPushButton>    36 #include <QMessageBox>    37 #include <QFileDialog>    41 #include <ogr_srs_api.h>    42 #include <gdal_version.h>    43 #include <cpl_error.h>    44 #include <cpl_string.h>    46 #if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,0,0)    47 #define SUPPORT_GEOMETRY_LESS    48 #define SUPPORT_CURVE_GEOMETRIES    49 #define SUPPORT_INTEGER64    50 #define SUPPORT_SPATIAL_INDEX    51 #define SUPPORT_IDENTIFIER_DESCRIPTION    52 #define SUPPORT_FIELD_WIDTH    57     , mOkButton( nullptr )
    58     , mTableNameEdited( false )
    59     , mLayerIdentifierEdited( false )
    69 #ifdef SUPPORT_GEOMETRY_LESS    70   mGeometryTypeBox->addItem( 
tr( 
"Non spatial" ), wkbNone );
    72   mGeometryTypeBox->addItem( 
tr( 
"Point" ), wkbPoint );
    73   mGeometryTypeBox->addItem( 
tr( 
"Line" ), wkbLineString );
    74   mGeometryTypeBox->addItem( 
tr( 
"Polygon" ), wkbPolygon );
    75   mGeometryTypeBox->addItem( 
tr( 
"Multi point" ), wkbMultiPoint );
    76   mGeometryTypeBox->addItem( 
tr( 
"Multi line" ), wkbMultiLineString );
    77   mGeometryTypeBox->addItem( 
tr( 
"Multi polygon" ), wkbMultiPolygon );
    78 #ifdef SUPPORT_CURVE_GEOMETRIES    81   mGeometryTypeBox->addItem( 
tr( 
"Circular string" ), wkbCircularString );
    83   mGeometryTypeBox->addItem( 
tr( 
"Compound curve" ), wkbCompoundCurve );
    84   mGeometryTypeBox->addItem( 
tr( 
"Curve polygon" ), wkbCurvePolygon );
    85   mGeometryTypeBox->addItem( 
tr( 
"Multi curve" ), wkbMultiCurve );
    86   mGeometryTypeBox->addItem( 
tr( 
"Multi surface" ), wkbMultiSurface );
    89 #ifdef SUPPORT_GEOMETRY_LESS    90   mGeometryColumnEdit->setEnabled( 
false );
    91   mCheckBoxCreateSpatialIndex->setEnabled( 
false );
    92   mCrsSelector->setEnabled( 
false );
    95   mFieldTypeBox->addItem( 
tr( 
"Text data" ), 
"text" );
    96   mFieldTypeBox->addItem( 
tr( 
"Whole number (integer)" ), 
"integer" );
    97 #ifdef SUPPORT_INTEGER64    98   mFieldTypeBox->addItem( 
tr( 
"Whole number (integer 64 bit)" ), 
"integer64" );
   100   mFieldTypeBox->addItem( 
tr( 
"Decimal number (real)" ), 
"real" );
   101   mFieldTypeBox->addItem( 
tr( 
"Date" ), 
"date" );
   102   mFieldTypeBox->addItem( 
tr( 
"Date&time" ), 
"datetime" );
   104   mOkButton = buttonBox->button( QDialogButtonBox::Ok );
   110   mCrsSelector->setCrs( defaultCrs );
   112   connect( mFieldNameEdit, SIGNAL( textChanged( 
const QString& ) ), 
this, SLOT( fieldNameChanged( 
QString ) ) );
   113   connect( mAttributeView, SIGNAL( itemSelectionChanged() ), 
this, SLOT( selectionChanged() ) );
   114   connect( mTableNameEdit, SIGNAL( textChanged( 
const QString& ) ), 
this, SLOT( checkOk() ) );
   115   connect( mDatabaseEdit, SIGNAL( textChanged( 
const QString& ) ), 
this, SLOT( checkOk() ) );
   117   mAddAttributeButton->setEnabled( 
false );
   118   mRemoveAttributeButton->setEnabled( 
false );
   120 #ifndef SUPPORT_SPATIAL_INDEX   121   mCheckBoxCreateSpatialIndex->hide();
   122   mCheckBoxCreateSpatialIndex->setChecked( 
false );
   124   mCheckBoxCreateSpatialIndex->setChecked( 
true );
   127 #ifndef SUPPORT_IDENTIFIER_DESCRIPTION   128   mLayerIdentifierLabel->hide();
   129   mLayerIdentifierEdit->hide();
   130   mLayerDescriptionLabel->hide();
   131   mLayerDescriptionEdit->hide();
   134 #ifndef SUPPORT_FIELD_WIDTH   135   mFieldLengthLabel->hide();
   136   mFieldLengthEdit->hide();
   146 void QgsNewGeoPackageLayerDialog::on_mFieldTypeBox_currentIndexChanged( 
int )
   148   QString myType = mFieldTypeBox->itemData( mFieldTypeBox->currentIndex(), Qt::UserRole ).toString();
   149   mFieldLengthEdit->setEnabled( myType == 
"text" );
   150   if ( myType != 
"text" )
   151     mFieldLengthEdit->setText( 
"" );
   155 void QgsNewGeoPackageLayerDialog::on_mGeometryTypeBox_currentIndexChanged( 
int )
   157   OGRwkbGeometryType geomType = 
static_cast<OGRwkbGeometryType
>   158                                 ( mGeometryTypeBox->itemData( mGeometryTypeBox->currentIndex(), Qt::UserRole ).toInt() );
   159   bool isSpatial = geomType != wkbNone;
   160   mGeometryColumnEdit->setEnabled( isSpatial );
   161   mCheckBoxCreateSpatialIndex->setEnabled( isSpatial );
   162   mCrsSelector->setEnabled( isSpatial );
   165 void QgsNewGeoPackageLayerDialog::on_mSelectDatabaseButton_clicked()
   169                      tr( 
"GeoPackage" ) + 
" (*.gpkg)",
   171                      QFileDialog::DontConfirmOverwrite );
   176   if ( !fileName.
endsWith( 
".gpkg", Qt::CaseInsensitive ) )
   181   mDatabaseEdit->setText( fileName );
   184 void QgsNewGeoPackageLayerDialog::on_mDatabaseEdit_textChanged( 
const QString& text )
   186   if ( !text.
isEmpty() && !mTableNameEdited )
   189     mTableNameEdit->setText( fileInfo.
baseName() );
   193 void QgsNewGeoPackageLayerDialog::on_mTableNameEdit_textChanged( 
const QString& text )
   195   mTableNameEdited = !text.
isEmpty();
   196   if ( !text.
isEmpty() && !mLayerIdentifierEdited )
   198     mLayerIdentifierEdit->setText( text );
   202 void QgsNewGeoPackageLayerDialog::on_mTableNameEdit_textEdited( 
const QString& text )
   205   mTableNameEdited = !text.
isEmpty();
   208 void QgsNewGeoPackageLayerDialog::on_mLayerIdentifierEdit_textEdited( 
const QString& text )
   211   mLayerIdentifierEdited = !text.
isEmpty();
   214 void QgsNewGeoPackageLayerDialog::checkOk()
   216   bool ok = !mDatabaseEdit->text().isEmpty() &&
   217             !mTableNameEdit->text().isEmpty();
   221 void QgsNewGeoPackageLayerDialog::on_mAddAttributeButton_clicked()
   223   if ( !mFieldNameEdit->text().isEmpty() )
   225     QString myName = mFieldNameEdit->text();
   226     if ( myName == mFeatureIdColumnEdit->text() )
   228       QMessageBox::critical( 
this, 
tr( 
"Invalid field name" ), 
tr( 
"The field cannot have the same name as the feature identifier" ) );
   233     QString myType = mFieldTypeBox->itemData( mFieldTypeBox->currentIndex(), Qt::UserRole ).toString();
   234     QString length = mFieldLengthEdit->text();
   239     mFieldNameEdit->clear();
   243 void QgsNewGeoPackageLayerDialog::on_mRemoveAttributeButton_clicked()
   245   delete mAttributeView->currentItem();
   250 void QgsNewGeoPackageLayerDialog::fieldNameChanged( 
const QString& 
name )
   252   mAddAttributeButton->setDisabled( name.
isEmpty() || ! mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
   255 void QgsNewGeoPackageLayerDialog::selectionChanged()
   257   mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
   260 void QgsNewGeoPackageLayerDialog::on_buttonBox_accepted()
   266 void QgsNewGeoPackageLayerDialog::on_buttonBox_rejected()
   271 bool QgsNewGeoPackageLayerDialog::apply()
   273   QString fileName( mDatabaseEdit->text() );
   274   bool createNewDb = 
false;
   278     msgBox.
setIcon( QMessageBox::Question );
   280     msgBox.
setText( 
tr( 
"Do you want to overwrite the existing file with a new database or add a new layer to it?" ) );
   285     bool overwrite = 
false;
   287     if ( 
property( 
"hideDialogs" ).toBool() )
   289       overwrite = 
property( 
"question_existing_db_answer_overwrite" ).
toBool();
   291         cancel = !
property( 
"question_existing_db_answer_add_new_layer" ).
toBool();
   295       int ret = msgBox.
exec();
   296       if ( ret == QMessageBox::Cancel )
   316   OGRSFDriverH hGpkgDriver = OGRGetDriverByName( 
"GPKG" );
   319     if ( !
property( 
"hideDialogs" ).toBool() )
   321                              tr( 
"GeoPackage driver not found" ) );
   325   OGRDataSourceH hDS = 
nullptr;
   328     hDS = OGR_Dr_CreateDataSource( hGpkgDriver, fileName.toUtf8().constData(), nullptr );
   332       if ( !
property( 
"hideDialogs" ).toBool() )
   339     OGRSFDriverH hDriver = 
nullptr;
   340     hDS = OGROpen( fileName.toUtf8().constData(), 
true, &hDriver );
   344       if ( !
property( 
"hideDialogs" ).toBool() )
   348     if ( hDriver != hGpkgDriver )
   350       QString msg( 
tr( 
"Opening of file succeeded, but this is not a GeoPackage database" ) );
   351       if ( !
property( 
"hideDialogs" ).toBool() )
   353       OGR_DS_Destroy( hDS );
   358   QString tableName( mTableNameEdit->text() );
   360   bool overwriteTable = 
false;
   361   if ( OGR_DS_GetLayerByName( hDS, tableName.toUtf8().constData() ) != 
nullptr )
   365       overwriteTable = 
property( 
"question_existing_layer_answer_overwrite" ).
toBool();
   368                                      tr( 
"A table with the same name already exists. Do you want to overwrite it?" ),
   369                                      QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
   371       overwriteTable = 
true;
   374     if ( !overwriteTable )
   376       OGR_DS_Destroy( hDS );
   381   QString layerIdentifier( mLayerIdentifierEdit->text() );
   382   QString layerDescription( mLayerDescriptionEdit->text() );
   384   OGRwkbGeometryType wkbType = 
static_cast<OGRwkbGeometryType
>   385                                ( mGeometryTypeBox->itemData( mGeometryTypeBox->currentIndex(), Qt::UserRole ).toInt() );
   389   int crsId = mCrsSelector->crs().srsid();
   390   if ( wkbType != wkbNone && crsId > 0 )
   398   char **options = 
nullptr;
   400   if ( overwriteTable )
   401     options = CSLSetNameValue( options, 
"OVERWRITE", 
"YES" );
   402   if ( !layerIdentifier.isEmpty() )
   403     options = CSLSetNameValue( options, 
"IDENTIFIER", layerIdentifier.toUtf8().constData() );
   404   if ( !layerDescription.isEmpty() )
   405     options = CSLSetNameValue( options, 
"DESCRIPTION", layerDescription.toUtf8().constData() );
   407   QString featureId( mFeatureIdColumnEdit->text() );
   408   if ( !featureId.isEmpty() )
   409     options = CSLSetNameValue( options, 
"FID", featureId.toUtf8().constData() );
   411   QString geometryColumn( mGeometryColumnEdit->text() );
   412   if ( wkbType != wkbNone && !geometryColumn.isEmpty() )
   413     options = CSLSetNameValue( options, 
"GEOMETRY_COLUMN", geometryColumn.toUtf8().constData() );
   415 #ifdef SUPPORT_SPATIAL_INDEX   416   if ( wkbType != wkbNone )
   417     options = CSLSetNameValue( options, 
"SPATIAL_INDEX", mCheckBoxCreateSpatialIndex->isChecked() ? 
"YES" : 
"NO" );
   420   OGRLayerH hLayer = OGR_DS_CreateLayer( hDS, tableName.toUtf8().constData(), hSRS, wkbType, options );
   421   CSLDestroy( options );
   422   if ( hSRS != 
nullptr )
   424   if ( hLayer == 
nullptr )
   427     if ( !
property( 
"hideDialogs" ).toBool() )
   429     OGR_DS_Destroy( hDS );
   436     QString fieldName(( *it )->text( 0 ) );
   437     QString fieldType(( *it )->text( 1 ) );
   438     QString fieldWidth(( *it )->text( 2 ) );
   440     OGRFieldType ogrType( OFTString );
   441     if ( fieldType == 
"text" )
   443     else if ( fieldType == 
"integer" )
   444       ogrType = OFTInteger;
   445 #ifdef SUPPORT_INTEGER64   446     else if ( fieldType == 
"integer64" )
   447       ogrType = OFTInteger64;
   449     else if ( fieldType == 
"real" )
   451     else if ( fieldType == 
"date" )
   453     else if ( fieldType == 
"datetime" )
   454       ogrType = OFTDateTime;
   456     int ogrWidth = fieldWidth.toInt();
   458     OGRFieldDefnH fld = OGR_Fld_Create( fieldName.toUtf8().constData(), ogrType );
   459     OGR_Fld_SetWidth( fld, ogrWidth );
   461     if ( OGR_L_CreateField( hLayer, fld, 
true ) != OGRERR_NONE )
   463       if ( !
property( 
"hideDialogs" ).toBool() )
   466                                tr( 
"Creation of field %1 failed (OGR error: %2)" )
   469       OGR_Fld_Destroy( fld );
   470       OGR_DS_Destroy( hDS );
   473     OGR_Fld_Destroy( fld );
   481   OGR_L_ResetReading( hLayer );
   482   if ( CPLGetLastErrorType() != CE_None )
   485     if ( !
property( 
"hideDialogs" ).toBool() )
   487     OGR_DS_Destroy( hDS );
   491   OGR_DS_Destroy( hDS );
   493   QString uri( 
QString( 
"%1|layername=%2" ).arg( mDatabaseEdit->text(), tableName ) );
   494   QString userVisiblelayerName( layerIdentifier.isEmpty() ? tableName : layerIdentifier );
   496   if ( layer->isValid() )
 QByteArray toByteArray() const
QgsCoordinateReferenceSystem crsByOgcWmsCrs(const QString &ogcCrs) const
Returns the CRS from a given OGC WMS-format Coordinate Reference System string. 
void validate()
Perform some validation on this CRS. 
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon. 
QString tr(const char *sourceText, const char *disambiguation, int n)
QgsCoordinateReferenceSystem crsBySrsId(long srsId) const
Returns the CRS from a specified QGIS SRS ID. 
void setValue(const QString &key, const QVariant &value)
const char * name() const
QString fromUtf8(const char *str, int size)
QVariant property(const char *name) const
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers. 
StandardButton question(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
void setWindowTitle(const QString &title)
void setText(const QString &text)
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority. 
QByteArray toLocal8Bit() const
QVariant value(const QString &key, const QVariant &defaultValue) const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call. 
QgsNewGeoPackageLayerDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgisGui::ModalDialogFlags)
Constructor. 
Class for storing a coordinate reference system (CRS) 
QString toWkt() const
Returns a WKT representation of this CRS. 
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets. 
~QgsNewGeoPackageLayerDialog()
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static QgsCRSCache * instance()
Returns a pointer to the QgsCRSCache singleton. 
void * OGRSpatialReferenceH