Line data Source code
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 5 : OGRGNMWrappedResultLayer::OGRGNMWrappedResultLayer(GDALDataset *poDSIn,
35 5 : OGRLayer *poLayerIn)
36 : {
37 5 : this->poDS = poDSIn;
38 5 : this->poLayer = poLayerIn;
39 :
40 : // create standard fields
41 :
42 10 : OGRFieldDefn oFieldGID(GNM_SYSFIELD_GFID, GNMGFIDInt);
43 5 : poLayer->CreateField(&oFieldGID);
44 :
45 10 : OGRFieldDefn oFieldLayerName(GNM_SYSFIELD_LAYERNAME, OFTString);
46 5 : oFieldLayerName.SetWidth(254);
47 5 : poLayer->CreateField(&oFieldLayerName);
48 :
49 10 : OGRFieldDefn oFieldNo(GNM_SYSFIELD_PATHNUM, OFTInteger);
50 5 : poLayer->CreateField(&oFieldNo);
51 :
52 10 : OGRFieldDefn oFieldType(GNM_SYSFIELD_TYPE, OFTString); // EDGE or VERTEX
53 5 : poLayer->CreateField(&oFieldType);
54 5 : }
55 :
56 10 : OGRGNMWrappedResultLayer::~OGRGNMWrappedResultLayer()
57 : {
58 5 : delete poDS;
59 10 : }
60 :
61 6 : void OGRGNMWrappedResultLayer::ResetReading()
62 : {
63 6 : poLayer->ResetReading();
64 6 : }
65 :
66 164 : OGRFeature *OGRGNMWrappedResultLayer::GetNextFeature()
67 : {
68 164 : return poLayer->GetNextFeature();
69 : }
70 :
71 0 : OGRErr OGRGNMWrappedResultLayer::SetNextByIndex(GIntBig nIndex)
72 : {
73 0 : return poLayer->SetNextByIndex(nIndex);
74 : }
75 :
76 0 : OGRFeature *OGRGNMWrappedResultLayer::GetFeature(GIntBig nFID)
77 : {
78 0 : return poLayer->GetFeature(nFID);
79 : }
80 :
81 598 : const OGRFeatureDefn *OGRGNMWrappedResultLayer::GetLayerDefn() const
82 : {
83 598 : return poLayer->GetLayerDefn();
84 : }
85 :
86 5 : GIntBig OGRGNMWrappedResultLayer::GetFeatureCount(int bForce)
87 : {
88 5 : return poLayer->GetFeatureCount(bForce);
89 : }
90 :
91 10 : int OGRGNMWrappedResultLayer::TestCapability(const char *pszCap) const
92 : {
93 10 : return poLayer->TestCapability(pszCap);
94 : }
95 :
96 20 : OGRErr OGRGNMWrappedResultLayer::CreateField(const OGRFieldDefn *poField,
97 : int bApproxOK)
98 : {
99 20 : return poLayer->CreateField(poField, bApproxOK);
100 : }
101 :
102 : OGRErr
103 0 : OGRGNMWrappedResultLayer::CreateGeomField(const OGRGeomFieldDefn *poField,
104 : int bApproxOK)
105 : {
106 0 : return poLayer->CreateGeomField(poField, bApproxOK);
107 : }
108 :
109 2 : const char *OGRGNMWrappedResultLayer::GetFIDColumn() const
110 : {
111 2 : return poLayer->GetFIDColumn();
112 : }
113 :
114 0 : const char *OGRGNMWrappedResultLayer::GetGeometryColumn() const
115 : {
116 0 : return poLayer->GetGeometryColumn();
117 : }
118 :
119 4 : const OGRSpatialReference *OGRGNMWrappedResultLayer::GetSpatialRef() const
120 : {
121 4 : return poLayer->GetSpatialRef();
122 : }
123 :
124 : /** Undocumented */
125 292 : OGRErr OGRGNMWrappedResultLayer::InsertFeature(OGRFeature *poFeature,
126 : const CPLString &soLayerName,
127 : int nPathNo, bool bIsEdge)
128 : {
129 292 : VALIDATE_POINTER1(poFeature, "Input feature is invalid",
130 : OGRERR_INVALID_HANDLE);
131 : // add fields from input feature
132 292 : const OGRFeatureDefn *poSrcDefn = poFeature->GetDefnRef();
133 292 : const OGRFeatureDefn *poDstFDefn = GetLayerDefn();
134 292 : if (nullptr == poSrcDefn || nullptr == poDstFDefn)
135 0 : return OGRERR_INVALID_HANDLE;
136 :
137 292 : const int nSrcFieldCount = poSrcDefn->GetFieldCount();
138 292 : int nDstFieldCount = poDstFDefn->GetFieldCount();
139 :
140 : // Initialize the index-to-index map to -1's
141 584 : std::vector<int> anMap(nSrcFieldCount, -1);
142 :
143 1460 : for (int iField = 0; iField < nSrcFieldCount; iField++)
144 : {
145 1168 : const OGRFieldDefn *poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
146 2336 : OGRFieldDefn oFieldDefn(poSrcFieldDefn);
147 :
148 : /* The field may have been already created at layer creation */
149 : const int iDstField =
150 1168 : poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
151 1168 : if (iDstField >= 0)
152 : {
153 : // TODO: by now skip fields with different types. In future should
154 : // cast types
155 : const OGRFieldDefn *poDstField =
156 1148 : poDstFDefn->GetFieldDefn(iDstField);
157 2296 : if (nullptr != poDstField &&
158 1148 : oFieldDefn.GetType() == poDstField->GetType())
159 1148 : anMap[iField] = iDstField;
160 : }
161 20 : else if (CreateField(&oFieldDefn) == OGRERR_NONE)
162 : {
163 : /* Sanity check : if it fails, the driver is buggy */
164 20 : if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
165 : {
166 0 : CPLError(CE_Warning, CPLE_AppDefined,
167 : "The output driver has claimed to have added the %s "
168 : "field, but it did not!",
169 : oFieldDefn.GetNameRef());
170 : }
171 : else
172 : {
173 20 : anMap[iField] = nDstFieldCount;
174 20 : nDstFieldCount++;
175 : }
176 : }
177 : }
178 :
179 584 : auto poInsertFeature = std::make_unique<OGRFeature>(GetLayerDefn());
180 292 : if (poInsertFeature->SetFrom(poFeature, anMap.data(), TRUE) != OGRERR_NONE)
181 : {
182 0 : CPLError(CE_Failure, CPLE_AppDefined,
183 : "Unable to translate feature " CPL_FRMT_GIB
184 : " from layer %s.\n",
185 : poFeature->GetFID(), soLayerName.c_str());
186 0 : return OGRERR_FAILURE;
187 : }
188 :
189 : // poInsertFeature->SetField( GNM_SYSFIELD_GFID,
190 : // (GNMGFID)poFeature->GetFID() );
191 292 : poInsertFeature->SetField(GNM_SYSFIELD_LAYERNAME, soLayerName);
192 292 : poInsertFeature->SetField(GNM_SYSFIELD_PATHNUM, nPathNo);
193 292 : poInsertFeature->SetField(GNM_SYSFIELD_TYPE, bIsEdge ? "EDGE" : "VERTEX");
194 :
195 292 : CPLErrorReset();
196 292 : return CreateFeature(poInsertFeature.get());
197 : }
198 :
199 0 : OGRErr OGRGNMWrappedResultLayer::ISetFeature(OGRFeature *poFeature)
200 : {
201 0 : return poLayer->SetFeature(poFeature);
202 : }
203 :
204 292 : OGRErr OGRGNMWrappedResultLayer::ICreateFeature(OGRFeature *poFeature)
205 : {
206 292 : return poLayer->CreateFeature(poFeature);
207 : }
|