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 : OGRFeatureDefn *OGRGNMWrappedResultLayer::GetLayerDefn()
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)
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()
110 : {
111 2 : return poLayer->GetFIDColumn();
112 : }
113 :
114 0 : const char *OGRGNMWrappedResultLayer::GetGeometryColumn()
115 : {
116 0 : return poLayer->GetGeometryColumn();
117 : }
118 :
119 4 : OGRSpatialReference *OGRGNMWrappedResultLayer::GetSpatialRef()
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 : OGRFeatureDefn *poSrcDefn = poFeature->GetDefnRef();
133 292 : OGRFeatureDefn *poDstFDefn = GetLayerDefn();
134 292 : if (nullptr == poSrcDefn || nullptr == poDstFDefn)
135 0 : return OGRERR_INVALID_HANDLE;
136 :
137 292 : int nSrcFieldCount = poSrcDefn->GetFieldCount();
138 292 : int nDstFieldCount = poDstFDefn->GetFieldCount();
139 : int iField, *panMap;
140 :
141 : // Initialize the index-to-index map to -1's
142 292 : panMap = (int *)CPLMalloc(sizeof(int) * nSrcFieldCount);
143 1460 : for (iField = 0; iField < nSrcFieldCount; iField++)
144 1168 : panMap[iField] = -1;
145 :
146 1460 : for (iField = 0; iField < nSrcFieldCount; iField++)
147 : {
148 1168 : OGRFieldDefn *poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
149 2336 : OGRFieldDefn oFieldDefn(poSrcFieldDefn);
150 :
151 : /* The field may have been already created at layer creation */
152 1168 : int iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
153 1168 : if (iDstField >= 0)
154 : {
155 : // TODO: by now skip fields with different types. In future shoul
156 : // cast types
157 1148 : OGRFieldDefn *poDstField = poDstFDefn->GetFieldDefn(iDstField);
158 2296 : if (nullptr != poDstField &&
159 1148 : oFieldDefn.GetType() == poDstField->GetType())
160 1148 : panMap[iField] = iDstField;
161 : }
162 20 : else if (CreateField(&oFieldDefn) == OGRERR_NONE)
163 : {
164 : /* Sanity check : if it fails, the driver is buggy */
165 20 : if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
166 : {
167 0 : CPLError(CE_Warning, CPLE_AppDefined,
168 : "The output driver has claimed to have added the %s "
169 : "field, but it did not!",
170 : oFieldDefn.GetNameRef());
171 : }
172 : else
173 : {
174 20 : panMap[iField] = nDstFieldCount;
175 20 : nDstFieldCount++;
176 : }
177 : }
178 : }
179 :
180 292 : OGRFeature *poInsertFeature = OGRFeature::CreateFeature(GetLayerDefn());
181 292 : if (poInsertFeature->SetFrom(poFeature, panMap, TRUE) != OGRERR_NONE)
182 : {
183 0 : CPLError(CE_Failure, CPLE_AppDefined,
184 : "Unable to translate feature " CPL_FRMT_GIB
185 : " from layer %s.\n",
186 : poFeature->GetFID(), soLayerName.c_str());
187 0 : OGRFeature::DestroyFeature(poInsertFeature);
188 0 : CPLFree(panMap);
189 0 : return OGRERR_FAILURE;
190 : }
191 :
192 : // poInsertFeature->SetField( GNM_SYSFIELD_GFID,
193 : // (GNMGFID)poFeature->GetFID() );
194 292 : poInsertFeature->SetField(GNM_SYSFIELD_LAYERNAME, soLayerName);
195 292 : poInsertFeature->SetField(GNM_SYSFIELD_PATHNUM, nPathNo);
196 292 : poInsertFeature->SetField(GNM_SYSFIELD_TYPE, bIsEdge ? "EDGE" : "VERTEX");
197 :
198 292 : CPLErrorReset();
199 292 : if (CreateFeature(poInsertFeature) != OGRERR_NONE)
200 : {
201 0 : OGRFeature::DestroyFeature(poInsertFeature);
202 0 : CPLFree(panMap);
203 0 : return OGRERR_FAILURE;
204 : }
205 :
206 292 : OGRFeature::DestroyFeature(poInsertFeature);
207 292 : CPLFree(panMap);
208 292 : return OGRERR_NONE;
209 : }
210 :
211 0 : OGRErr OGRGNMWrappedResultLayer::ISetFeature(OGRFeature *poFeature)
212 : {
213 0 : return poLayer->SetFeature(poFeature);
214 : }
215 :
216 292 : OGRErr OGRGNMWrappedResultLayer::ICreateFeature(OGRFeature *poFeature)
217 : {
218 292 : return poLayer->CreateFeature(poFeature);
219 : }
|