LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/xplane - ogr_xplane_nav_reader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 450 406 90.2 %
Date: 2011-12-18 Functions: 30 19 63.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr_xplane_nav_reader.cpp
       3                 :  *
       4                 :  * Project:  X-Plane nav.dat file reader
       5                 :  * Purpose:  Implements OGRXPlaneNavReader 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_nav_reader.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogr_xplane_nav_reader.cpp 21634 2011-02-06 14:45:00Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                   OGRXPlaneCreateNavFileReader                       */
      36                 : /************************************************************************/
      37                 : 
      38               1 : OGRXPlaneReader* OGRXPlaneCreateNavFileReader( OGRXPlaneDataSource* poDataSource )
      39                 : {
      40               1 :     OGRXPlaneReader* poReader = new OGRXPlaneNavReader(poDataSource);
      41               1 :     return poReader;
      42                 : }
      43                 : 
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                         OGRXPlaneNavReader()                         */
      47                 : /************************************************************************/
      48               0 : OGRXPlaneNavReader::OGRXPlaneNavReader()
      49                 : {
      50               0 :     poILSLayer = NULL;
      51               0 :     poVORLayer = NULL;
      52               0 :     poNDBLayer = NULL;
      53               0 :     poGSLayer = NULL;
      54               0 :     poMarkerLayer = NULL;
      55               0 :     poDMELayer = NULL;
      56               0 :     poDMEILSLayer = NULL;
      57               0 : }
      58                 : 
      59                 : /************************************************************************/
      60                 : /*                          OGRXPlaneNavReader()                        */
      61                 : /************************************************************************/
      62                 : 
      63               1 : OGRXPlaneNavReader::OGRXPlaneNavReader( OGRXPlaneDataSource* poDataSource )
      64                 : {
      65               1 :     poILSLayer = new OGRXPlaneILSLayer();
      66               2 :     poVORLayer = new OGRXPlaneVORLayer();
      67               2 :     poNDBLayer = new OGRXPlaneNDBLayer();
      68               2 :     poGSLayer = new OGRXPlaneGSLayer();
      69               2 :     poMarkerLayer = new OGRXPlaneMarkerLayer();
      70               2 :     poDMELayer = new OGRXPlaneDMELayer();
      71               2 :     poDMEILSLayer = new OGRXPlaneDMEILSLayer();
      72                 : 
      73               1 :     poDataSource->RegisterLayer(poILSLayer);
      74               1 :     poDataSource->RegisterLayer(poVORLayer);
      75               1 :     poDataSource->RegisterLayer(poNDBLayer);
      76               1 :     poDataSource->RegisterLayer(poGSLayer);
      77               1 :     poDataSource->RegisterLayer(poMarkerLayer);
      78               1 :     poDataSource->RegisterLayer(poDMELayer);
      79               1 :     poDataSource->RegisterLayer(poDMEILSLayer);
      80               1 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                        CloneForLayer()                               */
      84                 : /************************************************************************/
      85                 : 
      86               0 : OGRXPlaneReader* OGRXPlaneNavReader::CloneForLayer(OGRXPlaneLayer* poLayer)
      87                 : {
      88               0 :     OGRXPlaneNavReader* poReader = new OGRXPlaneNavReader();
      89                 : 
      90               0 :     poReader->poInterestLayer = poLayer;
      91                 : 
      92               0 :     SET_IF_INTEREST_LAYER(poILSLayer);
      93               0 :     SET_IF_INTEREST_LAYER(poVORLayer);
      94               0 :     SET_IF_INTEREST_LAYER(poNDBLayer);
      95               0 :     SET_IF_INTEREST_LAYER(poGSLayer);
      96               0 :     SET_IF_INTEREST_LAYER(poMarkerLayer);
      97               0 :     SET_IF_INTEREST_LAYER(poDMELayer);
      98               0 :     SET_IF_INTEREST_LAYER(poDMEILSLayer);
      99                 : 
     100               0 :     if (pszFilename)
     101                 :     {
     102               0 :         poReader->pszFilename = CPLStrdup(pszFilename);
     103               0 :         poReader->fp = VSIFOpenL( pszFilename, "rb" );
     104                 :     }
     105                 : 
     106               0 :     return poReader;
     107                 : }
     108                 : 
     109                 : /************************************************************************/
     110                 : /*                        IsRecognizedVersion()                         */
     111                 : /************************************************************************/
     112                 : 
     113               1 : int OGRXPlaneNavReader::IsRecognizedVersion( const char* pszVersionString)
     114                 : {
     115                 :     return EQUALN(pszVersionString, "810 Version", 11) ||
     116               1 :            EQUALN(pszVersionString, "740 Version", 11);
     117                 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                                Read()                                */
     121                 : /************************************************************************/
     122                 : 
     123               1 : void OGRXPlaneNavReader::Read()
     124                 : {
     125                 :     const char* pszLine;
     126              29 :     while((pszLine = CPLReadLineL(fp)) != NULL)
     127                 :     {
     128                 :         int nType;
     129              28 :         papszTokens = CSLTokenizeString(pszLine);
     130              28 :         nTokens = CSLCount(papszTokens);
     131                 : 
     132              28 :         nLineNumber ++;
     133                 : 
     134              28 :         if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0)
     135                 :         {
     136               1 :             CSLDestroy(papszTokens);
     137               1 :             papszTokens = NULL;
     138               1 :             bEOF = TRUE;
     139               1 :             return;
     140                 :         }
     141              27 :         else if (nTokens == 0 || assertMinCol(9) == FALSE)
     142                 :         {
     143               2 :             CSLDestroy(papszTokens);
     144               2 :             papszTokens = NULL;
     145               2 :             continue;
     146                 :         }
     147                 : 
     148              25 :         nType = atoi(papszTokens[0]);
     149              25 :         if (!((nType >= NAVAID_NDB && nType <= NAVAID_IM) ||
     150                 :                nType == NAVAID_DME_COLOC || nType == NAVAID_DME_STANDALONE))
     151                 :         {
     152                 :             CPLDebug("XPlane", "Line %d : bad feature code '%s'",
     153               0 :                      nLineNumber, papszTokens[0]);
     154               0 :             CSLDestroy(papszTokens);
     155               0 :             papszTokens = NULL;
     156               0 :             continue;
     157                 :         }
     158                 : 
     159              25 :         ParseRecord(nType);
     160                 : 
     161              25 :         CSLDestroy(papszTokens);
     162              25 :         papszTokens = NULL;
     163                 : 
     164              25 :         if (poInterestLayer && poInterestLayer->IsEmpty() == FALSE)
     165               0 :             return;
     166                 :     }
     167                 : 
     168               0 :     papszTokens = NULL;
     169               0 :     bEOF = TRUE;
     170                 : }
     171                 : 
     172                 : /************************************************************************/
     173                 : /*                            ParseRecord()                             */
     174                 : /************************************************************************/
     175                 : 
     176              25 : void    OGRXPlaneNavReader::ParseRecord(int nType)
     177                 : {
     178                 :     double dfVal, dfLat, dfLon, dfElevation, dfFrequency, dfRange;
     179              25 :     double dfSlavedVariation = 0, dfTrueHeading = 0,
     180              25 :             dfDMEBias = 0, dfSlope = 0;
     181                 :     char* pszNavaidId;
     182                 : 
     183              25 :     RET_IF_FAIL(readLatLon(&dfLat, &dfLon, 1));
     184                 : 
     185                 :     /* feet to meter */
     186              24 :     RET_IF_FAIL(readDoubleWithBoundsAndConversion(&dfElevation, 3, "elevation", FEET_TO_METER, -1000., 10000.));
     187                 : 
     188              24 :     RET_IF_FAIL(readDouble(&dfFrequency, 4, "frequency"));
     189                 :     /* NDB frequencies are in kHz. Others must be divided by 100 */
     190                 :     /* to get a frequency in MHz */
     191              24 :     if (nType != NAVAID_NDB)
     192              20 :         dfFrequency /= 100.;
     193                 : 
     194                 :     /* nautical miles to kilometer */
     195              24 :     RET_IF_FAIL(readDouble(&dfRange, 5, "range"));
     196              24 :     dfRange *= NM_TO_KM;
     197                 : 
     198              24 :     pszNavaidId = papszTokens[7];
     199                 : 
     200              24 :     if (nType == NAVAID_NDB)
     201                 :     {
     202               4 :         const char* pszSubType = "";
     203               4 :         CPLString osNavaidName;
     204              11 :         if (EQUAL(papszTokens[nTokens-1], "NDB") ||
     205               2 :             EQUAL(papszTokens[nTokens-1], "LOM") ||
     206               1 :             EQUAL(papszTokens[nTokens-1], "NDB-DME"))
     207                 :         {
     208               4 :             pszSubType = papszTokens[nTokens-1];
     209               4 :             nTokens--;
     210                 :         }
     211                 :         else
     212                 :         {
     213               0 :             CPLDebug("XPlane", "Unexpected NDB subtype : %s", papszTokens[nTokens-1]);
     214                 :         }
     215                 : 
     216               4 :         osNavaidName = readStringUntilEnd(8);
     217                 : 
     218               4 :         if (poNDBLayer)
     219                 :             poNDBLayer->AddFeature(pszNavaidId, osNavaidName, pszSubType,
     220                 :                                     dfLat, dfLon,
     221               4 :                                     dfElevation, dfFrequency, dfRange);
     222                 :     }
     223              20 :     else if (nType == NAVAID_VOR)
     224                 :     {
     225               3 :         const char* pszSubType = "";
     226               3 :         CPLString osNavaidName;
     227                 : 
     228               3 :         RET_IF_FAIL(readDoubleWithBounds(&dfSlavedVariation, 6, "slaved variation", -180., 180.));
     229                 : 
     230               9 :         if (EQUAL(papszTokens[nTokens-1], "VOR") ||
     231               2 :             EQUAL(papszTokens[nTokens-1], "VORTAC") ||
     232               1 :             EQUAL(papszTokens[nTokens-1], "VOR-DME"))
     233                 :         {
     234               3 :             pszSubType = papszTokens[nTokens-1];
     235               3 :             nTokens--;
     236                 :         }
     237                 :         else
     238                 :         {
     239               0 :             CPLDebug("XPlane", "Unexpected VOR subtype : %s", papszTokens[nTokens-1]);
     240                 :         }
     241                 : 
     242               3 :         osNavaidName = readStringUntilEnd(8);
     243                 : 
     244               3 :         if (poVORLayer)
     245                 :             poVORLayer->AddFeature(pszNavaidId, osNavaidName, pszSubType,
     246                 :                                     dfLat, dfLon,
     247               3 :                                     dfElevation, dfFrequency, dfRange, dfSlavedVariation);
     248                 :     }
     249              23 :     else if (nType == NAVAID_LOC_ILS || nType == NAVAID_LOC_STANDALONE)
     250                 :     {
     251                 :         const char* pszAptICAO, * pszRwyNum, * pszSubType;
     252                 : 
     253               6 :         RET_IF_FAIL(readDoubleWithBounds(&dfTrueHeading, 6, "true heading", 0., 360.));
     254                 : 
     255               6 :         RET_IF_FAIL(assertMinCol(11));
     256                 : 
     257               6 :         pszAptICAO = papszTokens[8];
     258               6 :         pszRwyNum = papszTokens[9];
     259               6 :         pszSubType = papszTokens[10];
     260                 : 
     261               6 :         if (EQUAL(pszSubType, "ILS-cat-I") ||
     262                 :             EQUAL(pszSubType, "ILS-cat-II") ||
     263                 :             EQUAL(pszSubType, "ILS-cat-III") ||
     264                 :             EQUAL(pszSubType, "LOC") ||
     265                 :             EQUAL(pszSubType, "LDA") ||
     266                 :             EQUAL(pszSubType, "SDF") ||
     267                 :             EQUAL(pszSubType, "IGS") ||
     268                 :             EQUAL(pszSubType, "LDA-GS"))
     269                 :         {
     270               6 :             if (poILSLayer)
     271                 :                 poILSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum, pszSubType,
     272                 :                                         dfLat, dfLon,
     273               6 :                                         dfElevation, dfFrequency, dfRange, dfTrueHeading);
     274                 :         }
     275                 :         else
     276                 :         {
     277                 :             CPLDebug("XPlane", "Line %d : invalid localizer subtype: '%s'",
     278               0 :                     nLineNumber, pszSubType);
     279               0 :             return;
     280                 :         }
     281                 :     }
     282              11 :     else if (nType == NAVAID_GS)
     283                 :     {
     284                 :         const char* pszAptICAO, * pszRwyNum, * pszSubType;
     285                 : 
     286               1 :         RET_IF_FAIL(readDouble(&dfVal, 6, "slope & heading"));
     287               1 :         dfSlope = (int)(dfVal / 1000) / 100.;
     288               1 :         dfTrueHeading = dfVal - dfSlope * 100000;
     289               1 :         if (dfTrueHeading < 0 || dfTrueHeading > 360)
     290                 :         {
     291                 :             CPLDebug("XPlane", "Line %d : invalid true heading '%f'",
     292               0 :                     nLineNumber, dfTrueHeading);
     293               0 :             return;
     294                 :         }
     295                 : 
     296               1 :         RET_IF_FAIL(assertMinCol(11));
     297                 : 
     298               1 :         pszAptICAO = papszTokens[8];
     299               1 :         pszRwyNum = papszTokens[9];
     300               1 :         pszSubType = papszTokens[10];
     301                 : 
     302               1 :         if (EQUAL(pszSubType, "GS") )
     303                 :         {
     304               1 :             if (poGSLayer)
     305                 :                 poGSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum,
     306                 :                                         dfLat, dfLon,
     307               1 :                                         dfElevation, dfFrequency, dfRange, dfTrueHeading, dfSlope);
     308                 :         }
     309                 :         else
     310                 :         {
     311                 :             CPLDebug("XPlane", "Line %d : invalid glideslope subtype: '%s'",
     312               0 :                     nLineNumber, pszSubType);
     313               0 :             return;
     314                 :         }
     315                 :     }
     316              13 :     else if (nType == NAVAID_OM || nType == NAVAID_MM || nType == NAVAID_IM)
     317                 :     {
     318                 :         const char* pszAptICAO, * pszRwyNum, * pszSubType;
     319                 : 
     320               3 :         RET_IF_FAIL(readDoubleWithBounds(&dfTrueHeading, 6, "true heading", 0., 360.));
     321                 : 
     322               3 :         RET_IF_FAIL(assertMinCol(11));
     323                 : 
     324               3 :         pszAptICAO = papszTokens[8];
     325               3 :         pszRwyNum = papszTokens[9];
     326               3 :         pszSubType = papszTokens[10];
     327                 : 
     328               3 :         if (EQUAL(pszSubType, "OM") ||
     329                 :             EQUAL(pszSubType, "MM") ||
     330                 :             EQUAL(pszSubType, "IM") )
     331                 :         {
     332               3 :             if (poMarkerLayer)
     333                 :                 poMarkerLayer->AddFeature(pszAptICAO, pszRwyNum, pszSubType,
     334                 :                                             dfLat, dfLon,
     335               3 :                                             dfElevation, dfTrueHeading);
     336                 :         }
     337                 :         else
     338                 :         {
     339                 :             CPLDebug("XPlane", "Line %d : invalid localizer marker subtype: '%s'",
     340               0 :                     nLineNumber, pszSubType);
     341               0 :             return;
     342                 :         }
     343                 :     }
     344              14 :     else if (nType == NAVAID_DME_COLOC || nType == NAVAID_DME_STANDALONE)
     345                 :     {
     346               7 :         const char* pszSubType = "";
     347               7 :         CPLString osNavaidName;
     348                 : 
     349               7 :         RET_IF_FAIL(readDouble(&dfDMEBias, 6, "DME bias"));
     350               7 :         dfDMEBias *= NM_TO_KM;
     351                 : 
     352               7 :         if (EQUAL(papszTokens[nTokens-1], "DME-ILS"))
     353                 :         {
     354                 :             char* pszAptICAO, * pszRwyNum, * pszSubType;
     355               1 :             if (nTokens != 11)
     356                 :             {
     357                 :                 CPLDebug("XPlane", "Line %d : not enough columns : %d",
     358               0 :                         nLineNumber, nTokens);
     359                 :                 return;
     360                 :             }
     361                 : 
     362               1 :             pszAptICAO = papszTokens[8];
     363               1 :             pszRwyNum = papszTokens[9];
     364               1 :             pszSubType = papszTokens[10];
     365                 : 
     366               1 :             if (poDMEILSLayer)
     367                 :                 poDMEILSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum,
     368                 :                                             dfLat, dfLon,
     369               1 :                                             dfElevation, dfFrequency, dfRange, dfDMEBias);
     370                 :         }
     371                 :         else
     372                 :         {
     373               6 :             if (EQUAL(papszTokens[nTokens-1], "DME"))
     374                 :             {
     375               6 :                 nTokens--;
     376              17 :                 if (EQUAL(papszTokens[nTokens-1], "VORTAC") ||
     377               5 :                     EQUAL(papszTokens[nTokens-1], "VOR-DME") ||
     378               4 :                     EQUAL(papszTokens[nTokens-1], "TACAN") ||
     379               2 :                     EQUAL(papszTokens[nTokens-1], "NDB-DME"))
     380                 :                 {
     381               5 :                     pszSubType = papszTokens[nTokens-1];
     382               5 :                     nTokens--;
     383                 :                 }
     384                 :             }
     385                 :             else
     386                 :             {
     387                 :                 CPLDebug("XPlane", "Line %d : Unexpected DME subtype : %s",
     388               0 :                             nLineNumber, papszTokens[nTokens-1]);
     389                 :             }
     390                 : 
     391               6 :             osNavaidName = readStringUntilEnd(8);
     392                 : 
     393               6 :             if (poDMELayer)
     394                 :                 poDMELayer->AddFeature(pszNavaidId, osNavaidName, pszSubType,
     395                 :                                         dfLat, dfLon,
     396               6 :                                         dfElevation, dfFrequency, dfRange, dfDMEBias);
     397               0 :         }
     398                 :     }
     399                 :     else
     400                 :     {
     401               0 :         CPLAssert(0);
     402                 :     }
     403                 : 
     404                 : }
     405                 : 
     406                 : 
     407                 : /************************************************************************/
     408                 : /*                           OGRXPlaneILSLayer()                        */
     409                 : /************************************************************************/
     410                 : 
     411               1 : OGRXPlaneILSLayer::OGRXPlaneILSLayer() : OGRXPlaneLayer("ILS")
     412                 : {
     413               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     414                 : 
     415               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     416               1 :     oFieldID.SetWidth( 4 );
     417               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     418                 : 
     419               1 :     OGRFieldDefn oFieldAptICAO("apt_icao", OFTString );
     420               1 :     oFieldAptICAO.SetWidth( 4 );
     421               1 :     poFeatureDefn->AddFieldDefn( &oFieldAptICAO );
     422                 : 
     423               1 :     OGRFieldDefn oFieldRwyNum("rwy_num", OFTString );
     424               1 :     oFieldRwyNum.SetWidth( 3 );
     425               1 :     poFeatureDefn->AddFieldDefn( &oFieldRwyNum );
     426                 : 
     427               1 :     OGRFieldDefn oFieldSubType("subtype", OFTString );
     428               1 :     oFieldSubType.SetWidth( 10 );
     429               1 :     poFeatureDefn->AddFieldDefn( &oFieldSubType );
     430                 : 
     431               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     432               1 :     oFieldElev.SetWidth( 8 );
     433               1 :     oFieldElev.SetPrecision( 2 );
     434               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     435                 : 
     436               1 :     OGRFieldDefn oFieldFreq("freq_mhz", OFTReal );
     437               1 :     oFieldFreq.SetWidth( 7 );
     438               1 :     oFieldFreq.SetPrecision( 3 );
     439               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     440                 : 
     441               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     442               1 :     oFieldRange.SetWidth( 7 );
     443               1 :     oFieldRange.SetPrecision( 3 );
     444               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     445                 : 
     446               1 :     OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal );
     447               1 :     oFieldTrueHeading.SetWidth( 6 );
     448               1 :     oFieldTrueHeading.SetPrecision( 2 );
     449               1 :     poFeatureDefn->AddFieldDefn( &oFieldTrueHeading );
     450               1 : }
     451                 : 
     452                 : /************************************************************************/
     453                 : /*                           AddFeature()                               */
     454                 : /************************************************************************/
     455                 : 
     456                 : OGRFeature*
     457               6 :      OGRXPlaneILSLayer::AddFeature(const char* pszNavaidID,
     458                 :                                    const char* pszAptICAO,
     459                 :                                    const char* pszRwyNum,
     460                 :                                    const char* pszSubType,
     461                 :                                    double dfLat,
     462                 :                                    double dfLon,
     463                 :                                    double dfEle,
     464                 :                                    double dfFreq,
     465                 :                                    double dfRange,
     466                 :                                    double dfTrueHeading)
     467                 : {
     468               6 :     int nCount = 0;
     469               6 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     470              12 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     471               6 :     poFeature->SetField( nCount++, pszNavaidID );
     472               6 :     poFeature->SetField( nCount++, pszAptICAO );
     473               6 :     poFeature->SetField( nCount++, pszRwyNum );
     474               6 :     poFeature->SetField( nCount++, pszSubType );
     475               6 :     poFeature->SetField( nCount++, dfEle );
     476               6 :     poFeature->SetField( nCount++, dfFreq );
     477               6 :     poFeature->SetField( nCount++, dfRange );
     478               6 :     poFeature->SetField( nCount++, dfTrueHeading );
     479                 : 
     480               6 :     RegisterFeature(poFeature);
     481                 : 
     482               6 :     return poFeature;
     483                 : }
     484                 : 
     485                 : /************************************************************************/
     486                 : /*                           OGRXPlaneVORLayer()                        */
     487                 : /************************************************************************/
     488                 : 
     489                 : 
     490               1 : OGRXPlaneVORLayer::OGRXPlaneVORLayer() : OGRXPlaneLayer("VOR")
     491                 : {
     492               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     493                 : 
     494               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     495               1 :     oFieldID.SetWidth( 4 );
     496               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     497                 : 
     498               1 :     OGRFieldDefn oFieldName("navaid_name", OFTString );
     499               1 :     poFeatureDefn->AddFieldDefn( &oFieldName );
     500                 : 
     501               1 :     OGRFieldDefn oFieldSubType("subtype", OFTString );
     502               1 :     oFieldSubType.SetWidth( 10 );
     503               1 :     poFeatureDefn->AddFieldDefn( &oFieldSubType );
     504                 : 
     505               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     506               1 :     oFieldElev.SetWidth( 8 );
     507               1 :     oFieldElev.SetPrecision( 2 );
     508               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     509                 : 
     510               1 :     OGRFieldDefn oFieldFreq("freq_mhz", OFTReal );
     511               1 :     oFieldFreq.SetWidth( 7 );
     512               1 :     oFieldFreq.SetPrecision( 3 );
     513               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     514                 : 
     515               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     516               1 :     oFieldRange.SetWidth( 7 );
     517               1 :     oFieldRange.SetPrecision( 3 );
     518               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     519                 : 
     520               1 :     OGRFieldDefn oFieldSlavedVariation("slaved_variation_deg", OFTReal );
     521               1 :     oFieldSlavedVariation.SetWidth( 6 );
     522               1 :     oFieldSlavedVariation.SetPrecision( 2 );
     523               1 :     poFeatureDefn->AddFieldDefn( &oFieldSlavedVariation );
     524               1 : }
     525                 : 
     526                 : /************************************************************************/
     527                 : /*                           AddFeature()                               */
     528                 : /************************************************************************/
     529                 : 
     530                 : OGRFeature*
     531               3 :      OGRXPlaneVORLayer::AddFeature(const char* pszNavaidID,
     532                 :                                    const char* pszNavaidName,
     533                 :                                    const char* pszSubType,
     534                 :                                    double dfLat,
     535                 :                                    double dfLon,
     536                 :                                    double dfEle,
     537                 :                                    double dfFreq,
     538                 :                                    double dfRange,
     539                 :                                    double dfSlavedVariation)
     540                 : {
     541               3 :     int nCount = 0;
     542               3 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     543               6 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     544               3 :     poFeature->SetField( nCount++, pszNavaidID );
     545               3 :     poFeature->SetField( nCount++, pszNavaidName );
     546               3 :     poFeature->SetField( nCount++, pszSubType );
     547               3 :     poFeature->SetField( nCount++, dfEle );
     548               3 :     poFeature->SetField( nCount++, dfFreq );
     549               3 :     poFeature->SetField( nCount++, dfRange );
     550               3 :     poFeature->SetField( nCount++, dfSlavedVariation );
     551                 : 
     552               3 :     RegisterFeature(poFeature);
     553                 : 
     554               3 :     return poFeature;
     555                 : }
     556                 : 
     557                 : /************************************************************************/
     558                 : /*                           OGRXPlaneNDBLayer()                        */
     559                 : /************************************************************************/
     560                 : 
     561               1 : OGRXPlaneNDBLayer::OGRXPlaneNDBLayer() : OGRXPlaneLayer("NDB")
     562                 : {
     563               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     564                 : 
     565               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     566               1 :     oFieldID.SetWidth( 4 );
     567               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     568                 : 
     569               1 :     OGRFieldDefn oFieldName("navaid_name", OFTString );
     570               1 :     poFeatureDefn->AddFieldDefn( &oFieldName );
     571                 : 
     572               1 :     OGRFieldDefn oFieldSubType("subtype", OFTString );
     573               1 :     oFieldSubType.SetWidth( 10 );
     574               1 :     poFeatureDefn->AddFieldDefn( &oFieldSubType );
     575                 : 
     576               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     577               1 :     oFieldElev.SetWidth( 8 );
     578               1 :     oFieldElev.SetPrecision( 2 );
     579               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     580                 : 
     581               1 :     OGRFieldDefn oFieldFreq("freq_khz", OFTReal );
     582               1 :     oFieldFreq.SetWidth( 7 );
     583               1 :     oFieldFreq.SetPrecision( 3 );
     584               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     585                 : 
     586               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     587               1 :     oFieldRange.SetWidth( 7 );
     588               1 :     oFieldRange.SetPrecision( 3 );
     589               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     590               1 : }
     591                 : 
     592                 : /************************************************************************/
     593                 : /*                           AddFeature()                               */
     594                 : /************************************************************************/
     595                 : 
     596                 : OGRFeature*
     597               4 :      OGRXPlaneNDBLayer::AddFeature(const char* pszNavaidID,
     598                 :                                    const char* pszNavaidName,
     599                 :                                    const char* pszSubType,
     600                 :                                    double dfLat,
     601                 :                                    double dfLon,
     602                 :                                    double dfEle,
     603                 :                                    double dfFreq,
     604                 :                                    double dfRange)
     605                 : {
     606               4 :     int nCount = 0;
     607               4 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     608               8 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     609               4 :     poFeature->SetField( nCount++, pszNavaidID );
     610               4 :     poFeature->SetField( nCount++, pszNavaidName );
     611               4 :     poFeature->SetField( nCount++, pszSubType );
     612               4 :     poFeature->SetField( nCount++, dfEle );
     613               4 :     poFeature->SetField( nCount++, dfFreq );
     614               4 :     poFeature->SetField( nCount++, dfRange );
     615                 : 
     616               4 :     RegisterFeature(poFeature);
     617                 : 
     618               4 :     return poFeature;
     619                 : }
     620                 : 
     621                 : /************************************************************************/
     622                 : /*                           OGRXPlaneGSLayer                          */
     623                 : /************************************************************************/
     624                 : 
     625               1 : OGRXPlaneGSLayer::OGRXPlaneGSLayer() : OGRXPlaneLayer("GS")
     626                 : {
     627               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     628                 : 
     629               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     630               1 :     oFieldID.SetWidth( 4 );
     631               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     632                 : 
     633               1 :     OGRFieldDefn oFieldAptICAO("apt_icao", OFTString );
     634               1 :     oFieldAptICAO.SetWidth( 4 );
     635               1 :     poFeatureDefn->AddFieldDefn( &oFieldAptICAO );
     636                 : 
     637               1 :     OGRFieldDefn oFieldRwyNum("rwy_num", OFTString );
     638               1 :     oFieldRwyNum.SetWidth( 3 );
     639               1 :     poFeatureDefn->AddFieldDefn( &oFieldRwyNum );
     640                 : 
     641               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     642               1 :     oFieldElev.SetWidth( 8 );
     643               1 :     oFieldElev.SetPrecision( 2 );
     644               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     645                 : 
     646               1 :     OGRFieldDefn oFieldFreq("freq_mhz", OFTReal );
     647               1 :     oFieldFreq.SetWidth( 7 );
     648               1 :     oFieldFreq.SetPrecision( 3 );
     649               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     650                 : 
     651               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     652               1 :     oFieldRange.SetWidth( 7 );
     653               1 :     oFieldRange.SetPrecision( 3 );
     654               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     655                 : 
     656               1 :     OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal );
     657               1 :     oFieldTrueHeading.SetWidth( 6 );
     658               1 :     oFieldTrueHeading.SetPrecision( 2 );
     659               1 :     poFeatureDefn->AddFieldDefn( &oFieldTrueHeading );
     660                 : 
     661               1 :     OGRFieldDefn oFieldGlideSlope("glide_slope", OFTReal );
     662               1 :     oFieldGlideSlope.SetWidth( 6 );
     663               1 :     oFieldGlideSlope.SetPrecision( 2 );
     664               1 :     poFeatureDefn->AddFieldDefn( &oFieldGlideSlope );
     665               1 : }
     666                 : 
     667                 : /************************************************************************/
     668                 : /*                           AddFeature()                               */
     669                 : /************************************************************************/
     670                 : 
     671                 : OGRFeature*
     672               1 :      OGRXPlaneGSLayer::AddFeature(const char* pszNavaidID,
     673                 :                                    const char* pszAptICAO,
     674                 :                                    const char* pszRwyNum,
     675                 :                                    double dfLat,
     676                 :                                    double dfLon,
     677                 :                                    double dfEle,
     678                 :                                    double dfFreq,
     679                 :                                    double dfRange,
     680                 :                                    double dfTrueHeading,
     681                 :                                    double dfSlope)
     682                 : {
     683               1 :     int nCount = 0;
     684               1 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     685               2 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     686               1 :     poFeature->SetField( nCount++, pszNavaidID );
     687               1 :     poFeature->SetField( nCount++, pszAptICAO );
     688               1 :     poFeature->SetField( nCount++, pszRwyNum );
     689               1 :     poFeature->SetField( nCount++, dfEle );
     690               1 :     poFeature->SetField( nCount++, dfFreq );
     691               1 :     poFeature->SetField( nCount++, dfRange );
     692               1 :     poFeature->SetField( nCount++, dfTrueHeading );
     693               1 :     poFeature->SetField( nCount++, dfSlope );
     694                 : 
     695               1 :     RegisterFeature(poFeature);
     696                 : 
     697               1 :     return poFeature;
     698                 : }
     699                 : 
     700                 : 
     701                 : /************************************************************************/
     702                 : /*                         OGRXPlaneMarkerLayer                         */
     703                 : /************************************************************************/
     704                 : 
     705               1 : OGRXPlaneMarkerLayer::OGRXPlaneMarkerLayer() : OGRXPlaneLayer("Marker")
     706                 : {
     707               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     708                 : 
     709               1 :     OGRFieldDefn oFieldAptICAO("apt_icao", OFTString );
     710               1 :     oFieldAptICAO.SetWidth( 4 );
     711               1 :     poFeatureDefn->AddFieldDefn( &oFieldAptICAO );
     712                 : 
     713               1 :     OGRFieldDefn oFieldRwyNum("rwy_num", OFTString );
     714               1 :     oFieldRwyNum.SetWidth( 3 );
     715               1 :     poFeatureDefn->AddFieldDefn( &oFieldRwyNum );
     716                 : 
     717               1 :     OGRFieldDefn oFieldSubType("subtype", OFTString );
     718               1 :     oFieldSubType.SetWidth( 10 );
     719               1 :     poFeatureDefn->AddFieldDefn( &oFieldSubType );
     720                 : 
     721               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     722               1 :     oFieldElev.SetWidth( 8 );
     723               1 :     oFieldElev.SetPrecision( 2 );
     724               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     725                 : 
     726               1 :     OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal );
     727               1 :     oFieldTrueHeading.SetWidth( 6 );
     728               1 :     oFieldTrueHeading.SetPrecision( 2 );
     729               1 :     poFeatureDefn->AddFieldDefn( &oFieldTrueHeading );
     730               1 : }
     731                 : 
     732                 : /************************************************************************/
     733                 : /*                           AddFeature()                               */
     734                 : /************************************************************************/
     735                 : 
     736                 : OGRFeature*
     737               3 :      OGRXPlaneMarkerLayer::AddFeature(const char* pszAptICAO,
     738                 :                                       const char* pszRwyNum,
     739                 :                                       const char* pszSubType,
     740                 :                                       double dfLat,
     741                 :                                       double dfLon,
     742                 :                                       double dfEle,
     743                 :                                       double dfTrueHeading)
     744                 : {
     745               3 :     int nCount = 0;
     746               3 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     747               6 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     748               3 :     poFeature->SetField( nCount++, pszAptICAO );
     749               3 :     poFeature->SetField( nCount++, pszRwyNum );
     750               3 :     poFeature->SetField( nCount++, pszSubType );
     751               3 :     poFeature->SetField( nCount++, dfEle );
     752               3 :     poFeature->SetField( nCount++, dfTrueHeading );
     753                 : 
     754               3 :     RegisterFeature(poFeature);
     755                 : 
     756               3 :     return poFeature;
     757                 : }
     758                 : 
     759                 : /************************************************************************/
     760                 : /*                           OGRXPlaneDMEILSLayer                          */
     761                 : /************************************************************************/
     762                 : 
     763               1 : OGRXPlaneDMEILSLayer::OGRXPlaneDMEILSLayer() : OGRXPlaneLayer("DMEILS")
     764                 : {
     765               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     766                 : 
     767               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     768               1 :     oFieldID.SetWidth( 4 );
     769               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     770                 : 
     771               1 :     OGRFieldDefn oFieldAptICAO("apt_icao", OFTString );
     772               1 :     oFieldAptICAO.SetWidth( 4 );
     773               1 :     poFeatureDefn->AddFieldDefn( &oFieldAptICAO );
     774                 : 
     775               1 :     OGRFieldDefn oFieldRwyNum("rwy_num", OFTString );
     776               1 :     oFieldRwyNum.SetWidth( 3 );
     777               1 :     poFeatureDefn->AddFieldDefn( &oFieldRwyNum );
     778                 : 
     779               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     780               1 :     oFieldElev.SetWidth( 8 );
     781               1 :     oFieldElev.SetPrecision( 2 );
     782               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     783                 : 
     784               1 :     OGRFieldDefn oFieldFreq("freq_mhz", OFTReal );
     785               1 :     oFieldFreq.SetWidth( 7 );
     786               1 :     oFieldFreq.SetPrecision( 3 );
     787               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     788                 : 
     789               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     790               1 :     oFieldRange.SetWidth( 7 );
     791               1 :     oFieldRange.SetPrecision( 3 );
     792               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     793                 : 
     794               1 :     OGRFieldDefn oFieldBias("bias_km", OFTReal );
     795               1 :     oFieldBias.SetWidth( 6 );
     796               1 :     oFieldBias.SetPrecision( 2 );
     797               1 :     poFeatureDefn->AddFieldDefn( &oFieldBias );
     798               1 : }
     799                 : 
     800                 : /************************************************************************/
     801                 : /*                           AddFeature()                               */
     802                 : /************************************************************************/
     803                 : 
     804                 : OGRFeature*
     805               1 :       OGRXPlaneDMEILSLayer::AddFeature(const char* pszNavaidID,
     806                 :                                       const char* pszAptICAO,
     807                 :                                       const char* pszRwyNum,
     808                 :                                       double dfLat,
     809                 :                                       double dfLon,
     810                 :                                       double dfEle,
     811                 :                                       double dfFreq,
     812                 :                                       double dfRange,
     813                 :                                       double dfBias)
     814                 : {
     815               1 :     int nCount = 0;
     816               1 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     817               2 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     818               1 :     poFeature->SetField( nCount++, pszNavaidID );
     819               1 :     poFeature->SetField( nCount++, pszAptICAO );
     820               1 :     poFeature->SetField( nCount++, pszRwyNum );
     821               1 :     poFeature->SetField( nCount++, dfEle );
     822               1 :     poFeature->SetField( nCount++, dfFreq );
     823               1 :     poFeature->SetField( nCount++, dfRange );
     824               1 :     poFeature->SetField( nCount++, dfBias );
     825                 : 
     826               1 :     RegisterFeature(poFeature);
     827                 : 
     828               1 :     return poFeature;
     829                 : }
     830                 : 
     831                 : /************************************************************************/
     832                 : /*                           OGRXPlaneDMELayer                          */
     833                 : /************************************************************************/
     834                 : 
     835                 : 
     836               1 : OGRXPlaneDMELayer::OGRXPlaneDMELayer() : OGRXPlaneLayer("DME")
     837                 : {
     838               1 :     poFeatureDefn->SetGeomType( wkbPoint );
     839                 : 
     840               1 :     OGRFieldDefn oFieldID("navaid_id", OFTString );
     841               1 :     oFieldID.SetWidth( 4 );
     842               1 :     poFeatureDefn->AddFieldDefn( &oFieldID );
     843                 : 
     844               1 :     OGRFieldDefn oFieldName("navaid_name", OFTString );
     845               1 :     poFeatureDefn->AddFieldDefn( &oFieldName );
     846                 : 
     847               1 :     OGRFieldDefn oFieldSubType("subtype", OFTString );
     848               1 :     oFieldSubType.SetWidth( 10 );
     849               1 :     poFeatureDefn->AddFieldDefn( &oFieldSubType );
     850                 : 
     851               1 :     OGRFieldDefn oFieldElev("elevation_m", OFTReal );
     852               1 :     oFieldElev.SetWidth( 8 );
     853               1 :     oFieldElev.SetPrecision( 2 );
     854               1 :     poFeatureDefn->AddFieldDefn( &oFieldElev );
     855                 : 
     856               1 :     OGRFieldDefn oFieldFreq("freq_mhz", OFTReal );
     857               1 :     oFieldFreq.SetWidth( 7 );
     858               1 :     oFieldFreq.SetPrecision( 3 );
     859               1 :     poFeatureDefn->AddFieldDefn( &oFieldFreq );
     860                 : 
     861               1 :     OGRFieldDefn oFieldRange("range_km", OFTReal );
     862               1 :     oFieldRange.SetWidth( 7 );
     863               1 :     oFieldRange.SetPrecision( 3 );
     864               1 :     poFeatureDefn->AddFieldDefn( &oFieldRange );
     865                 : 
     866               1 :     OGRFieldDefn oFieldBias("bias_km", OFTReal );
     867               1 :     oFieldBias.SetWidth( 6 );
     868               1 :     oFieldBias.SetPrecision( 2 );
     869               1 :     poFeatureDefn->AddFieldDefn( &oFieldBias );
     870               1 : }
     871                 : 
     872                 : /************************************************************************/
     873                 : /*                           AddFeature()                               */
     874                 : /************************************************************************/
     875                 : 
     876                 : OGRFeature*
     877               6 :      OGRXPlaneDMELayer::AddFeature(const char* pszNavaidID,
     878                 :                                    const char* pszNavaidName,
     879                 :                                    const char* pszSubType,
     880                 :                                    double dfLat,
     881                 :                                    double dfLon,
     882                 :                                    double dfEle,
     883                 :                                    double dfFreq,
     884                 :                                    double dfRange,
     885                 :                                    double dfBias)
     886                 : {
     887               6 :     int nCount = 0;
     888               6 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     889              12 :     poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
     890               6 :     poFeature->SetField( nCount++, pszNavaidID );
     891               6 :     poFeature->SetField( nCount++, pszNavaidName );
     892               6 :     poFeature->SetField( nCount++, pszSubType );
     893               6 :     poFeature->SetField( nCount++, dfEle );
     894               6 :     poFeature->SetField( nCount++, dfFreq );
     895               6 :     poFeature->SetField( nCount++, dfRange );
     896               6 :     poFeature->SetField( nCount++, dfBias );
     897                 : 
     898               6 :     RegisterFeature(poFeature);
     899                 : 
     900               6 :     return poFeature;
     901                 : }

Generated by: LCOV version 1.7