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

Generated by: LCOV version 1.14