LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/ili - ogrili2layer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 108 136 79.4 %
Date: 2024-11-25 23:50:41 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Interlis 2 Translator
       4             :  * Purpose:  Implements OGRILI2Layer class.
       5             :  * Author:   Markus Schnider, Sourcepole AG
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
       9             :  * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : #include "ogr_ili2.h"
      17             : 
      18             : /************************************************************************/
      19             : /*                           OGRILI2Layer()                              */
      20             : /************************************************************************/
      21             : 
      22          46 : OGRILI2Layer::OGRILI2Layer(OGRFeatureDefn *poFeatureDefnIn,
      23             :                            const GeomFieldInfos &oGeomFieldInfosIn,
      24          46 :                            OGRILI2DataSource *poDSIn)
      25             :     : poFeatureDefn(poFeatureDefnIn), oGeomFieldInfos(oGeomFieldInfosIn),
      26          46 :       poDS(poDSIn)
      27             : {
      28          46 :     SetDescription(poFeatureDefn->GetName());
      29          46 :     poFeatureDefn->Reference();
      30             : 
      31          46 :     listFeatureIt = listFeature.begin();
      32          46 : }
      33             : 
      34             : /************************************************************************/
      35             : /*                           ~OGRILI2Layer()                           */
      36             : /************************************************************************/
      37             : 
      38          92 : OGRILI2Layer::~OGRILI2Layer()
      39             : {
      40          46 :     if (poFeatureDefn)
      41          46 :         poFeatureDefn->Release();
      42             : 
      43          46 :     listFeatureIt = listFeature.begin();
      44         568 :     while (listFeatureIt != listFeature.end())
      45             :     {
      46         522 :         OGRFeature *poFeature = *(listFeatureIt++);
      47         522 :         delete poFeature;
      48             :     }
      49          92 : }
      50             : 
      51             : /************************************************************************/
      52             : /*                             AddFeature()                             */
      53             : /************************************************************************/
      54             : 
      55         522 : void OGRILI2Layer::AddFeature(OGRFeature *poFeature)
      56             : {
      57         522 :     poFeature->SetFID(static_cast<GIntBig>(1 + listFeature.size()));
      58         522 :     listFeature.push_back(poFeature);
      59         522 : }
      60             : 
      61             : /************************************************************************/
      62             : /*                            ResetReading()                            */
      63             : /************************************************************************/
      64             : 
      65          44 : void OGRILI2Layer::ResetReading()
      66             : {
      67          44 :     listFeatureIt = listFeature.begin();
      68          44 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                           GetNextFeature()                           */
      72             : /************************************************************************/
      73             : 
      74           6 : OGRFeature *OGRILI2Layer::GetNextFeature()
      75             : {
      76           6 :     while (listFeatureIt != listFeature.end())
      77             :     {
      78           6 :         OGRFeature *poFeature = *(listFeatureIt++);
      79             :         // apply filters
      80          12 :         if ((m_poFilterGeom == nullptr ||
      81          12 :              FilterGeometry(poFeature->GetGeometryRef())) &&
      82           6 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
      83           6 :             return poFeature->Clone();
      84             :     }
      85           0 :     return nullptr;
      86             : }
      87             : 
      88             : /************************************************************************/
      89             : /*                          GetFeatureCount()                           */
      90             : /************************************************************************/
      91             : 
      92           4 : GIntBig OGRILI2Layer::GetFeatureCount(int bForce)
      93             : {
      94           4 :     if (m_poFilterGeom == nullptr && m_poAttrQuery == nullptr)
      95             :     {
      96           4 :         return listFeature.size();
      97             :     }
      98             :     else
      99             :     {
     100           0 :         return OGRLayer::GetFeatureCount(bForce);
     101             :     }
     102             : }
     103             : 
     104             : #ifndef d2str_defined
     105             : #define d2str_defined
     106             : 
     107          40 : static const char *d2str(double val)
     108             : {
     109          40 :     if (val == (int)val)
     110           0 :         return CPLSPrintf("%d", (int)val);
     111          40 :     if (fabs(val) < 370)
     112          40 :         return CPLSPrintf("%.16g", val);
     113           0 :     if (fabs(val) > 100000000.0)
     114           0 :         return CPLSPrintf("%.16g", val);
     115             : 
     116           0 :     return CPLSPrintf("%.3f", val);
     117             : }
     118             : #endif
     119             : 
     120           1 : static void AppendCoordinateList(const OGRLineString *poLine, VSILFILE *fp)
     121             : {
     122           1 :     const bool b3D = CPL_TO_BOOL(wkbHasZ(poLine->getGeometryType()));
     123             : 
     124          20 :     for (int iPoint = 0; iPoint < poLine->getNumPoints(); iPoint++)
     125             :     {
     126          19 :         VSIFPrintfL(fp, "<COORD>");
     127          19 :         VSIFPrintfL(fp, "<C1>%s</C1>", d2str(poLine->getX(iPoint)));
     128          19 :         VSIFPrintfL(fp, "<C2>%s</C2>", d2str(poLine->getY(iPoint)));
     129          19 :         if (b3D)
     130           0 :             VSIFPrintfL(fp, "<C3>%s</C3>", d2str(poLine->getZ(iPoint)));
     131          19 :         VSIFPrintfL(fp, "</COORD>\n");
     132             :     }
     133           1 : }
     134             : 
     135           3 : static int OGR2ILIGeometryAppend(const OGRGeometry *poGeometry, VSILFILE *fp,
     136             :                                  const char *attrname,
     137             :                                  const CPLString &iliGeomType)
     138             : {
     139             : #ifdef DEBUG_VERBOSE
     140             :     CPLDebug("OGR_ILI",
     141             :              "OGR2ILIGeometryAppend getGeometryType %s iliGeomType %s",
     142             :              poGeometry->getGeometryName(), iliGeomType.c_str());
     143             : #endif
     144             :     /* -------------------------------------------------------------------- */
     145             :     /*      2D/3D Point                                                     */
     146             :     /* -------------------------------------------------------------------- */
     147           5 :     if (poGeometry->getGeometryType() == wkbPoint ||
     148           2 :         poGeometry->getGeometryType() == wkbPoint25D)
     149             :     {
     150           1 :         const OGRPoint *poPoint = poGeometry->toPoint();
     151             : 
     152           1 :         VSIFPrintfL(fp, "<%s>\n", attrname);
     153           1 :         VSIFPrintfL(fp, "<COORD>");
     154           1 :         VSIFPrintfL(fp, "<C1>%s</C1>", d2str(poPoint->getX()));
     155           1 :         VSIFPrintfL(fp, "<C2>%s</C2>", d2str(poPoint->getY()));
     156           1 :         if (poGeometry->getGeometryType() == wkbPoint25D)
     157           0 :             VSIFPrintfL(fp, "<C3>%s</C3>", d2str(poPoint->getZ()));
     158           1 :         VSIFPrintfL(fp, "</COORD>\n");
     159           1 :         VSIFPrintfL(fp, "</%s>\n", attrname);
     160             :     }
     161             : 
     162             :     /* -------------------------------------------------------------------- */
     163             :     /*      LineString and LinearRing                                       */
     164             :     /* -------------------------------------------------------------------- */
     165           3 :     else if (poGeometry->getGeometryType() == wkbLineString ||
     166           1 :              poGeometry->getGeometryType() == wkbLineString25D)
     167             :     {
     168           1 :         if (attrname)
     169           0 :             VSIFPrintfL(fp, "<%s>\n", attrname);
     170           1 :         VSIFPrintfL(fp, "<POLYLINE>\n");
     171             :         // unclipped polyline, add one sequence
     172             :         // VSIFPrintfL(fp, "<SEGMENTS>\n");
     173           1 :         AppendCoordinateList(poGeometry->toLineString(), fp);
     174             :         // VSIFPrintfL(fp, "</SEGMENTS>\n");
     175           1 :         VSIFPrintfL(fp, "</POLYLINE>\n");
     176           1 :         if (attrname)
     177           0 :             VSIFPrintfL(fp, "</%s>\n", attrname);
     178             :     }
     179             : 
     180             :     /* -------------------------------------------------------------------- */
     181             :     /*      Polygon                                                         */
     182             :     /* -------------------------------------------------------------------- */
     183           1 :     else if (poGeometry->getGeometryType() == wkbPolygon ||
     184           0 :              poGeometry->getGeometryType() == wkbPolygon25D)
     185             :     {
     186           1 :         const OGRPolygon *poPolygon = poGeometry->toPolygon();
     187             : 
     188           1 :         if (attrname)
     189           1 :             VSIFPrintfL(fp, "<%s>\n", attrname);
     190           1 :         if (iliGeomType == "Surface" || iliGeomType == "Area")
     191             :         {
     192             :             // VSIFPrintfL(fp, "<MULTISURFACE>\n");
     193           1 :             VSIFPrintfL(fp, "<SURFACE>\n");
     194           1 :             VSIFPrintfL(fp, "<BOUNDARY>\n");
     195             :         }
     196             : 
     197           2 :         for (auto &&poRing : *poPolygon)
     198             :         {
     199           1 :             if (!OGR2ILIGeometryAppend(poRing, fp, nullptr, ""))
     200           0 :                 return FALSE;
     201             :         }
     202           1 :         if (iliGeomType == "Surface" || iliGeomType == "Area")
     203             :         {
     204           1 :             VSIFPrintfL(fp, "</BOUNDARY>\n");
     205           1 :             VSIFPrintfL(fp, "</SURFACE>\n");
     206             :             // VSIFPrintfL(fp, "</MULTISURFACE>\n");
     207             :         }
     208           1 :         if (attrname)
     209           1 :             VSIFPrintfL(fp, "</%s>\n", attrname);
     210             :     }
     211             : 
     212             :     /* -------------------------------------------------------------------- */
     213             :     /*      MultiPolygon                                                    */
     214             :     /* -------------------------------------------------------------------- */
     215           0 :     else if (wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon ||
     216           0 :              wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString ||
     217           0 :              wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint ||
     218           0 :              wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection)
     219             :     {
     220           0 :         const OGRGeometryCollection *poGC = poGeometry->toGeometryCollection();
     221             : 
     222             : #if 0
     223             :         // TODO: Why were these all blank?
     224             :         if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
     225             :         {
     226             :         }
     227             :         else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
     228             :         {
     229             :         }
     230             :         else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
     231             :         {
     232             :         }
     233             :         else
     234             :         {
     235             :         }
     236             : #endif
     237           0 :         for (auto &&poMember : *poGC)
     238             :         {
     239           0 :             if (!OGR2ILIGeometryAppend(poMember, fp, nullptr, ""))
     240           0 :                 return FALSE;
     241             :         }
     242             :     }
     243             : 
     244             :     else
     245           0 :         return FALSE;
     246             : 
     247           3 :     return TRUE;
     248             : }
     249             : 
     250             : /************************************************************************/
     251             : /*                           ICreateFeature()                            */
     252             : /************************************************************************/
     253             : 
     254           2 : OGRErr OGRILI2Layer::ICreateFeature(OGRFeature *poFeature)
     255             : {
     256             :     char szTempBuffer[80];
     257           2 :     const char *tid = nullptr;
     258           2 :     int iField = 0;
     259           4 :     if (poFeatureDefn->GetFieldCount() &&
     260           2 :         EQUAL(poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), "TID"))
     261             :     {
     262           2 :         tid = poFeature->GetFieldAsString(0);
     263           2 :         ++iField;
     264             :     }
     265             :     else
     266             :     {
     267           0 :         snprintf(szTempBuffer, sizeof(szTempBuffer), CPL_FRMT_GIB,
     268             :                  poFeature->GetFID());
     269           0 :         tid = szTempBuffer;
     270             :     }
     271             : 
     272           2 :     VSILFILE *fp = poDS->GetOutputFP();
     273           2 :     if (fp == nullptr)
     274           0 :         return OGRERR_FAILURE;
     275             : 
     276           2 :     VSIFPrintfL(fp, "<%s TID=\"%s\">\n", poFeatureDefn->GetName(), tid);
     277             : 
     278             :     // Write out Geometries
     279           4 :     for (int iGeomField = 0; iGeomField < poFeatureDefn->GetGeomFieldCount();
     280             :          iGeomField++)
     281             :     {
     282             :         OGRGeomFieldDefn *poFieldDefn =
     283           2 :             poFeatureDefn->GetGeomFieldDefn(iGeomField);
     284           2 :         OGRGeometry *poGeom = poFeature->GetGeomFieldRef(iGeomField);
     285           2 :         if (poGeom != nullptr)
     286             :         {
     287           4 :             CPLString iliGeomType = GetIliGeomType(poFieldDefn->GetNameRef());
     288           2 :             OGR2ILIGeometryAppend(poGeom, fp, poFieldDefn->GetNameRef(),
     289             :                                   iliGeomType);
     290             :         }
     291             :     }
     292             : 
     293             :     // Write all "set" fields.
     294           4 :     for (; iField < poFeatureDefn->GetFieldCount(); iField++)
     295             :     {
     296             : 
     297           2 :         OGRFieldDefn *poField = poFeatureDefn->GetFieldDefn(iField);
     298             : 
     299           2 :         if (poFeature->IsFieldSetAndNotNull(iField))
     300             :         {
     301           2 :             const char *pszRaw = poFeature->GetFieldAsString(iField);
     302           2 :             VSIFPrintfL(fp, "<%s>%s</%s>\n", poField->GetNameRef(), pszRaw,
     303             :                         poField->GetNameRef());
     304             :         }
     305             :     }
     306             : 
     307           2 :     VSIFPrintfL(fp, "</%s>\n", poFeatureDefn->GetName());
     308             : 
     309           2 :     return OGRERR_NONE;
     310             : }
     311             : 
     312             : /************************************************************************/
     313             : /*                           TestCapability()                           */
     314             : /************************************************************************/
     315             : 
     316           4 : int OGRILI2Layer::TestCapability(CPL_UNUSED const char *pszCap)
     317             : {
     318           4 :     if (EQUAL(pszCap, OLCCurveGeometries))
     319           2 :         return TRUE;
     320           2 :     else if (EQUAL(pszCap, OLCZGeometries))
     321           0 :         return TRUE;
     322             : 
     323           2 :     return FALSE;
     324             : }
     325             : 
     326             : /************************************************************************/
     327             : /*                            CreateField()                             */
     328             : /************************************************************************/
     329             : 
     330           0 : OGRErr OGRILI2Layer::CreateField(const OGRFieldDefn *poField,
     331             :                                  int /* bApproxOK */)
     332             : {
     333           0 :     poFeatureDefn->AddFieldDefn(poField);
     334           0 :     return OGRERR_NONE;
     335             : }
     336             : 
     337             : /************************************************************************/
     338             : /*                             GetDataset()                             */
     339             : /************************************************************************/
     340             : 
     341           1 : GDALDataset *OGRILI2Layer::GetDataset()
     342             : {
     343           1 :     return poDS;
     344             : }

Generated by: LCOV version 1.14