LCOV - code coverage report
Current view: top level - frmts/sdts - sdtslinereader.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 76 105 72.4 %
Date: 2024-11-21 22:18:42 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SDTS Translator
       4             :  * Purpose:  Implementation of SDTSLineReader and SDTSRawLine classes.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "sdts_al.h"
      14             : 
      15             : /************************************************************************/
      16             : /* ==================================================================== */
      17             : /*                            SDTSRawLine                               */
      18             : /*                                                                      */
      19             : /*      This is a simple class for holding the data related with a      */
      20             : /*      line feature.                                                   */
      21             : /* ==================================================================== */
      22             : /************************************************************************/
      23             : 
      24             : /************************************************************************/
      25             : /*                            SDTSRawLine()                             */
      26             : /************************************************************************/
      27             : 
      28          55 : SDTSRawLine::SDTSRawLine()
      29          55 :     : nVertices(0), padfX(nullptr), padfY(nullptr), padfZ(nullptr)
      30             : {
      31          55 :     nAttributes = 0;
      32          55 : }
      33             : 
      34             : /************************************************************************/
      35             : /*                            ~STDSRawLine()                            */
      36             : /************************************************************************/
      37             : 
      38         110 : SDTSRawLine::~SDTSRawLine()
      39             : 
      40             : {
      41          55 :     CPLFree(padfX);
      42         110 : }
      43             : 
      44             : /************************************************************************/
      45             : /*                                Read()                                */
      46             : /*                                                                      */
      47             : /*      Read a record from the passed SDTSLineReader, and assign the    */
      48             : /*      values from that record to this line.  This is the bulk of      */
      49             : /*      the work in this whole file.                                    */
      50             : /************************************************************************/
      51             : 
      52          55 : int SDTSRawLine::Read(SDTS_IREF *poIREF, DDFRecord *poRecord)
      53             : 
      54             : {
      55             :     // E.Rouault: Not sure if this test is really useful
      56          55 :     if (poRecord->GetStringSubfield("LINE", 0, "MODN", 0) == nullptr)
      57           0 :         return FALSE;
      58             : 
      59             :     /* ==================================================================== */
      60             :     /*      Loop over fields in this record, looking for those we           */
      61             :     /*      recognise, and need.  I don't use the getSubfield()             */
      62             :     /*      interface on the record in order to retain some slight bit      */
      63             :     /*      of efficiency.                                                  */
      64             :     /* ==================================================================== */
      65         452 :     for (int iField = 0; iField < poRecord->GetFieldCount(); iField++)
      66             :     {
      67         397 :         DDFField *poField = poRecord->GetField(iField);
      68         397 :         if (poField == nullptr)
      69           0 :             return FALSE;
      70         397 :         DDFFieldDefn *poFieldDefn = poField->GetFieldDefn();
      71         397 :         if (poFieldDefn == nullptr)
      72           0 :             return FALSE;
      73             : 
      74         397 :         const char *pszFieldName = poFieldDefn->GetName();
      75             : 
      76         397 :         if (EQUAL(pszFieldName, "LINE"))
      77          55 :             oModId.Set(poField);
      78             : 
      79         342 :         else if (EQUAL(pszFieldName, "ATID"))
      80          12 :             ApplyATID(poField);
      81             : 
      82         330 :         else if (EQUAL(pszFieldName, "PIDL"))
      83          55 :             oLeftPoly.Set(poField);
      84             : 
      85         275 :         else if (EQUAL(pszFieldName, "PIDR"))
      86          55 :             oRightPoly.Set(poField);
      87             : 
      88         220 :         else if (EQUAL(pszFieldName, "SNID"))
      89          55 :             oStartNode.Set(poField);
      90             : 
      91         165 :         else if (EQUAL(pszFieldName, "ENID"))
      92          55 :             oEndNode.Set(poField);
      93             : 
      94         110 :         else if (EQUAL(pszFieldName, "SADR"))
      95             :         {
      96          55 :             nVertices = poIREF->GetSADRCount(poField);
      97             : 
      98          55 :             padfX = reinterpret_cast<double *>(
      99          55 :                 CPLRealloc(padfX, sizeof(double) * nVertices * 3));
     100          55 :             padfY = padfX + nVertices;
     101          55 :             padfZ = padfX + 2 * nVertices;
     102             : 
     103          55 :             if (!poIREF->GetSADR(poField, nVertices, padfX, padfY, padfZ))
     104             :             {
     105           0 :                 return FALSE;
     106             :             }
     107             :         }
     108             :     }
     109             : 
     110          55 :     return TRUE;
     111             : }
     112             : 
     113             : /************************************************************************/
     114             : /*                                Dump()                                */
     115             : /*                                                                      */
     116             : /*      Write info about this object to a text file.                    */
     117             : /************************************************************************/
     118             : 
     119           0 : void SDTSRawLine::Dump(FILE *fp)
     120             : 
     121             : {
     122           0 :     fprintf(fp, "SDTSRawLine\n");
     123           0 :     fprintf(fp, "  Module=%s, Record#=%d\n", oModId.szModule, oModId.nRecord);
     124           0 :     if (oLeftPoly.nRecord != -1)
     125           0 :         fprintf(fp, "  LeftPoly (Module=%s, Record=%d)\n", oLeftPoly.szModule,
     126             :                 oLeftPoly.nRecord);
     127           0 :     if (oRightPoly.nRecord != -1)
     128           0 :         fprintf(fp, "  RightPoly (Module=%s, Record=%d)\n", oRightPoly.szModule,
     129             :                 oRightPoly.nRecord);
     130           0 :     if (oStartNode.nRecord != -1)
     131           0 :         fprintf(fp, "  StartNode (Module=%s, Record=%d)\n", oStartNode.szModule,
     132             :                 oStartNode.nRecord);
     133           0 :     if (oEndNode.nRecord != -1)
     134           0 :         fprintf(fp, "  EndNode (Module=%s, Record=%d)\n", oEndNode.szModule,
     135             :                 oEndNode.nRecord);
     136           0 :     for (int i = 0; i < nAttributes; i++)
     137           0 :         fprintf(fp, "  Attribute (Module=%s, Record=%d)\n", paoATID[i].szModule,
     138           0 :                 paoATID[i].nRecord);
     139             : 
     140           0 :     for (int i = 0; i < nVertices; i++)
     141             :     {
     142           0 :         fprintf(fp, "  Vertex[%3d] = (%.2f,%.2f,%.2f)\n", i, padfX[i], padfY[i],
     143           0 :                 padfZ[i]);
     144             :     }
     145           0 : }
     146             : 
     147             : /************************************************************************/
     148             : /* ==================================================================== */
     149             : /*                             SDTSLineReader                           */
     150             : /*                                                                      */
     151             : /*      This is the class used to read a line module.                   */
     152             : /* ==================================================================== */
     153             : /************************************************************************/
     154             : 
     155             : /************************************************************************/
     156             : /*                           SDTSLineReader()                           */
     157             : /************************************************************************/
     158             : 
     159           1 : SDTSLineReader::SDTSLineReader(SDTS_IREF *poIREFIn) : poIREF(poIREFIn)
     160             : {
     161           1 : }
     162             : 
     163             : /************************************************************************/
     164             : /*                             ~SDTSLineReader()                        */
     165             : /************************************************************************/
     166             : 
     167           2 : SDTSLineReader::~SDTSLineReader()
     168             : {
     169           1 :     Close();
     170           2 : }
     171             : 
     172             : /************************************************************************/
     173             : /*                               Close()                                */
     174             : /************************************************************************/
     175             : 
     176           1 : void SDTSLineReader::Close()
     177             : 
     178             : {
     179           1 :     oDDFModule.Close();
     180           1 : }
     181             : 
     182             : /************************************************************************/
     183             : /*                                Open()                                */
     184             : /*                                                                      */
     185             : /*      Open the requested line file, and prepare to start reading      */
     186             : /*      data records.                                                   */
     187             : /************************************************************************/
     188             : 
     189           1 : int SDTSLineReader::Open(const char *pszFilename)
     190             : 
     191             : {
     192           1 :     return oDDFModule.Open(pszFilename);
     193             : }
     194             : 
     195             : /************************************************************************/
     196             : /*                            GetNextLine()                             */
     197             : /*                                                                      */
     198             : /*      Fetch the next line feature as an STDSRawLine.                  */
     199             : /************************************************************************/
     200             : 
     201          57 : SDTSRawLine *SDTSLineReader::GetNextLine()
     202             : 
     203             : {
     204             :     /* -------------------------------------------------------------------- */
     205             :     /*      Are we initialized?                                             */
     206             :     /* -------------------------------------------------------------------- */
     207          57 :     if (oDDFModule.GetFP() == nullptr)
     208           0 :         return nullptr;
     209             : 
     210             :     /* -------------------------------------------------------------------- */
     211             :     /*      Read the record.                                                */
     212             :     /* -------------------------------------------------------------------- */
     213          57 :     DDFRecord *poRecord = oDDFModule.ReadRecord();
     214             : 
     215          57 :     if (poRecord == nullptr)
     216           2 :         return nullptr;
     217             : 
     218             :     /* -------------------------------------------------------------------- */
     219             :     /*      Transform into a line feature.                                  */
     220             :     /* -------------------------------------------------------------------- */
     221          55 :     SDTSRawLine *poRawLine = new SDTSRawLine();
     222             : 
     223          55 :     if (poRawLine->Read(poIREF, poRecord))
     224             :     {
     225          55 :         return poRawLine;
     226             :     }
     227             : 
     228           0 :     delete poRawLine;
     229           0 :     return nullptr;
     230             : }
     231             : 
     232             : /************************************************************************/
     233             : /*                          AttachToPolygons()                          */
     234             : /*                                                                      */
     235             : /*      Attach line features to all the polygon features they relate    */
     236             : /*      to.                                                             */
     237             : /************************************************************************/
     238             : 
     239             : /**
     240             :   Attach lines in this module to their polygons as the first step in
     241             :   polygon formation.
     242             : 
     243             :   See also the SDTSRawPolygon::AssembleRings() method.
     244             : 
     245             :   @param poTransfer the SDTSTransfer of this SDTSLineReader, and from
     246             :   which the related SDTSPolygonReader will be instantiated.
     247             :   @param iTargetPolyLayer the polygon reader instance number, used to avoid
     248             :   processing lines for other layers.
     249             : 
     250             : */
     251             : 
     252           1 : void SDTSLineReader::AttachToPolygons(SDTSTransfer *poTransfer,
     253             :                                       int iTargetPolyLayer)
     254             : 
     255             : {
     256             :     /* -------------------------------------------------------------------- */
     257             :     /*      We force a filling of the index because when we attach the      */
     258             :     /*      lines we are just providing a pointer back to the line          */
     259             :     /*      features in this readers index.  If they aren't cached in       */
     260             :     /*      the index then the pointer will be invalid.                     */
     261             :     /* -------------------------------------------------------------------- */
     262           1 :     FillIndex();
     263             : 
     264             :     /* ==================================================================== */
     265             :     /*      Loop over all lines, attaching them to the polygons they        */
     266             :     /*      have as right and left faces.                                   */
     267             :     /* ==================================================================== */
     268           1 :     Rewind();
     269           1 :     SDTSRawLine *poLine = nullptr;
     270           1 :     SDTSPolygonReader *poPolyReader = nullptr;
     271          28 :     while ((poLine = reinterpret_cast<SDTSRawLine *>(GetNextFeature())) !=
     272             :            nullptr)
     273             :     {
     274             :         /* --------------------------------------------------------------------
     275             :          */
     276             :         /*      Skip lines with the same left and right polygon face.  These */
     277             :         /*      are dangles, and will not contribute in any useful fashion */
     278             :         /*      to the resulting polygon. */
     279             :         /* --------------------------------------------------------------------
     280             :          */
     281          27 :         if (poLine->oLeftPoly.nRecord == poLine->oRightPoly.nRecord)
     282           2 :             continue;
     283             : 
     284             :         /* --------------------------------------------------------------------
     285             :          */
     286             :         /*      If we don't have our indexed polygon reader yet, try to get */
     287             :         /*      it now. */
     288             :         /* --------------------------------------------------------------------
     289             :          */
     290          25 :         if (poPolyReader == nullptr)
     291             :         {
     292             :             int iPolyLayer;
     293             : 
     294           1 :             if (poLine->oLeftPoly.nRecord != -1)
     295             :             {
     296           1 :                 iPolyLayer = poTransfer->FindLayer(poLine->oLeftPoly.szModule);
     297             :             }
     298             :             else /* if( poLine->oRightPoly.nRecord != -1 ) */
     299             :             {
     300           0 :                 iPolyLayer = poTransfer->FindLayer(poLine->oRightPoly.szModule);
     301             :             }
     302             : 
     303           1 :             if (iPolyLayer == -1)
     304           0 :                 continue;
     305             : 
     306           1 :             if (iPolyLayer != iTargetPolyLayer)
     307           0 :                 continue;
     308             : 
     309             :             poPolyReader = reinterpret_cast<SDTSPolygonReader *>(
     310           1 :                 poTransfer->GetLayerIndexedReader(iPolyLayer));
     311             : 
     312           1 :             if (poPolyReader == nullptr)
     313           0 :                 return;
     314             :         }
     315             : 
     316             :         /* --------------------------------------------------------------------
     317             :          */
     318             :         /*      Attach line to right and/or left polygons. */
     319             :         /* --------------------------------------------------------------------
     320             :          */
     321          25 :         if (poLine->oLeftPoly.nRecord != -1)
     322             :         {
     323             :             SDTSRawPolygon *poPoly = reinterpret_cast<SDTSRawPolygon *>(
     324          25 :                 poPolyReader->GetIndexedFeatureRef(poLine->oLeftPoly.nRecord));
     325          25 :             if (poPoly != nullptr)
     326          25 :                 poPoly->AddEdge(poLine);
     327             :         }
     328             : 
     329          25 :         if (poLine->oRightPoly.nRecord != -1)
     330             :         {
     331             :             SDTSRawPolygon *poPoly = reinterpret_cast<SDTSRawPolygon *>(
     332          25 :                 poPolyReader->GetIndexedFeatureRef(poLine->oRightPoly.nRecord));
     333             : 
     334          25 :             if (poPoly != nullptr)
     335          25 :                 poPoly->AddEdge(poLine);
     336             :         }
     337             :     }
     338             : }

Generated by: LCOV version 1.14