EVOLUTION-MANAGER
Edit File: ogr_xplane_nav_reader.cpp
/****************************************************************************** * * Project: X-Plane nav.dat file reader * Purpose: Implements OGRXPlaneNavReader class * Author: Even Rouault, even dot rouault at mines dash paris dot org * ****************************************************************************** * Copyright (c) 2008-2011, Even Rouault <even dot rouault at mines-paris dot org> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "ogr_xplane_nav_reader.h" CPL_CVSID("$Id: ogr_xplane_nav_reader.cpp 36061 2016-11-01 02:26:58Z goatbar $"); /************************************************************************/ /* OGRXPlaneCreateNavFileReader */ /************************************************************************/ OGRXPlaneReader* OGRXPlaneCreateNavFileReader( OGRXPlaneDataSource* poDataSource ) { OGRXPlaneReader* poReader = new OGRXPlaneNavReader(poDataSource); return poReader; } /************************************************************************/ /* OGRXPlaneNavReader() */ /************************************************************************/ OGRXPlaneNavReader::OGRXPlaneNavReader() : poILSLayer(NULL), poVORLayer(NULL), poNDBLayer(NULL), poGSLayer(NULL), poMarkerLayer(NULL), poDMELayer(NULL), poDMEILSLayer(NULL) {} /************************************************************************/ /* OGRXPlaneNavReader() */ /************************************************************************/ OGRXPlaneNavReader::OGRXPlaneNavReader( OGRXPlaneDataSource* poDataSource ) : poILSLayer(new OGRXPlaneILSLayer()), poVORLayer(new OGRXPlaneVORLayer()), poNDBLayer(new OGRXPlaneNDBLayer()), poGSLayer(new OGRXPlaneGSLayer()), poMarkerLayer(new OGRXPlaneMarkerLayer()), poDMELayer(new OGRXPlaneDMELayer()), poDMEILSLayer(new OGRXPlaneDMEILSLayer()) { poDataSource->RegisterLayer(poILSLayer); poDataSource->RegisterLayer(poVORLayer); poDataSource->RegisterLayer(poNDBLayer); poDataSource->RegisterLayer(poGSLayer); poDataSource->RegisterLayer(poMarkerLayer); poDataSource->RegisterLayer(poDMELayer); poDataSource->RegisterLayer(poDMEILSLayer); } /************************************************************************/ /* CloneForLayer() */ /************************************************************************/ OGRXPlaneReader* OGRXPlaneNavReader::CloneForLayer(OGRXPlaneLayer* poLayer) { OGRXPlaneNavReader* poReader = new OGRXPlaneNavReader(); poReader->poInterestLayer = poLayer; SET_IF_INTEREST_LAYER(poILSLayer); SET_IF_INTEREST_LAYER(poVORLayer); SET_IF_INTEREST_LAYER(poNDBLayer); SET_IF_INTEREST_LAYER(poGSLayer); SET_IF_INTEREST_LAYER(poMarkerLayer); SET_IF_INTEREST_LAYER(poDMELayer); SET_IF_INTEREST_LAYER(poDMEILSLayer); if (pszFilename) { poReader->pszFilename = CPLStrdup(pszFilename); poReader->fp = VSIFOpenL( pszFilename, "rb" ); } return poReader; } /************************************************************************/ /* IsRecognizedVersion() */ /************************************************************************/ int OGRXPlaneNavReader::IsRecognizedVersion( const char* pszVersionString) { return STARTS_WITH_CI(pszVersionString, "810 Version") || STARTS_WITH_CI(pszVersionString, "740 Version"); } /************************************************************************/ /* Read() */ /************************************************************************/ void OGRXPlaneNavReader::Read() { const char* pszLine = NULL; while( (pszLine = CPLReadLineL(fp)) != NULL ) { papszTokens = CSLTokenizeString(pszLine); nTokens = CSLCount(papszTokens); nLineNumber++; if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0) { CSLDestroy(papszTokens); papszTokens = NULL; bEOF = true; return; } else if( nTokens == 0 || !assertMinCol(9) ) { CSLDestroy(papszTokens); papszTokens = NULL; continue; } const int nType = atoi(papszTokens[0]); if (!((nType >= NAVAID_NDB && nType <= NAVAID_IM) || nType == NAVAID_DME_COLOC || nType == NAVAID_DME_STANDALONE)) { CPLDebug("XPlane", "Line %d : bad feature code '%s'", nLineNumber, papszTokens[0]); CSLDestroy(papszTokens); papszTokens = NULL; continue; } ParseRecord(nType); CSLDestroy(papszTokens); papszTokens = NULL; if( poInterestLayer && !poInterestLayer->IsEmpty() ) return; } papszTokens = NULL; bEOF = true; } /************************************************************************/ /* ParseRecord() */ /************************************************************************/ void OGRXPlaneNavReader::ParseRecord( int nType ) { double dfVal = 0.0; double dfTrueHeading = 0.0; double dfLat = 0.0; double dfLon = 0.0; RET_IF_FAIL(readLatLon(&dfLat, &dfLon, 1)); double dfElevation = 0.0; /* feet to meter */ RET_IF_FAIL(readDoubleWithBoundsAndConversion(&dfElevation, 3, "elevation", FEET_TO_METER, -1000., 10000.)); double dfFrequency = 0.0; RET_IF_FAIL(readDouble(&dfFrequency, 4, "frequency")); /* NDB frequencies are in kHz. Others must be divided by 100 */ /* to get a frequency in MHz */ if (nType != NAVAID_NDB) dfFrequency /= 100.; double dfRange = 0.0; /* nautical miles to kilometer */ RET_IF_FAIL(readDouble(&dfRange, 5, "range")); dfRange *= NM_TO_KM; char* pszNavaidId = papszTokens[7]; if (nType == NAVAID_NDB) { const char* pszSubType = ""; CPLString osNavaidName; if (EQUAL(papszTokens[nTokens-1], "NDB") || EQUAL(papszTokens[nTokens-1], "LOM") || EQUAL(papszTokens[nTokens-1], "NDB-DME")) { pszSubType = papszTokens[nTokens-1]; nTokens--; } else { CPLDebug("XPlane", "Unexpected NDB subtype : %s", papszTokens[nTokens-1]); } osNavaidName = readStringUntilEnd(8); if (poNDBLayer) poNDBLayer->AddFeature(pszNavaidId, osNavaidName, pszSubType, dfLat, dfLon, dfElevation, dfFrequency, dfRange); } else if (nType == NAVAID_VOR) { const char* pszSubType = ""; CPLString osNavaidName; double dfSlavedVariation = 0.0; RET_IF_FAIL(readDoubleWithBounds(&dfSlavedVariation, 6, "slaved variation", -180., 180.)); if (EQUAL(papszTokens[nTokens-1], "VOR") || EQUAL(papszTokens[nTokens-1], "VORTAC") || EQUAL(papszTokens[nTokens-1], "VOR-DME")) { pszSubType = papszTokens[nTokens-1]; nTokens--; } else { CPLDebug("XPlane", "Unexpected VOR subtype : %s", papszTokens[nTokens-1]); } osNavaidName = readStringUntilEnd(8); if (poVORLayer) poVORLayer->AddFeature(pszNavaidId, osNavaidName, pszSubType, dfLat, dfLon, dfElevation, dfFrequency, dfRange, dfSlavedVariation); } else if (nType == NAVAID_LOC_ILS || nType == NAVAID_LOC_STANDALONE) { RET_IF_FAIL(readDoubleWithBounds(&dfTrueHeading, 6, "true heading", 0.0, 360.)); RET_IF_FAIL(assertMinCol(11)); const char *pszAptICAO = papszTokens[8]; const char *pszRwyNum = papszTokens[9]; const char *pszSubType = papszTokens[10]; if (EQUAL(pszSubType, "ILS-cat-I") || EQUAL(pszSubType, "ILS-cat-II") || EQUAL(pszSubType, "ILS-cat-III") || EQUAL(pszSubType, "LOC") || EQUAL(pszSubType, "LDA") || EQUAL(pszSubType, "SDF") || EQUAL(pszSubType, "IGS") || EQUAL(pszSubType, "LDA-GS")) { if (poILSLayer) poILSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum, pszSubType, dfLat, dfLon, dfElevation, dfFrequency, dfRange, dfTrueHeading); } else { CPLDebug("XPlane", "Line %d : invalid localizer subtype: '%s'", nLineNumber, pszSubType); return; } } else if (nType == NAVAID_GS) { RET_IF_FAIL(readDouble(&dfVal, 6, "slope & heading")); const double dfSlope = (int)(dfVal / 1000) / 100.; dfTrueHeading = dfVal - dfSlope * 100000; if (dfTrueHeading < 0 || dfTrueHeading > 360) { CPLDebug("XPlane", "Line %d : invalid true heading '%f'", nLineNumber, dfTrueHeading); return; } RET_IF_FAIL(assertMinCol(11)); const char *pszAptICAO = papszTokens[8]; const char *pszRwyNum = papszTokens[9]; const char *pszSubType = papszTokens[10]; if (EQUAL(pszSubType, "GS") ) { if (poGSLayer) poGSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum, dfLat, dfLon, dfElevation, dfFrequency, dfRange, dfTrueHeading, dfSlope); } else { CPLDebug("XPlane", "Line %d : invalid glideslope subtype: '%s'", nLineNumber, pszSubType); return; } } else if (nType == NAVAID_OM || nType == NAVAID_MM || nType == NAVAID_IM) { const char* pszAptICAO, * pszRwyNum, * pszSubType; RET_IF_FAIL(readDoubleWithBounds(&dfTrueHeading, 6, "true heading", 0.0, 360.0)); RET_IF_FAIL(assertMinCol(11)); pszAptICAO = papszTokens[8]; pszRwyNum = papszTokens[9]; pszSubType = papszTokens[10]; if (EQUAL(pszSubType, "OM") || EQUAL(pszSubType, "MM") || EQUAL(pszSubType, "IM") ) { if (poMarkerLayer) poMarkerLayer->AddFeature(pszAptICAO, pszRwyNum, pszSubType, dfLat, dfLon, dfElevation, dfTrueHeading); } else { CPLDebug("XPlane", "Line %d : invalid localizer marker subtype: '%s'", nLineNumber, pszSubType); return; } } else if (nType == NAVAID_DME_COLOC || nType == NAVAID_DME_STANDALONE) { const char* pszSubType = ""; CPLString osNavaidName; double dfDMEBias = 0.0; RET_IF_FAIL(readDouble(&dfDMEBias, 6, "DME bias")); dfDMEBias *= NM_TO_KM; if (EQUAL(papszTokens[nTokens-1], "DME-ILS")) { char* pszAptICAO, * pszRwyNum /* , * pszSubType */; if (nTokens != 11) { CPLDebug("XPlane", "Line %d : not enough columns : %d", nLineNumber, nTokens); return; } pszAptICAO = papszTokens[8]; pszRwyNum = papszTokens[9]; /* pszSubType = papszTokens[10]; */ if (poDMEILSLayer) poDMEILSLayer->AddFeature(pszNavaidId, pszAptICAO, pszRwyNum, dfLat, dfLon, dfElevation, dfFrequency, dfRange, dfDMEBias); } else { if (EQUAL(papszTokens[nTokens-1], "DME")) { nTokens--; if (EQUAL(papszTokens[nTokens-1], "VORTAC") || EQUAL(papszTokens[nTokens-1], "VOR-DME") || EQUAL(papszTokens[nTokens-1], "TACAN") || EQUAL(papszTokens[nTokens-1], "NDB-DME")) { /* pszSubType = papszTokens[nTokens-1]; */ nTokens--; } } else { CPLDebug("XPlane", "Line %d : Unexpected DME subtype : %s", nLineNumber, papszTokens[nTokens-1]); } osNavaidName = readStringUntilEnd(8); if (poDMELayer) poDMELayer->AddFeature(pszNavaidId, osNavaidName, pszSubType, dfLat, dfLon, dfElevation, dfFrequency, dfRange, dfDMEBias); } } else { CPLAssert(false); } } /************************************************************************/ /* OGRXPlaneILSLayer() */ /************************************************************************/ OGRXPlaneILSLayer::OGRXPlaneILSLayer() : OGRXPlaneLayer("ILS") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldAptICAO("apt_icao", OFTString ); oFieldAptICAO.SetWidth( 5 ); poFeatureDefn->AddFieldDefn( &oFieldAptICAO ); OGRFieldDefn oFieldRwyNum("rwy_num", OFTString ); oFieldRwyNum.SetWidth( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRwyNum ); OGRFieldDefn oFieldSubType("subtype", OFTString ); oFieldSubType.SetWidth( 10 ); poFeatureDefn->AddFieldDefn( &oFieldSubType ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_mhz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal ); oFieldTrueHeading.SetWidth( 6 ); oFieldTrueHeading.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldTrueHeading ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneILSLayer::AddFeature(const char* pszNavaidID, const char* pszAptICAO, const char* pszRwyNum, const char* pszSubType, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange, double dfTrueHeading) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszAptICAO ); poFeature->SetField( nCount++, pszRwyNum ); poFeature->SetField( nCount++, pszSubType ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); poFeature->SetField( nCount++, dfTrueHeading ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneVORLayer() */ /************************************************************************/ OGRXPlaneVORLayer::OGRXPlaneVORLayer() : OGRXPlaneLayer("VOR") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldName("navaid_name", OFTString ); poFeatureDefn->AddFieldDefn( &oFieldName ); OGRFieldDefn oFieldSubType("subtype", OFTString ); oFieldSubType.SetWidth( 10 ); poFeatureDefn->AddFieldDefn( &oFieldSubType ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_mhz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); OGRFieldDefn oFieldSlavedVariation("slaved_variation_deg", OFTReal ); oFieldSlavedVariation.SetWidth( 6 ); oFieldSlavedVariation.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldSlavedVariation ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneVORLayer::AddFeature(const char* pszNavaidID, const char* pszNavaidName, const char* pszSubType, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange, double dfSlavedVariation) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszNavaidName ); poFeature->SetField( nCount++, pszSubType ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); poFeature->SetField( nCount++, dfSlavedVariation ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneNDBLayer() */ /************************************************************************/ OGRXPlaneNDBLayer::OGRXPlaneNDBLayer() : OGRXPlaneLayer("NDB") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldName("navaid_name", OFTString ); poFeatureDefn->AddFieldDefn( &oFieldName ); OGRFieldDefn oFieldSubType("subtype", OFTString ); oFieldSubType.SetWidth( 10 ); poFeatureDefn->AddFieldDefn( &oFieldSubType ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_khz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneNDBLayer::AddFeature(const char* pszNavaidID, const char* pszNavaidName, const char* pszSubType, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszNavaidName ); poFeature->SetField( nCount++, pszSubType ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneGSLayer */ /************************************************************************/ OGRXPlaneGSLayer::OGRXPlaneGSLayer() : OGRXPlaneLayer("GS") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldAptICAO("apt_icao", OFTString ); oFieldAptICAO.SetWidth( 5 ); poFeatureDefn->AddFieldDefn( &oFieldAptICAO ); OGRFieldDefn oFieldRwyNum("rwy_num", OFTString ); oFieldRwyNum.SetWidth( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRwyNum ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_mhz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal ); oFieldTrueHeading.SetWidth( 6 ); oFieldTrueHeading.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldTrueHeading ); OGRFieldDefn oFieldGlideSlope("glide_slope", OFTReal ); oFieldGlideSlope.SetWidth( 6 ); oFieldGlideSlope.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldGlideSlope ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneGSLayer::AddFeature(const char* pszNavaidID, const char* pszAptICAO, const char* pszRwyNum, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange, double dfTrueHeading, double dfSlope) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszAptICAO ); poFeature->SetField( nCount++, pszRwyNum ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); poFeature->SetField( nCount++, dfTrueHeading ); poFeature->SetField( nCount++, dfSlope ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneMarkerLayer */ /************************************************************************/ OGRXPlaneMarkerLayer::OGRXPlaneMarkerLayer() : OGRXPlaneLayer("Marker") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldAptICAO("apt_icao", OFTString ); oFieldAptICAO.SetWidth( 5 ); poFeatureDefn->AddFieldDefn( &oFieldAptICAO ); OGRFieldDefn oFieldRwyNum("rwy_num", OFTString ); oFieldRwyNum.SetWidth( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRwyNum ); OGRFieldDefn oFieldSubType("subtype", OFTString ); oFieldSubType.SetWidth( 10 ); poFeatureDefn->AddFieldDefn( &oFieldSubType ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldTrueHeading("true_heading_deg", OFTReal ); oFieldTrueHeading.SetWidth( 6 ); oFieldTrueHeading.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldTrueHeading ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneMarkerLayer::AddFeature(const char* pszAptICAO, const char* pszRwyNum, const char* pszSubType, double dfLat, double dfLon, double dfEle, double dfTrueHeading) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszAptICAO ); poFeature->SetField( nCount++, pszRwyNum ); poFeature->SetField( nCount++, pszSubType ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfTrueHeading ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneDMEILSLayer */ /************************************************************************/ OGRXPlaneDMEILSLayer::OGRXPlaneDMEILSLayer() : OGRXPlaneLayer("DMEILS") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldAptICAO("apt_icao", OFTString ); oFieldAptICAO.SetWidth( 5 ); poFeatureDefn->AddFieldDefn( &oFieldAptICAO ); OGRFieldDefn oFieldRwyNum("rwy_num", OFTString ); oFieldRwyNum.SetWidth( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRwyNum ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_mhz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); OGRFieldDefn oFieldBias("bias_km", OFTReal ); oFieldBias.SetWidth( 6 ); oFieldBias.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldBias ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneDMEILSLayer::AddFeature(const char* pszNavaidID, const char* pszAptICAO, const char* pszRwyNum, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange, double dfBias) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszAptICAO ); poFeature->SetField( nCount++, pszRwyNum ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); poFeature->SetField( nCount++, dfBias ); RegisterFeature(poFeature); return poFeature; } /************************************************************************/ /* OGRXPlaneDMELayer */ /************************************************************************/ OGRXPlaneDMELayer::OGRXPlaneDMELayer() : OGRXPlaneLayer("DME") { poFeatureDefn->SetGeomType( wkbPoint ); OGRFieldDefn oFieldID("navaid_id", OFTString ); oFieldID.SetWidth( 4 ); poFeatureDefn->AddFieldDefn( &oFieldID ); OGRFieldDefn oFieldName("navaid_name", OFTString ); poFeatureDefn->AddFieldDefn( &oFieldName ); OGRFieldDefn oFieldSubType("subtype", OFTString ); oFieldSubType.SetWidth( 10 ); poFeatureDefn->AddFieldDefn( &oFieldSubType ); OGRFieldDefn oFieldElev("elevation_m", OFTReal ); oFieldElev.SetWidth( 8 ); oFieldElev.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldElev ); OGRFieldDefn oFieldFreq("freq_mhz", OFTReal ); oFieldFreq.SetWidth( 7 ); oFieldFreq.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldFreq ); OGRFieldDefn oFieldRange("range_km", OFTReal ); oFieldRange.SetWidth( 7 ); oFieldRange.SetPrecision( 3 ); poFeatureDefn->AddFieldDefn( &oFieldRange ); OGRFieldDefn oFieldBias("bias_km", OFTReal ); oFieldBias.SetWidth( 6 ); oFieldBias.SetPrecision( 2 ); poFeatureDefn->AddFieldDefn( &oFieldBias ); } /************************************************************************/ /* AddFeature() */ /************************************************************************/ OGRFeature* OGRXPlaneDMELayer::AddFeature(const char* pszNavaidID, const char* pszNavaidName, const char* pszSubType, double dfLat, double dfLon, double dfEle, double dfFreq, double dfRange, double dfBias) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) ); poFeature->SetField( nCount++, pszNavaidID ); poFeature->SetField( nCount++, pszNavaidName ); poFeature->SetField( nCount++, pszSubType ); poFeature->SetField( nCount++, dfEle ); poFeature->SetField( nCount++, dfFreq ); poFeature->SetField( nCount++, dfRange ); poFeature->SetField( nCount++, dfBias ); RegisterFeature(poFeature); return poFeature; }