LCOV - code coverage report
Current view: top level - gnm - gnmresultlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 78 82.1 %
Date: 2025-09-10 17:48:50 Functions: 13 18 72.2 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL/OGR Geography Network support (Geographic Network Model)
       4             :  * Purpose:  GNM result layer class.
       5             :  * Authors:  Mikhail Gusev (gusevmihs at gmail dot com)
       6             :  *           Dmitry Baryshnikov, polimax@mail.ru
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2014, Mikhail Gusev
      10             :  * Copyright (c) 2014-2015, NextGIS <info@nextgis.com>
      11             :  *
      12             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : #include "gnm.h"
      31             : #include "gnm_priv.h"
      32             : 
      33             : /** Constructor */
      34           5 : OGRGNMWrappedResultLayer::OGRGNMWrappedResultLayer(GDALDataset *poDSIn,
      35           5 :                                                    OGRLayer *poLayerIn)
      36             : {
      37           5 :     this->poDS = poDSIn;
      38           5 :     this->poLayer = poLayerIn;
      39             : 
      40             :     // create standard fields
      41             : 
      42          10 :     OGRFieldDefn oFieldGID(GNM_SYSFIELD_GFID, GNMGFIDInt);
      43           5 :     poLayer->CreateField(&oFieldGID);
      44             : 
      45          10 :     OGRFieldDefn oFieldLayerName(GNM_SYSFIELD_LAYERNAME, OFTString);
      46           5 :     oFieldLayerName.SetWidth(254);
      47           5 :     poLayer->CreateField(&oFieldLayerName);
      48             : 
      49          10 :     OGRFieldDefn oFieldNo(GNM_SYSFIELD_PATHNUM, OFTInteger);
      50           5 :     poLayer->CreateField(&oFieldNo);
      51             : 
      52          10 :     OGRFieldDefn oFieldType(GNM_SYSFIELD_TYPE, OFTString);  // EDGE or VERTEX
      53           5 :     poLayer->CreateField(&oFieldType);
      54           5 : }
      55             : 
      56          10 : OGRGNMWrappedResultLayer::~OGRGNMWrappedResultLayer()
      57             : {
      58           5 :     delete poDS;
      59          10 : }
      60             : 
      61           6 : void OGRGNMWrappedResultLayer::ResetReading()
      62             : {
      63           6 :     poLayer->ResetReading();
      64           6 : }
      65             : 
      66         164 : OGRFeature *OGRGNMWrappedResultLayer::GetNextFeature()
      67             : {
      68         164 :     return poLayer->GetNextFeature();
      69             : }
      70             : 
      71           0 : OGRErr OGRGNMWrappedResultLayer::SetNextByIndex(GIntBig nIndex)
      72             : {
      73           0 :     return poLayer->SetNextByIndex(nIndex);
      74             : }
      75             : 
      76           0 : OGRFeature *OGRGNMWrappedResultLayer::GetFeature(GIntBig nFID)
      77             : {
      78           0 :     return poLayer->GetFeature(nFID);
      79             : }
      80             : 
      81         598 : const OGRFeatureDefn *OGRGNMWrappedResultLayer::GetLayerDefn() const
      82             : {
      83         598 :     return poLayer->GetLayerDefn();
      84             : }
      85             : 
      86           5 : GIntBig OGRGNMWrappedResultLayer::GetFeatureCount(int bForce)
      87             : {
      88           5 :     return poLayer->GetFeatureCount(bForce);
      89             : }
      90             : 
      91          10 : int OGRGNMWrappedResultLayer::TestCapability(const char *pszCap) const
      92             : {
      93          10 :     return poLayer->TestCapability(pszCap);
      94             : }
      95             : 
      96          20 : OGRErr OGRGNMWrappedResultLayer::CreateField(const OGRFieldDefn *poField,
      97             :                                              int bApproxOK)
      98             : {
      99          20 :     return poLayer->CreateField(poField, bApproxOK);
     100             : }
     101             : 
     102             : OGRErr
     103           0 : OGRGNMWrappedResultLayer::CreateGeomField(const OGRGeomFieldDefn *poField,
     104             :                                           int bApproxOK)
     105             : {
     106           0 :     return poLayer->CreateGeomField(poField, bApproxOK);
     107             : }
     108             : 
     109           2 : const char *OGRGNMWrappedResultLayer::GetFIDColumn() const
     110             : {
     111           2 :     return poLayer->GetFIDColumn();
     112             : }
     113             : 
     114           0 : const char *OGRGNMWrappedResultLayer::GetGeometryColumn() const
     115             : {
     116           0 :     return poLayer->GetGeometryColumn();
     117             : }
     118             : 
     119           4 : const OGRSpatialReference *OGRGNMWrappedResultLayer::GetSpatialRef() const
     120             : {
     121           4 :     return poLayer->GetSpatialRef();
     122             : }
     123             : 
     124             : /** Undocumented */
     125         292 : OGRErr OGRGNMWrappedResultLayer::InsertFeature(OGRFeature *poFeature,
     126             :                                                const CPLString &soLayerName,
     127             :                                                int nPathNo, bool bIsEdge)
     128             : {
     129         292 :     VALIDATE_POINTER1(poFeature, "Input feature is invalid",
     130             :                       OGRERR_INVALID_HANDLE);
     131             :     // add fields from input feature
     132         292 :     const OGRFeatureDefn *poSrcDefn = poFeature->GetDefnRef();
     133         292 :     const OGRFeatureDefn *poDstFDefn = GetLayerDefn();
     134         292 :     if (nullptr == poSrcDefn || nullptr == poDstFDefn)
     135           0 :         return OGRERR_INVALID_HANDLE;
     136             : 
     137         292 :     const int nSrcFieldCount = poSrcDefn->GetFieldCount();
     138         292 :     int nDstFieldCount = poDstFDefn->GetFieldCount();
     139             : 
     140             :     // Initialize the index-to-index map to -1's
     141         584 :     std::vector<int> anMap(nSrcFieldCount, -1);
     142             : 
     143        1460 :     for (int iField = 0; iField < nSrcFieldCount; iField++)
     144             :     {
     145        1168 :         const OGRFieldDefn *poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
     146        2336 :         OGRFieldDefn oFieldDefn(poSrcFieldDefn);
     147             : 
     148             :         /* The field may have been already created at layer creation */
     149             :         const int iDstField =
     150        1168 :             poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
     151        1168 :         if (iDstField >= 0)
     152             :         {
     153             :             // TODO: by now skip fields with different types. In future should
     154             :             // cast types
     155             :             const OGRFieldDefn *poDstField =
     156        1148 :                 poDstFDefn->GetFieldDefn(iDstField);
     157        2296 :             if (nullptr != poDstField &&
     158        1148 :                 oFieldDefn.GetType() == poDstField->GetType())
     159        1148 :                 anMap[iField] = iDstField;
     160             :         }
     161          20 :         else if (CreateField(&oFieldDefn) == OGRERR_NONE)
     162             :         {
     163             :             /* Sanity check : if it fails, the driver is buggy */
     164          20 :             if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
     165             :             {
     166           0 :                 CPLError(CE_Warning, CPLE_AppDefined,
     167             :                          "The output driver has claimed to have added the %s "
     168             :                          "field, but it did not!",
     169             :                          oFieldDefn.GetNameRef());
     170             :             }
     171             :             else
     172             :             {
     173          20 :                 anMap[iField] = nDstFieldCount;
     174          20 :                 nDstFieldCount++;
     175             :             }
     176             :         }
     177             :     }
     178             : 
     179         584 :     auto poInsertFeature = std::make_unique<OGRFeature>(GetLayerDefn());
     180         292 :     if (poInsertFeature->SetFrom(poFeature, anMap.data(), TRUE) != OGRERR_NONE)
     181             :     {
     182           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     183             :                  "Unable to translate feature " CPL_FRMT_GIB
     184             :                  " from layer %s.\n",
     185             :                  poFeature->GetFID(), soLayerName.c_str());
     186           0 :         return OGRERR_FAILURE;
     187             :     }
     188             : 
     189             :     // poInsertFeature->SetField( GNM_SYSFIELD_GFID,
     190             :     // (GNMGFID)poFeature->GetFID() );
     191         292 :     poInsertFeature->SetField(GNM_SYSFIELD_LAYERNAME, soLayerName);
     192         292 :     poInsertFeature->SetField(GNM_SYSFIELD_PATHNUM, nPathNo);
     193         292 :     poInsertFeature->SetField(GNM_SYSFIELD_TYPE, bIsEdge ? "EDGE" : "VERTEX");
     194             : 
     195         292 :     CPLErrorReset();
     196         292 :     return CreateFeature(poInsertFeature.get());
     197             : }
     198             : 
     199           0 : OGRErr OGRGNMWrappedResultLayer::ISetFeature(OGRFeature *poFeature)
     200             : {
     201           0 :     return poLayer->SetFeature(poFeature);
     202             : }
     203             : 
     204         292 : OGRErr OGRGNMWrappedResultLayer::ICreateFeature(OGRFeature *poFeature)
     205             : {
     206         292 :     return poLayer->CreateFeature(poFeature);
     207             : }

Generated by: LCOV version 1.14