コード例 #1
0
ファイル: ogr2vrt.py プロジェクト: MattLatt/GDAL_2.0.x_VC
            type = 'RealList'
        elif src_fd.GetType() == ogr.OFTBinary:
            type = 'Binary'
        elif src_fd.GetType() == ogr.OFTDate:
            type = 'Date'
        elif src_fd.GetType() == ogr.OFTTime:
            type = 'Time'
        elif src_fd.GetType() == ogr.OFTDateTime:
            type = 'DateTime'
        else:
            type = 'String'

        vrt += '    <Field name="%s" type="%s"' \
               % (Esc(src_fd.GetName()), type)
        if src_fd.GetSubType() != ogr.OFSTNone:
            vrt += ' subtype="%s"' % ogr.GetFieldSubTypeName(src_fd.GetSubType())
        if not schema:
            vrt += ' src="%s"' % Esc(src_fd.GetName())
        if src_fd.GetWidth() > 0:
            vrt += ' width="%d"' % src_fd.GetWidth()
        if src_fd.GetPrecision() > 0:
            vrt += ' precision="%d"' % src_fd.GetPrecision()
        if src_fd.IsNullable() == 0:
            vrt += ' nullable="false"'
        vrt += '/>\n'

    if feature_count:
        vrt += '    <FeatureCount>%d</FeatureCount>\n' % layer.GetFeatureCount()

    vrt += '  </OGRVRTLayer>\n'
コード例 #2
0
ファイル: ogr_basic_test.py プロジェクト: wegiangb/gdal-js
def ogr_basic_12():

    # boolean integer
    feat_def = ogr.FeatureDefn()
    if ogr.GetFieldSubTypeName(ogr.OFSTBoolean) != 'Boolean':
        gdaltest.post_reason('fail')
        return 'fail'
    field_def = ogr.FieldDefn('fld', ogr.OFTInteger)
    field_def.SetSubType(ogr.OFSTBoolean)
    if field_def.GetSubType() != ogr.OFSTBoolean:
        gdaltest.post_reason('fail')
        return 'fail'
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetField('fld', 0)
    f.SetField('fld', 1)
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', 2)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if f.GetField('fld') != 1:
        gdaltest.post_reason('fail')
        return 'fail'

    f.SetField('fld', '0')
    f.SetField('fld', '1')
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', '2')
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if f.GetField('fld') != 1:
        gdaltest.post_reason('fail')
        return 'fail'

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFTString)
    field_def.SetSubType(ogr.OFSTBoolean)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if field_def.GetSubType() != ogr.OFSTNone:
        gdaltest.post_reason('fail')
        return 'fail'

    # boolean list
    feat_def = ogr.FeatureDefn()
    field_def = ogr.FieldDefn('fld', ogr.OFTIntegerList)
    field_def.SetSubType(ogr.OFSTBoolean)
    if field_def.GetSubType() != ogr.OFSTBoolean:
        gdaltest.post_reason('fail')
        return 'fail'
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetFieldIntegerList(0, [0, 1])
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetFieldIntegerList(0, [0, 1, 2, 1])
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if f.GetField('fld') != [0, 1, 1, 1]:
        print(f.GetField('fld'))
        gdaltest.post_reason('fail')
        return 'fail'

    # int16 integer
    feat_def = ogr.FeatureDefn()
    if ogr.GetFieldSubTypeName(ogr.OFSTInt16) != 'Int16':
        gdaltest.post_reason('fail')
        return 'fail'
    field_def = ogr.FieldDefn('fld', ogr.OFTInteger)
    field_def.SetSubType(ogr.OFSTInt16)
    if field_def.GetSubType() != ogr.OFSTInt16:
        gdaltest.post_reason('fail')
        return 'fail'
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetField('fld', -32768)
    f.SetField('fld', 32767)
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', -32769)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if f.GetField('fld') != -32768:
        gdaltest.post_reason('fail')
        return 'fail'
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', 32768)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if f.GetField('fld') != 32767:
        gdaltest.post_reason('fail')
        return 'fail'

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFTString)
    field_def.SetSubType(ogr.OFSTInt16)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if field_def.GetSubType() != ogr.OFSTNone:
        gdaltest.post_reason('fail')
        return 'fail'

    # float32
    feat_def = ogr.FeatureDefn()
    if ogr.GetFieldSubTypeName(ogr.OFSTFloat32) != 'Float32':
        gdaltest.post_reason('fail')
        return 'fail'
    field_def = ogr.FieldDefn('fld', ogr.OFTReal)
    field_def.SetSubType(ogr.OFSTFloat32)
    if field_def.GetSubType() != ogr.OFSTFloat32:
        gdaltest.post_reason('fail')
        return 'fail'
    feat_def.AddFieldDefn(field_def)

    if False:
        f = ogr.Feature(feat_def)
        gdal.ErrorReset()
        f.SetField('fld', '1.23')
        if gdal.GetLastErrorMsg() != '':
            gdaltest.post_reason('fail')
            return 'fail'
        gdal.ErrorReset()
        gdal.PushErrorHandler('CPLQuietErrorHandler')
        f.SetField('fld', 1.230000000001)
        gdal.PopErrorHandler()
        if gdal.GetLastErrorMsg() == '':
            gdaltest.post_reason('fail')
            return 'fail'
        if abs(f.GetField('fld') - 1.23) < 1e-8:
            gdaltest.post_reason('fail')
            f.DumpReadable()
            return 'fail'

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFSTFloat32)
    field_def.SetSubType(ogr.OFSTInt16)
    gdal.PopErrorHandler()
    if gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'
    if field_def.GetSubType() != ogr.OFSTNone:
        gdaltest.post_reason('fail')
        return 'fail'

    return 'success'
