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 : const 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 : 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 shoul
154 : // cast types
155 1148 : OGRFieldDefn *poDstField = poDstFDefn->GetFieldDefn(iDstField);
156 2296 : if (nullptr != poDstField &&
157 1148 : oFieldDefn.GetType() == poDstField->GetType())
158 1148 : anMap[iField] = iDstField;
159 : }
160 20 : else if (CreateField(&oFieldDefn) == OGRERR_NONE)
161 : {
162 : /* Sanity check : if it fails, the driver is buggy */
163 20 : if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
164 : {
165 0 : CPLError(CE_Warning, CPLE_AppDefined,
166 : "The output driver has claimed to have added the %s "
167 : "field, but it did not!",
168 : oFieldDefn.GetNameRef());
169 : }
170 : else
171 : {
172 20 : anMap[iField] = nDstFieldCount;
173 20 : nDstFieldCount++;
174 : }
175 : }
176 : }
177 :
178 584 : auto poInsertFeature = std::make_unique<OGRFeature>(GetLayerDefn());
179 292 : if (poInsertFeature->SetFrom(poFeature, anMap.data(), TRUE) != OGRERR_NONE)
180 : {
181 0 : CPLError(CE_Failure, CPLE_AppDefined,
182 : "Unable to translate feature " CPL_FRMT_GIB
183 : " from layer %s.\n",
184 : poFeature->GetFID(), soLayerName.c_str());
185 0 : return OGRERR_FAILURE;
186 : }
187 :
188 : // poInsertFeature->SetField( GNM_SYSFIELD_GFID,
189 : // (GNMGFID)poFeature->GetFID() );
190 292 : poInsertFeature->SetField(GNM_SYSFIELD_LAYERNAME, soLayerName);
191 292 : poInsertFeature->SetField(GNM_SYSFIELD_PATHNUM, nPathNo);
192 292 : poInsertFeature->SetField(GNM_SYSFIELD_TYPE, bIsEdge ? "EDGE" : "VERTEX");
193 :
194 292 : CPLErrorReset();
195 292 : return CreateFeature(poInsertFeature.get());
196 : }
197 :
198 0 : OGRErr OGRGNMWrappedResultLayer::ISetFeature(OGRFeature *poFeature)
199 : {
200 0 : return poLayer->SetFeature(poFeature);
201 : }
202 :
203 292 : OGRErr OGRGNMWrappedResultLayer::ICreateFeature(OGRFeature *poFeature)
204 : {
205 292 : return poLayer->CreateFeature(poFeature);
206 : }
|