From 40ed58bffea8cf5f37481d0969e262addf505990 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 May 2024 22:28:24 +0200 Subject: [PATCH] [OGR provider] Mark special Shape_Area/Shape_Length FileGDB fields as read-only --- src/core/providers/ogr/qgsogrprovider.cpp | 11 ++++++++++- tests/src/python/test_provider_ogr.py | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/providers/ogr/qgsogrprovider.cpp b/src/core/providers/ogr/qgsogrprovider.cpp index 2f76ba11800..ee34373ffc9 100644 --- a/src/core/providers/ogr/qgsogrprovider.cpp +++ b/src/core/providers/ogr/qgsogrprovider.cpp @@ -875,7 +875,16 @@ void QgsOgrProvider::loadFields() // check if field has default value QString defaultValue = textEncoding()->toUnicode( OGR_Fld_GetDefault( fldDef ) ); - if ( !defaultValue.isEmpty() && !OGR_Fld_IsDefaultDriverSpecific( fldDef ) ) + if ( defaultValue == QLatin1String( "FILEGEODATABASE_SHAPE_LENGTH" ) || + defaultValue == QLatin1String( "FILEGEODATABASE_SHAPE_AREA" ) ) + { + // FileGeodatabase may have special fields with autocomputed geometry + // length and area. Their content is generated by the driver. The + // user must not fill it (if they do, it will be overridden by the + // driver) + newField.setReadOnly( true ); + } + else if ( !defaultValue.isEmpty() && !OGR_Fld_IsDefaultDriverSpecific( fldDef ) ) { if ( defaultValue.startsWith( '\'' ) ) { diff --git a/tests/src/python/test_provider_ogr.py b/tests/src/python/test_provider_ogr.py index 9cce2949f46..f176bf458ba 100644 --- a/tests/src/python/test_provider_ogr.py +++ b/tests/src/python/test_provider_ogr.py @@ -3597,6 +3597,18 @@ class PyQgsOGRProvider(QgisTestCase): self.assertAlmostEqual(vl.extent3D().zMaximum(), 105.6, places=3) del vl + @unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 6, 0), "GDAL 3.6 required") + def testReadOnlyFieldsFileGeodatabase(self): + + with tempfile.TemporaryDirectory() as temp_dir: + dest_file_name = os.path.join(temp_dir, 'testReadOnlyFieldsFileGeodatabase.gdb') + ds = ogr.GetDriverByName("OpenFileGDB").CreateDataSource(dest_file_name) + ds.CreateLayer("test", geom_type=ogr.wkbPolygon, options=["CREATE_SHAPE_AREA_AND_LENGTH_FIELDS=YES"]) + ds = None + + vl = QgsVectorLayer(dest_file_name, 'vl') + self.assertTrue(vl.fields()["Shape_Area"].isReadOnly()) + if __name__ == '__main__': unittest.main()