Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix geojson attr table field order
Fixes #45139

See GH issue #45139 for the long explanation.
  • Loading branch information
elpaso committed Sep 21, 2021
1 parent 5950326 commit 46c7c12
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -3720,7 +3720,7 @@ bool QgsOgrProvider::leaveUpdateMode()
{
// Backup fields since if we created new fields, but didn't populate it
// with any feature yet, it will disappear.
QgsFields oldFields = mAttributeFields;
const QgsFields oldFields = mAttributeFields;
reloadData();
if ( mValid )
{
Expand All @@ -3734,9 +3734,9 @@ bool QgsOgrProvider::leaveUpdateMode()
{
bool ignoreErrorOut = false;
addAttributeOGRLevel( field, ignoreErrorOut );
mAttributeFields.append( field );
}
}
mAttributeFields = oldFields;
}
}
return true;
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/ogr/qgsogrprovider.h
Expand Up @@ -329,6 +329,7 @@ class QgsOgrProvider final: public QgsVectorDataProvider
* and the new file will be opened.
*/
void reloadProviderData() override;

};

///@endcond
Expand Down
11 changes: 10 additions & 1 deletion src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -3495,10 +3495,18 @@ bool QgsVectorLayer::commitChanges( bool stopEditing )
}

updateFields();
mDataProvider->updateExtents();

mDataProvider->updateExtents();
mDataProvider->leaveUpdateMode();

// This second call is required because OGR provider with JSON
// driver might have changed fields order after the call to
// leaveUpdateMode
if ( mFields.names() != mDataProvider->fields().names() )
{
updateFields();
}

triggerRepaint();

return success;
Expand Down Expand Up @@ -4025,6 +4033,7 @@ void QgsVectorLayer::updateFields()
emit updatedFields();
mEditFormConfig.setFields( mFields );
}

}


Expand Down
66 changes: 66 additions & 0 deletions tests/src/python/test_provider_ogr.py
Expand Up @@ -2247,6 +2247,72 @@ def test_provider_sidecar_files_for_uri(self):
['/home/me/special.gfs', '/home/me/special.xsd'])
self.assertEqual(metadata.sidecarFilesForUri('/home/me/special.csv'), ['/home/me/special.csvt'])

def testGeoJsonFieldOrder(self):
"""Test issue GH #45139"""

d = QTemporaryDir()
json_path = os.path.join(d.path(), 'test.geojson')
with open(json_path, 'w+') as f:
f.write("""
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [11.1215698,46.0677293]
},
"properties": {
"A": "A",
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [11.1214686,46.0677385]
},
"properties": {
"A": "A",
"B": "B",
}
}
]
}
""")

vl = QgsVectorLayer(json_path, 'json')
self.assertTrue(vl.isValid())
self.assertEqual(vl.featureCount(), 2)
self.assertEqual(vl.fields().names(), ['A', 'B'])

# Append a field
self.assertTrue(vl.startEditing())
self.assertTrue(vl.addAttribute(QgsField('C', QVariant.String)))

for f in vl.getFeatures():
vl.changeAttributeValue(f.id(), 2, 'C')

self.assertEqual(vl.fields().names(), ['A', 'B', 'C'])

features = [f for f in vl.getFeatures()]

self.assertEqual(features[0].attribute('B'), NULL)
self.assertEqual(features[0].attribute('C'), 'C')
self.assertEqual(features[1].attribute('B'), 'B')
self.assertEqual(features[1].attribute('C'), 'C')

self.assertTrue(vl.commitChanges())
self.assertEqual(vl.fields().names(), ['A', 'C', 'B'])

features = [f for f in vl.getFeatures()]

self.assertEqual(features[0].attribute('B'), NULL)
self.assertEqual(features[0].attribute('C'), 'C')
self.assertEqual(features[1].attribute('B'), 'B')
self.assertEqual(features[1].attribute('C'), 'C')


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

0 comments on commit 46c7c12

Please sign in to comment.