コード例 #3
0
def main(argv):
    infile = None
    outfile = None
    layer_list = []
    relative = "0"
    schema = 0
    feature_count = 0
    extent = 0
    openoptions = []

    argv = gdal.GeneralCmdLineProcessor(argv)
    if argv is None:
        return 0

    i = 1
    while i < len(argv):
        arg = argv[i]

        if arg == '-relative':
            relative = "1"

        elif arg == '-schema':
            schema = 1

        elif arg == '-feature_count':
            feature_count = 1

        elif arg == '-extent':
            extent = 1

        elif arg == '-oo':
            i += 1
            openoptions.append(argv[i])

        elif arg[0] == '-':
            return Usage()

        elif infile is None:
            infile = arg

        elif outfile is None:
            outfile = arg

        else:
            layer_list.append(arg)

        i = i + 1

    if outfile is None:
        return Usage()

    if schema and feature_count:
        sys.stderr.write('Ignoring -feature_count when used with -schema.\n')
        feature_count = 0

    if schema and extent:
        sys.stderr.write('Ignoring -extent when used with -schema.\n')
        extent = 0

    #############################################################################
    # Open the datasource to read.

    src_ds = gdal.OpenEx(infile, gdal.OF_VECTOR, open_options=openoptions)

    if schema:
        infile = '@dummy@'

    if not layer_list:
        for lyr_idx in range(src_ds.GetLayerCount()):
            layer_list.append(
                src_ds.GetLayer(lyr_idx).GetLayerDefn().GetName())

    #############################################################################
    # Start the VRT file.

    vrt = '<OGRVRTDataSource>\n'

    #############################################################################
    # Metadata

    mdd_list = src_ds.GetMetadataDomainList()
    if mdd_list is not None:
        for domain in mdd_list:
            if domain == '':
                vrt += '  <Metadata>\n'
            elif len(domain) > 4 and domain[0:4] == 'xml:':
                vrt += '  <Metadata domain="%s" format="xml">\n' % Esc(domain)
            else:
                vrt += '  <Metadata domain="%s">\n' % Esc(domain)
            if len(domain) > 4 and domain[0:4] == 'xml:':
                vrt += src_ds.GetMetadata_List(domain)[0]
            else:
                md = src_ds.GetMetadata(domain)
                for key in md:
                    vrt += '    <MDI key="%s">%s</MDI>\n' % (Esc(key),
                                                             Esc(md[key]))
            vrt += '  </Metadata>\n'

    #############################################################################
    # Process each source layer.

    for name in layer_list:
        layer = src_ds.GetLayerByName(name)
        layerdef = layer.GetLayerDefn()

        vrt += '  <OGRVRTLayer name="%s">\n' % Esc(name)

        mdd_list = layer.GetMetadataDomainList()
        if mdd_list is not None:
            for domain in mdd_list:
                if domain == '':
                    vrt += '    <Metadata>\n'
                elif len(domain) > 4 and domain[0:4] == 'xml:':
                    vrt += '    <Metadata domain="%s" format="xml">\n' % Esc(
                        domain)
                else:
                    vrt += '    <Metadata domain="%s">\n' % Esc(domain)
                if len(domain) > 4 and domain[0:4] == 'xml:':
                    vrt += layer.GetMetadata_List(domain)[0]
                else:
                    md = layer.GetMetadata(domain)
                    for key in md:
                        vrt += '      <MDI key="%s">%s</MDI>\n' % (
                            Esc(key), Esc(md[key]))
                vrt += '    </Metadata>\n'

        if not os.path.isabs(outfile) and not os.path.isabs(infile) and \
           os.path.dirname(outfile) == '' and os.path.dirname(infile) == '':
            relative = 1

        vrt += '    <SrcDataSource relativeToVRT="%s" shared="%d">%s</SrcDataSource>\n' \
               % (relative, not schema, Esc(infile))

        if openoptions:
            vrt += '    <OpenOptions>\n'
            for option in openoptions:
                (key, value) = option.split('=')
                vrt += '        <OOI key="%s">%s</OOI>\n' % (Esc(key),
                                                             Esc(value))
            vrt += '    </OpenOptions>\n'

        if schema:
            vrt += '    <SrcLayer>@dummy@</SrcLayer>\n'
        else:
            vrt += '    <SrcLayer>%s</SrcLayer>\n' % Esc(name)

        # Historic format for mono-geometry layers
        if layerdef.GetGeomFieldCount() == 0:
            vrt += '    <GeometryType>wkbNone</GeometryType>\n'
        elif layerdef.GetGeomFieldCount() == 1 and \
                layerdef.GetGeomFieldDefn(0).IsNullable():
            vrt += '    <GeometryType>%s</GeometryType>\n' \
                % GeomType2Name(layerdef.GetGeomType())
            srs = layer.GetSpatialRef()
            if srs is not None:
                vrt += '    <LayerSRS>%s</LayerSRS>\n' \
                    % (Esc(srs.ExportToWkt()))
            if extent:
                (xmin, xmax, ymin, ymax) = layer.GetExtent()
                vrt += '    <ExtentXMin>%.15g</ExtentXMin>\n' % xmin
                vrt += '    <ExtentYMin>%.15g</ExtentYMin>\n' % ymin
                vrt += '    <ExtentXMax>%.15g</ExtentXMax>\n' % xmax
                vrt += '    <ExtentYMax>%.15g</ExtentYMax>\n' % ymax

        # New format for multi-geometry field support
        else:
            for fld_index in range(layerdef.GetGeomFieldCount()):
                src_fd = layerdef.GetGeomFieldDefn(fld_index)
                vrt += '    <GeometryField name="%s"' % src_fd.GetName()
                if src_fd.IsNullable() == 0:
                    vrt += ' nullable="false"'
                vrt += '>\n'
                vrt += '      <GeometryType>%s</GeometryType>\n' \
                    % GeomType2Name(src_fd.GetType())
                srs = src_fd.GetSpatialRef()
                if srs is not None:
                    vrt += '      <SRS>%s</SRS>\n' \
                        % (Esc(srs.ExportToWkt()))
                if extent:
                    (xmin, xmax, ymin,
                     ymax) = layer.GetExtent(geom_field=fld_index)
                    vrt += '      <ExtentXMin>%.15g</ExtentXMin>\n' % xmin
                    vrt += '      <ExtentYMin>%.15g</ExtentYMin>\n' % ymin
                    vrt += '      <ExtentXMax>%.15g</ExtentXMax>\n' % xmax
                    vrt += '      <ExtentYMax>%.15g</ExtentYMax>\n' % ymax
                vrt += '    </GeometryField>\n'

        # Process all the fields.
        for fld_index in range(layerdef.GetFieldCount()):
            src_fd = layerdef.GetFieldDefn(fld_index)
            if src_fd.GetType() == ogr.OFTInteger:
                typ = 'Integer'
            elif src_fd.GetType() == ogr.OFTInteger64:
                typ = 'Integer64'
            elif src_fd.GetType() == ogr.OFTString:
                typ = 'String'
            elif src_fd.GetType() == ogr.OFTReal:
                typ = 'Real'
            elif src_fd.GetType() == ogr.OFTStringList:
                typ = 'StringList'
            elif src_fd.GetType() == ogr.OFTIntegerList:
                typ = 'IntegerList'
            elif src_fd.GetType() == ogr.OFTInteger64List:
                typ = 'Integer64List'
            elif src_fd.GetType() == ogr.OFTRealList:
                typ = 'RealList'
            elif src_fd.GetType() == ogr.OFTBinary:
                typ = 'Binary'
            elif src_fd.GetType() == ogr.OFTDate:
                typ = 'Date'
            elif src_fd.GetType() == ogr.OFTTime:
                typ = 'Time'
            elif src_fd.GetType() == ogr.OFTDateTime:
                typ = 'DateTime'
            else:
                typ = 'String'

            vrt += '    <Field name="%s" type="%s"' \
                   % (Esc(src_fd.GetName()), typ)
            if src_fd.GetSubType() != ogr.OFSTNone:
                vrt += ' subtype="%s"' % ogr.GetFieldSubTypeName(
                    src_fd.GetSubType())
            if not schema:
                vrt += ' src="%s"' % Esc(src_fd.GetName())
            if src_fd.GetWidth() > 0:
                vrt += ' width="%d"' % src_fd.GetWidth()
            if src_fd.GetPrecision() > 0:
                vrt += ' precision="%d"' % src_fd.GetPrecision()
            if src_fd.IsNullable() == 0:
                vrt += ' nullable="false"'
            try:
                if src_fd.IsUnique():
                    vrt += ' unique="true"'
            except AttributeError:  # if run with GDAL < 3.2
                pass
            vrt += '/>\n'

        if feature_count:
            vrt += '    <FeatureCount>%d</FeatureCount>\n' % layer.GetFeatureCount(
            )

        vrt += '  </OGRVRTLayer>\n'

    vrt += '</OGRVRTDataSource>\n'

    #############################################################################
    # Write vrt

    open(outfile, 'w').write(vrt)
    return 0
