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

Generated by: LCOV version 1.14