[QGIS-Developer] QgsJsonExporter and order

Jean Felder jean.felder at oslandia.com
Tue Jan 21 10:14:49 PST 2025


Hi,

QgsJsonExporter does not respect the attributes order. This has already 
been discussed in this issue: https://github.com/qgis/QGIS/issues/41290

For example:

```
#!/usr/bin/env python3

from qgis.core import (QgsFeature, QgsGeometry, QgsJsonExporter, QgsPointXY,
                        QgsVectorLayer)

layer = QgsVectorLayer("Point?field=B:string&field=A:integer", "foo", 
"memory")
feature = QgsFeature()
feature.setAttributes(["test", 123])
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
provider = layer.dataProvider()
provider.addFeatures([feature])

exp = QgsJsonExporter(layer)
print(exp.exportFeatures(layer.getFeatures()))
```

The output:
```
{"features":[{"geometry":{"coordinates":[100.0,200.0],"type":"Point"},"id":1,"properties":{"A":123,"B":"test"},"type":"Feature"}],"type":"FeatureCollection"}
```

The layer has been created with the features in the order ["B", "A"]. 
However, QgsJsonExporter returns in the order ["A", "B"]
As answered in the issue, it is not really a bug because according to 
the json specs, "The order of properties in GeoJSON isn’t defined"

However, QgsJsonExporter is used in QGIS Server and for WFS and WMS 
requests.
I got some reports from users who don't understand the difference 
between an xml and a json output of the same request.
Indeed, an xml request will respect the attributes order and return 
["B", "A"]
A json request will not respect the attributes order and return ["A", "B"]
 From a user perspective, this may look like a bug.

In fact, this "issue" comes from our usage of the "nlohmann" library 
used to generate the json.
Indeed, its main object (used by QgsJsonExporter) is `nlohmann::json` 
which does sort the keys by alphabetical order as explained in the 
documentation.
If we want to respect the order of insertion, they provide an other 
object: `nlohmann::ordered_json`
For a full explanation, see:
- https://json.nlohmann.me/features/object_order/
- https://github.com/nlohmann/json?tab=readme-ov-file#order-of-object-keys


So, a proper fix would be to remplace `nlohmann::json` by 
`nlohmann::ordered_json` in all the `QgsJsonExporter` code and its caller.
 From a performance point of view, I guess it would be similar to a 
switch from std::map to std::unordered_map

I don't mind creating a Pull Request to change it but I would like to 
know first if it would be accepted.
Any ideas or opinions?

Thanks,

Jean


-- 
Jean Felder
Développeur SIG
Oslandia

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x12722DC64D3F429E.asc
Type: application/pgp-keys
Size: 2444 bytes
Desc: OpenPGP public key
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20250121/58d0bf33/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 665 bytes
Desc: OpenPGP digital signature
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20250121/58d0bf33/attachment.sig>


More information about the QGIS-Developer mailing list