コード例 #4
0
def test_ogr_basic_12():

    # boolean integer
    feat_def = ogr.FeatureDefn()
    assert ogr.GetFieldSubTypeName(ogr.OFSTBoolean) == 'Boolean'
    field_def = ogr.FieldDefn('fld', ogr.OFTInteger)
    field_def.SetSubType(ogr.OFSTBoolean)
    assert field_def.GetSubType() == ogr.OFSTBoolean
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetField('fld', 0)
    f.SetField('fld', 1)
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', 2)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert f.GetField('fld') == 1

    f.SetField('fld', '0')
    f.SetField('fld', '1')
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', '2')
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert f.GetField('fld') == 1

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFTString)
    field_def.SetSubType(ogr.OFSTBoolean)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert field_def.GetSubType() == ogr.OFSTNone

    # boolean list
    feat_def = ogr.FeatureDefn()
    field_def = ogr.FieldDefn('fld', ogr.OFTIntegerList)
    field_def.SetSubType(ogr.OFSTBoolean)
    assert field_def.GetSubType() == ogr.OFSTBoolean
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetFieldIntegerList(0, [0, 1])
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetFieldIntegerList(0, [0, 1, 2, 1])
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert f.GetField('fld') == [0, 1, 1, 1]

    # int16 integer
    feat_def = ogr.FeatureDefn()
    assert ogr.GetFieldSubTypeName(ogr.OFSTInt16) == 'Int16'
    field_def = ogr.FieldDefn('fld', ogr.OFTInteger)
    field_def.SetSubType(ogr.OFSTInt16)
    assert field_def.GetSubType() == ogr.OFSTInt16
    feat_def.AddFieldDefn(field_def)

    f = ogr.Feature(feat_def)
    f.SetField('fld', -32768)
    f.SetField('fld', 32767)
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', -32769)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert f.GetField('fld') == -32768
    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    f.SetField('fld', 32768)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert f.GetField('fld') == 32767

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFTString)
    field_def.SetSubType(ogr.OFSTInt16)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert field_def.GetSubType() == ogr.OFSTNone

    # float32
    feat_def = ogr.FeatureDefn()
    assert ogr.GetFieldSubTypeName(ogr.OFSTFloat32) == 'Float32'
    field_def = ogr.FieldDefn('fld', ogr.OFTReal)
    field_def.SetSubType(ogr.OFSTFloat32)
    assert field_def.GetSubType() == ogr.OFSTFloat32
    feat_def.AddFieldDefn(field_def)

    if False:  # pylint: disable=using-constant-test
        f = ogr.Feature(feat_def)
        gdal.ErrorReset()
        f.SetField('fld', '1.23')
        assert gdal.GetLastErrorMsg() == ''
        gdal.ErrorReset()
        gdal.PushErrorHandler('CPLQuietErrorHandler')
        f.SetField('fld', 1.230000000001)
        gdal.PopErrorHandler()
        assert gdal.GetLastErrorMsg() != ''
        if f.GetField('fld') == pytest.approx(1.23, abs=1e-8):
            f.DumpReadable()
            pytest.fail()

    gdal.ErrorReset()
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    field_def = ogr.FieldDefn('fld', ogr.OFSTFloat32)
    field_def.SetSubType(ogr.OFSTInt16)
    gdal.PopErrorHandler()
    assert gdal.GetLastErrorMsg() != ''
    assert field_def.GetSubType() == ogr.OFSTNone
