Skip to content

Commit

Permalink
Create shapefile layer: allow to create Bool fields
Browse files Browse the repository at this point in the history
Fixes #60324
  • Loading branch information
rouault authored and nyalldawson committed Jan 29, 2025
1 parent 55d788f commit a5ebd6c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/core/providers/ogr/qgsogrproviderutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,11 @@ bool QgsOgrProviderUtils::createEmptyDataSource( const QString &uri,
{
field = OGR_Fld_Create( codec->fromUnicode( it->first ).constData(), OFTDateTime );
}
else if ( fields[0] == QLatin1String( "bool" ) )
{
field = OGR_Fld_Create( codec->fromUnicode( it->first ).constData(), OFTInteger );
OGR_Fld_SetSubType( field, OFSTBoolean );
}
else
{
QgsMessageLog::logMessage( QObject::tr( "field %1 with unsupported type %2 skipped" ).arg( it->first, fields[0] ), QObject::tr( "OGR" ) );
Expand Down
13 changes: 12 additions & 1 deletion src/gui/qgsnewvectorlayerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "qgsvariantutils.h"
#include "qgsogrproviderutils.h"

#include <gdal.h>

#include <QPushButton>
#include <QComboBox>
#include <QFileDialog>
Expand All @@ -57,6 +59,9 @@ QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WindowFla
mTypeBox->addItem( QgsFields::iconForFieldType( QMetaType::Type::Int ), QgsVariantUtils::typeToDisplayString( QMetaType::Type::Int ), "Integer" );
mTypeBox->addItem( QgsFields::iconForFieldType( QMetaType::Type::Double ), QgsVariantUtils::typeToDisplayString( QMetaType::Type::Double ), "Real" );
mTypeBox->addItem( QgsFields::iconForFieldType( QMetaType::Type::QDate ), QgsVariantUtils::typeToDisplayString( QMetaType::Type::QDate ), "Date" );
#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 )
mTypeBox->addItem( QgsFields::iconForFieldType( QMetaType::Type::Bool ), QgsVariantUtils::typeToDisplayString( QMetaType::Type::Bool ), "bool" );
#endif

mWidth->setValidator( new QIntValidator( 1, 255, this ) );
mPrecision->setValidator( new QIntValidator( 0, 15, this ) );
Expand Down Expand Up @@ -154,13 +159,15 @@ void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged( int index )
if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
mWidth->setText( QStringLiteral( "80" ) );
mPrecision->setEnabled( false );
mWidth->setEnabled( true );
mWidth->setValidator( new QIntValidator( 1, 255, this ) );
break;

case 1: // Whole number
if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
mWidth->setText( QStringLiteral( "10" ) );
mPrecision->setEnabled( false );
mWidth->setEnabled( true );
mWidth->setValidator( new QIntValidator( 1, 10, this ) );
break;

Expand All @@ -171,11 +178,15 @@ void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged( int index )
mPrecision->setText( QStringLiteral( "6" ) );

mPrecision->setEnabled( true );
mWidth->setEnabled( true );
mWidth->setValidator( new QIntValidator( 1, 20, this ) );
break;

default:
QgsDebugError( QStringLiteral( "unexpected index" ) );
mPrecision->setEnabled( false );
mWidth->setEnabled( false );
mWidth->clear();
mPrecision->clear();
break;
}
}
Expand Down
36 changes: 36 additions & 0 deletions tests/src/core/testqgsogrutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class TestQgsOgrUtils : public QObject
void testOgrStringToVariant_data();
void testOgrStringToVariant();
void testOgrUtilsStoredStyle();
void testOgrUtilsCreateFields();

#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 3, 0 )
void testConvertFieldDomain();
Expand Down Expand Up @@ -1086,6 +1087,41 @@ void TestQgsOgrUtils::testOgrUtilsStoredStyle()
QCOMPARE( QSet<QString>( names.constBegin(), names.constEnd() ), QSet<QString>() << QStringLiteral( "style1" ) << QStringLiteral( "style2" ) << QStringLiteral( "style3" ) );
}

/**
* Test for issue GH #60324
*/
void TestQgsOgrUtils::testOgrUtilsCreateFields()
{
// Create a test GPKG file with layer in a temporary directory
QTemporaryDir tempDir;
QVERIFY( tempDir.isValid() );
QString tempDirPath = tempDir.path();
QString testFile = tempDirPath + "/test.gpkg";
// Create datasource
QString error;
QList<QPair<QString, QString>> fields;
fields << QPair<QString, QString>( QStringLiteral( "boolfield" ), QStringLiteral( "bool" ) );
fields << QPair<QString, QString>( QStringLiteral( "intfield" ), QStringLiteral( "Integer" ) );
fields << QPair<QString, QString>( QStringLiteral( "realfield" ), QStringLiteral( "Real" ) );
fields << QPair<QString, QString>( QStringLiteral( "stringfield" ), QStringLiteral( "String" ) );
fields << QPair<QString, QString>( QStringLiteral( "datefield" ), QStringLiteral( "Date" ) );
fields << QPair<QString, QString>( QStringLiteral( "datetimefield" ), QStringLiteral( "DateTime" ) );
QVERIFY( QgsOgrProviderUtils::createEmptyDataSource( testFile, QStringLiteral( "GPKG" ), QStringLiteral( "UTF-8" ), Qgis::WkbType::Point, fields, QgsCoordinateReferenceSystem::fromEpsgId( 4326 ), error ) );

// Open the datasource
QgsVectorLayer vl = QgsVectorLayer( testFile, QStringLiteral( "test" ), QStringLiteral( "ogr" ) );
QVERIFY( vl.isValid() );

const QgsFields gotFields = vl.fields();
// Field 0 is the FID
QCOMPARE( gotFields[1].type(), QMetaType::Type::Bool );
QCOMPARE( gotFields[2].type(), QMetaType::Type::Int );
QCOMPARE( gotFields[3].type(), QMetaType::Type::Double );
QCOMPARE( gotFields[4].type(), QMetaType::Type::QString );
QCOMPARE( gotFields[5].type(), QMetaType::Type::QDate );
QCOMPARE( gotFields[6].type(), QMetaType::Type::QDateTime );
}

#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 3, 0 )
void TestQgsOgrUtils::testConvertFieldDomain()
{
Expand Down

0 comments on commit a5ebd6c

Please sign in to comment.