Coverage Report

Created: 2025-06-13 06:18

/src/gdal/gnm/gnmresultlayer.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GDAL/OGR Geography Network support (Geographic Network Model)
4
 * Purpose:  GNM result layer class.
5
 * Authors:  Mikhail Gusev (gusevmihs at gmail dot com)
6
 *           Dmitry Baryshnikov, polimax@mail.ru
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 2014, Mikhail Gusev
10
 * Copyright (c) 2014-2015, NextGIS <info@nextgis.com>
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a
13
 * copy of this software and associated documentation files (the "Software"),
14
 * to deal in the Software without restriction, including without limitation
15
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16
 * and/or sell copies of the Software, and to permit persons to whom the
17
 * Software is furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included
20
 * in all copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28
 * DEALINGS IN THE SOFTWARE.
29
 ****************************************************************************/
30
#include "gnm.h"
31
#include "gnm_priv.h"
32
33
/** Constructor */
34
OGRGNMWrappedResultLayer::OGRGNMWrappedResultLayer(GDALDataset *poDSIn,
35
                                                   OGRLayer *poLayerIn)
36
0
{
37
0
    this->poDS = poDSIn;
38
0
    this->poLayer = poLayerIn;
39
40
    // create standard fields
41
42
0
    OGRFieldDefn oFieldGID(GNM_SYSFIELD_GFID, GNMGFIDInt);
43
0
    poLayer->CreateField(&oFieldGID);
44
45
0
    OGRFieldDefn oFieldLayerName(GNM_SYSFIELD_LAYERNAME, OFTString);
46
0
    oFieldLayerName.SetWidth(254);
47
0
    poLayer->CreateField(&oFieldLayerName);
48
49
0
    OGRFieldDefn oFieldNo(GNM_SYSFIELD_PATHNUM, OFTInteger);
50
0
    poLayer->CreateField(&oFieldNo);
51
52
0
    OGRFieldDefn oFieldType(GNM_SYSFIELD_TYPE, OFTString);  // EDGE or VERTEX
53
0
    poLayer->CreateField(&oFieldType);
54
0
}
55
56
OGRGNMWrappedResultLayer::~OGRGNMWrappedResultLayer()
57
0
{
58
0
    delete poDS;
59
0
}
60
61
void OGRGNMWrappedResultLayer::ResetReading()
62
0
{
63
0
    poLayer->ResetReading();
64
0
}
65
66
OGRFeature *OGRGNMWrappedResultLayer::GetNextFeature()
67
0
{
68
0
    return poLayer->GetNextFeature();
69
0
}
70
71
OGRErr OGRGNMWrappedResultLayer::SetNextByIndex(GIntBig nIndex)
72
0
{
73
0
    return poLayer->SetNextByIndex(nIndex);
74
0
}
75
76
OGRFeature *OGRGNMWrappedResultLayer::GetFeature(GIntBig nFID)
77
0
{
78
0
    return poLayer->GetFeature(nFID);
79
0
}
80
81
OGRFeatureDefn *OGRGNMWrappedResultLayer::GetLayerDefn()
82
0
{
83
0
    return poLayer->GetLayerDefn();
84
0
}
85
86
GIntBig OGRGNMWrappedResultLayer::GetFeatureCount(int bForce)
87
0
{
88
0
    return poLayer->GetFeatureCount(bForce);
89
0
}
90
91
int OGRGNMWrappedResultLayer::TestCapability(const char *pszCap)
92
0
{
93
0
    return poLayer->TestCapability(pszCap);
94
0
}
95
96
OGRErr OGRGNMWrappedResultLayer::CreateField(const OGRFieldDefn *poField,
97
                                             int bApproxOK)
98
0
{
99
0
    return poLayer->CreateField(poField, bApproxOK);
100
0
}
101
102
OGRErr
103
OGRGNMWrappedResultLayer::CreateGeomField(const OGRGeomFieldDefn *poField,
104
                                          int bApproxOK)
