Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #52774 from elpaso/bugfix-gh52677-json-map-write
GPKG: fix json map filewriter
  • Loading branch information
elpaso committed Apr 21, 2023
2 parents 456d725 + 4ffed5b commit 7557095
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/core/qgsvectorfilewriter.cpp
Expand Up @@ -703,6 +703,21 @@ void QgsVectorFileWriter::init( QString vectorFileName,
break;
}

case QVariant::Map:
{
// handle GPKG conversion to JSON
const char *pszDataSubTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATASUBTYPES, nullptr );
if ( pszDataSubTypes && strstr( pszDataSubTypes, "JSON" ) )
{
ogrType = OFTString;
ogrSubType = OFSTJSON;
break;
}
}

//intentional fall-through
FALLTHROUGH

case QVariant::List:
// handle GPKG conversion to JSON
if ( mOgrDriverName == QLatin1String( "GPKG" ) )
Expand Down Expand Up @@ -2923,6 +2938,28 @@ gdal::ogr_feature_unique_ptr QgsVectorFileWriter::createFeature( const QgsFeatur
//intentional fall-through
FALLTHROUGH

case QVariant::Map:
{
// handle GPKG conversion to JSON
const char *pszDataSubTypes = GDALGetMetadataItem( OGRGetDriverByName( mOgrDriverName.toLocal8Bit().constData() ), GDAL_DMD_CREATIONFIELDDATASUBTYPES, nullptr );
if ( pszDataSubTypes && strstr( pszDataSubTypes, "JSON" ) )
{
const QJsonDocument doc = QJsonDocument::fromVariant( attrValue );
QString jsonString;
if ( !doc.isNull() )
{
const QByteArray json { doc.toJson( QJsonDocument::Compact ) };
jsonString = QString::fromUtf8( json.data() );
}
OGR_F_SetFieldString( poFeature.get(), ogrField, mCodec->fromUnicode( jsonString.constData() ) );
break;
}
}

//intentional fall-through
FALLTHROUGH


default:
mErrorMessage = QObject::tr( "Invalid variant type for field %1[%2]: received %3 with type %4" )
.arg( mFields.at( fldIdx ).name() )
Expand Down
43 changes: 43 additions & 0 deletions tests/src/python/test_qgsvectorfilewriter.py
Expand Up @@ -12,6 +12,7 @@

import os
import tempfile
import json

import osgeo.gdal # NOQA
import qgis # NOQA
Expand Down Expand Up @@ -1602,6 +1603,48 @@ def testWriteUnsetAttributeToGpkg(self):
f = next(features)
self.assertEqual(f['int'], 12345)

@unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 7, 0), "GDAL 3.7 required")
def testWriteJsonMapToGpkg(self):

tmp_dir = QTemporaryDir()
tmp_path = tmp_dir.path()
dest_file_name = os.path.join(tmp_path, 'test.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(dest_file_name)
lyr = ds.CreateLayer('testLayer', geom_type=ogr.wkbLineString, options=['SPATIAL_INDEX=NO'])
field_def = ogr.FieldDefn('text_field', ogr.OFTString)
field_def.SetSubType(ogr.OFSTJSON)
lyr.CreateField(field_def)
f = ogr.Feature(lyr.GetLayerDefn())
attr_val = {'my_int': 1, 'my_str': 'str', 'my_list': [1, 2, 3]}
f['text_field'] = json.dumps(attr_val)
f.SetGeometry(ogr.CreateGeometryFromWkt('LINESTRING(1 2,3 4)'))
lyr.CreateFeature(f)
f = None
ds = None

layer = QgsVectorLayer(dest_file_name)
fields = layer.fields()
field = fields.at(1)
self.assertEqual(field.type(), QVariant.Map)
f = next(layer.getFeatures())
self.assertEqual(f.attributes()[1], attr_val)

dest_file_name_exported = os.path.join(tmp_path, 'test_exported.gpkg')
write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
layer,
dest_file_name_exported,
'utf-8',
layer.crs(),
'GPKG')
self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message)

layer = QgsVectorLayer(dest_file_name_exported)
fields = layer.fields()
field = fields.at(1)
self.assertEqual(field.type(), QVariant.Map)
f = next(layer.getFeatures())
self.assertEqual(f.attributes()[1], attr_val)


if __name__ == '__main__':
unittest.main()

0 comments on commit 7557095

Please sign in to comment.