/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 | } |