Coverage Report

Created: 2026-08-11 08:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/vfk/ogrvfkdatasource.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Implements OGRVFKDatasource class.
5
 * Author:   Martin Landa, landa.martin gmail.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2009-2010, 2013-2018 Martin Landa <landa.martin gmail.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "ogr_vfk.h"
14
#include "cpl_conv.h"
15
#include "cpl_string.h"
16
17
/*!
18
  \brief OGRVFKDataSource constructor
19
*/
20
OGRVFKDataSource::OGRVFKDataSource()
21
3.77k
    : papoLayers(nullptr), nLayers(0), poReader(nullptr)
22
3.77k
{
23
3.77k
}
24
25
/*!
26
  \brief OGRVFKDataSource destructor
27
*/
28
OGRVFKDataSource::~OGRVFKDataSource()
29
3.77k
{
30
3.77k
    if (poReader)
31
3.77k
        delete poReader;
32
33
14.7k
    for (int i = 0; i < nLayers; i++)
34
10.9k
        delete papoLayers[i];
35
36
3.77k
    CPLFree(papoLayers);
37
3.77k
}
38
39
/*!
40
  \brief Open VFK datasource
41
42
  \param poOpenInfo open info
43
44
  \return TRUE on success or FALSE on failure
45
*/
46
int OGRVFKDataSource::Open(GDALOpenInfo *poOpenInfo)
47
3.77k
{
48
    /* create VFK reader */
49
3.77k
    poReader = CreateVFKReader(poOpenInfo);
50
3.77k
    if (poReader == nullptr || !poReader->IsValid())
51
22
    {
52
        /*
53
        CPLError(CE_Failure, CPLE_AppDefined,
54
                 "File %s appears to be VFK but the VFK reader can't"
55
                 "be instantiated",
56
                     pszFileName);
57
        */
58
22
        return FALSE;
59
22
    }
60
61
3.75k
    bool bSuppressGeometry =
62
3.75k
        CPLFetchBool(poOpenInfo->papszOpenOptions, "SUPPRESS_GEOMETRY", false);
63
    /* read data blocks, i.e. &B */
64
3.75k
    poReader->ReadDataBlocks(bSuppressGeometry);
65
66
    /* get list of layers */
67
3.75k
    papoLayers = (OGRVFKLayer **)CPLCalloc(sizeof(OGRVFKLayer *),
68
3.75k
                                           poReader->GetDataBlockCount());
69
70
    /* create layers from VFK blocks */
71
14.7k
    for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); iLayer++)
72
10.9k
    {
73
10.9k
        papoLayers[iLayer] =
74
10.9k
            CreateLayerFromBlock(poReader->GetDataBlock(iLayer));
75
10.9k
        nLayers++;
76
10.9k
    }
77
78
3.75k
    if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_READ_ALL_BLOCKS", "YES")))
79
3.75k
    {
80
        /* read data records if requested */
81
3.75k
        poReader->ReadDataRecords();
82
83
3.75k
        if (!bSuppressGeometry)
84
3.75k
        {
85
14.7k
            for (int iLayer = 0; iLayer < poReader->GetDataBlockCount();
86
10.9k
                 iLayer++)
87
10.9k
            {
88
                /* load geometry */
89
10.9k
                poReader->GetDataBlock(iLayer)->LoadGeometry();
90
10.9k
            }
91
3.75k
        }
92
3.75k
    }
93
94
3.75k
    return TRUE;
95
3.77k
}
96
97
/*!
98
  \brief Get VFK layer
99
100
  \param iLayer layer number
101
102
  \return pointer to OGRLayer instance or NULL on error
103
*/
104
const OGRLayer *OGRVFKDataSource::GetLayer(int iLayer) const
105
6.13k
{
106
6.13k
    if (iLayer < 0 || iLayer >= nLayers)
107
0
        return nullptr;
108
109
6.13k
    return papoLayers[iLayer];
110
6.13k
}
111
112
/*!
113
  \brief Test datasource capabilities
114
115
  \param pszCap capability
116
117
  \return TRUE if supported or FALSE if not supported
118
*/
119
int OGRVFKDataSource::TestCapability(const char *pszCap) const
120
0
{
121
0
    if (EQUAL(pszCap, "IsPreProcessed") && poReader)
122
0
    {
123
0
        if (poReader->IsPreProcessed())
124
0
            return TRUE;
125
0
    }
126
127
0
    return FALSE;
128
0
}
129
130
/*!
131
  \brief Create OGR layer from VFKDataBlock
132
133
  \param poDataBlock pointer to VFKDataBlock instance
134
135
  \return pointer to OGRVFKLayer instance or NULL on error
136
*/
137
OGRVFKLayer *
138
OGRVFKDataSource::CreateLayerFromBlock(const IVFKDataBlock *poDataBlock)
139
10.9k
{
140
    /* create an empty layer */
141
10.9k
    OGRVFKLayer *poLayer = new OGRVFKLayer(
142
10.9k
        poDataBlock->GetName(), nullptr, poDataBlock->GetGeometryType(), this);
143
144
    /* define attributes (properties) */
145
71.4k
    for (int iField = 0; iField < poDataBlock->GetPropertyCount(); iField++)
146
60.5k
    {
147
60.5k
        VFKPropertyDefn *poProperty = poDataBlock->GetProperty(iField);
148
60.5k
        OGRFieldDefn oField(poProperty->GetName(), poProperty->GetType());
149
150
60.5k
        if (poProperty->GetWidth() > 0)
151
32.5k
            oField.SetWidth(poProperty->GetWidth());
152
60.5k
        if (poProperty->GetPrecision() > 0)
153
2.18k
            oField.SetPrecision(poProperty->GetPrecision());
154
155
60.5k
        poLayer->GetLayerDefn()->AddFieldDefn(&oField);
156
60.5k
    }
157
158
10.9k
    if (poDataBlock->GetReader()->HasFileField())
159
0
    {
160
        /* open option FILE_FIELD=YES specified, append extra
161
         * attribute */
162
0
        OGRFieldDefn oField(FILE_COLUMN, OFTString);
163
0
        oField.SetWidth(255);
164
0
        poLayer->GetLayerDefn()->AddFieldDefn(&oField);
165
0
    }
166
167
10.9k
    return poLayer;
168
10.9k
}