1 /******************************************************************************
2  *
3  * Project:  GDAL/OGR Geography Network support (Geographic Network Model)
4  * Purpose:  GNM 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 CPL_CVSID("$Id: gnmlayer.cpp 7e07230bbff24eb333608de4dbd460b7312839d0 2017-12-11 19:08:47Z Even Rouault $")
34 
35 /**
36  * GNMGenericLayer
37  */
GNMGenericLayer(OGRLayer * poLayer,GNMGenericNetwork * poNetwork)38 GNMGenericLayer::GNMGenericLayer(OGRLayer* poLayer,
39                                  GNMGenericNetwork* poNetwork) :
40     OGRLayer(),
41     m_soLayerName( poLayer->GetName() ),
42     m_poLayer( poLayer ),
43     m_poNetwork( poNetwork )
44 {
45 }
46 
47 /**
48  * ~GNMGenericLayer
49  */
~GNMGenericLayer()50 GNMGenericLayer::~GNMGenericLayer() {}
51 
GetFIDColumn()52 const char *GNMGenericLayer::GetFIDColumn()
53 {
54     return GNM_SYSFIELD_GFID;
55 }
56 
GetGeometryColumn()57 const char *GNMGenericLayer::GetGeometryColumn()
58 {
59     return m_poLayer->GetGeometryColumn();
60 }
61 
SetIgnoredFields(const char ** papszFields)62 OGRErr GNMGenericLayer::SetIgnoredFields(const char **papszFields)
63 {
64     return m_poLayer->SetIgnoredFields(papszFields);
65 }
66 
Intersection(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)67 OGRErr GNMGenericLayer::Intersection(OGRLayer *pLayerMethod,
68                                      OGRLayer *pLayerResult,
69                                      char **papszOptions,
70                                      GDALProgressFunc pfnProgress,
71                                      void *pProgressArg)
72 {
73     return m_poLayer->Intersection(pLayerMethod, pLayerResult, papszOptions,
74                                    pfnProgress, pProgressArg);
75 }
76 
Union(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)77 OGRErr GNMGenericLayer::Union(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
78                               char **papszOptions, GDALProgressFunc pfnProgress,
79                               void *pProgressArg)
80 {
81     return m_poLayer->Union(pLayerMethod, pLayerResult, papszOptions,
82                                    pfnProgress, pProgressArg);
83 }
84 
SymDifference(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)85 OGRErr GNMGenericLayer::SymDifference(OGRLayer *pLayerMethod,
86                                       OGRLayer *pLayerResult, char **papszOptions,
87                                       GDALProgressFunc pfnProgress, void *pProgressArg)
88 {
89     return m_poLayer->Union(pLayerMethod, pLayerResult, papszOptions,
90                                    pfnProgress, pProgressArg);
91 }
92 
Identity(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)93 OGRErr GNMGenericLayer::Identity(OGRLayer *pLayerMethod,
94                                  OGRLayer *pLayerResult, char **papszOptions,
95                                  GDALProgressFunc pfnProgress, void *pProgressArg)
96 {
97     return m_poLayer->Union(pLayerMethod, pLayerResult, papszOptions,
98                                    pfnProgress, pProgressArg);
99 }
100 
Update(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)101 OGRErr GNMGenericLayer::Update(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
102                                char **papszOptions, GDALProgressFunc pfnProgress,
103                                void *pProgressArg)
104 {
105     return m_poLayer->Update(pLayerMethod, pLayerResult, papszOptions,
106                                    pfnProgress, pProgressArg);
107 }
108 
Clip(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)109 OGRErr GNMGenericLayer::Clip(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
110                              char **papszOptions, GDALProgressFunc pfnProgress,
111                              void *pProgressArg)
112 {
113     return m_poLayer->Clip(pLayerMethod, pLayerResult, papszOptions,
114                                    pfnProgress, pProgressArg);
115 }
116 
Erase(OGRLayer * pLayerMethod,OGRLayer * pLayerResult,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressArg)117 OGRErr GNMGenericLayer::Erase(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
118                               char **papszOptions, GDALProgressFunc pfnProgress,
119                               void *pProgressArg)
120 {
121     return m_poLayer->Erase(pLayerMethod, pLayerResult, papszOptions,
122                                    pfnProgress, pProgressArg);
123 }
124 
GetFeaturesRead()125 GIntBig GNMGenericLayer::GetFeaturesRead()
126 {
127     return m_poLayer->GetFeaturesRead();
128 }
129 
AttributeFilterEvaluationNeedsGeometry()130 int GNMGenericLayer::AttributeFilterEvaluationNeedsGeometry()
131 {
132     return m_poLayer->AttributeFilterEvaluationNeedsGeometry();
133 }
134 
135 //! @cond Doxygen_Suppress
InitializeIndexSupport(const char * pszVal)136 OGRErr GNMGenericLayer::InitializeIndexSupport(const char *pszVal)
137 {
138     return m_poLayer->InitializeIndexSupport(pszVal);
139 }
140 
GetIndex()141 OGRLayerAttrIndex *GNMGenericLayer::GetIndex()
142 {
143     return m_poLayer->GetIndex();
144 }
145 
ISetFeature(OGRFeature * poFeature)146 OGRErr GNMGenericLayer::ISetFeature(OGRFeature *poFeature)
147 {
148     VALIDATE_POINTER1(poFeature, "GNMGenericLayer::ISetFeature", CE_Failure);
149     std::map<GNMGFID, GIntBig>::iterator it = m_mnFIDMap.find(poFeature->GetFID());
150     if (it == m_mnFIDMap.end())
151     {
152         CPLError( CE_Failure, CPLE_IllegalArg, "The FID " CPL_FRMT_GIB " is invalid",
153                   poFeature->GetFID() );
154         return OGRERR_NON_EXISTING_FEATURE;
155     }
156 
157     // TODO: check connection rules if feature can be changed.
158 
159     poFeature->SetFID(it->second);
160     return m_poLayer->SetFeature(poFeature);
161 }
162 
ICreateFeature(OGRFeature * poFeature)163 OGRErr GNMGenericLayer::ICreateFeature(OGRFeature *poFeature)
164 {
165     VALIDATE_POINTER1(poFeature, "GNMGenericLayer::ICreateFeature", CE_Failure);
166     GNMGFID nFID = m_poNetwork->GetNewGlobalFID();
167     poFeature->SetFID(nFID);
168     poFeature->SetField(GNM_SYSFIELD_GFID, nFID);
169     poFeature->SetField(GNM_SYSFIELD_BLOCKED, GNM_BLOCK_NONE);
170     if(m_poNetwork->AddFeatureGlobalFID(nFID, GetName()) != CE_None)
171         return OGRERR_FAILURE;
172     return m_poLayer->CreateFeature(poFeature);
173 }
174 //! @endcond
175 
GetSpatialFilter()176 OGRGeometry *GNMGenericLayer::GetSpatialFilter()
177 {
178     return m_poLayer->GetSpatialFilter();
179 }
180 
SetSpatialFilter(OGRGeometry * poGeometry)181 void GNMGenericLayer::SetSpatialFilter(OGRGeometry *poGeometry)
182 {
183     m_poLayer->SetSpatialFilter(poGeometry);
184 }
185 
SetSpatialFilterRect(double dfMinX,double dfMinY,double dfMaxX,double dfMaxY)186 void GNMGenericLayer::SetSpatialFilterRect(double dfMinX, double dfMinY,
187                                            double dfMaxX, double dfMaxY)
188 {
189     m_poLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
190 }
191 
SetSpatialFilter(int iGeomField,OGRGeometry * poGeometry)192 void GNMGenericLayer::SetSpatialFilter(int iGeomField, OGRGeometry *poGeometry)
193 {
194     m_poLayer->SetSpatialFilter(iGeomField ,poGeometry);
195 }
196 
SetSpatialFilterRect(int iGeomField,double dfMinX,double dfMinY,double dfMaxX,double dfMaxY)197 void GNMGenericLayer::SetSpatialFilterRect(int iGeomField,
198                                            double dfMinX, double dfMinY,
199                                            double dfMaxX, double dfMaxY)
200 {
201     m_poLayer->SetSpatialFilterRect(iGeomField, dfMinX, dfMinY, dfMaxX, dfMaxY);
202 }
203 
SetAttributeFilter(const char * pszFilter)204 OGRErr GNMGenericLayer::SetAttributeFilter(const char *pszFilter)
205 {
206     return m_poLayer->SetAttributeFilter(pszFilter);
207 }
208 
ResetReading()209 void GNMGenericLayer::ResetReading()
210 {
211     m_poLayer->ResetReading();
212 }
213 
GetNextFeature()214 OGRFeature *GNMGenericLayer::GetNextFeature()
215 {
216     OGRFeature* pFeature = m_poLayer->GetNextFeature();
217     if(nullptr == pFeature)
218         return nullptr;
219     GNMGFID nGFID = pFeature->GetFieldAsGNMGFID(GNM_SYSFIELD_GFID);
220     m_mnFIDMap[nGFID] = pFeature->GetFID();
221     pFeature->SetFID(nGFID);
222     return pFeature;
223 }
224 
SetNextByIndex(GIntBig nIndex)225 OGRErr GNMGenericLayer::SetNextByIndex(GIntBig nIndex)
226 {
227     return m_poLayer->SetNextByIndex(nIndex);
228 }
229 
DeleteFeature(GIntBig nFID)230 OGRErr GNMGenericLayer::DeleteFeature(GIntBig nFID)
231 {
232     OGRFeature *poFeature = GetFeature(nFID);
233     if(nullptr == poFeature)
234         return CE_Failure;
235 
236     nFID = poFeature->GetFID();
237     std::map<GNMGFID, GIntBig>::iterator it = m_mnFIDMap.find(nFID);
238     if (it == m_mnFIDMap.end())
239     {
240         CPLError( CE_Failure, CPLE_IllegalArg, "The FID " CPL_FRMT_GIB " is invalid",
241                   nFID );
242         return OGRERR_NON_EXISTING_FEATURE;
243     }
244 
245     OGRFeature::DestroyFeature(poFeature);
246 
247     //delete from graph
248     if(m_poNetwork->DisconnectFeaturesWithId((GNMGFID)nFID) !=
249             CE_None)
250         return CE_Failure;
251 
252     return m_poLayer->DeleteFeature(it->second);
253 }
254 
GetName()255 const char *GNMGenericLayer::GetName()
256 {
257     return m_soLayerName;
258 }
259 
GetGeomType()260 OGRwkbGeometryType GNMGenericLayer::GetGeomType()
261 {
262     return m_poLayer->GetGeomType();
263 }
264 
FindFieldIndex(const char * pszFieldName,int bExactMatch)265 int GNMGenericLayer::FindFieldIndex(const char *pszFieldName, int bExactMatch)
266 {
267     return m_poLayer->FindFieldIndex(pszFieldName, bExactMatch);
268 }
269 
GetSpatialRef()270 OGRSpatialReference *GNMGenericLayer::GetSpatialRef()
271 {
272     return m_poLayer->GetSpatialRef();
273 }
274 
GetFeatureCount(int bForce)275 GIntBig GNMGenericLayer::GetFeatureCount(int bForce)
276 {
277     return m_poLayer->GetFeatureCount(bForce);
278 }
279 
GetExtent(OGREnvelope * psExtent,int bForce)280 OGRErr GNMGenericLayer::GetExtent(OGREnvelope *psExtent, int bForce)
281 {
282     return m_poLayer->GetExtent(psExtent, bForce);
283 }
284 
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)285 OGRErr GNMGenericLayer::GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce)
286 {
287     return m_poLayer->GetExtent(iGeomField, psExtent, bForce);
288 }
289 
TestCapability(const char * pszCapability)290 int GNMGenericLayer::TestCapability(const char *pszCapability)
291 {
292     return m_poLayer->TestCapability(pszCapability);
293 }
294 
CreateField(OGRFieldDefn * poField,int bApproxOK)295 OGRErr GNMGenericLayer::CreateField(OGRFieldDefn *poField, int bApproxOK)
296 {
297     return m_poLayer->CreateField(poField, bApproxOK);
298 }
299 
DeleteField(int iField)300 OGRErr GNMGenericLayer::DeleteField(int iField)
301 {
302     if(iField == FindFieldIndex(GNM_SYSFIELD_GFID, TRUE))
303         return OGRERR_UNSUPPORTED_OPERATION;
304     if(iField == FindFieldIndex(GNM_SYSFIELD_BLOCKED, TRUE))
305         return OGRERR_UNSUPPORTED_OPERATION;
306     return m_poLayer->DeleteField(iField);
307 }
308 
ReorderFields(int * panMap)309 OGRErr GNMGenericLayer::ReorderFields(int *panMap)
310 {
311     return m_poLayer->ReorderFields(panMap);
312 }
313 
AlterFieldDefn(int iField,OGRFieldDefn * poNewFieldDefn,int nFlagsIn)314 OGRErr GNMGenericLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn, int nFlagsIn)
315 {
316     if(iField == FindFieldIndex(GNM_SYSFIELD_GFID, TRUE))
317         return OGRERR_UNSUPPORTED_OPERATION;
318     if(iField == FindFieldIndex(GNM_SYSFIELD_BLOCKED, TRUE))
319         return OGRERR_UNSUPPORTED_OPERATION;
320     return m_poLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
321 }
322 
CreateGeomField(OGRGeomFieldDefn * poField,int bApproxOK)323 OGRErr GNMGenericLayer::CreateGeomField(OGRGeomFieldDefn *poField, int bApproxOK)
324 {
325     return m_poLayer->CreateGeomField(poField, bApproxOK);
326 }
327 
SyncToDisk()328 OGRErr GNMGenericLayer::SyncToDisk()
329 {
330     return m_poLayer->SyncToDisk();
331 }
332 
GetStyleTable()333 OGRStyleTable *GNMGenericLayer::GetStyleTable()
334 {
335     return m_poLayer->GetStyleTable();
336 }
337 
SetStyleTableDirectly(OGRStyleTable * poStyleTable)338 void GNMGenericLayer::SetStyleTableDirectly(OGRStyleTable *poStyleTable)
339 {
340     return m_poLayer->SetStyleTableDirectly(poStyleTable);
341 }
342 
SetStyleTable(OGRStyleTable * poStyleTable)343 void GNMGenericLayer::SetStyleTable(OGRStyleTable *poStyleTable)
344 {
345     return m_poLayer->SetStyleTable(poStyleTable);
346 }
347 
StartTransaction()348 OGRErr GNMGenericLayer::StartTransaction()
349 {
350     return m_poLayer->StartTransaction();
351 }
352 
CommitTransaction()353 OGRErr GNMGenericLayer::CommitTransaction()
354 {
355     return m_poLayer->CommitTransaction();
356 }
357 
RollbackTransaction()358 OGRErr GNMGenericLayer::RollbackTransaction()
359 {
360     return m_poLayer->RollbackTransaction();
361 }
362 
GetLayerDefn()363 OGRFeatureDefn *GNMGenericLayer::GetLayerDefn()
364 {
365     //TODO: hide GNM_SYSFIELD_GFID filed
366     return m_poLayer->GetLayerDefn();
367 }
368