double stopway2 = atof( stop[1].c_str() );
int surface_code = atoi( token[10].c_str() );
-
- FGRunway* rwy = new FGRunway(NULL, rwy_no, lon, lat, heading, length,
+ SGGeod pos(SGGeod::fromDegFt(lon, lat, 0.0));
+ FGRunway* rwy = new FGRunway(NULL, rwy_no, pos, heading, length,
width, displ_thresh1, stopway1, surface_code, false);
-
- FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no),
- lon, lat, heading + 180.0, length, width,
- displ_thresh2, stopway2, surface_code, true);
runways.push_back(rwy);
- runways.push_back(reciprocal);
+ if (rwy_no[0] != 'x') {
+ // runways need a reciprocal, taxiways do not
+ FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no),
+ pos, heading + 180.0, length, width,
+ displ_thresh2, stopway2, surface_code, true);
+
+ runways.push_back(reciprocal);
+ }
} else if ( line_id == 18 ) {
// beacon entry (ignore)
} else if ( line_id == 14 ) {
}
FGRunway::FGRunway(FGAirport* aAirport, const string& rwy_no,
- const double longitude, const double latitude,
+ const SGGeod& aGeod,
const double heading, const double length,
const double width,
const double displ_thresh,
const double stopway,
const int surface_code,
bool reciprocal) :
- FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), latitude, longitude, 0.0),
+ FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), aGeod,
+ (runwayTypeFromNumber(rwy_no) == FGPositioned::RUNWAY)),
_airport(aAirport),
_reciprocal(reciprocal)
{
- _rwy_no = ident();
-
- _lon = longitude;
- _lat = latitude;
_heading = heading;
_length = length;
_width = width;
public:
FGRunway(FGAirport* aAirport, const std::string& rwy_no,
- const double longitude, const double latitude,
+ const SGGeod& aGeod,
const double heading, const double length,
const double width,
const double displ_thresh,
int surface() const
{ return _surface_code; }
- std::string _rwy_no;
+ double _displ_thresh;
+ double _stopway;
- double _lon;
- double _lat;
- double _displ_thresh;
- double _stopway;
-
- double _heading;
- double _length;
- double _width;
-
- int _surface_code;
+ double _heading;
+ double _length;
+ double _width;
+
+ int _surface_code;
};
#endif // _FG_RUNWAYS_HXX
double length = runway->lengthM() * 0.5;
double width = runway->widthM() * 0.5;
double frontLat, frontLon, backLat, backLon,az, tempLat, tempLon;
-
- geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading, length, &backLat, &backLon, &az);
+ double runwayLon = runway->geod().getLongitudeDeg(),
+ runwayLat = runway->geod().getLatitudeDeg();
+ double heading = runway->headingDeg();
+
+ geo_direct_wgs_84(alt, runwayLat, runwayLon, heading, length, &backLat, &backLon, &az);
sgGeodToCart(backLat * SG_DEGREES_TO_RADIANS, backLon * SG_DEGREES_TO_RADIANS, alt, points3d[4]);
- geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading + 180, length, &frontLat, &frontLon, &az);
+ geo_direct_wgs_84(alt, runwayLat, runwayLon, heading + 180, length, &frontLat, &frontLon, &az);
sgGeodToCart(frontLat * SG_DEGREES_TO_RADIANS, frontLon * SG_DEGREES_TO_RADIANS, alt, points3d[5]);
- geo_direct_wgs_84(alt, backLat, backLon, runway->_heading + 90, width, &tempLat, &tempLon, &az);
+ geo_direct_wgs_84(alt, backLat, backLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[0]);
- geo_direct_wgs_84(alt, backLat, backLon, runway->_heading - 90, width, &tempLat, &tempLon, &az);
+ geo_direct_wgs_84(alt, backLat, backLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[1]);
- geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading - 90, width, &tempLat, &tempLon, &az);
+ geo_direct_wgs_84(alt, frontLat, frontLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[2]);
- geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading + 90, width, &tempLat, &tempLon, &az);
+ geo_direct_wgs_84(alt, frontLat, frontLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[3]);
}
Point3D ac(0.0), rwy(0.0);
ac.setlat(current_aircraft.fdm_state->get_Latitude_deg());
ac.setlon(current_aircraft.fdm_state->get_Longitude_deg());
- rwy.setlat(runway->_lat);
- rwy.setlon(runway->_lon);
+ rwy.setlat(runway->latitude());
+ rwy.setlon(runway->longitude());
float theta = GetHeadingFromTo(ac, rwy);
theta -= fgGetDouble("/orientation/heading-deg");
theta = -theta;
if (_runway->_length < mk->conf.runway_database)
return false;
- // get position of threshold
- double latitude, longitude, az;
- geo_direct_wgs_84(0,
- _runway->_lat,
- _runway->_lon,
- get_reciprocal_heading(_runway->_heading),
- _runway->_length / 2 * SG_FEET_TO_METER,
- &latitude,
- &longitude,
- &az);
-
+ SGGeod pos(
+ SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()));
+
// get distance to threshold
double distance, az1, az2;
- geo_inverse_wgs_84(0,
- mk_data(gps_latitude).get(),
- mk_data(gps_longitude).get(),
- latitude,
- longitude,
- &az1, &az2, &distance);
-
+ SGGeodesy::inverse(pos, _runway->threshold(), az1, az2, distance);
return distance * SG_METER_TO_NM <= 5;
}
{
return get_azimuth_difference(mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
- _runway->_lat,
- _runway->_lon,
- _runway->_heading);
+ _runway->latitude(),
+ _runway->longitude(),
+ _runway->headingDeg());
}
// Selects the most likely intended destination runway of @airport,
return true;
}
-
FGNavRecord *FGNavList::findByFreq( double freq, double lon, double lat, double elev )
{
const nav_list_type& stations = navaids[(int)(freq*100.0 + 0.5)];
}
-nav_list_type FGNavList::findFirstByIdent( const string& ident, fg_nav_types type, bool exact)
-{
- nav_list_type n2;
- n2.clear();
-
- if ((type != FG_NAV_VOR) && (type != FG_NAV_NDB)) {
- return n2;
- }
-
- nav_ident_map_iterator it;
- if(exact) {
- it = ident_navaids.find(ident);
- } else {
- bool typeMatch = false;
- int safety_count = 0;
- it = ident_navaids.lower_bound(ident);
- while(!typeMatch) {
- nav_list_type n0 = it->second;
- // local copy, so we should be able to do anything with n0.
- // Remove the types that don't match request.
- for(nav_list_iterator it0 = n0.begin(); it0 != n0.end();) {
- FGNavRecord* nv = *it0;
- if(nv->type() == type) {
- typeMatch = true;
- ++it0;
- } else {
- it0 = n0.erase(it0);
- }
- }
- if(typeMatch) {
- return(n0);
- }
- if(it == ident_navaids.begin()) {
- // We didn't find a match before reaching the beginning of the map
- n0.clear();
- return(n0);
- }
- safety_count++;
- if(safety_count == 1000000) {
- SG_LOG(SG_INSTR, SG_ALERT,
- "safety_count triggered exit from while loop in findFirstByIdent!");
- break;
- }
- ++it;
- if(it == ident_navaids.end()) {
- n0.clear();
- return(n0);
- }
- }
- }
- if(it == ident_navaids.end()) {
- n2.clear();
- return(n2);
- } else {
- nav_list_type n1 = it->second;
- n2.clear();
- for(nav_list_iterator it2 = n1.begin(); it2 != n1.end(); ++it2) {
- FGNavRecord* nv = *it2;
- if(nv->type() == type) n2.push_back(nv);
- }
- return(n2);
- }
-}
// Given an Ident and optional freqency, return the first matching
// locate closest item in the DB matching the requested ident
FGNavRecord *findByIdent( const char* ident, const double lon, const double lat );
- // Find items of requested type with closest exact or subsequent ident
- // (by ASCII code value) to that supplied.
- // Supplying true for exact forces only exact matches to be returned (similar to above function)
- // Returns an empty list if no match found - calling function should check for this!
- nav_list_type findFirstByIdent( const string& ident, FGPositioned::Type type, bool exact = false );
-
// Given an Ident and optional freqency, return the first matching
// station.
FGNavRecord *findByIdentAndFreq( const char* ident,
#include "Main/fg_props.hxx"
FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent,
- const std::string& aName,
- double lat, double lon, double aElevFt,
+ const std::string& aName, const SGGeod& aPos,
int aFreq, int aRange, double aMultiuse) :
- FGPositioned(aTy, aIdent, lat, lon, aElevFt),
+ FGPositioned(aTy, aIdent, aPos),
freq(aFreq),
range(aRange),
multiuse(aMultiuse),
}
FGNavRecord* result = new FGNavRecord(type, ident,
- simgear::strutils::strip(name),
- lat, lon, elev_ft, freq, range, multiuse);
+ simgear::strutils::strip(name), SGGeod::fromDegFt(lon, lat, elev_ft),
+ freq, range, multiuse);
return result;
}
set_multiuse( aRunway->headingDeg() );
} else {
SG_LOG(SG_GENERAL, SG_WARN, "localizer:" << ident() << ", aligning with runway "
- << aRunway->_rwy_no << " exceeded heading threshold");
+ << aRunway->ident() << " exceeded heading threshold");
}
}
static FGNavRecord* createFromStream(std::istream& aStream);
FGNavRecord(Type type, const std::string& ident, const std::string& name,
- double lat, double lon, double aElevFt,
+ const SGGeod& aPos,
int freq, int range, double multiuse);
inline double get_lon() const { return longitude(); } // degrees
addToIndices(FGPositioned* aPos)
{
assert(aPos);
- global_namedIndex.insert(global_namedIndex.begin(),
- std::make_pair(aPos->ident(), aPos));
+ if (!aPos->ident().empty()) {
+ global_namedIndex.insert(global_namedIndex.begin(),
+ std::make_pair(aPos->ident(), aPos));
+ }
SpatialPositionedIndex::iterator it = bucketEntryForPositioned(aPos);
it->second.insert(aPos);
{
assert(aPos);
- NamedPositionedIndex::iterator it = global_namedIndex.find(aPos->ident());
- while (it != global_namedIndex.end() && (it->first == aPos->ident())) {
- if (it->second == aPos) {
- global_namedIndex.erase(it);
- break;
- }
-
- ++it;
+ if (!aPos->ident().empty()) {
+ NamedPositionedIndex::iterator it = global_namedIndex.find(aPos->ident());
+ while (it != global_namedIndex.end() && (it->first == aPos->ident())) {
+ if (it->second == aPos) {
+ global_namedIndex.erase(it);
+ break;
+ }
+
+ ++it;
+ } // of multimap walk
}
SpatialPositionedIndex::iterator sit = bucketEntryForPositioned(aPos);
NamedPositionedIndex::const_iterator it = range.first;
for (; it != range.second; ++it) {
- // filter by type
- FGPositioned::Type ty = it->second->type();
if (aFilter && !aFilter->pass(range.first->second)) {
continue;
}
// find distance
double d, az1, az2;
- SGGeodesy::inverse(aOrigin, it->second->geod(), az2, az2, d);
+ SGGeodesy::inverse(aOrigin, it->second->geod(), az1, az2, d);
if (d < minDist) {
minDist = d;
result = it->second;
///////////////////////////////////////////////////////////////////////////////
-FGPositioned::FGPositioned(Type ty, const std::string& aIdent, double aLat, double aLon, double aElev) :
- mType(ty),
- mPosition(SGGeod::fromDegFt(aLon, aLat, aElev)),
- mIdent(aIdent)
-{
- addToIndices(this);
- SGReferenced::get(this); // hold an owning ref, for the moment
-}
-
-FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos) :
+FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndexed) :
mType(ty),
mPosition(aPos),
mIdent(aIdent)
-{
- addToIndices(this);
+{
SGReferenced::get(this); // hold an owning ref, for the moment
+
+ if (aIndexed) {
+ assert(ty != TAXIWAY);
+ addToIndices(this);
+ }
}
FGPositioned::~FGPositioned()
*/
static const char* nameForType(Type aTy);
protected:
- FGPositioned(Type ty, const std::string& aIdent, double aLat, double aLon, double aElev);
- FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos);
+ FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndex = true);
- SGGeod mPosition; // can't be const right now
+ // can't be const right now, navrecord at least needs to fix up the position
+ // after navaids are parsed
+ SGGeod mPosition;
- Type mType;
- std::string mIdent;
+ const Type mType;
+ const std::string mIdent;
};
#endif // of FG_POSITIONED_HXX