Coverage Report

Created: 2025-12-03 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/vfk/ogrvfklayer.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Implements OGRVFKLayer class.
5
 * Author:   Martin Landa, landa.martin gmail.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2009-2010, 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 OGRVFKLayer constructor
19
20
  \param pszName layer name
21
  \param poSRSIn spatial reference
22
  \param eReqType WKB geometry type
23
  \param poDSIn  data source where to register OGR layer
24
*/
25
OGRVFKLayer::OGRVFKLayer(const char *pszName, OGRSpatialReference *poSRSIn,
26
                         OGRwkbGeometryType eReqType, OGRVFKDataSource *poDSIn)
27
8.48k
    : poSRS(poSRSIn == nullptr ? new OGRSpatialReference() : poSRSIn->Clone()),
28
8.48k
      poFeatureDefn(new OGRFeatureDefn(pszName)),
29
8.48k
      poDataBlock(poDSIn->GetReader()->GetDataBlock(pszName)), m_iNextFeature(0)
30
8.48k
{
31
8.48k
    poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
32
33
8.48k
    if (poSRSIn == nullptr)
34
8.48k
    {
35
        // Default is S-JTSK (EPSG: 5514).
36
8.48k
        if (poSRS->importFromEPSG(5514) != OGRERR_NONE)
37
0
        {
38
0
            delete poSRS;
39
0
            poSRS = nullptr;
40
0
        }
41
8.48k
    }
42
43
8.48k
    SetDescription(poFeatureDefn->GetName());
44
8.48k
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
45
46
8.48k
    poFeatureDefn->Reference();
47
8.48k
    poFeatureDefn->SetGeomType(eReqType);
48
8.48k
}
49
50
/*!
51
  \brief OGRVFKLayer() destructor
52
*/
53
OGRVFKLayer::~OGRVFKLayer()
54
8.48k
{
55
8.48k
    if (poFeatureDefn)
56
8.48k
        poFeatureDefn->Release();
57
58
8.48k
    if (poSRS)
59
8.48k
        poSRS->Release();
60
8.48k
}
61
62
/*!
63
  \brief Test capability (random access, etc.)
64
65
  \param pszCap capability name
66
*/
67
int OGRVFKLayer::TestCapability(const char *pszCap) const
68
0
{
69
0
    if (EQUAL(pszCap, OLCRandomRead))
70
0
    {
71
0
        return TRUE; /* ? */
72
0
    }
73
0
    if (EQUAL(pszCap, OLCStringsAsUTF8))
74
0
    {
75
0
        return TRUE;
76
0
    }
77
78
0
    return FALSE;
79
0
}
80
81
/*!
82
  \brief Reset reading
83
84
  \todo To be implemented
85
*/
86
void OGRVFKLayer::ResetReading()
87
0
{
88
0
    m_iNextFeature = 0;
89
0
    poDataBlock->ResetReading();
90
0
}
91
92
/*!
93
  \brief Get geometry from VFKFeature
94
95
  \param poVfkFeature pointer to VFKFeature
96
97
  \return pointer to OGRGeometry or NULL on error
98
*/
99
const OGRGeometry *OGRVFKLayer::GetGeometry(IVFKFeature *poVfkFeature)
100
12.9k
{
101
12.9k
    return poVfkFeature->GetGeometry();
102
12.9k
}
103
104
/*!
105
  \brief Get feature count
106
107
  This method overwrites OGRLayer::GetFeatureCount(),
108
109
  \param bForce skip (return -1)
110
111
  \return number of features
112
*/
113
GIntBig OGRVFKLayer::GetFeatureCount(CPL_UNUSED int bForce)
114
0
{
115
    /* note that 'nfeatures' is 0 when data are not read from DB */
116
0
    int nfeatures = (int)poDataBlock->GetFeatureCount();
117
0
    if (m_poFilterGeom || m_poAttrQuery || nfeatures < 1)
118
0
    {
119
        /* force real feature count */
120
0
        nfeatures = (int)OGRLayer::GetFeatureCount();
121
0
    }
122
123
0
    CPLDebug("OGR-VFK", "OGRVFKLayer::GetFeatureCount(): name=%s -> n=%d",
124
0
             GetName(), nfeatures);
125
126
0
    return nfeatures;
127
0
}
128
129
/*!
130
  \brief Get next feature
131
132
  \return pointer to OGRFeature instance
133
*/
134
OGRFeature *OGRVFKLayer::GetNextFeature()
135
17.4k
{
136
    /* loop till we find and translate a feature meeting all our
137
       requirements
138
    */
139
17.4k
    if (m_iNextFeature < 1 && m_poFilterGeom == nullptr &&
140
4.49k
        m_poAttrQuery == nullptr)
141
4.49k
    {
142
        /* sequential feature properties access only supported when no
143
        filter enabled */
144
4.49k
        poDataBlock->LoadProperties();
145
4.49k
    }
146
17.4k
    while (true)
147
17.4k
    {
148
17.4k
        IVFKFeature *poVFKFeature = poDataBlock->GetNextFeature();
149
17.4k
        if (!poVFKFeature)
150
4.49k
        {
151
            /* clean loaded feature properties for a next run */
152
4.49k
            poDataBlock->CleanProperties();
153
4.49k
            return nullptr;
154
4.49k
        }
155
156
        /* skip feature with unknown geometry type */
157
12.9k
        if (poVFKFeature->GetGeometryType() == wkbUnknown)
158
0
            continue;
159
160
12.9k
        OGRFeature *poOGRFeature = GetFeature(poVFKFeature);
161
12.9k
        if (poOGRFeature)
162
12.9k
            return poOGRFeature;
163
12.9k
    }
164
17.4k
}
165
166
/*!
167
  \brief Get feature by fid
168
169
  \param nFID feature id (-1 for next)
170
171
  \return pointer to OGRFeature or NULL not found
172
*/
173
OGRFeature *OGRVFKLayer::GetFeature(GIntBig nFID)
174
0
{
175
0
    IVFKFeature *poVFKFeature = poDataBlock->GetFeature(nFID);
176
177
0
    if (!poVFKFeature)
178
0
        return nullptr;
179
180
    /* clean loaded feature properties (sequential access not
181
       finished) */
182
0
    if (m_iNextFeature > 0)
183
0
    {
184
0
        ResetReading();
185
0
        poDataBlock->CleanProperties();
186
0
    }
187
188
0
    CPLAssert(nFID == poVFKFeature->GetFID());
189
0
    CPLDebug("OGR-VFK", "OGRVFKLayer::GetFeature(): name=%s fid=" CPL_FRMT_GIB,
190
0
             GetName(), nFID);
191
192
0
    return GetFeature(poVFKFeature);
193
0
}
194
195
/*!
196
  \brief Get feature (private)
197
198
  \return pointer to OGRFeature or NULL not found
199
*/
200
OGRFeature *OGRVFKLayer::GetFeature(IVFKFeature *poVFKFeature)
201
12.9k
{
202
    /* skip feature with unknown geometry type */
203
12.9k
    if (poVFKFeature->GetGeometryType() == wkbUnknown)
204
0
        return nullptr;
205
206
    /* get features geometry */
207
12.9k
    const OGRGeometry *poGeomRef = GetGeometry(poVFKFeature);
208
209
    /* does it satisfy the spatial query, if there is one? */
210
12.9k
    if (m_poFilterGeom != nullptr && poGeomRef && !FilterGeometry(poGeomRef))
211
0
    {
212
0
        return nullptr;
213
0
    }
214
215
    /* convert the whole feature into an OGRFeature */
216
12.9k
    OGRFeature *poOGRFeature = new OGRFeature(GetLayerDefn());
217
12.9k
    poOGRFeature->SetFID(poVFKFeature->GetFID());
218
12.9k
    poVFKFeature->LoadProperties(poOGRFeature);
219
220
    /* test against the attribute query */
221
12.9k
    if (m_poAttrQuery != nullptr && !m_poAttrQuery->Evaluate(poOGRFeature))
222
0
    {
223
0
        delete poOGRFeature;
224
0
        return nullptr;
225
0
    }
226
227
12.9k
    if (poGeomRef)
228
3.70k
    {
229
3.70k
        auto poGeom = poGeomRef->clone();
230
3.70k
        poGeom->assignSpatialReference(poSRS);
231
3.70k
        poOGRFeature->SetGeometryDirectly(poGeom);
232
3.70k
    }
233
234
12.9k
    m_iNextFeature++;
235
236
12.9k
    return poOGRFeature;
237
12.9k
}