LCOV - code coverage report
Current view: top level - apps - gnmanalyse.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 119 262 45.4 %
Date: 2024-11-21 22:18:42 Functions: 2 5 40.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * Project:  geography network utility
       3             :  * Purpose:  Analyse GNM networks
       4             :  * Authors:  Mikhail Gusev, gusevmihs at gmail dot com
       5             :  *           Dmitry Baryshnikov, polimax@mail.ru
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (C) 2014 Mikhail Gusev
       9             :  * Copyright (c) 2014-2015, NextGIS <info@nextgis.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "commonutils.h"
      15             : #include "gdal_version.h"
      16             : #include "gnm.h"
      17             : #include "gnm_priv.h"
      18             : #include "ogr_p.h"
      19             : 
      20             : enum operation
      21             : {
      22             :     op_unknown = 0, /** no operation */
      23             :     op_dijkstra,    /** create shortest path using Dijkstra algorithm */
      24             :     op_kpaths,      /** create k shortest paths using Yens algorithm */
      25             :     op_resource     /** create resource distribution layer */
      26             : };
      27             : 
      28             : /************************************************************************/
      29             : /*                               Usage()                                */
      30             : /************************************************************************/
      31           0 : static void Usage(bool bIsError, const char *pszAdditionalMsg = nullptr,
      32             :                   bool bShort = true)
      33             : {
      34           0 :     fprintf(
      35             :         bIsError ? stderr : stdout,
      36             :         "Usage: gnmanalyse [--help][--help-general][-q][-quiet][--long-usage]\n"
      37             :         "                  [dijkstra <start_gfid> <end_gfid "
      38             :         "[-alo <NAME>=<VALUE>]...]\n"
      39             :         "                  [kpaths <start_gfid> <end_gfid> <k> "
      40             :         "[-alo NAME=VALUE]...]\n"
      41             :         "                  [resource [-alo <NAME>=<VALUE>]...]\n"
      42             :         "                  [-ds <ds_name>][-f <ds_format>][-l <layer_name>]\n"
      43             :         "                  [-dsco <NAME>=<VALUE>]... [-lco <NAME>=<VALUE>]...\n"
      44             :         "                  <gnm_name>\n");
      45             : 
      46           0 :     if (bShort)
      47             :     {
      48           0 :         printf("\nNote: gnmanalyse --long-usage for full help.\n");
      49           0 :         if (pszAdditionalMsg)
      50           0 :             fprintf(stderr, "\nFAILURE: %s\n", pszAdditionalMsg);
      51           0 :         exit(1);
      52             :     }
      53             : 
      54           0 :     fprintf(bIsError ? stderr : stdout,
      55             :             "\n   dijkstra start_gfid end_gfid: calculates the best path "
      56             :             "between two points using Dijkstra algorithm from start_gfid point "
      57             :             "to end_gfid point\n"
      58             :             "   kpaths start_gfid end_gfid k: calculates k (up to 10) best "
      59             :             "paths between two points using Yen\'s algorithm (which internally "
      60             :             "uses Dijkstra algorithm for single path calculating) from "
      61             :             "start_gfid point to end_gfid point\n"
      62             :             "   resource: calculates the \"resource distribution\". The "
      63             :             "connected components search is performed using breadth-first "
      64             :             "search and starting from that features which are marked by rules "
      65             :             "as \'EMITTERS\'\n"
      66             :             "   -ds ds_name: the name&path of the dataset to save the layer "
      67             :             "with resulting paths. Not need to be existed dataset\n"
      68             :             "   -f ds_format: define this to set the format of newly created "
      69             :             "dataset\n"
      70             :             "   -l layer_name: the name of the resulting layer. If the layer "
      71             :             "exists already - it will be rewritten. For K shortest paths "
      72             :             "several layers are created in format layer_nameN, where N - is "
      73             :             "number of the path (0 - is the most shortest one)\n"
      74             :             "   -dsco NAME=VALUE: Dataset creation option (format specific)\n"
      75             :             "   -lco  NAME=VALUE: Layer creation option (format specific)\n"
      76             :             "   -alo  NAME=VALUE: Algorithm option (format specific)\n"
      77             :             "   gnm_name: the network to work with (path and name)\n");
      78             : 
      79           0 :     if (pszAdditionalMsg)
      80           0 :         fprintf(stderr, "\nFAILURE: %s\n", pszAdditionalMsg);
      81             : 
      82           0 :     exit(bIsError ? 1 : 0);
      83             : }
      84             : 
      85             : /************************************************************************/
      86             : /*                   GetLayerAndOverwriteIfNecessary()                  */
      87             : /************************************************************************/
      88             : 
      89           0 : static OGRLayer *GetLayerAndOverwriteIfNecessary(GDALDataset *poDstDS,
      90             :                                                  const char *pszNewLayerName,
      91             :                                                  int bOverwrite,
      92             :                                                  int *pbErrorOccurred)
      93             : {
      94           0 :     if (pbErrorOccurred)
      95           0 :         *pbErrorOccurred = FALSE;
      96             : 
      97             :     /* GetLayerByName() can instantiate layers that would have been */
      98             :     /* 'hidden' otherwise, for example, non-spatial tables in a */
      99             :     /* PostGIS-enabled database, so this apparently useless command is */
     100             :     /* not useless... (#4012) */
     101           0 :     CPLPushErrorHandler(CPLQuietErrorHandler);
     102           0 :     OGRLayer *poDstLayer = poDstDS->GetLayerByName(pszNewLayerName);
     103           0 :     CPLPopErrorHandler();
     104           0 :     CPLErrorReset();
     105             : 
     106           0 :     int iLayer = -1;
     107           0 :     if (poDstLayer != nullptr)
     108             :     {
     109           0 :         int nLayerCount = poDstDS->GetLayerCount();
     110           0 :         for (iLayer = 0; iLayer < nLayerCount; iLayer++)
     111             :         {
     112           0 :             OGRLayer *poLayer = poDstDS->GetLayer(iLayer);
     113           0 :             if (poLayer == poDstLayer)
     114           0 :                 break;
     115             :         }
     116             : 
     117           0 :         if (iLayer == nLayerCount)
     118             :             /* should not happen with an ideal driver */
     119           0 :             poDstLayer = nullptr;
     120             :     }
     121             : 
     122             :     /* -------------------------------------------------------------------- */
     123             :     /*      If the user requested overwrite, and we have the layer in       */
     124             :     /*      question we need to delete it now so it will get recreated      */
     125             :     /*      (overwritten).                                                  */
     126             :     /* -------------------------------------------------------------------- */
     127           0 :     if (poDstLayer != nullptr && bOverwrite)
     128             :     {
     129           0 :         if (poDstDS->DeleteLayer(iLayer) != OGRERR_NONE)
     130             :         {
     131           0 :             fprintf(stderr, "DeleteLayer() failed when overwrite requested.\n");
     132           0 :             if (pbErrorOccurred)
     133           0 :                 *pbErrorOccurred = TRUE;
     134             :         }
     135           0 :         poDstLayer = nullptr;
     136             :     }
     137             : 
     138           0 :     return poDstLayer;
     139             : }
     140             : 
     141             : /************************************************************************/
     142             : /*                     CreateAndFillOutputDataset                       */
     143             : /************************************************************************/
     144           0 : static OGRErr CreateAndFillOutputDataset(OGRLayer *poSrcLayer,
     145             :                                          const char *pszDestDataSource,
     146             :                                          const char *pszFormat,
     147             :                                          const char *pszLayer, char **papszDSCO,
     148             :                                          char **papszLCO, int bQuiet)
     149             : {
     150           0 :     GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
     151           0 :     if (poDriver == nullptr)
     152             :     {
     153           0 :         fprintf(stderr, "%s driver not available\n", pszFormat);
     154           0 :         return OGRERR_FAILURE;
     155             :     }
     156             : 
     157           0 :     if (!CPLTestBool(CSLFetchNameValueDef(poDriver->GetMetadata(),
     158             :                                           GDAL_DCAP_CREATE, "FALSE")))
     159             :     {
     160           0 :         fprintf(stderr, "%s driver does not support data source creation.\n",
     161             :                 pszFormat);
     162           0 :         return OGRERR_FAILURE;
     163             :     }
     164             : 
     165             :     GDALDataset *poODS =
     166           0 :         poDriver->Create(pszDestDataSource, 0, 0, 0, GDT_Unknown, papszDSCO);
     167           0 :     if (poODS == nullptr)
     168             :     {
     169           0 :         fprintf(stderr, "%s driver failed to create %s\n", pszFormat,
     170             :                 pszDestDataSource);
     171           0 :         return OGRERR_FAILURE;
     172             :     }
     173             : 
     174           0 :     if (nullptr == pszLayer)
     175           0 :         pszLayer = poSrcLayer->GetName();
     176             :     int nError;
     177           0 :     GetLayerAndOverwriteIfNecessary(poODS, pszLayer, TRUE, &nError);
     178           0 :     if (nError == TRUE)
     179             :     {
     180           0 :         return OGRERR_FAILURE;
     181             :     }
     182             : 
     183             :     // create layer
     184           0 :     OGRLayer *poLayer = poODS->CopyLayer(poSrcLayer, pszLayer, papszLCO);
     185           0 :     if (nullptr == poLayer)
     186             :     {
     187           0 :         fprintf(stderr, "\nFAILURE: Can not copy path to %s\n",
     188             :                 pszDestDataSource);
     189           0 :         GDALClose(poODS);
     190             : 
     191           0 :         return OGRERR_FAILURE;
     192             :     }
     193             : 
     194           0 :     if (bQuiet == FALSE)
     195             :     {
     196           0 :         printf("\nPath successfully copied and added to the network at %s\n",
     197             :                pszDestDataSource);
     198             :     }
     199             : 
     200           0 :     GDALClose(poODS);
     201             : 
     202           0 :     return OGRERR_NONE;
     203             : }
     204             : 
     205             : /************************************************************************/
     206             : /*                           ReportOnLayer()                            */
     207             : /************************************************************************/
     208             : 
     209           2 : static void ReportOnLayer(OGRLayer *poLayer, int bVerbose)
     210             : 
     211             : {
     212           2 :     OGRFeatureDefn *poDefn = poLayer->GetLayerDefn();
     213             : 
     214             :     /* -------------------------------------------------------------------- */
     215             :     /*      Report various overall information.                             */
     216             :     /* -------------------------------------------------------------------- */
     217           2 :     printf("\n");
     218             : 
     219           2 :     printf("Layer name: %s\n", poLayer->GetName());
     220             : 
     221           2 :     if (bVerbose)
     222             :     {
     223           2 :         int nGeomFieldCount = poLayer->GetLayerDefn()->GetGeomFieldCount();
     224           2 :         if (nGeomFieldCount > 1)
     225             :         {
     226           0 :             for (int iGeom = 0; iGeom < nGeomFieldCount; iGeom++)
     227             :             {
     228             :                 OGRGeomFieldDefn *poGFldDefn =
     229           0 :                     poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom);
     230           0 :                 printf("Geometry (%s): %s\n", poGFldDefn->GetNameRef(),
     231             :                        OGRGeometryTypeToName(poGFldDefn->GetType()));
     232             :             }
     233             :         }
     234             :         else
     235             :         {
     236           2 :             printf("Geometry: %s\n",
     237           2 :                    OGRGeometryTypeToName(poLayer->GetGeomType()));
     238             :         }
     239             : 
     240           2 :         printf("Feature Count: " CPL_FRMT_GIB "\n", poLayer->GetFeatureCount());
     241             : 
     242           2 :         OGREnvelope oExt;
     243           2 :         if (nGeomFieldCount > 1)
     244             :         {
     245           0 :             for (int iGeom = 0; iGeom < nGeomFieldCount; iGeom++)
     246             :             {
     247           0 :                 if (poLayer->GetExtent(iGeom, &oExt, TRUE) == OGRERR_NONE)
     248             :                 {
     249             :                     OGRGeomFieldDefn *poGFldDefn =
     250           0 :                         poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom);
     251           0 :                     CPLprintf("Extent (%s): (%f, %f) - (%f, %f)\n",
     252             :                               poGFldDefn->GetNameRef(), oExt.MinX, oExt.MinY,
     253             :                               oExt.MaxX, oExt.MaxY);
     254             :                 }
     255             :             }
     256             :         }
     257           2 :         else if (poLayer->GetExtent(&oExt, TRUE) == OGRERR_NONE)
     258             :         {
     259           2 :             CPLprintf("Extent: (%f, %f) - (%f, %f)\n", oExt.MinX, oExt.MinY,
     260             :                       oExt.MaxX, oExt.MaxY);
     261             :         }
     262             : 
     263             :         char *pszWKT;
     264             : 
     265           2 :         if (nGeomFieldCount > 1)
     266             :         {
     267           0 :             for (int iGeom = 0; iGeom < nGeomFieldCount; iGeom++)
     268             :             {
     269             :                 OGRGeomFieldDefn *poGFldDefn =
     270           0 :                     poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom);
     271           0 :                 const OGRSpatialReference *poSRS = poGFldDefn->GetSpatialRef();
     272           0 :                 if (poSRS == nullptr)
     273           0 :                     pszWKT = CPLStrdup("(unknown)");
     274             :                 else
     275             :                 {
     276           0 :                     poSRS->exportToPrettyWkt(&pszWKT);
     277             :                 }
     278             : 
     279           0 :                 printf("SRS WKT (%s):\n%s\n", poGFldDefn->GetNameRef(), pszWKT);
     280           0 :                 CPLFree(pszWKT);
     281             :             }
     282             :         }
     283             :         else
     284             :         {
     285           2 :             if (poLayer->GetSpatialRef() == nullptr)
     286           0 :                 pszWKT = CPLStrdup("(unknown)");
     287             :             else
     288             :             {
     289           2 :                 poLayer->GetSpatialRef()->exportToPrettyWkt(&pszWKT);
     290             :             }
     291             : 
     292           2 :             printf("Layer SRS WKT:\n%s\n", pszWKT);
     293           2 :             CPLFree(pszWKT);
     294             :         }
     295             : 
     296           2 :         if (strlen(poLayer->GetFIDColumn()) > 0)
     297           0 :             printf("FID Column = %s\n", poLayer->GetFIDColumn());
     298             : 
     299           2 :         for (int iGeom = 0; iGeom < nGeomFieldCount; iGeom++)
     300             :         {
     301             :             OGRGeomFieldDefn *poGFldDefn =
     302           2 :                 poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom);
     303           4 :             if (nGeomFieldCount == 1 && EQUAL(poGFldDefn->GetNameRef(), "") &&
     304           2 :                 poGFldDefn->IsNullable())
     305           2 :                 break;
     306           0 :             printf("Geometry Column ");
     307           0 :             if (nGeomFieldCount > 1)
     308           0 :                 printf("%d ", iGeom + 1);
     309           0 :             if (!poGFldDefn->IsNullable())
     310           0 :                 printf("NOT NULL ");
     311           0 :             printf("= %s\n", poGFldDefn->GetNameRef());
     312             :         }
     313             : 
     314          18 :         for (int iAttr = 0; iAttr < poDefn->GetFieldCount(); iAttr++)
     315             :         {
     316          16 :             OGRFieldDefn *poField = poDefn->GetFieldDefn(iAttr);
     317             :             const char *pszType =
     318          16 :                 (poField->GetSubType() != OFSTNone)
     319          16 :                     ? CPLSPrintf(
     320             :                           "%s(%s)",
     321             :                           poField->GetFieldTypeName(poField->GetType()),
     322             :                           poField->GetFieldSubTypeName(poField->GetSubType()))
     323          16 :                     : poField->GetFieldTypeName(poField->GetType());
     324          16 :             printf("%s: %s (%d.%d)", poField->GetNameRef(), pszType,
     325             :                    poField->GetWidth(), poField->GetPrecision());
     326          16 :             if (!poField->IsNullable())
     327           0 :                 printf(" NOT NULL");
     328          16 :             if (poField->GetDefault() != nullptr)
     329           0 :                 printf(" DEFAULT %s", poField->GetDefault());
     330          16 :             printf("\n");
     331             :         }
     332             :     }
     333             : 
     334             :     /* -------------------------------------------------------------------- */
     335             :     /*      Read, and dump features.                                        */
     336             :     /* -------------------------------------------------------------------- */
     337          82 :     for (auto &poFeature : poLayer)
     338             :     {
     339          80 :         poFeature->DumpReadable(nullptr);
     340             :     }
     341           2 : }
     342             : 
     343             : /************************************************************************/
     344             : /*                                main()                                */
     345             : /************************************************************************/
     346             : 
     347             : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg)                            \
     348             :     do                                                                         \
     349             :     {                                                                          \
     350             :         if (iArg + nExtraArg >= nArgc)                                         \
     351             :             Usage(true, CPLSPrintf("%s option requires %d argument(s)",        \
     352             :                                    papszArgv[iArg], nExtraArg));               \
     353             :     } while (false)
     354             : 
     355           3 : MAIN_START(nArgc, papszArgv)
     356             : 
     357             : {
     358           3 :     int bQuiet = FALSE;
     359             : 
     360           3 :     const char *pszDataSource = nullptr;
     361             : 
     362           3 :     GNMGFID nFromFID = -1;
     363           3 :     GNMGFID nToFID = -1;
     364           3 :     int nK = 1;
     365           3 :     const char *pszDataset = nullptr;
     366           3 :     const char *pszFormat = "ESRI Shapefile";
     367           3 :     const char *pszLayer = nullptr;
     368           3 :     GNMNetwork *poDS = nullptr;
     369           3 :     OGRLayer *poResultLayer = nullptr;
     370           3 :     char **papszDSCO = nullptr, **papszLCO = nullptr, **papszALO = nullptr;
     371             : 
     372           3 :     operation stOper = op_unknown;
     373             : 
     374           3 :     int nRet = 0;
     375             : 
     376             :     // Check strict compilation and runtime library version as we use C++ API
     377           3 :     if (!GDAL_CHECK_VERSION(papszArgv[0]))
     378           0 :         exit(1);
     379             : 
     380           3 :     EarlySetConfigOptions(nArgc, papszArgv);
     381             : 
     382             :     /* -------------------------------------------------------------------- */
     383             :     /*      Register format(s).                                             */
     384             :     /* -------------------------------------------------------------------- */
     385           3 :     GDALAllRegister();
     386             : 
     387             :     /* -------------------------------------------------------------------- */
     388             :     /*      Processing command line arguments.                              */
     389             :     /* -------------------------------------------------------------------- */
     390           3 :     nArgc = GDALGeneralCmdLineProcessor(nArgc, &papszArgv, GDAL_OF_GNM);
     391             : 
     392           3 :     if (nArgc < 1)
     393             :     {
     394           0 :         exit(-nArgc);
     395             :     }
     396             : 
     397           7 :     for (int iArg = 1; iArg < nArgc; iArg++)
     398             :     {
     399           5 :         if (EQUAL(papszArgv[1], "--utility_version"))
     400             :         {
     401           1 :             printf("%s was compiled against GDAL %s and is running against "
     402             :                    "GDAL %s\n",
     403             :                    papszArgv[0], GDAL_RELEASE_NAME,
     404             :                    GDALVersionInfo("RELEASE_NAME"));
     405           1 :             CSLDestroy(papszArgv);
     406           1 :             return 0;
     407             :         }
     408             : 
     409           4 :         else if (EQUAL(papszArgv[iArg], "--help"))
     410             :         {
     411           0 :             Usage(false);
     412             :         }
     413             : 
     414           4 :         else if (EQUAL(papszArgv[iArg], "--long-usage"))
     415             :         {
     416           0 :             Usage(false, nullptr, false);
     417             :         }
     418             : 
     419           4 :         else if (EQUAL(papszArgv[iArg], "-q") ||
     420           4 :                  EQUAL(papszArgv[iArg], "-quiet"))
     421             :         {
     422           0 :             bQuiet = TRUE;
     423             :         }
     424             : 
     425           4 :         else if (EQUAL(papszArgv[iArg], "dijkstra"))
     426             :         {
     427           1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
     428           1 :             stOper = op_dijkstra;
     429           1 :             nFromFID = atoi(papszArgv[++iArg]);
     430           1 :             nToFID = atoi(papszArgv[++iArg]);
     431             :         }
     432             : 
     433           3 :         else if (EQUAL(papszArgv[iArg], "kpaths"))
     434             :         {
     435           1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(3);
     436           1 :             stOper = op_kpaths;
     437           1 :             nFromFID = atoi(papszArgv[++iArg]);
     438           1 :             nToFID = atoi(papszArgv[++iArg]);
     439           1 :             nK = atoi(papszArgv[++iArg]);
     440             :         }
     441             : 
     442           2 :         else if (EQUAL(papszArgv[iArg], "resource"))
     443             :         {
     444           0 :             stOper = op_resource;
     445             :         }
     446             : 
     447           2 :         else if (EQUAL(papszArgv[iArg], "-ds"))
     448             :         {
     449           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     450           0 :             pszDataset = papszArgv[++iArg];
     451             :         }
     452             : 
     453           2 :         else if ((EQUAL(papszArgv[iArg], "-f") ||
     454           2 :                   EQUAL(papszArgv[iArg], "-of")))
     455             :         {
     456           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     457           0 :             pszFormat = papszArgv[++iArg];
     458             :         }
     459             : 
     460           2 :         else if (EQUAL(papszArgv[iArg], "-l"))
     461             :         {
     462           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     463           0 :             pszLayer = papszArgv[++iArg];
     464             :         }
     465           2 :         else if (EQUAL(papszArgv[iArg], "-dsco"))
     466             :         {
     467           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     468           0 :             papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg]);
     469             :         }
     470           2 :         else if (EQUAL(papszArgv[iArg], "-lco"))
     471             :         {
     472           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     473           0 :             papszLCO = CSLAddString(papszLCO, papszArgv[++iArg]);
     474             :         }
     475           2 :         else if (EQUAL(papszArgv[iArg], "-alo"))
     476             :         {
     477           0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     478           0 :             papszALO = CSLAddString(papszALO, papszArgv[++iArg]);
     479             :         }
     480           2 :         else if (papszArgv[iArg][0] == '-')
     481             :         {
     482           0 :             Usage(true,
     483           0 :                   CPLSPrintf("Unknown option name '%s'", papszArgv[iArg]));
     484             :         }
     485             : 
     486           2 :         else if (pszDataSource == nullptr)
     487           2 :             pszDataSource = papszArgv[iArg];
     488             :     }
     489             : 
     490             :     // do the work
     491             :     // ////////////////////////////////////////////////////////////////
     492             : 
     493           2 :     if (stOper == op_dijkstra)
     494             :     {
     495           1 :         if (pszDataSource == nullptr)
     496           0 :             Usage(true, "No network dataset provided");
     497             : 
     498           1 :         if (nFromFID == -1 || nToFID == -1)
     499           0 :             Usage(true, "Invalid input from or to identificators");
     500             : 
     501             :         // open
     502           2 :         poDS = cpl::down_cast<GNMNetwork *>(static_cast<GDALDataset *>(
     503           1 :             GDALOpenEx(pszDataSource, GDAL_OF_UPDATE | GDAL_OF_GNM, nullptr,
     504             :                        nullptr, nullptr)));
     505           1 :         if (nullptr == poDS)
     506             :         {
     507           0 :             fprintf(stderr, "\nFailed to open network at %s\n", pszDataSource);
     508           0 :             nRet = 1;
     509           0 :             goto exit;
     510             :         }
     511             : 
     512             :         poResultLayer =
     513           1 :             poDS->GetPath(nFromFID, nToFID, GATDijkstraShortestPath, papszALO);
     514           1 :         if (nullptr == pszDataset)
     515             :         {
     516           1 :             ReportOnLayer(poResultLayer, bQuiet == FALSE);
     517             :         }
     518             :         else
     519             :         {
     520           0 :             if (CreateAndFillOutputDataset(poResultLayer, pszDataset, pszFormat,
     521             :                                            pszLayer, papszDSCO, papszLCO,
     522           0 :                                            bQuiet) != OGRERR_NONE)
     523             :             {
     524           0 :                 nRet = 1;
     525           0 :                 goto exit;
     526             :             }
     527             :         }
     528             :     }
     529           1 :     else if (stOper == op_kpaths)
     530             :     {
     531           1 :         if (pszDataSource == nullptr)
     532           0 :             Usage(true, "No network dataset provided");
     533             : 
     534           1 :         if (nFromFID == -1 || nToFID == -1)
     535           0 :             Usage(true, "Invalid input from or to identificators");
     536             : 
     537             :         // open
     538           2 :         poDS = cpl::down_cast<GNMNetwork *>(static_cast<GDALDataset *>(
     539           1 :             GDALOpenEx(pszDataSource, GDAL_OF_UPDATE | GDAL_OF_GNM, nullptr,
     540             :                        nullptr, nullptr)));
     541           1 :         if (nullptr == poDS)
     542             :         {
     543           0 :             fprintf(stderr, "\nFailed to open network at %s\n", pszDataSource);
     544           0 :             nRet = 1;
     545           0 :             goto exit;
     546             :         }
     547             : 
     548           1 :         if (CSLFindName(papszALO, GNM_MD_NUM_PATHS) == -1)
     549             :         {
     550           1 :             CPLDebug("GNM", "No K in options, add %d value", nK);
     551           1 :             papszALO = CSLAddNameValue(papszALO, GNM_MD_NUM_PATHS,
     552             :                                        CPLSPrintf("%d", nK));
     553             :         }
     554             : 
     555             :         poResultLayer =
     556           1 :             poDS->GetPath(nFromFID, nToFID, GATKShortestPath, papszALO);
     557             : 
     558           1 :         if (nullptr == pszDataset)
     559             :         {
     560           1 :             ReportOnLayer(poResultLayer, bQuiet == FALSE);
     561             :         }
     562             :         else
     563             :         {
     564           0 :             if (CreateAndFillOutputDataset(poResultLayer, pszDataset, pszFormat,
     565             :                                            pszLayer, papszDSCO, papszLCO,
     566           0 :                                            bQuiet) != OGRERR_NONE)
     567             :             {
     568           0 :                 nRet = 1;
     569           0 :                 goto exit;
     570             :             }
     571             :         }
     572             :     }
     573           0 :     else if (stOper == op_resource)
     574             :     {
     575           0 :         if (pszDataSource == nullptr)
     576           0 :             Usage(true, "No network dataset provided");
     577             : 
     578             :         // open
     579           0 :         poDS = cpl::down_cast<GNMNetwork *>(static_cast<GDALDataset *>(
     580           0 :             GDALOpenEx(pszDataSource, GDAL_OF_UPDATE | GDAL_OF_GNM, nullptr,
     581             :                        nullptr, nullptr)));
     582           0 :         if (nullptr == poDS)
     583             :         {
     584           0 :             fprintf(stderr, "\nFailed to open network at %s\n", pszDataSource);
     585           0 :             nRet = 1;
     586           0 :             goto exit;
     587             :         }
     588             : 
     589             :         poResultLayer =
     590           0 :             poDS->GetPath(nFromFID, nToFID, GATConnectedComponents, papszALO);
     591             : 
     592           0 :         if (nullptr == pszDataset)
     593             :         {
     594           0 :             ReportOnLayer(poResultLayer, bQuiet == FALSE);
     595             :         }
     596             :         else
     597             :         {
     598           0 :             if (CreateAndFillOutputDataset(poResultLayer, pszDataset, pszFormat,
     599             :                                            pszLayer, papszDSCO, papszLCO,
     600           0 :                                            bQuiet) != OGRERR_NONE)
     601             :             {
     602           0 :                 nRet = 1;
     603           0 :                 goto exit;
     604             :             }
     605             :         }
     606             :     }
     607             :     else
     608             :     {
     609           0 :         fprintf(
     610             :             stderr,
     611             :             "Need an operation. See help what you can do with gnmanalyse:\n");
     612           0 :         Usage(true);
     613             :     }
     614             : 
     615           2 : exit:
     616           2 :     CSLDestroy(papszDSCO);
     617           2 :     CSLDestroy(papszLCO);
     618           2 :     CSLDestroy(papszALO);
     619           2 :     CSLDestroy(papszArgv);
     620             : 
     621           2 :     if (poResultLayer != nullptr)
     622           2 :         poDS->ReleaseResultSet(poResultLayer);
     623             : 
     624           2 :     if (poDS)
     625             :     {
     626           2 :         if (GDALClose(poDS) != CE_None)
     627           0 :             nRet = 1;
     628             :     }
     629             : 
     630           2 :     GDALDestroyDriverManager();
     631             : 
     632           2 :     return nRet;
     633             : }
     634             : 
     635           0 : MAIN_END

Generated by: LCOV version 1.14