コード例 #5
0
def _check_test_parquet(filename,
                        expect_fast_feature_count=True,
                        expect_fast_get_extent=True,
                        expect_ignore_fields=True):
    with gdaltest.config_option('OGR_PARQUET_BATCH_SIZE', '2'):
        ds = gdal.OpenEx(filename)
    assert ds is not None, 'cannot open dataset'
    assert ds.TestCapability("foo") == 0
    assert ds.GetLayerCount() == 1, 'bad layer count'
    assert ds.GetLayer(-1) is None
    assert ds.GetLayer(1) is None
    lyr = ds.GetLayer(0)
    assert lyr is not None
    lyr_defn = lyr.GetLayerDefn()
    assert lyr_defn.GetGeomFieldCount() == 1
    assert lyr_defn.GetGeomFieldDefn(0).GetName() == 'geometry'
    srs = lyr_defn.GetGeomFieldDefn(0).GetSpatialRef()
    assert srs is not None
    assert srs.GetAuthorityCode(None) == '4326'
    assert lyr_defn.GetGeomFieldDefn(0).GetType() == ogr.wkbPoint
    assert lyr_defn.GetFieldCount() == 71
    got_field_defns = [
        (lyr_defn.GetFieldDefn(i).GetName(),
         ogr.GetFieldTypeName(lyr_defn.GetFieldDefn(i).GetType()),
         ogr.GetFieldSubTypeName(lyr_defn.GetFieldDefn(i).GetSubType()),
         lyr_defn.GetFieldDefn(i).GetWidth(),
         lyr_defn.GetFieldDefn(i).GetPrecision())
        for i in range(lyr_defn.GetFieldCount())
    ]
    #import pprint
    #pprint.pprint(got_field_defns)
    expected_field_defns = [
        ('boolean', 'Integer', 'Boolean', 0, 0),
        ('uint8', 'Integer', 'None', 0, 0), ('int8', 'Integer', 'None', 0, 0),
        ('uint16', 'Integer', 'None', 0, 0),
        ('int16', 'Integer', 'Int16', 0, 0),
        ('uint32', 'Integer64', 'None', 0, 0),
        ('int32', 'Integer', 'None', 0, 0), ('uint64', 'Real', 'None', 0, 0),
        ('int64', 'Integer64', 'None', 0, 0),
        ('float32', 'Real', 'Float32', 0, 0),
        ('float64', 'Real', 'None', 0, 0), ('string', 'String', 'None', 0, 0),
        ('large_string', 'String', 'None', 0, 0),
        ('timestamp_ms_gmt', 'DateTime', 'None', 0, 0),
        ('timestamp_ms_gmt_plus_2', 'DateTime', 'None', 0, 0),
        ('timestamp_ms_gmt_minus_0215', 'DateTime', 'None', 0, 0),
        ('timestamp_s_no_tz', 'DateTime', 'None', 0, 0),
        ('time32_s', 'Time', 'None', 0, 0),
        ('time32_ms', 'Time', 'None', 0, 0),
        ('time64_us', 'Integer64', 'None', 0, 0),
        ('time64_ns', 'Integer64', 'None', 0, 0),
        ('date32', 'Date', 'None', 0, 0), ('date64', 'Date', 'None', 0, 0),
        ('binary', 'Binary', 'None', 0, 0),
        ('large_binary', 'Binary', 'None', 0, 0),
        ('fixed_size_binary', 'Binary', 'None', 2, 0),
        ('decimal128', 'Real', 'None', 7, 3),
        ('decimal256', 'Real', 'None', 7, 3),
        ('list_boolean', 'IntegerList', 'Boolean', 0, 0),
        ('list_uint8', 'IntegerList', 'None', 0, 0),
        ('list_int8', 'IntegerList', 'None', 0, 0),
        ('list_uint16', 'IntegerList', 'None', 0, 0),
        ('list_int16', 'IntegerList', 'None', 0, 0),
        ('list_uint32', 'Integer64List', 'None', 0, 0),
        ('list_int32', 'IntegerList', 'None', 0, 0),
        ('list_uint64', 'RealList', 'None', 0, 0),
        ('list_int64', 'Integer64List', 'None', 0, 0),
        ('list_float32', 'RealList', 'Float32', 0, 0),
        ('list_float64', 'RealList', 'None', 0, 0),
        ('list_string', 'StringList', 'None', 0, 0),
        ('fixed_size_list_boolean', 'IntegerList', 'Boolean', 0, 0),
        ('fixed_size_list_uint8', 'IntegerList', 'None', 0, 0),
        ('fixed_size_list_int8', 'IntegerList', 'None', 0, 0),
        ('fixed_size_list_uint16', 'IntegerList', 'None', 0, 0),
        ('fixed_size_list_int16', 'IntegerList', 'None', 0, 0),
        ('fixed_size_list_uint32', 'Integer64List', 'None', 0, 0),
        ('fixed_size_list_int32', 'IntegerList', 'None', 0, 0),
        ('fixed_size_list_uint64', 'RealList', 'None', 0, 0),
        ('fixed_size_list_int64', 'Integer64List', 'None', 0, 0),
        ('fixed_size_list_float32', 'RealList', 'Float32', 0, 0),
        ('fixed_size_list_float64', 'RealList', 'None', 0, 0),
        ('fixed_size_list_string', 'StringList', 'None', 0, 0),
        ('struct_field.a', 'Integer64', 'None', 0, 0),
        ('struct_field.b', 'Real', 'None', 0, 0),
        ('struct_field.c.d', 'String', 'None', 0, 0),
        ('struct_field.c.f', 'String', 'None', 0, 0),
        ('struct_field.h', 'Integer64List', 'None', 0, 0),
        ('struct_field.i', 'Integer64', 'None', 0, 0),
        ('map_boolean', 'String', 'JSON', 0, 0),
        ('map_uint8', 'String', 'JSON', 0, 0),
        ('map_int8', 'String', 'JSON', 0, 0),
        ('map_uint16', 'String', 'JSON', 0, 0),
        ('map_int16', 'String', 'JSON', 0, 0),
        ('map_uint32', 'String', 'JSON', 0, 0),
        ('map_int32', 'String', 'JSON', 0, 0),
        ('map_uint64', 'String', 'JSON', 0, 0),
        ('map_int64', 'String', 'JSON', 0, 0),
        ('map_float32', 'String', 'JSON', 0, 0),
        ('map_float64', 'String', 'JSON', 0, 0),
        ('map_string', 'String', 'JSON', 0, 0),
        ('dict', 'Integer', 'None', 0, 0)
    ]
    assert got_field_defns == expected_field_defns
    if expect_fast_feature_count:
        assert lyr.TestCapability(ogr.OLCFastFeatureCount) == 1
    assert lyr.TestCapability(ogr.OLCStringsAsUTF8) == 1
    if expect_fast_get_extent:
        assert lyr.TestCapability(ogr.OLCFastGetExtent) == 1
    if expect_ignore_fields:
        assert lyr.TestCapability(ogr.OLCIgnoreFields) == 1
    assert lyr.GetFeatureCount() == 5
    assert lyr.GetExtent() == (0.0, 4.0, 2.0, 2.0)
    assert lyr.GetExtent(geom_field=0) == (0.0, 4.0, 2.0, 2.0)
    with gdaltest.error_handler():
        lyr.GetExtent(geom_field=-1)
        lyr.GetExtent(geom_field=1)

    assert ds.GetFieldDomainNames() == ['dictDomain']
    assert ds.GetFieldDomain('not_existing') is None
    for _ in range(2):
        domain = ds.GetFieldDomain('dictDomain')
        assert domain is not None
        assert domain.GetName() == 'dictDomain'
        assert domain.GetDescription() == ''
        assert domain.GetDomainType() == ogr.OFDT_CODED
        assert domain.GetFieldType() == ogr.OFTInteger
        assert domain.GetFieldSubType() == ogr.OFSTNone
        assert domain.GetEnumeration() == {'0': 'foo', '1': 'bar', '2': 'baz'}

    f = lyr.GetNextFeature()
    assert f.GetFID() == 0
    assert f['boolean']
    assert f['uint8'] == 1
    assert f['int8'] == -2
    assert f['uint16'] == 1
    assert f['int16'] == -20000
    assert f['uint32'] == 1
    assert f['int32'] == -2000000000
    assert f['uint64'] == 1
    assert f['int64'] == -200000000000
    assert f['float32'] == 1.5
    assert f['float64'] == 1.5
    assert f['string'] == 'abcd'
    assert f['large_string'] == 'abcd'
    assert f['timestamp_ms_gmt'] == '2019/01/01 14:00:00+00'
    assert f['timestamp_ms_gmt_plus_2'] == '2019/01/01 14:00:00+02'
    assert f['timestamp_ms_gmt_minus_0215'] == '2019/01/01 14:00:00-0215'
    assert f['timestamp_s_no_tz'] == '2019/01/01 14:00:00'
    assert f['time32_s'] == '01:02:03'
    assert f['time32_ms'] == '01:02:03.456'
    assert f['time64_us'] == 3723000000
    assert f['time64_ns'] == 3723000000456
    assert f['date32'] == '1970/01/02'
    assert f['date64'] == '1970/01/02'
    assert f['binary'] == '0001'
    assert f['large_binary'] == '0001'
    assert f['fixed_size_binary'] == '0001'
    assert f['decimal128'] == 1234.567
    assert f['decimal256'] == 1234.567
    assert f['list_boolean'] == []
    assert f['list_uint8'] == []
    assert f['list_int8'] == []
    assert f['list_uint16'] == []
    assert f['list_int16'] == []
    assert f['list_uint32'] == []
    assert f['list_int32'] == []
    assert f['list_uint64'] == []
    assert f['list_int64'] == []
    assert f['list_float32'] == []
    assert f['list_float64'] == []
    assert f['list_string'] is None
    assert f['fixed_size_list_boolean'] == [1, 0]
    assert f['fixed_size_list_uint8'] == [0, 1]
    assert f['fixed_size_list_int8'] == [0, 1]
    assert f['fixed_size_list_uint16'] == [0, 1]
    assert f['fixed_size_list_int16'] == [0, 1]
    assert f['fixed_size_list_uint32'] == [0, 1]
    assert f['fixed_size_list_int32'] == [0, 1]
    assert f['fixed_size_list_uint64'] == [0, 1]
    assert f['fixed_size_list_int64'] == [0, 1]
    assert f['fixed_size_list_float32'][0] == 0
    assert math.isnan(f['fixed_size_list_float32'][1])
    assert f['fixed_size_list_float64'][0] == 0
    assert math.isnan(f['fixed_size_list_float64'][1])
    assert f['fixed_size_list_string'] == ['a', 'b']
    assert f['struct_field.a'] == 1
    assert f['struct_field.b'] == 2.5
    assert f['struct_field.c.d'] == 'e'
    assert f['struct_field.c.f'] == 'g'
    assert f['struct_field.h'] == [5, 6]
    assert f['struct_field.i'] == 3
    assert f['map_boolean'] == '{"x":null,"y":true}'
    assert f['map_uint8'] == '{"x":1,"y":null}'
    assert f['map_int8'] == '{"x":1,"y":null}'
    assert f['map_uint16'] == '{"x":1,"y":null}'
    assert f['map_int16'] == '{"x":1,"y":null}'
    assert f['map_uint32'] == '{"x":4000000000,"y":null}'
    assert f['map_int32'] == '{"x":2000000000,"y":null}'
    assert f['map_uint64'] == '{"x":4000000000000.0,"y":null}'
    assert f['map_int64'] == '{"x":-2000000000000,"y":null}'
    assert f['map_float32'] == '{"x":1.5,"y":null}'
    assert f['map_float64'] == '{"x":1.5,"y":null}'
    assert f['map_string'] == '{"x":"x_val","y":null}'
    assert f['dict'] == 0
    assert f.GetGeometryRef().ExportToWkt() == 'POINT (0 2)'

    f = lyr.GetNextFeature()
    assert f.GetFID() == 1
    assert not f['boolean']
    assert f['uint8'] == 2
    assert f.GetGeometryRef() is None

    f = lyr.GetNextFeature()
    assert f.GetFID() == 2
    assert f['uint8'] is None
    assert f.GetGeometryRef().ExportToWkt() == 'POINT (2 2)'

    f = lyr.GetNextFeature()
    assert f.GetFID() == 3
    assert f['uint8'] == 4
    assert f.GetGeometryRef().ExportToWkt() == 'POINT (3 2)'

    f = lyr.GetNextFeature()
    assert f.GetFID() == 4
    assert f['uint8'] == 5
    assert f.GetGeometryRef().ExportToWkt() == 'POINT (4 2)'

    assert lyr.GetNextFeature() is None

    assert lyr.GetNextFeature() is None

    lyr.ResetReading()
    f = lyr.GetNextFeature()
    assert f.GetFID() == 0

    lyr.SetSpatialFilterRect(4, 2, 4, 2)
    lyr.ResetReading()
    f = lyr.GetNextFeature()
    assert f.GetFID() == 4
    lyr.SetSpatialFilter(None)

    if expect_ignore_fields:
        # Ignore just one member of a structure
        assert lyr.SetIgnoredFields(['struct_field.a']) == ogr.OGRERR_NONE
        lyr.ResetReading()
        f = lyr.GetNextFeature()
        assert f['fixed_size_list_string'] == ['a', 'b']
        assert f['struct_field.a'] is None
        assert f['struct_field.b'] == 2.5
        assert f['map_boolean'] == '{"x":null,"y":true}'
        assert f.GetGeometryRef().ExportToWkt() == 'POINT (0 2)'

        # Ignore all members of a structure
        assert lyr.SetIgnoredFields([
            'struct_field.a', 'struct_field.b', 'struct_field.c.d',
            'struct_field.c.f', 'struct_field.h', 'struct_field.i'
        ]) == ogr.OGRERR_NONE
        lyr.ResetReading()
        f = lyr.GetNextFeature()
        assert f['fixed_size_list_string'] == ['a', 'b']
        assert f['struct_field.a'] is None
        assert f['struct_field.b'] is None
        assert f['struct_field.c.d'] is None
        assert f['struct_field.c.f'] is None
        assert f['struct_field.h'] is None
        assert f['struct_field.i'] is None
        assert f['map_boolean'] == '{"x":null,"y":true}'
        assert f.GetGeometryRef().ExportToWkt() == 'POINT (0 2)'

        # Ignore a map
        assert lyr.SetIgnoredFields(['map_boolean']) == ogr.OGRERR_NONE
        lyr.ResetReading()
        f = lyr.GetNextFeature()
        assert f['fixed_size_list_string'] == ['a', 'b']
        assert f['struct_field.a'] == 1
        assert f['struct_field.b'] == 2.5
        assert f['map_boolean'] is None
        assert f['map_uint8'] == '{"x":1,"y":null}'
        assert f.GetGeometryRef().ExportToWkt() == 'POINT (0 2)'

        # Ignore geometry
        assert lyr.SetIgnoredFields(['geometry']) == ogr.OGRERR_NONE
        lyr.ResetReading()
        f = lyr.GetNextFeature()
        assert f['fixed_size_list_string'] == ['a', 'b']
        assert f['struct_field.a'] == 1
        assert f['struct_field.b'] == 2.5
        assert f['map_boolean'] == '{"x":null,"y":true}'
        assert f.GetGeometryRef() is None

        # Cancel ignored fields
        assert lyr.SetIgnoredFields([]) == ogr.OGRERR_NONE
        lyr.ResetReading()
        f = lyr.GetNextFeature()
        assert f['fixed_size_list_string'] == ['a', 'b']
        assert f['struct_field.a'] == 1
        assert f['struct_field.b'] == 2.5
        assert f['map_boolean'] == '{"x":null,"y":true}'
        assert f.GetGeometryRef().ExportToWkt() == 'POINT (0 2)'