Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL/OGR Geography Network support (Geographic Network Model)
4 : * Purpose: GNM file based generic driver.
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 :
31 : #include "gnmfile.h"
32 : #include "gnm_priv.h"
33 :
34 16 : GNMFileNetwork::GNMFileNetwork() : GNMGenericNetwork()
35 : {
36 16 : m_pMetadataDS = nullptr;
37 16 : m_pGraphDS = nullptr;
38 16 : m_pFeaturesDS = nullptr;
39 16 : }
40 :
41 31 : GNMFileNetwork::~GNMFileNetwork()
42 : {
43 16 : FlushCache(true);
44 :
45 21 : for (std::map<OGRLayer *, GDALDataset *>::iterator it =
46 16 : m_mpLayerDatasetMap.begin();
47 58 : it != m_mpLayerDatasetMap.end(); ++it)
48 : {
49 21 : GDALClose(it->second);
50 : }
51 :
52 16 : m_mpLayerDatasetMap.clear();
53 :
54 16 : GDALClose(m_pGraphDS);
55 16 : GDALClose(m_pFeaturesDS);
56 16 : GDALClose(m_pMetadataDS);
57 31 : }
58 :
59 14 : CPLErr GNMFileNetwork::Open(GDALOpenInfo *poOpenInfo)
60 : {
61 14 : m_soNetworkFullName = poOpenInfo->pszFilename;
62 14 : char **papszFiles = VSIReadDir(m_soNetworkFullName);
63 14 : if (CSLCount(papszFiles) == 0)
64 : {
65 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Open '%s' file failed",
66 : m_soNetworkFullName.c_str());
67 0 : return CE_Failure;
68 : }
69 :
70 : // search for metadata file
71 28 : CPLString soMetadatafile;
72 39 : for (int i = 0; papszFiles[i] != nullptr; i++)
73 : {
74 39 : if (EQUAL(papszFiles[i], ".") || EQUAL(papszFiles[i], ".."))
75 0 : continue;
76 :
77 39 : if (EQUAL(CPLGetBasename(papszFiles[i]), GNM_SYSLAYER_META))
78 : {
79 : soMetadatafile =
80 14 : CPLFormFilename(m_soNetworkFullName, papszFiles[i], nullptr);
81 14 : break;
82 : }
83 : }
84 :
85 14 : CSLDestroy(papszFiles);
86 :
87 14 : m_pMetadataDS = (GDALDataset *)GDALOpenEx(soMetadatafile,
88 : GDAL_OF_VECTOR | GDAL_OF_UPDATE,
89 : nullptr, nullptr, nullptr);
90 14 : if (nullptr == m_pMetadataDS)
91 : {
92 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Open '%s' file failed",
93 : m_soNetworkFullName.c_str());
94 0 : return CE_Failure;
95 : }
96 :
97 14 : if (LoadMetadataLayer(m_pMetadataDS) != CE_None)
98 : {
99 0 : return CE_Failure;
100 : }
101 :
102 14 : m_poLayerDriver = m_pMetadataDS->GetDriver();
103 28 : CPLString osExt = CPLGetExtension(soMetadatafile);
104 :
105 : CPLString soGraphfile =
106 28 : CPLFormFilename(m_soNetworkFullName, GNM_SYSLAYER_GRAPH, osExt);
107 14 : m_pGraphDS =
108 14 : (GDALDataset *)GDALOpenEx(soGraphfile, GDAL_OF_VECTOR | GDAL_OF_UPDATE,
109 : nullptr, nullptr, nullptr);
110 14 : if (nullptr == m_pGraphDS)
111 : {
112 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Open '%s' file failed",
113 : m_soNetworkFullName.c_str());
114 0 : return CE_Failure;
115 : }
116 :
117 14 : if (LoadGraphLayer(m_pGraphDS) != CE_None)
118 : {
119 0 : return CE_Failure;
120 : }
121 :
122 : CPLString soFeaturesfile =
123 28 : CPLFormFilename(m_soNetworkFullName, GNM_SYSLAYER_FEATURES, osExt);
124 14 : m_pFeaturesDS = (GDALDataset *)GDALOpenEx(soFeaturesfile,
125 : GDAL_OF_VECTOR | GDAL_OF_UPDATE,
126 : nullptr, nullptr, nullptr);
127 14 : if (nullptr == m_pFeaturesDS)
128 : {
129 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Open '%s' file failed",
130 : m_soNetworkFullName.c_str());
131 0 : return CE_Failure;
132 : }
133 :
134 14 : if (LoadFeaturesLayer(m_pFeaturesDS) != CE_None)
135 : {
136 0 : return CE_Failure;
137 : }
138 :
139 14 : return CE_None;
140 : }
141 :
142 2 : int GNMFileNetwork::CheckNetworkExist(const char *pszFilename,
143 : char **papszOptions)
144 : {
145 : // check if path exist
146 : // if path exist check if network already present and OVERWRITE option
147 : // else create the path
148 :
149 2 : const bool bOverwrite = CPLFetchBool(papszOptions, "OVERWRITE", false);
150 :
151 2 : if (m_soName.empty())
152 : {
153 : const char *pszNetworkName =
154 0 : CSLFetchNameValue(papszOptions, GNM_MD_NAME);
155 :
156 0 : if (nullptr != pszNetworkName)
157 : {
158 0 : m_soName = pszNetworkName;
159 : }
160 : }
161 :
162 2 : if (FormPath(pszFilename, papszOptions) != CE_None)
163 : {
164 0 : return TRUE;
165 : }
166 :
167 2 : if (CPLCheckForFile((char *)m_soNetworkFullName.c_str(), nullptr))
168 : {
169 0 : char **papszFiles = VSIReadDir(m_soNetworkFullName);
170 0 : if (CSLCount(papszFiles) == 0)
171 : {
172 0 : return FALSE;
173 : }
174 :
175 : // search for base GNM files
176 0 : for (int i = 0; papszFiles[i] != nullptr; i++)
177 : {
178 0 : if (EQUAL(papszFiles[i], ".") || EQUAL(papszFiles[i], ".."))
179 0 : continue;
180 :
181 0 : if (EQUAL(CPLGetBasename(papszFiles[i]), GNM_SYSLAYER_META) ||
182 0 : EQUAL(CPLGetBasename(papszFiles[i]), GNM_SYSLAYER_GRAPH) ||
183 0 : EQUAL(CPLGetBasename(papszFiles[i]), GNM_SYSLAYER_FEATURES) ||
184 0 : EQUAL(papszFiles[i], GNM_SRSFILENAME))
185 : {
186 0 : if (bOverwrite)
187 : {
188 0 : const char *pszDeleteFile = CPLFormFilename(
189 0 : m_soNetworkFullName, papszFiles[i], nullptr);
190 0 : CPLDebug("GNM", "Delete file: %s", pszDeleteFile);
191 0 : if (VSIUnlink(pszDeleteFile) != 0)
192 : {
193 0 : return TRUE;
194 : }
195 : }
196 : else
197 : {
198 0 : return TRUE;
199 : }
200 : }
201 : }
202 0 : CSLDestroy(papszFiles);
203 : }
204 : else
205 : {
206 2 : if (VSIMkdir(m_soNetworkFullName, 0755) != 0)
207 : {
208 0 : return TRUE;
209 : }
210 : }
211 :
212 2 : return FALSE;
213 : }
214 :
215 2 : CPLErr GNMFileNetwork::Delete()
216 : {
217 2 : CPLErr eResult = GNMGenericNetwork::Delete();
218 2 : if (eResult != CE_None)
219 0 : return eResult;
220 :
221 : // check if folder empty
222 2 : char **papszFiles = VSIReadDir(m_soNetworkFullName);
223 2 : bool bIsEmpty = true;
224 6 : for (int i = 0; papszFiles[i] != nullptr; ++i)
225 : {
226 4 : if (!(EQUAL(papszFiles[i], "..") || EQUAL(papszFiles[i], ".")))
227 : {
228 0 : bIsEmpty = false;
229 0 : break;
230 : }
231 : }
232 :
233 2 : CSLDestroy(papszFiles);
234 :
235 2 : if (!bIsEmpty)
236 : {
237 0 : return eResult;
238 : }
239 2 : return VSIRmdir(m_soNetworkFullName) == 0 ? CE_None : CE_Failure;
240 : }
241 :
242 2 : CPLErr GNMFileNetwork::CreateMetadataLayerFromFile(const char *pszFilename,
243 : int nVersion,
244 : char **papszOptions)
245 : {
246 2 : CPLErr eResult = CheckLayerDriver(GNM_MD_DEFAULT_FILE_FORMAT, papszOptions);
247 2 : if (CE_None != eResult)
248 0 : return eResult;
249 :
250 2 : eResult = FormPath(pszFilename, papszOptions);
251 2 : if (CE_None != eResult)
252 0 : return eResult;
253 :
254 2 : const char *pszExt = m_poLayerDriver->GetMetadataItem(GDAL_DMD_EXTENSION);
255 : CPLString osDSFileName =
256 4 : CPLFormFilename(m_soNetworkFullName, GNM_SYSLAYER_META, pszExt);
257 :
258 2 : m_pMetadataDS =
259 2 : m_poLayerDriver->Create(osDSFileName, 0, 0, 0, GDT_Unknown, nullptr);
260 2 : if (nullptr == m_pMetadataDS)
261 : {
262 0 : CPLError(CE_Failure, CPLE_AppDefined, "Creation of '%s' file failed",
263 : osDSFileName.c_str());
264 0 : return CE_Failure;
265 : }
266 :
267 2 : return GNMGenericNetwork::CreateMetadataLayer(m_pMetadataDS, nVersion, 254);
268 : }
269 :
270 2 : CPLErr GNMFileNetwork::StoreNetworkSrs()
271 : {
272 2 : if (m_oSRS.IsEmpty())
273 0 : return CE_None;
274 : const char *pszSrsFileName =
275 2 : CPLFormFilename(m_soNetworkFullName, GNM_SRSFILENAME, nullptr);
276 2 : VSILFILE *fpSrsPrj = VSIFOpenL(pszSrsFileName, "w");
277 2 : if (fpSrsPrj != nullptr)
278 : {
279 2 : char *pszWKT = nullptr;
280 2 : m_oSRS.exportToWkt(&pszWKT);
281 2 : if (pszWKT && VSIFWriteL(pszWKT, (int)strlen(pszWKT), 1, fpSrsPrj) != 1)
282 : {
283 0 : CPLFree(pszWKT);
284 0 : CPLError(CE_Failure, CPLE_AppDefined,
285 : "Write SRS failed, disk full?");
286 0 : VSIFCloseL(fpSrsPrj);
287 0 : return CE_Failure;
288 : }
289 2 : CPLFree(pszWKT);
290 2 : VSIFCloseL(fpSrsPrj);
291 : }
292 2 : return CE_None;
293 : }
294 :
295 0 : CPLErr GNMFileNetwork::LoadNetworkSrs()
296 : {
297 : const char *pszSrsFileName =
298 0 : CPLFormFilename(m_soNetworkFullName, GNM_SRSFILENAME, nullptr);
299 0 : char **papszLines = CSLLoad(pszSrsFileName);
300 0 : if (nullptr == papszLines)
301 : {
302 0 : CPLError(CE_Failure, CPLE_AppDefined, "Loading of '%s' layer failed",
303 : GNM_SYSLAYER_META);
304 0 : return CE_Failure;
305 : }
306 :
307 0 : m_oSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
308 0 : m_oSRS.importFromWkt(papszLines[0]);
309 :
310 0 : CSLDestroy(papszLines);
311 :
312 0 : return CE_None;
313 : }
314 :
315 2 : CPLErr GNMFileNetwork::DeleteMetadataLayer()
316 : {
317 2 : if (nullptr != m_pMetadataDS)
318 : {
319 : const char *pszSrsFileName =
320 2 : CPLFormFilename(m_soNetworkFullName, GNM_SRSFILENAME, nullptr);
321 2 : VSIUnlink(
322 : pszSrsFileName); // just try to delete as file may not be existed
323 2 : return m_pMetadataDS->DeleteLayer(0) == OGRERR_NONE ? CE_None
324 2 : : CE_Failure;
325 : }
326 0 : return CE_Failure;
327 : }
328 :
329 2 : CPLErr GNMFileNetwork::CreateGraphLayerFromFile(const char *pszFilename,
330 : char **papszOptions)
331 : {
332 2 : CPLErr eResult = CheckLayerDriver(GNM_MD_DEFAULT_FILE_FORMAT, papszOptions);
333 2 : if (CE_None != eResult)
334 0 : return eResult;
335 :
336 2 : eResult = FormPath(pszFilename, papszOptions);
337 2 : if (CE_None != eResult)
338 0 : return eResult;
339 :
340 2 : const char *pszExt = m_poLayerDriver->GetMetadataItem(GDAL_DMD_EXTENSION);
341 : CPLString osDSFileName =
342 4 : CPLFormFilename(m_soNetworkFullName, GNM_SYSLAYER_GRAPH, pszExt);
343 :
344 2 : m_pGraphDS =
345 2 : m_poLayerDriver->Create(osDSFileName, 0, 0, 0, GDT_Unknown, nullptr);
346 :
347 2 : if (m_pGraphDS == nullptr)
348 : {
349 0 : CPLError(CE_Failure, CPLE_AppDefined, "Creation of '%s' file failed",
350 : osDSFileName.c_str());
351 0 : return CE_Failure;
352 : }
353 :
354 2 : return GNMGenericNetwork::CreateGraphLayer(m_pGraphDS);
355 : }
356 :
357 2 : CPLErr GNMFileNetwork::DeleteGraphLayer()
358 : {
359 2 : if (nullptr != m_pGraphDS)
360 : {
361 2 : return m_pGraphDS->DeleteLayer(0) == OGRERR_NONE ? CE_None : CE_Failure;
362 : }
363 0 : return CE_Failure;
364 : }
365 :
366 2 : CPLErr GNMFileNetwork::CreateFeaturesLayerFromFile(const char *pszFilename,
367 : char **papszOptions)
368 : {
369 2 : CPLErr eResult = CheckLayerDriver(GNM_MD_DEFAULT_FILE_FORMAT, papszOptions);
370 2 : if (CE_None != eResult)
371 0 : return eResult;
372 :
373 2 : eResult = FormPath(pszFilename, papszOptions);
374 2 : if (CE_None != eResult)
375 0 : return eResult;
376 :
377 2 : const char *pszExt = m_poLayerDriver->GetMetadataItem(GDAL_DMD_EXTENSION);
378 : CPLString osDSFileName =
379 4 : CPLFormFilename(m_soNetworkFullName, GNM_SYSLAYER_FEATURES, pszExt);
380 :
381 2 : m_pFeaturesDS =
382 2 : m_poLayerDriver->Create(osDSFileName, 0, 0, 0, GDT_Unknown, nullptr);
383 :
384 2 : if (m_pFeaturesDS == nullptr)
385 : {
386 0 : CPLError(CE_Failure, CPLE_AppDefined, "Creation of '%s' file failed",
387 : osDSFileName.c_str());
388 0 : return CE_Failure;
389 : }
390 :
391 2 : return GNMGenericNetwork::CreateFeaturesLayer(m_pFeaturesDS);
392 : }
393 :
394 2 : CPLErr GNMFileNetwork::DeleteFeaturesLayer()
395 : {
396 2 : if (nullptr != m_pFeaturesDS)
397 : {
398 2 : return m_pFeaturesDS->DeleteLayer(0) == OGRERR_NONE ? CE_None
399 2 : : CE_Failure;
400 : }
401 0 : return CE_Failure;
402 : }
403 :
404 6 : CPLErr GNMFileNetwork::DeleteNetworkLayers()
405 : {
406 6 : while (GetLayerCount() > 0)
407 : {
408 4 : OGRErr eErr = DeleteLayer(0);
409 4 : if (eErr != OGRERR_NONE)
410 0 : return CE_Failure;
411 : }
412 2 : return CE_None;
413 : }
414 :
415 673 : CPLErr GNMFileNetwork::LoadNetworkLayer(const char *pszLayername)
416 : {
417 : // check if not loaded
418 983 : for (size_t i = 0; i < m_apoLayers.size(); ++i)
419 : {
420 962 : if (EQUAL(m_apoLayers[i]->GetName(), pszLayername))
421 652 : return CE_None;
422 : }
423 :
424 21 : const char *pszExt = m_poLayerDriver->GetMetadataItem(GDAL_DMD_EXTENSION);
425 :
426 : CPLString soFile =
427 42 : CPLFormFilename(m_soNetworkFullName, pszLayername, pszExt);
428 21 : GDALDataset *poDS = (GDALDataset *)GDALOpenEx(
429 : soFile, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr);
430 21 : if (nullptr == poDS)
431 : {
432 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Open '%s' file failed",
433 : soFile.c_str());
434 0 : return CE_Failure;
435 : }
436 :
437 21 : OGRLayer *poLayer = poDS->GetLayer(0);
438 21 : if (nullptr == poLayer)
439 : {
440 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Layer '%s' is not exist",
441 : pszLayername);
442 0 : return CE_Failure;
443 : }
444 :
445 21 : CPLDebug("GNM", "Layer '%s' loaded", poLayer->GetName());
446 :
447 21 : GNMGenericLayer *pGNMLayer = new GNMGenericLayer(poLayer, this);
448 21 : m_apoLayers.push_back(pGNMLayer);
449 21 : m_mpLayerDatasetMap[pGNMLayer] = poDS;
450 :
451 21 : return CE_None;
452 : }
453 :
454 2 : bool GNMFileNetwork::CheckStorageDriverSupport(const char *pszDriverName)
455 : {
456 2 : if (EQUAL(pszDriverName, GNM_MD_DEFAULT_FILE_FORMAT))
457 2 : return true;
458 : // TODO: expand this list with supported OGR direvers
459 0 : return false;
460 : }
461 :
462 8 : CPLErr GNMFileNetwork::FormPath(const char *pszFilename, char **papszOptions)
463 : {
464 8 : if (m_soNetworkFullName.empty())
465 : {
466 : const char *pszNetworkName =
467 2 : CSLFetchNameValue(papszOptions, GNM_MD_NAME);
468 2 : if (nullptr == pszNetworkName)
469 : {
470 0 : CPLError(CE_Failure, CPLE_IllegalArg,
471 : "The network name should be present");
472 0 : return CE_Failure;
473 : }
474 : m_soNetworkFullName =
475 2 : CPLFormFilename(pszFilename, pszNetworkName, nullptr);
476 :
477 2 : CPLDebug("GNM", "Network name: %s", m_soNetworkFullName.c_str());
478 : }
479 8 : return CE_None;
480 : }
481 :
482 0 : int GNMFileNetwork::CloseDependentDatasets()
483 : {
484 0 : size_t nCount = m_mpLayerDatasetMap.size();
485 0 : for (std::map<OGRLayer *, GDALDataset *>::iterator it =
486 0 : m_mpLayerDatasetMap.begin();
487 0 : it != m_mpLayerDatasetMap.end(); ++it)
488 : {
489 0 : GDALClose(it->second);
490 : }
491 :
492 0 : m_mpLayerDatasetMap.clear();
493 :
494 0 : GNMGenericNetwork::CloseDependentDatasets();
495 :
496 0 : return nCount > 0 ? TRUE : FALSE;
497 : }
498 :
499 4 : OGRErr GNMFileNetwork::DeleteLayer(int nIndex)
500 : {
501 4 : OGRLayer *pLayer = GetLayer(nIndex);
502 :
503 4 : GDALDataset *poDS = m_mpLayerDatasetMap[pLayer];
504 4 : if (nullptr == poDS)
505 : {
506 0 : return OGRERR_FAILURE;
507 : }
508 :
509 4 : CPLDebug("GNM", "Delete network layer '%s'", pLayer->GetName());
510 :
511 4 : if (poDS->DeleteLayer(0) != OGRERR_NONE)
512 : {
513 0 : return OGRERR_FAILURE;
514 : }
515 :
516 4 : GDALClose(poDS);
517 :
518 : // remove pointer from map
519 4 : m_mpLayerDatasetMap.erase(pLayer);
520 :
521 4 : return GNMGenericNetwork::DeleteLayer(nIndex);
522 : }
523 :
524 4 : OGRLayer *GNMFileNetwork::ICreateLayer(const char *pszName,
525 : const OGRGeomFieldDefn *poGeomFieldDefn,
526 : CSLConstList papszOptions)
527 : {
528 4 : if (nullptr == m_poLayerDriver)
529 : {
530 0 : CPLError(CE_Failure, CPLE_AppDefined,
531 : "The network storage format driver is not defined.");
532 0 : return nullptr;
533 : }
534 :
535 4 : const auto eGType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
536 :
537 : // check if layer with such name exist
538 6 : for (int i = 0; i < GetLayerCount(); ++i)
539 : {
540 2 : OGRLayer *pLayer = GetLayer(i);
541 2 : if (nullptr == pLayer)
542 0 : continue;
543 2 : if (EQUAL(pLayer->GetName(), pszName))
544 : {
545 0 : CPLError(CE_Failure, CPLE_IllegalArg,
546 : "The network layer '%s' already exist.", pszName);
547 0 : return nullptr;
548 : }
549 : }
550 :
551 : // form path
552 4 : const char *pszExt = m_poLayerDriver->GetMetadataItem(GDAL_DMD_EXTENSION);
553 8 : CPLString soPath = CPLFormFilename(m_soNetworkFullName, pszName, pszExt);
554 :
555 : GDALDataset *poDS =
556 4 : m_poLayerDriver->Create(soPath, 0, 0, 0, GDT_Unknown, papszOptions);
557 4 : if (poDS == nullptr)
558 : {
559 0 : CPLError(CE_Failure, CPLE_FileIO, "Creation of output file failed.");
560 0 : return nullptr;
561 : }
562 :
563 8 : OGRSpatialReference oSpaRef(m_oSRS);
564 :
565 : OGRLayer *poLayer =
566 4 : poDS->CreateLayer(pszName, &oSpaRef, eGType, papszOptions);
567 4 : if (poLayer == nullptr)
568 : {
569 0 : CPLError(CE_Failure, CPLE_FileIO, "Layer creation failed.");
570 0 : GDALClose(poDS);
571 0 : return nullptr;
572 : }
573 :
574 8 : OGRFieldDefn oField(GNM_SYSFIELD_GFID, GNMGFIDInt);
575 4 : if (poLayer->CreateField(&oField) != OGRERR_NONE)
576 : {
577 0 : CPLError(CE_Failure, CPLE_FileIO,
578 : "Creating global identificator field failed.");
579 0 : GDALClose(poDS);
580 0 : return nullptr;
581 : }
582 :
583 8 : OGRFieldDefn oFieldBlock(GNM_SYSFIELD_BLOCKED, OFTInteger);
584 4 : if (poLayer->CreateField(&oFieldBlock) != OGRERR_NONE)
585 : {
586 0 : CPLError(CE_Failure, CPLE_FileIO, "Creating is blocking field failed.");
587 0 : GDALClose(poDS);
588 0 : return nullptr;
589 : }
590 :
591 4 : GNMGenericLayer *pGNMLayer = new GNMGenericLayer(poLayer, this);
592 4 : m_apoLayers.push_back(pGNMLayer);
593 4 : m_mpLayerDatasetMap[pGNMLayer] = poDS;
594 4 : return pGNMLayer;
595 : }
596 :
597 2 : CPLErr GNMFileNetwork::Create(const char *pszFilename, char **papszOptions)
598 : {
599 : // check required options
600 :
601 : // check name
602 2 : const char *pszNetworkName = CSLFetchNameValue(papszOptions, GNM_MD_NAME);
603 :
604 2 : if (nullptr == pszNetworkName)
605 : {
606 0 : CPLError(CE_Failure, CPLE_IllegalArg,
607 : "The network name should be present");
608 0 : return CE_Failure;
609 : }
610 : else
611 : {
612 2 : m_soName = pszNetworkName;
613 : }
614 :
615 : const char *pszNetworkDescription =
616 2 : CSLFetchNameValue(papszOptions, GNM_MD_DESCR);
617 2 : if (nullptr != pszNetworkDescription)
618 2 : sDescription = pszNetworkDescription;
619 :
620 : // check Spatial reference
621 2 : const char *pszSRS = CSLFetchNameValue(papszOptions, GNM_MD_SRS);
622 2 : if (nullptr == pszSRS)
623 : {
624 0 : CPLError(CE_Failure, CPLE_IllegalArg,
625 : "The network spatial reference should be present");
626 0 : return CE_Failure;
627 : }
628 : else
629 : {
630 2 : OGRSpatialReference spatialRef;
631 2 : spatialRef.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
632 2 : if (spatialRef.SetFromUserInput(pszSRS) != OGRERR_NONE)
633 : {
634 0 : CPLError(CE_Failure, CPLE_IllegalArg,
635 : "The network spatial reference should be present");
636 0 : return CE_Failure;
637 : }
638 :
639 2 : m_oSRS = std::move(spatialRef);
640 : }
641 :
642 2 : int nResult = CheckNetworkExist(pszFilename, papszOptions);
643 :
644 2 : if (TRUE == nResult)
645 : {
646 0 : CPLError(CE_Failure, CPLE_IllegalArg, "The network already exist");
647 0 : return CE_Failure;
648 : }
649 :
650 : // Create the necessary system layers and fields
651 :
652 : // Create meta layer
653 :
654 : CPLErr eResult =
655 2 : CreateMetadataLayerFromFile(pszFilename, GNM_VERSION_NUM, papszOptions);
656 :
657 2 : if (CE_None != eResult)
658 : {
659 : // an error message should come from function
660 0 : return CE_Failure;
661 : }
662 :
663 : // Create graph layer
664 :
665 2 : eResult = CreateGraphLayerFromFile(pszFilename, papszOptions);
666 :
667 2 : if (CE_None != eResult)
668 : {
669 0 : DeleteMetadataLayer();
670 0 : return CE_Failure;
671 : }
672 :
673 : // Create features layer
674 :
675 2 : eResult = CreateFeaturesLayerFromFile(pszFilename, papszOptions);
676 :
677 2 : if (CE_None != eResult)
678 : {
679 0 : DeleteMetadataLayer();
680 0 : DeleteGraphLayer();
681 0 : return CE_Failure;
682 : }
683 :
684 2 : return CE_None;
685 : }
|