LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/xplane - ogr_xplane_awy_reader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 162 125 77.2 %
Date: 2012-12-26 Functions: 23 14 60.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr_xplane_awy_reader.cpp
       3                 :  *
       4                 :  * Project:  X-Plane awy.dat file reader
       5                 :  * Purpose:  Implements OGRXPlaneAwyReader class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2008, Even Rouault
      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 "ogr_xplane_awy_reader.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogr_xplane_awy_reader.cpp 21634 2011-02-06 14:45:00Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                   OGRXPlaneCreateAwyFileReader                       */
      36                 : /************************************************************************/
      37                 : 
      38               1 : OGRXPlaneReader* OGRXPlaneCreateAwyFileReader( OGRXPlaneDataSource* poDataSource )
      39                 : {
      40               1 :     OGRXPlaneReader* poReader = new OGRXPlaneAwyReader(poDataSource);
      41               1 :     return poReader;
      42                 : }
      43                 : 
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                         OGRXPlaneAwyReader()                         */
      47                 : /************************************************************************/
      48               0 : OGRXPlaneAwyReader::OGRXPlaneAwyReader()
      49                 : {
      50               0 :     poAirwaySegmentLayer = NULL;
      51               0 :     poAirwayIntersectionLayer = NULL;
      52               0 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                          OGRXPlaneAwyReader()                        */
      56                 : /************************************************************************/
      57                 : 
      58               1 : OGRXPlaneAwyReader::OGRXPlaneAwyReader( OGRXPlaneDataSource* poDataSource )
      59                 : {
      60               1 :     poAirwaySegmentLayer = new OGRXPlaneAirwaySegmentLayer();
      61               2 :     poAirwayIntersectionLayer = new OGRXPlaneAirwayIntersectionLayer();
      62                 : 
      63               1 :     poDataSource->RegisterLayer(poAirwaySegmentLayer);
      64               1 :     poDataSource->RegisterLayer(poAirwayIntersectionLayer);
      65               1 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                        CloneForLayer()                               */
      69                 : /************************************************************************/
      70                 : 
      71               0 : OGRXPlaneReader* OGRXPlaneAwyReader::CloneForLayer(OGRXPlaneLayer* poLayer)
      72                 : {
      73               0 :     OGRXPlaneAwyReader* poReader = new OGRXPlaneAwyReader();
      74                 : 
      75               0 :     poReader->poInterestLayer = poLayer;
      76                 : 
      77               0 :     SET_IF_INTEREST_LAYER(poAirwaySegmentLayer);
      78               0 :     SET_IF_INTEREST_LAYER(poAirwayIntersectionLayer);
      79                 : 
      80               0 :     if (pszFilename)
      81                 :     {
      82               0 :         poReader->pszFilename = CPLStrdup(pszFilename);
      83               0 :         poReader->fp = VSIFOpenL( pszFilename, "rt" );
      84                 :     }
      85                 : 
      86               0 :     return poReader;
      87                 : }
      88                 : 
      89                 : 
      90                 : /************************************************************************/
      91                 : /*                       IsRecognizedVersion()                          */
      92                 : /************************************************************************/
      93                 : 
      94               1 : int OGRXPlaneAwyReader::IsRecognizedVersion( const char* pszVersionString)
      95                 : {
      96               1 :     return EQUALN(pszVersionString, "640 Version", 11);
      97                 : }
      98                 : 
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                                Read()                                */
     102                 : /************************************************************************/
     103                 : 
     104               1 : void OGRXPlaneAwyReader::Read()
     105                 : {
     106                 :     const char* pszLine;
     107              13 :     while((pszLine = CPLReadLineL(fp)) != NULL)
     108                 :     {
     109              12 :         papszTokens = CSLTokenizeString(pszLine);
     110              12 :         nTokens = CSLCount(papszTokens);
     111                 : 
     112              12 :         nLineNumber ++;
     113                 : 
     114              12 :         if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0)
     115                 :         {
     116               1 :             CSLDestroy(papszTokens);
     117               1 :             papszTokens = NULL;
     118               1 :             bEOF = TRUE;
     119               1 :             return;
     120                 :         }
     121              11 :         else if (nTokens == 0 || assertMinCol(10) == FALSE)
     122                 :         {
     123               1 :             CSLDestroy(papszTokens);
     124               1 :             papszTokens = NULL;
     125               1 :             continue;
     126                 :         }
     127                 : 
     128              10 :         ParseRecord();
     129                 : 
     130              10 :         CSLDestroy(papszTokens);
     131              10 :         papszTokens = NULL;
     132                 : 
     133              10 :         if (poInterestLayer && poInterestLayer->IsEmpty() == FALSE)
     134               0 :             return;
     135                 :     }
     136                 : 
     137               0 :     papszTokens = NULL;
     138               0 :     bEOF = TRUE;
     139                 : }
     140                 : 
     141                 : /************************************************************************/
     142                 : /*                            ParseRecord()                             */
     143                 : /************************************************************************/
     144                 : 
     145              10 : void    OGRXPlaneAwyReader::ParseRecord()
     146                 : {
     147                 :     const char* pszFirstPointName;
     148                 :     const char* pszSecondPointName;
     149                 :     const char* pszAirwaySegmentName;
     150                 :     double dfLat1, dfLon1;
     151                 :     double dfLat2, dfLon2;
     152                 :     int bIsHigh;
     153                 :     int nBaseFL, nTopFL;
     154                 : 
     155              10 :     pszFirstPointName = papszTokens[0];
     156              10 :     RET_IF_FAIL(readLatLon(&dfLat1, &dfLon1, 1));
     157              10 :     pszSecondPointName = papszTokens[3];
     158              10 :     RET_IF_FAIL(readLatLon(&dfLat2, &dfLon2, 4));
     159              10 :     bIsHigh = atoi(papszTokens[6]) == 2;
     160              10 :     nBaseFL = atoi(papszTokens[7]);
     161              10 :     nTopFL = atoi(papszTokens[8]);
     162              10 :     pszAirwaySegmentName = papszTokens[9];
     163                 : 
     164              10 :     if (poAirwayIntersectionLayer)
     165                 :     {
     166              10 :         poAirwayIntersectionLayer->AddFeature(pszFirstPointName, dfLat1, dfLon1);
     167              10 :         poAirwayIntersectionLayer->AddFeature(pszSecondPointName, dfLat2, dfLon2);
     168                 :     }
     169                 : 
     170              10 :     if (poAirwaySegmentLayer)
     171                 :     {
     172                 : /*
     173                 :         poAirwaySegmentLayer->AddFeature(pszAirwaySegmentName,
     174                 :                                          pszFirstPointName,
     175                 :                                          pszSecondPointName,
     176                 :                                          dfLat1, dfLon1, dfLat2, dfLon2,
     177                 :                                          bIsHigh, nBaseFL, nTopFL);
     178                 : */
     179              10 :         if (strchr(pszAirwaySegmentName, '-'))
     180                 :         {
     181               1 :             char** papszSegmentNames = CSLTokenizeString2( pszAirwaySegmentName, "-", CSLT_HONOURSTRINGS );
     182               1 :             int i = 0;
     183               4 :             while(papszSegmentNames[i])
     184                 :             {
     185               2 :                 poAirwaySegmentLayer->AddFeature(papszSegmentNames[i],
     186                 :                                                  pszFirstPointName,
     187                 :                                                  pszSecondPointName,
     188                 :                                                  dfLat1, dfLon1, dfLat2, dfLon2,
     189               4 :                                                  bIsHigh, nBaseFL, nTopFL);
     190               2 :                 i++;
     191                 :             }
     192               1 :             CSLDestroy(papszSegmentNames);
     193                 :         }
     194                 :         else
     195                 :         {
     196                 :             poAirwaySegmentLayer->AddFeature(pszAirwaySegmentName,
     197                 :                                             pszFirstPointName,
     198                 :                                             pszSecondPointName,
     199                 :                                             dfLat1, dfLon1, dfLat2, dfLon2,
     200               9 :                                             bIsHigh, nBaseFL, nTopFL);
     201                 :         }
     202                 :     }
     203                 : }
     204                 : 
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                       OGRXPlaneAirwaySegmentLayer()                  */
     208                 : /************************************************************************/
     209                 : 
     210               1 : OGRXPlaneAirwaySegmentLayer::OGRXPlaneAirwaySegmentLayer() : OGRXPlaneLayer("AirwaySegment")
     211                 : {
     212               1 :     poFeatureDefn->SetGeomType( wkbLineString );
     213                 : 
     214               1 :     OGRFieldDefn oFieldSegmentName("segment_name", OFTString );
     215               1 :     poFeatureDefn->AddFieldDefn( &oFieldSegmentName );
     216                 : 
     217               1 :     OGRFieldDefn oFieldPoint1Name("point1_name", OFTString );
     218               1 :     poFeatureDefn->AddFieldDefn( &oFieldPoint1Name );
     219                 : 
     220               1 :     OGRFieldDefn oFieldPoint2Name("point2_name", OFTString );
     221               1 :     poFeatureDefn->AddFieldDefn( &oFieldPoint2Name );
     222                 : 
     223               1 :     OGRFieldDefn oFieldIsHigh("is_high", OFTInteger );
     224               1 :     oFieldIsHigh.SetWidth( 1 );
     225               1 :     poFeatureDefn->AddFieldDefn( &oFieldIsHigh );
     226                 : 
     227               1 :     OGRFieldDefn oFieldBase("base_FL", OFTInteger );
     228               1 :     oFieldBase.SetWidth( 3 );
     229               1 :     poFeatureDefn->AddFieldDefn( &oFieldBase );
     230                 : 
     231               1 :     OGRFieldDefn oFieldTop("top_FL", OFTInteger );
     232               1 :     oFieldTop.SetWidth( 3 );
     233               1 :     poFeatureDefn->AddFieldDefn( &oFieldTop );
     234               1 : }
     235                 : 
     236                 : /************************************************************************/
     237                 : /*                           AddFeature()                               */
     238                 : /************************************************************************/
     239                 : 
     240                 : OGRFeature*
     241              11 :      OGRXPlaneAirwaySegmentLayer::AddFeature(const char* pszAirwaySegmentName,
     242                 :                                              const char* pszFirstPointName,
     243                 :                                              const char* pszSecondPointName,
     244                 :                                              double dfLat1,
     245                 :                                              double dfLon1,
     246                 :                                              double dfLat2,
     247                 :                                              double dfLon2,
     248                 :                                              int    bIsHigh,
     249                 :                                              int    nBaseFL,
     250                 :                                              int    nTopFL)
     251                 : {
     252              11 :     int nCount = 0;
     253              11 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     254              11 :     if (fabs(dfLon1 - dfLon2) < 270)
     255                 :     {
     256              11 :         OGRLineString* lineString = new OGRLineString();
     257              11 :         lineString->addPoint(dfLon1, dfLat1);
     258              11 :         lineString->addPoint(dfLon2, dfLat2);
     259              11 :         poFeature->SetGeometryDirectly( lineString );
     260                 :     }
     261                 :     else
     262                 :     {
     263                 :         /* Crossing antemeridian */
     264               0 :         OGRMultiLineString* multiLineString = new OGRMultiLineString();
     265               0 :         OGRLineString* lineString1 = new OGRLineString();
     266               0 :         OGRLineString* lineString2 = new OGRLineString();
     267                 :         double dfLatInt;
     268               0 :         lineString1->addPoint(dfLon1, dfLat1);
     269               0 :         if (dfLon1 < dfLon2)
     270                 :         {
     271               0 :             dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (-180 - dfLon1) / ((dfLon2 - 360) - dfLon1);
     272               0 :             lineString1->addPoint(-180, dfLatInt);
     273               0 :             lineString2->addPoint(180, dfLatInt);
     274                 :         }
     275                 :         else
     276                 :         {
     277               0 :             dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (180 - dfLon1) / ((dfLon2 + 360) - dfLon1);
     278               0 :             lineString1->addPoint(180, dfLatInt);
     279               0 :             lineString2->addPoint(-180, dfLatInt);
     280                 :         }
     281               0 :         lineString2->addPoint(dfLon2, dfLat2);
     282               0 :         multiLineString->addGeometryDirectly( lineString1 );
     283               0 :         multiLineString->addGeometryDirectly( lineString2 );
     284               0 :         poFeature->SetGeometryDirectly( multiLineString );
     285                 :     }
     286              11 :     poFeature->SetField( nCount++, pszAirwaySegmentName );
     287              11 :     poFeature->SetField( nCount++, pszFirstPointName );
     288              11 :     poFeature->SetField( nCount++, pszSecondPointName );
     289              11 :     poFeature->SetField( nCount++, bIsHigh );
     290              11 :     poFeature->SetField( nCount++, nBaseFL );
     291              11 :     poFeature->SetField( nCount++, nTopFL );
     292                 : 
     293              11 :     RegisterFeature(poFeature);
     294                 : 
     295              11 :     return poFeature;
     296                 : }
     297                 : 
     298                 : /************************************************************************/
     299                 : /*                 EqualAirwayIntersectionFeature                       */
     300                 : /************************************************************************/
     301                 : 
     302              14 : static int EqualAirwayIntersectionFeatureFunc(const void* _feature1, const void* _feature2)
     303                 : {
     304              14 :     OGRFeature* feature1 = (OGRFeature*)_feature1;
     305              14 :     OGRFeature* feature2 = (OGRFeature*)_feature2;
     306              14 :     if (strcmp(feature1->GetFieldAsString(0), feature2->GetFieldAsString(0)) == 0)
     307                 :     {
     308               6 :         OGRPoint* point1 = (OGRPoint*) feature1->GetGeometryRef();
     309               6 :         OGRPoint* point2 = (OGRPoint*) feature2->GetGeometryRef();
     310               6 :         return (point1->getX() == point2->getX() && point1->getY() == point2->getY());
     311                 :     }
     312               8 :     return FALSE;
     313                 : }
     314                 : 
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                      OGRXPlaneAirwayHashDouble()                     */
     318                 : /************************************************************************/
     319                 : 
     320              96 : static unsigned long OGRXPlaneAirwayHashDouble(const double& dfVal)
     321                 : {
     322                 :     /* To make a long story short, we must copy the double into */
     323                 :     /* an array in order to respect C strict-aliasing rule */
     324                 :     /* We can't directly cast into an unsigned int* */
     325                 :     /* See #2521 for the longer version */
     326                 :     unsigned int anValue[2];
     327              96 :     memcpy(anValue, &dfVal, sizeof(double));
     328              96 :     return anValue[0] ^ anValue[1];
     329                 : }
     330                 : 
     331                 : /************************************************************************/
     332                 : /*               HashAirwayIntersectionFeatureFunc                      */
     333                 : /************************************************************************/
     334                 : 
     335              48 : static unsigned long HashAirwayIntersectionFeatureFunc(const void* _feature)
     336                 : {
     337              48 :     OGRFeature* feature = (OGRFeature*)_feature;
     338              48 :     OGRPoint* point = (OGRPoint*) feature->GetGeometryRef();
     339              48 :     unsigned long hash = CPLHashSetHashStr((unsigned char*)feature->GetFieldAsString(0));
     340              48 :     const double x = point->getX();
     341              48 :     const double y = point->getY();
     342              48 :     return hash ^ OGRXPlaneAirwayHashDouble(x) ^ OGRXPlaneAirwayHashDouble(y);
     343                 : }
     344                 : 
     345                 : /************************************************************************/
     346                 : /*               FreeAirwayIntersectionFeatureFunc                      */
     347                 : /************************************************************************/
     348                 : 
     349              14 : static void FreeAirwayIntersectionFeatureFunc(void* _feature)
     350                 : {
     351              14 :     delete (OGRFeature*)_feature;
     352              14 : }
     353                 : 
     354                 : /************************************************************************/
     355                 : /*                 OGRXPlaneAirwayIntersectionLayer()                   */
     356                 : /************************************************************************/
     357                 : 
     358               1 : OGRXPlaneAirwayIntersectionLayer::OGRXPlaneAirwayIntersectionLayer() : OGRXPlaneLayer("AirwayIntersection")
     359                 : {
     360               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     361                 : 
     362               1 :     OGRFieldDefn oFieldName("name", OFTString );
     363               1 :     poFeatureDefn->AddFieldDefn( &oFieldName );
     364                 : 
     365                 :     poSet = CPLHashSetNew(HashAirwayIntersectionFeatureFunc,
     366                 :                           EqualAirwayIntersectionFeatureFunc,
     367               1 :                           FreeAirwayIntersectionFeatureFunc);
     368               1 : }
     369                 : 
     370                 : /************************************************************************/
     371                 : /*                ~OGRXPlaneAirwayIntersectionLayer()                   */
     372                 : /************************************************************************/
     373                 : 
     374               1 : OGRXPlaneAirwayIntersectionLayer::~OGRXPlaneAirwayIntersectionLayer()
     375                 : {
     376               1 :     CPLHashSetDestroy(poSet);
     377               1 : }
     378                 : 
     379                 : /************************************************************************/
     380                 : /*                           AddFeature()                               */
     381                 : /************************************************************************/
     382                 : 
     383                 : OGRFeature*
     384              20 :      OGRXPlaneAirwayIntersectionLayer::AddFeature(const char* pszIntersectionName,
     385                 :                                                   double dfLat,
     386                 :                                                   double dfLon)
     387                 : {
     388              20 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     389              40 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     390              20 :     poFeature->SetField( 0, pszIntersectionName );
     391                 : 
     392              20 :     if (CPLHashSetLookup(poSet, poFeature) == NULL)
     393                 :     {
     394              14 :         CPLHashSetInsert(poSet, poFeature->Clone());
     395              14 :         RegisterFeature(poFeature);
     396                 : 
     397              14 :         return poFeature;
     398                 :     }
     399                 :     else
     400                 :     {
     401               6 :         delete poFeature;
     402               6 :         return NULL;
     403                 :     }
     404                 : }
     405                 : 
     406                 : /************************************************************************/
     407                 : /*                            ResetReading()                            */
     408                 : /************************************************************************/
     409                 : 
     410               0 : void OGRXPlaneAirwayIntersectionLayer::ResetReading()
     411                 : {
     412               0 :     if (poReader)
     413                 :     {
     414               0 :         CPLHashSetDestroy(poSet);
     415                 :         poSet = CPLHashSetNew(HashAirwayIntersectionFeatureFunc,
     416                 :                               EqualAirwayIntersectionFeatureFunc,
     417               0 :                               FreeAirwayIntersectionFeatureFunc);
     418                 :     }
     419                 : 
     420               0 :     OGRXPlaneLayer::ResetReading();
     421               0 : }

Generated by: LCOV version 1.7