mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-05 00:09:32 -04:00
parent
78aa6f1fc4
commit
107f3169bf
@ -886,9 +886,9 @@ void QgsOgrProvider::loadFields()
|
||||
QMutexLocker locker( datasetMutex );
|
||||
#endif
|
||||
|
||||
for ( int i = 0; i < fdef.GetFieldCount(); ++i )
|
||||
for ( int fieldIndex = 0; fieldIndex < fdef.GetFieldCount(); ++fieldIndex )
|
||||
{
|
||||
OGRFieldDefnH fldDef = fdef.GetFieldDefn( i );
|
||||
OGRFieldDefnH fldDef = fdef.GetFieldDefn( fieldIndex );
|
||||
const OGRFieldType ogrType = OGR_Fld_GetType( fldDef );
|
||||
const OGRFieldSubType ogrSubType = OGR_Fld_GetSubType( fldDef );
|
||||
|
||||
@ -896,6 +896,38 @@ void QgsOgrProvider::loadFields()
|
||||
QMetaType::Type varSubType = QMetaType::Type::UnknownType;
|
||||
QgsOgrUtils::ogrFieldTypeToQVariantType( ogrType, ogrSubType, varType, varSubType );
|
||||
|
||||
// Handle special case for OGRFieldType::OFSTJSON which is not always a map.
|
||||
// If subtype is JSON and varType is map, try to load a feature and check if it's
|
||||
// really an object (rather than something else like an array)
|
||||
// fallback to string given that only JSON object (map) is supported.
|
||||
if ( varType == QMetaType::Type::QVariantMap && ogrSubType == OFSTJSON )
|
||||
{
|
||||
QRecursiveMutex *layerMutex = nullptr;
|
||||
OGRLayerH ogrLayer = mOgrLayer->getHandleAndMutex( layerMutex );
|
||||
QMutexLocker layerLocker( layerMutex );
|
||||
gdal::ogr_feature_unique_ptr f( OGR_L_GetNextFeature( ogrLayer ) );
|
||||
if ( f )
|
||||
{
|
||||
const char *json = OGR_F_GetFieldAsString( f.get(), fieldIndex );
|
||||
if ( json && json[0] != '\0' )
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto json_element = json::parse( json );
|
||||
if ( ! json_element.is_object() )
|
||||
{
|
||||
varType = QMetaType::Type::QString;
|
||||
}
|
||||
}
|
||||
catch ( const json::parse_error & )
|
||||
{
|
||||
varType = QMetaType::Type::QString;
|
||||
}
|
||||
}
|
||||
OGR_L_ResetReading( ogrLayer );
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: fix this hack
|
||||
#ifdef ANDROID
|
||||
QString name = OGR_Fld_GetNameRef( fldDef );
|
||||
|
@ -1862,7 +1862,6 @@ void QgsOgrUtils::ogrFieldTypeToQVariantType( OGRFieldType ogrType, OGRFieldSubT
|
||||
case OFTWideString:
|
||||
if ( ogrSubType == OFSTJSON )
|
||||
{
|
||||
ogrSubType = OFSTJSON;
|
||||
variantType = QMetaType::Type::QVariantMap;
|
||||
variantSubType = QMetaType::Type::QString;
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ class TestQgsOgrProvider : public QgsTest
|
||||
void testExtent();
|
||||
void testVsiCredentialOptions();
|
||||
void testVsiCredentialOptionsQuerySublayers();
|
||||
void testJSONFields_data();
|
||||
void testJSONFields();
|
||||
|
||||
private:
|
||||
QString mTestDataDir;
|
||||
@ -579,5 +581,168 @@ void TestQgsOgrProvider::testVsiCredentialOptionsQuerySublayers()
|
||||
}
|
||||
|
||||
|
||||
void TestQgsOgrProvider::testJSONFields_data()
|
||||
{
|
||||
QTest::addColumn<QString>( "jsonData" );
|
||||
QTest::addColumn<int>( "expectedType" );
|
||||
|
||||
QTest::newRow( "array of map" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"array_of_map": [
|
||||
{
|
||||
"a": 1,
|
||||
"b": 2.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QString );
|
||||
|
||||
QTest::newRow( "map" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"map": {
|
||||
"a": 1,
|
||||
"b": 2.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QVariantMap );
|
||||
|
||||
QTest::newRow( "int" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"int": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::Int );
|
||||
|
||||
QTest::newRow( "stringlist" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"string_list": [ "a", "b", "c" ]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QStringList );
|
||||
|
||||
QTest::newRow( "string" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"string": "a"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QString );
|
||||
|
||||
QTest::newRow( "double" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"double": 1.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::Double );
|
||||
|
||||
QTest::newRow( "bool" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"bool": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::Bool );
|
||||
|
||||
QTest::newRow( "int list" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"int_list": [1, 2, 3]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QVariantList );
|
||||
|
||||
QTest::newRow( "real list" ) << QStringLiteral( R"json(
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"real_list": [1.0, 2.1, 3]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)json" ) << static_cast<int>( QMetaType::Type::QVariantList );
|
||||
}
|
||||
|
||||
void TestQgsOgrProvider::testJSONFields()
|
||||
{
|
||||
QFETCH( QString, jsonData );
|
||||
QFETCH( int, expectedType );
|
||||
|
||||
QTemporaryDir dir;
|
||||
QString filePath = dir.path() + "/test.json";
|
||||
QFile file( filePath );
|
||||
if ( file.open( QIODevice::WriteOnly ) )
|
||||
{
|
||||
QTextStream textStream( &file );
|
||||
textStream << jsonData;
|
||||
file.close();
|
||||
}
|
||||
QgsVectorLayer layer { filePath, QStringLiteral( "json" ), QLatin1String( "ogr" ) };
|
||||
QVERIFY( layer.isValid() );
|
||||
QgsFields fields = layer.fields();
|
||||
QCOMPARE( fields.count(), 1 );
|
||||
QgsField field = fields.at( 0 );
|
||||
QCOMPARE( static_cast<int>( field.type() ), expectedType );
|
||||
}
|
||||
|
||||
|
||||
QGSTEST_MAIN( TestQgsOgrProvider )
|
||||
#include "testqgsogrprovider.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user