Skip to content

Commit 82c2aaa

Browse files
committed
[OGR provider] Fix adding a new GeoJSON field, starting a new edit session and filling it (fixes #7205)
1 parent 7f85cee commit 82c2aaa

File tree

2 files changed

+87
-57
lines changed

2 files changed

+87
-57
lines changed

src/providers/ogr/qgsogrprovider.cpp

+85-57
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,73 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList &flist, Flags flags )
15481548
return returnvalue;
15491549
}
15501550

1551+
bool QgsOgrProvider::addAttributeOGRLevel( const QgsField &field, bool &ignoreErrorOut )
1552+
{
1553+
ignoreErrorOut = false;
1554+
1555+
OGRFieldType type;
1556+
1557+
switch ( field.type() )
1558+
{
1559+
case QVariant::Int:
1560+
case QVariant::Bool:
1561+
type = OFTInteger;
1562+
break;
1563+
case QVariant::LongLong:
1564+
{
1565+
const char *pszDataTypes = GDALGetMetadataItem( mOgrLayer->driver(), GDAL_DMD_CREATIONFIELDDATATYPES, nullptr );
1566+
if ( pszDataTypes && strstr( pszDataTypes, "Integer64" ) )
1567+
type = OFTInteger64;
1568+
else
1569+
{
1570+
type = OFTReal;
1571+
}
1572+
break;
1573+
}
1574+
case QVariant::Double:
1575+
type = OFTReal;
1576+
break;
1577+
case QVariant::Date:
1578+
type = OFTDate;
1579+
break;
1580+
case QVariant::Time:
1581+
type = OFTTime;
1582+
break;
1583+
case QVariant::DateTime:
1584+
type = OFTDateTime;
1585+
break;
1586+
case QVariant::String:
1587+
type = OFTString;
1588+
break;
1589+
default:
1590+
pushError( tr( "type %1 for field %2 not found" ).arg( field.typeName(), field.name() ) );
1591+
ignoreErrorOut = true;
1592+
return false;
1593+
}
1594+
1595+
gdal::ogr_field_def_unique_ptr fielddefn( OGR_Fld_Create( textEncoding()->fromUnicode( field.name() ).constData(), type ) );
1596+
int width = field.length();
1597+
if ( field.precision() )
1598+
width += 1;
1599+
OGR_Fld_SetWidth( fielddefn.get(), width );
1600+
OGR_Fld_SetPrecision( fielddefn.get(), field.precision() );
1601+
1602+
switch ( field.type() )
1603+
{
1604+
case QVariant::Bool:
1605+
OGR_Fld_SetSubType( fielddefn.get(), OFSTBoolean );
1606+
default:
1607+
break;
1608+
}
1609+
1610+
if ( mOgrLayer->CreateField( fielddefn.get(), true ) != OGRERR_NONE )
1611+
{
1612+
pushError( tr( "OGR error creating field %1: %2" ).arg( field.name(), CPLGetLastErrorMsg() ) );
1613+
return false;
1614+
}
1615+
return true;
1616+
}
1617+
15511618
bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
15521619
{
15531620
if ( !doInitialActionsForEdition() )
@@ -1564,69 +1631,18 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
15641631

15651632
QMap< QString, QgsField > mapFieldNameToOriginalField;
15661633

1567-
for ( QList<QgsField>::const_iterator iter = attributes.constBegin(); iter != attributes.constEnd(); ++iter )
1634+
for ( const auto &field : attributes )
15681635
{
1569-
mapFieldNameToOriginalField[ iter->name()] = *iter;
1636+
mapFieldNameToOriginalField[ field.name()] = field;
15701637

1571-
OGRFieldType type;
1572-
1573-
switch ( iter->type() )
1638+
bool ignoreErrorOut = false;
1639+
if ( !addAttributeOGRLevel( field, ignoreErrorOut ) )
15741640
{
1575-
case QVariant::Int:
1576-
case QVariant::Bool:
1577-
type = OFTInteger;
1578-
break;
1579-
case QVariant::LongLong:
1641+
returnvalue = false;
1642+
if ( !ignoreErrorOut )
15801643
{
1581-
const char *pszDataTypes = GDALGetMetadataItem( mOgrLayer->driver(), GDAL_DMD_CREATIONFIELDDATATYPES, nullptr );
1582-
if ( pszDataTypes && strstr( pszDataTypes, "Integer64" ) )
1583-
type = OFTInteger64;
1584-
else
1585-
{
1586-
type = OFTReal;
1587-
}
15881644
break;
15891645
}
1590-
case QVariant::Double:
1591-
type = OFTReal;
1592-
break;
1593-
case QVariant::Date:
1594-
type = OFTDate;
1595-
break;
1596-
case QVariant::Time:
1597-
type = OFTTime;
1598-
break;
1599-
case QVariant::DateTime:
1600-
type = OFTDateTime;
1601-
break;
1602-
case QVariant::String:
1603-
type = OFTString;
1604-
break;
1605-
default:
1606-
pushError( tr( "type %1 for field %2 not found" ).arg( iter->typeName(), iter->name() ) );
1607-
returnvalue = false;
1608-
continue;
1609-
}
1610-
1611-
gdal::ogr_field_def_unique_ptr fielddefn( OGR_Fld_Create( textEncoding()->fromUnicode( iter->name() ).constData(), type ) );
1612-
int width = iter->length();
1613-
if ( iter->precision() )
1614-
width += 1;
1615-
OGR_Fld_SetWidth( fielddefn.get(), width );
1616-
OGR_Fld_SetPrecision( fielddefn.get(), iter->precision() );
1617-
1618-
switch ( iter->type() )
1619-
{
1620-
case QVariant::Bool:
1621-
OGR_Fld_SetSubType( fielddefn.get(), OFSTBoolean );
1622-
default:
1623-
break;
1624-
}
1625-
1626-
if ( mOgrLayer->CreateField( fielddefn.get(), true ) != OGRERR_NONE )
1627-
{
1628-
pushError( tr( "OGR error creating field %1: %2" ).arg( iter->name(), CPLGetLastErrorMsg() ) );
1629-
returnvalue = false;
16301646
}
16311647
}
16321648

@@ -4270,6 +4286,18 @@ bool QgsOgrProvider::leaveUpdateMode()
42704286
reloadData();
42714287
if ( mValid )
42724288
{
4289+
// Make sure that new fields we added, but didn't populate yet, are
4290+
// recreated at the OGR level, otherwise we won't be able to populate
4291+
// them.
4292+
for ( const auto &field : oldFields )
4293+
{
4294+
int idx = mAttributeFields.lookupField( field.name() );
4295+
if ( idx < 0 )
4296+
{
4297+
bool ignoreErrorOut = false;
4298+
addAttributeOGRLevel( field, ignoreErrorOut );
4299+
}
4300+
}
42734301
mAttributeFields = oldFields;
42744302
}
42754303
}

src/providers/ogr/qgsogrprovider.h

+2
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ class QgsOgrProvider : public QgsVectorDataProvider
313313

314314
bool doInitialActionsForEdition();
315315

316+
bool addAttributeOGRLevel( const QgsField &field, bool &ignoreErrorOut );
317+
316318
#ifndef QT_NO_NETWORKPROXY
317319
void setupProxy();
318320
#endif

0 commit comments

Comments
 (0)