105
0
{
106
0
    return poLayer->CreateGeomField(poField, bApproxOK);
107
0
}
108
109
const char *OGRGNMWrappedResultLayer::GetFIDColumn()
110
0
{
111
0
    return poLayer->GetFIDColumn();
112
0
}
113
114
const char *OGRGNMWrappedResultLayer::GetGeometryColumn()
115
0
{
116
0
    return poLayer->GetGeometryColumn();
117
0
}
118
119
OGRSpatialReference *OGRGNMWrappedResultLayer::GetSpatialRef()
120
0
{
121
0
    return poLayer->GetSpatialRef();
122
0
}
123
124
/** Undocumented */
125
OGRErr OGRGNMWrappedResultLayer::InsertFeature(OGRFeature *poFeature,
126
                                               const CPLString &soLayerName,
127
                                               int nPathNo, bool bIsEdge)
128
0
{
129
0
    VALIDATE_POINTER1(poFeature, "Input feature is invalid",
130
0
                      OGRERR_INVALID_HANDLE);
131
    // add fields from input feature
132
0
    const OGRFeatureDefn *poSrcDefn = poFeature->GetDefnRef();
133
0
    OGRFeatureDefn *poDstFDefn = GetLayerDefn();
134
0
    if (nullptr == poSrcDefn || nullptr == poDstFDefn)
135
0
        return OGRERR_INVALID_HANDLE;
136
137
0
    const int nSrcFieldCount = poSrcDefn->GetFieldCount();
138
0
    int nDstFieldCount = poDstFDefn->GetFieldCount();
139
140
    // Initialize the index-to-index map to -1's
141
0
    std::vector<int> anMap(nSrcFieldCount, -1);
142
143
0
    for (int iField = 0; iField < nSrcFieldCount; iField++)
144
0
    {
145
0
        const OGRFieldDefn *poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
146
0
        OGRFieldDefn oFieldDefn(poSrcFieldDefn);
147
148
        /* The field may have been already created at layer creation */
149
0
        const int iDstField =
150
0
            poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
151
0
        if (iDstField >= 0)
152
0
        {
153
            // TODO: by now skip fields with different types. In future shoul
154
            // cast types
155
0
            OGRFieldDefn *poDstField = poDstFDefn->GetFieldDefn(iDstField);
156
0
            if (nullptr != poDstField &&
157
0
                oFieldDefn.GetType() == poDstField->GetType())
158
0
                anMap[iField] = iDstField;
159
0
        }
160
0
        else if (CreateField(&oFieldDefn) == OGRERR_NONE)
161
0
        {
162
            /* Sanity check : if it fails, the driver is buggy */
163
0
            if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
164
0
            {
165
0
                CPLError(CE_Warning, CPLE_AppDefined,
166
0
                         "The output driver has claimed to have added the %s "
167
0
                         "field, but it did not!",
168
0
                         oFieldDefn.GetNameRef());
169
0
            }
170
0
            else
171
0
            {
172
0
                anMap[iField] = nDstFieldCount;
173
0
                nDstFieldCount++;
174
0
            }
175
0
        }
176
0
    }
177
178
0
    auto poInsertFeature = std::make_unique<OGRFeature>(GetLayerDefn());
179
0
    if (poInsertFeature->SetFrom(poFeature, anMap.data(), TRUE) != OGRERR_NONE)
180
0
    {
181
0
        CPLError(CE_Failure, CPLE_AppDefined,
182
0
                 "Unable to translate feature " CPL_FRMT_GIB
183
0
                 " from layer %s.\n",
184
0
                 poFeature->GetFID(), soLayerName.c_str());
185
0
        return OGRERR_FAILURE;
186
0
    }
187
188
    // poInsertFeature->SetField( GNM_SYSFIELD_GFID,
189
    // (GNMGFID)poFeature->GetFID() );
190
0
    poInsertFeature->SetField(GNM_SYSFIELD_LAYERNAME, soLayerName);
191
0
    poInsertFeature->SetField(GNM_SYSFIELD_PATHNUM, nPathNo);
192
0
    poInsertFeature->SetField(GNM_SYSFIELD_TYPE, bIsEdge ? "EDGE" : "VERTEX");
193
194
0
    CPLErrorReset();
195
0
    return CreateFeature(poInsertFeature.get());
196
0
}
197
198
OGRErr OGRGNMWrappedResultLayer::ISetFeature(OGRFeature *poFeature)
199
0
{
200
0
    return poLayer->SetFeature(poFeature);
201
0
}
202
203
OGRErr OGRGNMWrappedResultLayer::ICreateFeature(OGRFeature *poFeature)
204
0
{
205
0
    return poLayer->CreateFeature(poFeature);
206
0
}