From 425cc4063f45feb2a508d63dd43bf2572d7844d5 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 21 Jun 2024 23:28:41 +0200 Subject: webmap-import: Improve OGRFieldDefn::[GS]et*() capability detection. The PostgreSQL driver doesn't support AlternativeName, for instance. --- webmap-import | 78 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/webmap-import b/webmap-import index 8512e6d..c1d07a3 100755 --- a/webmap-import +++ b/webmap-import @@ -330,19 +330,44 @@ def formatTZFlag(tzFlag): tzSign = '+' if tzFlag > 100 else '-' return f'{tzSign}{tzHour:02}{tzMinute:02}' +def setFieldIf(cond, attrName, val, data, fldName, drvName, log=logging.warning): + if cond: + data[attrName] = val + else: + if isinstance(val, str): + val2 = '"' + val + '"' + else: + val2 = str(val) + log('Ignoring %s=%s on field "%s" (not supported by %s driver)', + attrName, val2, fldName, drvName) + # Validate layer creation options and schema. The schema is modified in # place with the parsed result. # (We need the driver of the output dataset to determine capability on # constraints.) def validateSchema(layers, drvo=None, lco_defaults=None): - # cache driver capabilities - drvoSupportsDefaultFields = getMetadataItem(drvo, GDAL_DCAP_DEFAULT_FIELDS) - drvoSupportsNotNULLFields = getMetadataItem(drvo, GDAL_DCAP_NOTNULL_FIELDS) - drvoSupportsUniqueFields = getMetadataItem(drvo, GDAL_DCAP_UNIQUE_FIELDS) - # Cf. https://github.com/OSGeo/gdal/blob/master/NEWS.md - hasCommentSupport = common.gdal_version_min(maj=3, min=7) # GetComment()/SetComment() added in 3.7.0 - hasTZFlagSupport = common.gdal_version_min(maj=3, min=8) # GetTZFlag()/SetTZFlag() and OGR_TZFLAG_* constants added in 3.8.0 + if common.gdal_version_min(maj=3, min=7): + # list of capability flags supported by the CreateField() API + drvoFieldDefnFlags = drvo.GetMetadataItem(gdalconst.DMD_CREATION_FIELD_DEFN_FLAGS) + drvoFieldDefnFlags = drvoFieldDefnFlags.split(' ') if drvoFieldDefnFlags is not None else [] + drvoSupportsFieldComment = 'Comment' in drvoFieldDefnFlags + # GetTZFlag()/SetTZFlag() and OGR_TZFLAG_* constants added in 3.8.0 + hasTZFlagSupport = common.gdal_version_min(maj=3, min=8) + else: + # list of flags supported by the OGRLayer::AlterFieldDefn() API + drvoFieldDefnFlags = drvo.GetMetadataItem(gdalconst.DMD_ALTER_FIELD_DEFN_FLAGS) + drvoFieldDefnFlags = drvoFieldDefnFlags.split(' ') if drvoFieldDefnFlags is not None else [] + # GetComment()/SetComment() added in 3.7.0 + drvoSupportsFieldComment = False + hasTZFlagSupport = False + + # cache driver capabilities + drvoSupportsFieldWidthPrecision = 'WidthPrecision' in drvoFieldDefnFlags + drvoSupportsFieldNullable = 'Nullable' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_NOTNULL_FIELDS) + drvoSupportsFieldUnique = 'Unique' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_UNIQUE_FIELDS) + drvoSupportsFieldDefault = 'Default' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_DEFAULT_FIELDS) + drvoSupportsFieldAlternativeName = 'AlternativeName' in drvoFieldDefnFlags for layername, layerdef in layers.items(): create = layerdef.get('create', None) @@ -383,13 +408,13 @@ def validateSchema(layers, drvo=None, lco_defaults=None): if k2 == 'name': pass elif k2 == 'alternativename' or k2 == 'alias': - fld_def2['AlternativeName'] = v + setFieldIf(drvoSupportsFieldAlternativeName, + 'AlternativeName', v, fld_def2, fld_name, drvo.ShortName, + log=logging.debug) elif k2 == 'comment': - if hasCommentSupport: - fld_def2['Comment'] = v - else: - logging.debug('Ignoring Comment="%s" on field "%s" (OGR v%s is too old)', - v, fld_name, gdal.__version__) + setFieldIf(drvoSupportsFieldComment, + 'Comment', v, fld_def2, fld_name, drvo.ShortName, + log=logging.debug) elif k2 == 'type': fld_def2['Type'] = parseFieldType(v) @@ -402,29 +427,22 @@ def validateSchema(layers, drvo=None, lco_defaults=None): logging.debug('Ignoring TZ="%s" on field "%s" (OGR v%s is too old)', v, fld_name, gdal.__version__) elif k2 == 'width' and v is not None and isinstance(v, int): - fld_def2['Width'] = v + setFieldIf(drvoSupportsFieldWidthPrecision, + 'Width', v, fld_def2, fld_name, drvo.ShortName) elif k2 == 'precision' and v is not None and isinstance(v, int): - fld_def2['Precision'] = v + setFieldIf(drvoSupportsFieldWidthPrecision, + 'Precision', v, fld_def2, fld_name, drvo.ShortName) # constraints elif k2 == 'default': - if drvoSupportsDefaultFields: - fld_def2['Default'] = v - else: - logging.warning('%s driver lacks GDAL_DCAP_DEFAULT_FIELDS support', - drvo.ShortName) + setFieldIf(drvoSupportsFieldDefault, + 'Default', v, fld_def2, fld_name, drvo.ShortName) elif k2 == 'nullable' and v is not None and isinstance(v, bool): - if drvoSupportsNotNULLFields: - fld_def2['Nullable'] = v - else: - logging.warning('%s driver lacks GDAL_DCAP_NOTNULL_FIELDS support', - drvo.ShortName) + setFieldIf(drvoSupportsFieldNullable, + 'Nullable', v, fld_def2, fld_name, drvo.ShortName) elif k2 == 'unique' and v is not None and isinstance(v, bool): - if drvoSupportsUniqueFields: - fld_def2['Unique'] = v - else: - logging.warning('%s driver lacks GDAL_DCAP_UNIQUE_FIELDS support', - drvo.ShortName) + setFieldIf(drvoSupportsFieldUnique, + 'Unique', v, fld_def2, fld_name, drvo.ShortName) else: raise Exception(f'Field "{fld_name}" has unknown key "{k}"') -- cgit v1.2.3