LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/segukooa - ogrsegukooalayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 343 287 83.7 %
Date: 2011-12-18 Functions: 26 15 57.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsegukooalayer.cpp 23222 2011-10-11 22:29:08Z rouault $
       3                 :  *
       4                 :  * Project:  SEG-P1 / UKOOA P1-90 Translator
       5                 :  * Purpose:  Implements OGRUKOOAP190Layer class.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      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, DAMSEGUKOOAS 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 "ogr_segukooa.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "ogr_p.h"
      34                 : #include "ogr_srs_api.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrsegukooalayer.cpp 23222 2011-10-11 22:29:08Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                            ExtractField()                            */
      40                 : /************************************************************************/
      41                 : 
      42             135 : static void ExtractField(char* szField, const char* pszLine, int nOffset, int nLen)
      43                 : {
      44             135 :     memcpy(szField, pszLine + nOffset, nLen);
      45             135 :     szField[nLen] = '\0';
      46             135 : }
      47                 : 
      48                 : /************************************************************************/
      49                 : /*                           GetNextFeature()                           */
      50                 : /************************************************************************/
      51                 : 
      52              16 : OGRFeature *OGRSEGUKOOABaseLayer::GetNextFeature()
      53                 : {
      54                 :     OGRFeature  *poFeature;
      55                 : 
      56               0 :     while(TRUE)
      57                 :     {
      58              16 :         poFeature = GetNextRawFeature();
      59              16 :         if (poFeature == NULL)
      60               2 :             return NULL;
      61                 : 
      62              14 :         if((m_poFilterGeom == NULL
      63                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
      64                 :         && (m_poAttrQuery == NULL
      65                 :             || m_poAttrQuery->Evaluate( poFeature )) )
      66                 :         {
      67              14 :             return poFeature;
      68                 :         }
      69                 :         else
      70               0 :             delete poFeature;
      71                 :     }
      72                 : }
      73                 : 
      74                 : /************************************************************************/
      75                 : /*                         OGRUKOOAP190Layer()                          */
      76                 : /************************************************************************/
      77                 : 
      78                 : typedef struct
      79                 : {
      80                 :     const char*     pszName;
      81                 :     OGRFieldType    eType;
      82                 : } FieldDesc;
      83                 : 
      84                 : static const FieldDesc UKOOAP190Fields[] =
      85                 : {
      86                 :     { "LINENAME", OFTString },
      87                 :     { "VESSEL_ID", OFTString },
      88                 :     { "SOURCE_ID", OFTString },
      89                 :     { "OTHER_ID", OFTString },
      90                 :     { "POINTNUMBER", OFTInteger },
      91                 :     { "LONGITUDE", OFTReal },
      92                 :     { "LATITUDE", OFTReal },
      93                 :     { "EASTING", OFTReal },
      94                 :     { "NORTHING", OFTReal },
      95                 :     { "DEPTH", OFTReal },
      96                 :     { "DAYOFYEAR", OFTInteger },
      97                 :     { "TIME", OFTTime },
      98                 :     { "DATETIME", OFTDateTime }
      99                 : };
     100                 : 
     101                 : #define FIELD_LINENAME      0
     102                 : #define FIELD_VESSEL_ID     1
     103                 : #define FIELD_SOURCE_ID     2
     104                 : #define FIELD_OTHER_ID      3
     105                 : #define FIELD_POINTNUMBER   4
     106                 : #define FIELD_LONGITUDE     5
     107                 : #define FIELD_LATITUDE      6
     108                 : #define FIELD_EASTING       7
     109                 : #define FIELD_NORTHING      8
     110                 : #define FIELD_DEPTH         9
     111                 : #define FIELD_DAYOFYEAR     10
     112                 : #define FIELD_TIME          11
     113                 : #define FIELD_DATETIME      12
     114                 : 
     115               4 : OGRUKOOAP190Layer::OGRUKOOAP190Layer( const char* pszFilename,
     116               4 :                                       VSILFILE* fp )
     117                 : 
     118                 : {
     119               4 :     this->fp = fp;
     120               4 :     nNextFID = 0;
     121               4 :     bEOF = FALSE;
     122               4 :     poSRS = NULL;
     123               4 :     nYear = 0;
     124                 : 
     125               4 :     poFeatureDefn = new OGRFeatureDefn( CPLGetBasename(pszFilename) );
     126               4 :     poFeatureDefn->Reference();
     127               4 :     poFeatureDefn->SetGeomType( wkbPoint );
     128                 : 
     129              56 :     for(int i=0;i<(int)(sizeof(UKOOAP190Fields)/sizeof(UKOOAP190Fields[0]));i++)
     130                 :     {
     131                 :         OGRFieldDefn    oField( UKOOAP190Fields[i].pszName,
     132              52 :                                 UKOOAP190Fields[i].eType );
     133              52 :         poFeatureDefn->AddFieldDefn( &oField );
     134                 :     }
     135                 : 
     136                 :     bUseEastingNorthingAsGeometry =
     137               4 :         CSLTestBoolean(CPLGetConfigOption("UKOOAP190_USE_EASTING_NORTHING", "NO"));
     138                 : 
     139               4 :     ParseHeaders();
     140               4 : }
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                         ~OGRUKOOAP190Layer()                         */
     144                 : /************************************************************************/
     145                 : 
     146               4 : OGRUKOOAP190Layer::~OGRUKOOAP190Layer()
     147                 : 
     148                 : {
     149               4 :     poFeatureDefn->Release();
     150                 : 
     151               4 :     VSIFCloseL( fp );
     152                 : 
     153               4 :     if (poSRS)
     154               4 :         poSRS->Release();
     155               4 : }
     156                 : 
     157                 : /************************************************************************/
     158                 : /*                          ParseHeaders()                              */
     159                 : /************************************************************************/
     160                 : 
     161              52 : void OGRUKOOAP190Layer::ParseHeaders()
     162                 : {
     163              48 :     while(TRUE)
     164                 :     {
     165              52 :         const char* pszLine = CPLReadLine2L(fp,81,NULL);
     166              52 :         if (pszLine == NULL || EQUALN(pszLine, "EOF", 3))
     167                 :         {
     168               0 :             break;
     169                 :         }
     170                 : 
     171              52 :         int nLineLen = strlen(pszLine);
     172             104 :         while(nLineLen > 0 && pszLine[nLineLen-1] == ' ')
     173                 :         {
     174               0 :             ((char*)pszLine)[nLineLen-1] = '\0';
     175               0 :             nLineLen --;
     176                 :         }
     177                 : 
     178              52 :         if (pszLine[0] != 'H')
     179               4 :             break;
     180                 : 
     181              48 :         if (nLineLen < 33)
     182               0 :             continue;
     183                 : 
     184              52 :         if (!bUseEastingNorthingAsGeometry &&
     185                 :             strncmp(pszLine, "H1500", 5) == 0 && poSRS == NULL)
     186                 :         {
     187               8 :             if (strncmp(pszLine + 33 - 1, "WGS84", 5) == 0 ||
     188                 :                 strncmp(pszLine + 33 - 1, "WGS-84", 6) == 0)
     189                 :             {
     190               4 :                 poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
     191                 :             }
     192               0 :             else if (strncmp(pszLine + 33 - 1, "WGS72", 5) == 0)
     193                 :             {
     194               0 :                 poSRS = new OGRSpatialReference();
     195               0 :                 poSRS->SetFromUserInput("WGS72");
     196                 :             }
     197                 :         }
     198              44 :         else if (!bUseEastingNorthingAsGeometry &&
     199                 :                  strncmp(pszLine, "H1501", 5) == 0 && poSRS != NULL &&
     200                 :                  nLineLen >= 32 + 6 * 6 + 10)
     201                 :         {
     202                 :             char aszParams[6][6+1];
     203                 :             char szZ[10+1];
     204                 :             int i;
     205               0 :             for(i=0;i<6;i++)
     206                 :             {
     207               0 :                 ExtractField(aszParams[i], pszLine, 33 - 1 + i * 6, 6);
     208                 :             }
     209               0 :             ExtractField(szZ, pszLine, 33 - 1 + 6 * 6, 10);
     210                 :             poSRS->SetTOWGS84(atof(aszParams[0]),
     211                 :                               atof(aszParams[1]),
     212                 :                               atof(aszParams[2]),
     213                 :                               atof(aszParams[3]),
     214                 :                               atof(aszParams[4]),
     215                 :                               atof(aszParams[5]),
     216               0 :                               atof(szZ));
     217                 :         }
     218              44 :         else if (strncmp(pszLine, "H0200", 5) == 0)
     219                 :         {
     220               4 :             char** papszTokens = CSLTokenizeString(pszLine + 33 - 1);
     221              16 :             for(int i = 0; papszTokens[i] != NULL; i++)
     222                 :             {
     223              12 :                 if (strlen(papszTokens[i]) == 4)
     224                 :                 {
     225               4 :                     int nVal = atoi(papszTokens[i]);
     226               4 :                     if (nVal >= 1900)
     227                 :                     {
     228               4 :                         if (nYear != 0 && nYear != nVal)
     229                 :                         {
     230                 :                             CPLDebug("SEGUKOOA",
     231               0 :                                      "Several years found in H0200. Ignoring them!");
     232               0 :                             nYear = 0;
     233               0 :                             break;
     234                 :                         }
     235               4 :                         nYear = nVal;
     236                 :                     }
     237                 :                 }
     238                 :             }
     239               4 :             CSLDestroy(papszTokens);
     240                 :         }
     241                 :     }
     242               4 :     VSIFSeekL( fp, 0, SEEK_SET );
     243               4 : }
     244                 : 
     245                 : /************************************************************************/
     246                 : /*                            ResetReading()                            */
     247                 : /************************************************************************/
     248                 : 
     249               0 : void OGRUKOOAP190Layer::ResetReading()
     250                 : 
     251                 : {
     252               0 :     nNextFID = 0;
     253               0 :     bEOF = FALSE;
     254               0 :     VSIFSeekL( fp, 0, SEEK_SET );
     255               0 : }
     256                 : 
     257                 : /************************************************************************/
     258                 : /*                         GetNextRawFeature()                          */
     259                 : /************************************************************************/
     260                 : 
     261               6 : OGRFeature *OGRUKOOAP190Layer::GetNextRawFeature()
     262                 : {
     263               6 :     if (bEOF)
     264               0 :         return NULL;
     265                 : 
     266                 :     const char* pszLine;
     267                 : 
     268              24 :     while(TRUE)
     269                 :     {
     270              30 :         pszLine = CPLReadLine2L(fp,81,NULL);
     271              30 :         if (pszLine == NULL || EQUALN(pszLine, "EOF", 3))
     272                 :         {
     273               1 :             bEOF = TRUE;
     274               1 :             return NULL;
     275                 :         }
     276                 : 
     277              29 :         int nLineLen = strlen(pszLine);
     278              58 :         while(nLineLen > 0 && pszLine[nLineLen-1] == ' ')
     279                 :         {
     280               0 :             ((char*)pszLine)[nLineLen-1] = '\0';
     281               0 :             nLineLen --;
     282                 :         }
     283                 : 
     284              29 :         if (pszLine[0] == 'H' || nLineLen < 46)
     285              24 :             continue;
     286                 : 
     287               5 :         OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     288               5 :         poFeature->SetFID(nNextFID ++);
     289                 : 
     290                 :         char szLineName[12 + 1];
     291               5 :         ExtractField(szLineName, pszLine, 2-1, 12);
     292               5 :         int i = 11;
     293              23 :         while (i >= 0)
     294                 :         {
     295              18 :             if (szLineName[i] == ' ')
     296              13 :                 szLineName[i] = '\0';
     297                 :             else
     298               5 :                 break;
     299              13 :             i --;
     300                 :         }
     301               5 :         poFeature->SetField(FIELD_LINENAME, szLineName);
     302                 : 
     303                 :         char szVesselId[1+1];
     304               5 :         szVesselId[0] = pszLine[17-1];
     305               5 :         if (szVesselId[0] != ' ')
     306                 :         {
     307               0 :             szVesselId[1] = '\0';
     308               0 :             poFeature->SetField(FIELD_VESSEL_ID, szVesselId);
     309                 :         }
     310                 : 
     311                 :         char szSourceId[1+1];
     312               5 :         szSourceId[0] = pszLine[18-1];
     313               5 :         if (szSourceId[0] != ' ')
     314                 :         {
     315               0 :             szSourceId[1] = '\0';
     316               0 :             poFeature->SetField(FIELD_SOURCE_ID, szSourceId);
     317                 :         }
     318                 : 
     319                 :         char szOtherId[1+1];
     320               5 :         szOtherId[0] = pszLine[19-1];
     321               5 :         if (szOtherId[0] != ' ')
     322                 :         {
     323               0 :             szOtherId[1] = '\0';
     324               0 :             poFeature->SetField(FIELD_OTHER_ID, szOtherId);
     325                 :         }
     326                 : 
     327                 :         char szPointNumber[6+1];
     328               5 :         ExtractField(szPointNumber, pszLine, 20-1, 6);
     329               5 :         poFeature->SetField(4, atoi(szPointNumber));
     330                 : 
     331                 :         char szDeg[3+1];
     332                 :         char szMin[2+1];
     333                 :         char szSec[5+1];
     334                 : 
     335               5 :         ExtractField(szDeg, pszLine, 26-1, 2);
     336               5 :         ExtractField(szMin, pszLine, 26+2-1, 2);
     337               5 :         ExtractField(szSec, pszLine, 26+2+2-1, 5);
     338               5 :         double dfLat = atoi(szDeg) + atoi(szMin) / 60.0 + atof(szSec) / 3600.0;
     339               5 :         if (pszLine[26+2+2+5-1] == 'S')
     340               2 :             dfLat = -dfLat;
     341               5 :         poFeature->SetField(FIELD_LATITUDE, dfLat);
     342                 : 
     343               5 :         ExtractField(szDeg, pszLine, 36-1, 3);
     344               5 :         ExtractField(szMin, pszLine, 36+3-1, 2);
     345               5 :         ExtractField(szSec, pszLine, 36+3+2-1, 5);
     346               5 :         double dfLon = atoi(szDeg) + atoi(szMin) / 60.0 + atof(szSec) / 3600.0;
     347               5 :         if (pszLine[36+3+2+5-1] == 'W')
     348               2 :             dfLon = -dfLon;
     349               5 :         poFeature->SetField(FIELD_LONGITUDE, dfLon);
     350                 : 
     351               5 :         OGRGeometry* poGeom = NULL;
     352               5 :         if (!bUseEastingNorthingAsGeometry)
     353               5 :             poGeom = new OGRPoint(dfLon, dfLat);
     354                 : 
     355               5 :         if (nLineLen >= 64)
     356                 :         {
     357                 :             char szEasting[9+1];
     358               5 :             ExtractField(szEasting, pszLine, 47-1, 9);
     359               5 :             double dfEasting = atof(szEasting);
     360               5 :             poFeature->SetField(FIELD_EASTING, dfEasting);
     361                 : 
     362                 :             char szNorthing[9+1];
     363               5 :             ExtractField(szNorthing, pszLine, 56-1, 9);
     364               5 :             double dfNorthing = atof(szNorthing);
     365               5 :             poFeature->SetField(FIELD_NORTHING, dfNorthing);
     366                 : 
     367               5 :             if (bUseEastingNorthingAsGeometry)
     368               0 :                 poGeom = new OGRPoint(dfEasting, dfNorthing);
     369                 :         }
     370                 : 
     371               5 :         if (poGeom)
     372                 :         {
     373               5 :             if (poSRS)
     374               5 :                 poGeom->assignSpatialReference(poSRS);
     375               5 :             poFeature->SetGeometryDirectly(poGeom);
     376                 :         }
     377                 : 
     378               5 :         if (nLineLen >= 70)
     379                 :         {
     380                 :             char szDepth[6+1];
     381               5 :             ExtractField(szDepth, pszLine, 65-1, 6);
     382               5 :             double dfDepth = atof(szDepth);
     383               5 :             poFeature->SetField(FIELD_DEPTH, dfDepth);
     384                 :         }
     385                 : 
     386               5 :         int nDayOfYear = 0;
     387               5 :         if (nLineLen >= 73)
     388                 :         {
     389                 :             char szDayOfYear[3+1];
     390               5 :             ExtractField(szDayOfYear, pszLine, 71-1, 3);
     391               5 :             nDayOfYear = atoi(szDayOfYear);
     392               5 :             poFeature->SetField(FIELD_DAYOFYEAR, nDayOfYear);
     393                 :         }
     394                 : 
     395               5 :         if (nLineLen >= 79)
     396                 :         {
     397                 :             char szH[2+1], szM[2+1], szS[2+1];
     398               5 :             ExtractField(szH, pszLine, 74-1, 2);
     399               5 :             ExtractField(szM, pszLine, 74-1+2, 2);
     400               5 :             ExtractField(szS, pszLine, 74-1+2+2, 2);
     401               5 :             poFeature->SetField(FIELD_TIME, 0, 0, 0, atoi(szH), atoi(szM), atoi(szS) );
     402                 : 
     403               5 :             if (nYear != 0)
     404                 :             {
     405                 :                 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
     406                 :                 static const int mon_lengths[2][12] = {
     407                 :                     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
     408                 :                     {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
     409                 :                 } ;
     410               5 :                 int bIsLeap = isleap(nYear);
     411               5 :                 int nMonth = 0;
     412               5 :                 int nDays = 0;
     413               5 :                 if ((bIsLeap && nDayOfYear >= 1 && nDayOfYear <= 366) ||
     414                 :                     (!bIsLeap && nDayOfYear >= 1 && nDayOfYear <= 365))
     415                 :                 {
     416              10 :                     while(nDayOfYear > nDays + mon_lengths[bIsLeap][nMonth])
     417                 :                     {
     418               0 :                         nDays += mon_lengths[bIsLeap][nMonth];
     419               0 :                         nMonth ++;
     420                 :                     }
     421               5 :                     int nDayOfMonth = nDayOfYear - nDays;
     422               5 :                     nMonth ++;
     423                 : 
     424                 :                     poFeature->SetField(FIELD_DATETIME, nYear, nMonth, nDayOfMonth,
     425               5 :                                         atoi(szH), atoi(szM), atoi(szS) );
     426                 :                 }
     427                 : 
     428                 :             }
     429                 :         }
     430                 : 
     431               5 :         return poFeature;
     432                 :     }
     433                 : }
     434                 : 
     435                 : /************************************************************************/
     436                 : /*                           OGRSEGP1Layer()                            */
     437                 : /************************************************************************/
     438                 : 
     439                 : static const FieldDesc SEGP1Fields[] =
     440                 : {
     441                 :     { "LINENAME", OFTString },
     442                 :     { "POINTNUMBER", OFTInteger },
     443                 :     { "RESHOOTCODE", OFTString },
     444                 :     { "LONGITUDE", OFTReal },
     445                 :     { "LATITUDE", OFTReal },
     446                 :     { "EASTING", OFTReal },
     447                 :     { "NORTHING", OFTReal },
     448                 :     { "DEPTH", OFTReal },
     449                 : #if 0
     450                 :     { "YEAR", OFTInteger },
     451                 :     { "DAYOFYEAR", OFTInteger },
     452                 :     { "TIME", OFTTime },
     453                 :     { "DATETIME", OFTDateTime }
     454                 : #endif
     455                 : };
     456                 : 
     457                 : #define SEGP1_FIELD_LINENAME      0
     458                 : #define SEGP1_FIELD_POINTNUMBER   1
     459                 : #define SEGP1_FIELD_RESHOOTCODE   2
     460                 : #define SEGP1_FIELD_LONGITUDE     3
     461                 : #define SEGP1_FIELD_LATITUDE      4
     462                 : #define SEGP1_FIELD_EASTING       5
     463                 : #define SEGP1_FIELD_NORTHING      6
     464                 : #define SEGP1_FIELD_DEPTH         7
     465                 : #define SEGP1_FIELD_DAYOFYEAR     8
     466                 : #define SEGP1_FIELD_TIME          9
     467                 : #define SEGP1_FIELD_DATETIME      10
     468                 : 
     469               4 : OGRSEGP1Layer::OGRSEGP1Layer( const char* pszFilename,
     470                 :                               VSILFILE* fp,
     471               4 :                               int nLatitudeCol )
     472                 : 
     473                 : {
     474               4 :     this->fp = fp;
     475               4 :     this->nLatitudeCol = nLatitudeCol;
     476               4 :     nNextFID = 0;
     477               4 :     bEOF = FALSE;
     478               4 :     poSRS = NULL;
     479                 : 
     480               4 :     poFeatureDefn = new OGRFeatureDefn( CPLGetBasename(pszFilename) );
     481               4 :     poFeatureDefn->Reference();
     482               4 :     poFeatureDefn->SetGeomType( wkbPoint );
     483                 : 
     484              36 :     for(int i=0;i<(int)(sizeof(SEGP1Fields)/sizeof(SEGP1Fields[0]));i++)
     485                 :     {
     486                 :         OGRFieldDefn    oField( SEGP1Fields[i].pszName,
     487              32 :                                 SEGP1Fields[i].eType );
     488              32 :         poFeatureDefn->AddFieldDefn( &oField );
     489                 :     }
     490                 : 
     491                 :     bUseEastingNorthingAsGeometry =
     492               4 :         CSLTestBoolean(CPLGetConfigOption("SEGP1_USE_EASTING_NORTHING", "NO"));
     493                 : 
     494               4 :     ResetReading();
     495               4 : }
     496                 : 
     497                 : /************************************************************************/
     498                 : /*                            ~OGRSEGP1Layer()                          */
     499                 : /************************************************************************/
     500                 : 
     501               4 : OGRSEGP1Layer::~OGRSEGP1Layer()
     502                 : 
     503                 : {
     504               4 :     poFeatureDefn->Release();
     505                 : 
     506               4 :     VSIFCloseL( fp );
     507                 : 
     508               4 :     if (poSRS)
     509               0 :         poSRS->Release();
     510               4 : }
     511                 : 
     512                 : /************************************************************************/
     513                 : /*                            ResetReading()                            */
     514                 : /************************************************************************/
     515                 : 
     516               4 : void OGRSEGP1Layer::ResetReading()
     517                 : 
     518                 : {
     519               4 :     nNextFID = 0;
     520               4 :     bEOF = FALSE;
     521               4 :     VSIFSeekL( fp, 0, SEEK_SET );
     522                 : 
     523                 :     /* Skip first 20 header lines */
     524               4 :     const char* pszLine = NULL;
     525              84 :     for(int i=0; i<20;i++)
     526                 :     {
     527              80 :         pszLine = CPLReadLine2L(fp,81,NULL);
     528              80 :         if (pszLine == NULL)
     529                 :         {
     530               0 :             bEOF = TRUE;
     531               0 :             break;
     532                 :         }
     533                 :     }
     534               4 : }
     535                 : 
     536                 : /************************************************************************/
     537                 : /*                         GetNextRawFeature()                          */
     538                 : /************************************************************************/
     539                 : 
     540               6 : OGRFeature *OGRSEGP1Layer::GetNextRawFeature()
     541                 : {
     542               6 :     if (bEOF)
     543               0 :         return NULL;
     544                 : 
     545               6 :     const char* pszLine = NULL;
     546                 :     while(TRUE)
     547                 :     {
     548               6 :         pszLine = CPLReadLine2L(fp,81,NULL);
     549               6 :         if (pszLine == NULL || EQUALN(pszLine, "EOF", 3))
     550                 :         {
     551               1 :             bEOF = TRUE;
     552               1 :             return NULL;
     553                 :         }
     554                 : 
     555               5 :         int nLineLen = strlen(pszLine);
     556              10 :         while(nLineLen > 0 && pszLine[nLineLen-1] == ' ')
     557                 :         {
     558               0 :             ((char*)pszLine)[nLineLen-1] = '\0';
     559               0 :             nLineLen --;
     560                 :         }
     561                 : 
     562               5 :         char* pszExpandedLine = ExpandTabs(pszLine);
     563               5 :         pszLine = pszExpandedLine;
     564               5 :         nLineLen = strlen(pszLine);
     565                 : 
     566               5 :         OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     567               5 :         poFeature->SetFID(nNextFID ++);
     568                 : 
     569               5 :         OGRGeometry* poGeom = NULL;
     570                 : 
     571               5 :         if (nLatitudeCol-1 + 19 <= nLineLen)
     572                 :         {
     573                 :             char szDeg[3+1];
     574                 :             char szMin[2+1];
     575                 :             char szSec[4+1];
     576                 : 
     577               5 :             ExtractField(szDeg, pszLine, nLatitudeCol-1, 2);
     578               5 :             ExtractField(szMin, pszLine, nLatitudeCol+2-1, 2);
     579               5 :             ExtractField(szSec, pszLine, nLatitudeCol+2+2-1, 4);
     580               5 :             double dfLat = atoi(szDeg) + atoi(szMin) / 60.0 + atoi(szSec) / 100.0 / 3600.0;
     581               5 :             if (pszLine[nLatitudeCol+2+2+4-1] == 'S')
     582               2 :                 dfLat = -dfLat;
     583               5 :             poFeature->SetField(SEGP1_FIELD_LATITUDE, dfLat);
     584                 : 
     585               5 :             ExtractField(szDeg, pszLine, nLatitudeCol+9-1, 3);
     586               5 :             ExtractField(szMin, pszLine, nLatitudeCol+9+3-1, 2);
     587               5 :             ExtractField(szSec, pszLine, nLatitudeCol+9+3+2-1, 4);
     588               5 :             double dfLon = atoi(szDeg) + atoi(szMin) / 60.0 + atoi(szSec) / 100.0 / 3600.0;
     589               5 :             if (pszLine[nLatitudeCol+9+3+2+4-1] == 'W')
     590               2 :                 dfLon = -dfLon;
     591               5 :             poFeature->SetField(SEGP1_FIELD_LONGITUDE, dfLon);
     592                 : 
     593               5 :             if (!bUseEastingNorthingAsGeometry)
     594               5 :                 poGeom = new OGRPoint(dfLon, dfLat);
     595                 :         }
     596                 : 
     597                 :         /* Normal layout -> extract other fields */
     598               5 :         if (nLatitudeCol == 27)
     599                 :         {
     600                 :             char szLineName[16 + 1];
     601               5 :             ExtractField(szLineName, pszLine, 2-1, 16);
     602               5 :             int i = 15;
     603              43 :             while (i >= 0)
     604                 :             {
     605              38 :                 if (szLineName[i] == ' ')
     606              33 :                     szLineName[i] = '\0';
     607                 :                 else
     608               5 :                     break;
     609              33 :                 i --;
     610                 :             }
     611               5 :             poFeature->SetField(SEGP1_FIELD_LINENAME, szLineName);
     612                 : 
     613                 :             char szPointNumber[8+1];
     614               5 :             ExtractField(szPointNumber, pszLine, 18-1, 8);
     615               5 :             poFeature->SetField(SEGP1_FIELD_POINTNUMBER, atoi(szPointNumber));
     616                 : 
     617                 :             char szReshootCode[1+1];
     618               5 :             ExtractField(szReshootCode, pszLine, 26-1, 1);
     619               5 :             poFeature->SetField(SEGP1_FIELD_RESHOOTCODE, szReshootCode);
     620                 : 
     621               5 :             if (nLineLen >= 61)
     622                 :             {
     623                 :                 char szEasting[8+1];
     624               5 :                 ExtractField(szEasting, pszLine, 46-1, 8);
     625               5 :                 double dfEasting = atof(szEasting);
     626               5 :                 poFeature->SetField(SEGP1_FIELD_EASTING, dfEasting);
     627                 : 
     628                 :                 char szNorthing[8+1];
     629               5 :                 ExtractField(szNorthing, pszLine, 54-1, 8);
     630               5 :                 double dfNorthing = atof(szNorthing);
     631               5 :                 poFeature->SetField(SEGP1_FIELD_NORTHING, dfNorthing);
     632                 : 
     633               5 :                 if (bUseEastingNorthingAsGeometry)
     634               0 :                     poGeom = new OGRPoint(dfEasting, dfNorthing);
     635                 :             }
     636                 : 
     637               5 :             if (nLineLen >= 66)
     638                 :             {
     639                 :                 char szDepth[5+1];
     640               5 :                 ExtractField(szDepth, pszLine, 62-1, 5);
     641               5 :                 double dfDepth = atof(szDepth);
     642               5 :                 poFeature->SetField(SEGP1_FIELD_DEPTH, dfDepth);
     643                 :             }
     644                 :         }
     645                 : 
     646               5 :         if (poGeom)
     647                 :         {
     648               5 :             if (poSRS)
     649               0 :                 poGeom->assignSpatialReference(poSRS);
     650               5 :             poFeature->SetGeometryDirectly(poGeom);
     651                 :         }
     652                 : 
     653               5 :         CPLFree(pszExpandedLine);
     654                 : 
     655               5 :         return poFeature;
     656                 :     }
     657                 : }
     658                 : 
     659                 : /************************************************************************/
     660                 : /*                           ExpandTabs()                               */
     661                 : /************************************************************************/
     662                 : 
     663               7 : char* OGRSEGP1Layer::ExpandTabs(const char* pszLine)
     664                 : {
     665               7 :     char* pszExpandedLine = (char*)CPLMalloc(strlen(pszLine) * 8 + 1);
     666               7 :     int j = 0;
     667             469 :     for(int i=0; pszLine[i] != '\0'; i++)
     668                 :     {
     669                 :         /* A tab must be space-expanded to reach the next column number */
     670                 :         /* which is a multiple of 8 */
     671             462 :         if (pszLine[i] == 9)
     672                 :         {
     673               0 :             do
     674                 :             {
     675               0 :                 pszExpandedLine[j ++] = ' ';
     676                 :             } while ((j % 8) != 0);
     677                 :         }
     678                 :         else
     679             462 :             pszExpandedLine[j ++] = pszLine[i];
     680                 :     }
     681               7 :     pszExpandedLine[j] = '\0';
     682                 : 
     683               7 :     return pszExpandedLine;
     684                 : }
     685                 : 
     686                 : /************************************************************************/
     687                 : /*                        DetectLatitudeColumn()                        */
     688                 : /************************************************************************/
     689                 : 
     690                 : /* Some SEG-P1 files have unusual offsets for latitude/longitude, so */
     691                 : /* we try our best to identify it even in case of non-standard layout */
     692                 : /* Return non-0 if detection is successfull (column number starts at 1) */
     693                 : 
     694               2 : int OGRSEGP1Layer::DetectLatitudeColumn(const char* pszLine)
     695                 : {
     696               2 :     int nLen = strlen(pszLine);
     697               6 :     if (nLen >= 45 && pszLine[0] == ' ' &&
     698               2 :         (pszLine[35-1] == 'N' || pszLine[35-1] == 'S') &&
     699               2 :         (pszLine[45-1] == 'E' || pszLine[45-1] == 'W'))
     700               2 :         return 27;
     701                 : 
     702               0 :     for(int i=8;i<nLen-10;i++)
     703                 :     {
     704               0 :         if ((pszLine[i] == 'N' || pszLine[i] == 'S') &&
     705               0 :             (pszLine[i+10] == 'E' || pszLine[i+10] == 'W'))
     706               0 :             return i - 8 + 1;
     707                 :     }
     708                 : 
     709               0 :     return 0;
     710                 : }
     711                 : 
     712                 : 
     713                 : /************************************************************************/
     714                 : /*                        OGRSEGUKOOALineLayer()                        */
     715                 : /************************************************************************/
     716                 : 
     717               4 : OGRSEGUKOOALineLayer::OGRSEGUKOOALineLayer(const char* pszFilename,
     718               4 :                                            OGRLayer *poBaseLayer)
     719                 : {
     720               4 :     nNextFID = 0;
     721               4 :     bEOF = FALSE;
     722                 : 
     723                 :     poFeatureDefn = new OGRFeatureDefn( CPLSPrintf("%s_lines",
     724               4 :                                                    CPLGetBasename(pszFilename)) );
     725               4 :     poFeatureDefn->Reference();
     726               4 :     poFeatureDefn->SetGeomType( wkbLineString );
     727                 : 
     728               4 :     OGRFieldDefn    oField( "LINENAME", OFTString );
     729               4 :     poFeatureDefn->AddFieldDefn( &oField );
     730                 : 
     731               4 :     this->poBaseLayer = poBaseLayer;
     732               4 :     poNextBaseFeature = NULL;
     733               4 : }
     734                 : 
     735                 : /************************************************************************/
     736                 : /*                       ~OGRSEGUKOOALineLayer()                        */
     737                 : /************************************************************************/
     738                 : 
     739               4 : OGRSEGUKOOALineLayer::~OGRSEGUKOOALineLayer()
     740                 : {
     741               4 :     delete poNextBaseFeature;
     742               4 :     delete poBaseLayer;
     743                 : 
     744               4 :     poFeatureDefn->Release();
     745               4 : }
     746                 : 
     747                 : /************************************************************************/
     748                 : /*                            ResetReading()                            */
     749                 : /************************************************************************/
     750                 : 
     751               0 : void OGRSEGUKOOALineLayer::ResetReading()
     752                 : 
     753                 : {
     754               0 :     nNextFID = 0;
     755               0 :     bEOF = FALSE;
     756               0 :     delete poNextBaseFeature;
     757               0 :     poNextBaseFeature = NULL;
     758               0 :     poBaseLayer->ResetReading();
     759               0 : }
     760                 : 
     761                 : /************************************************************************/
     762                 : /*                         GetNextRawFeature()                          */
     763                 : /************************************************************************/
     764                 : 
     765               4 : OGRFeature *OGRSEGUKOOALineLayer::GetNextRawFeature()
     766                 : {
     767               4 :     if (bEOF)
     768               0 :         return NULL;
     769                 : 
     770                 :     /* Merge points of base layer that have same value for attribute(0) */
     771                 :     /* into a single linestring */
     772                 : 
     773               4 :     OGRFeature* poFeature = NULL;
     774               4 :     OGRLineString* poLS = NULL;
     775                 : 
     776               4 :     if (poNextBaseFeature == NULL)
     777               2 :         poNextBaseFeature = poBaseLayer->GetNextFeature();
     778                 : 
     779              16 :     while(poNextBaseFeature != NULL)
     780                 :     {
     781              20 :         if (poNextBaseFeature->IsFieldSet(0) &&
     782              10 :             poNextBaseFeature->GetFieldAsString(0)[0] != '\0')
     783                 :         {
     784              10 :             if (poFeature != NULL &&
     785                 :                 strcmp(poFeature->GetFieldAsString(0),
     786                 :                     poNextBaseFeature->GetFieldAsString(0)) != 0)
     787                 :             {
     788               2 :                 return poFeature;
     789                 :             }
     790                 : 
     791                 :             OGRPoint* poPoint =
     792               8 :                 (OGRPoint*) poNextBaseFeature->GetGeometryRef();
     793               8 :             if (poPoint != NULL)
     794                 :             {
     795               8 :                 if (poFeature == NULL)
     796                 :                 {
     797               4 :                     poFeature = new OGRFeature(poFeatureDefn);
     798               4 :                     poFeature->SetFID(nNextFID ++);
     799                 :                     poFeature->SetField(0,
     800               4 :                         poNextBaseFeature->GetFieldAsString(0));
     801               8 :                     poLS = new OGRLineString();
     802               4 :                     if (poBaseLayer->GetSpatialRef())
     803                 :                         poLS->assignSpatialReference(
     804               2 :                                     poBaseLayer->GetSpatialRef());
     805               4 :                     poFeature->SetGeometryDirectly(poLS);
     806                 :                 }
     807                 : 
     808               8 :                 poLS->addPoint(poPoint);
     809                 :             }
     810                 :         }
     811                 : 
     812               8 :         delete poNextBaseFeature;
     813               8 :         poNextBaseFeature = poBaseLayer->GetNextFeature();
     814                 :     }
     815                 : 
     816               2 :     bEOF = TRUE;
     817               2 :     return poFeature;
     818                 : }

Generated by: LCOV version 1.7