31#include <simgear/debug/logstream.hxx>
32#include <simgear/math/sg_geodesy.hxx>
33#include <simgear/sg_inlines.h>
45class NavRecordDistanceSortPredicate
48 NavRecordDistanceSortPredicate(
const SGGeod & position ) :
49 _position(SGVec3d::fromGeod(position)) {}
53 if( n1 == NULL || n2 == NULL )
return false;
54 return distSqr(n1->cart(), _position) < distSqr(n2->cart(), _position);
64bool navidUsable(
FGNavRecord* aNav,
const SGGeod &aircraft)
67 if (!r || !r->reciprocalRunway()) {
83 double crs = SGGeodesy::courseDeg(aircraft, r->geod());
84 double hdgDiff = crs - r->headingDeg();
85 SG_NORMALIZE_RANGE(hdgDiff, -180.0, 180.0);
86 return (fabs(hdgDiff) < 90.0);
151 string::size_type loc1 = pos->
name().find(
"TACAN" );
152 string::size_type loc2 = pos->
name().find(
"VORTAC" );
153 return (loc1 != string::npos) || (loc2 != string::npos);
188 const SGGeod& position,
192 int freqKhz =
static_cast<int>(freq * 100 + 0.5);
194 if (stations.empty()) {
199 SGVec3d acCart(SGVec3d::fromGeod(position));
203 for (
auto id : stations) {
205 if (filter && !filter->
pass(station)) {
209 double d2 = distSqr(station->cart(), acCart);
216 if (navidUsable(station, position)) {
228 int freqKhz =
static_cast<int>(freq * 100 + 0.5);
230 if (stations.empty()) {
234 for (
auto id : stations) {
236 if (filter->
pass(station)) {
252 int f =
static_cast<int>(freq * 100 + 0.5);
257 if (!filter->
pass(station)) {
261 stations.push_back(station);
271 int f = (int)(freq*100.0 + 0.5);
274 for (
auto ref : stations) {
276 if ( f <= 0.0 || nav->get_freq() == f) {
277 reply.push_back( nav );
287 const std::string& ident,
const double freq,
291 NavRecordDistanceSortPredicate sortPredicate( position );
292 std::sort( reply.begin(), reply.end(), sortPredicate );
331 int tfreq = frequency_kHz / 10;
332 for (tacan_ident_map_type::iterator it = ident_channels.begin(); it != ident_channels.end(); it++)
334 for (tacan_list_type::iterator lit = it->second.begin(); lit != it->second.end(); lit++)
335 if ((*lit)->get_freq() == tfreq)
344 SG_LOG( SG_NAVAID, SG_DEBUG,
"findByChannel " << channel<<
" size " << stations.size() );
346 if (!stations.empty()) {
virtual FGPositioned::Type minType() const
TypeFilter(const FGPositioned::Type type=FGPositioned::INVALID)
virtual FGPositioned::Type maxType() const
FGPositioned::Type _mintype
bool fromTypeString(const std::string &type)
Construct from string containing type.
FGPositioned::Type _maxtype
static TypeFilter * locFilter()
filter matching ILS/LOC transmitter
static FGNavRecordRef findByFreq(double freq, const SGGeod &position, TypeFilter *filter=nullptr)
Query the database for the specified station.
static TypeFilter * ndbFilter()
static TypeFilter * navFilter()
filter matching VOR & ILS/LOC transmitters
static nav_list_type findAllByFreq(double freq, const SGGeod &position, TypeFilter *filter=NULL)
static nav_list_type findByIdentAndFreq(const std::string &ident, const double freq, TypeFilter *filter=NULL)
static TypeFilter * mobileTacanFilter()
static TypeFilter * tacanFilter()
Filter returning TACANs and VORTACs.
FGRunwayRef runway() const
Retrieve the runway this navaid is associated with (for ILS/LOC/GS)
virtual bool pass(FGPositioned *aPos) const
Over-rideable filter method.
virtual const std::string & name() const
Return the name of this positioned.
static SGSharedPtr< T > loadById(PositionedID id)
@ DME
important that DME & TACAN are adjacent to keep the TacanFilter efficient - DMEs are proxies for TACA...
static FGPositionedList findAllWithIdent(const std::string &aIdent, Filter *aFilter=NULL, bool aExact=true)
Find all items with the specified ident.
bool add(FGTACANRecord *r)
FGTACANRecord * findByFrequency(int frequency_kHz)
FGTACANRecord * findByChannel(const std::string &channel)
const std::string & get_channel() const
Filter returning Tacan stations.
virtual bool pass(FGPositioned *pos) const
Over-rideable filter method.
static NavDataCache * instance()
PositionedIDVec findNavaidsByFreq(int freqKhz, const SGGeod &pos, FGPositioned::Filter *filt)
Find all navaids matching a particular frequency, sorted by range from the supplied position.
SGSharedPtr< FGNavRecord > FGNavRecordRef
std::vector< nav_rec_ptr > nav_list_type
std::vector< tacan_rec_ptr > tacan_list_type
SGSharedPtr< FGNavRecord > nav_rec_ptr
const double FG_NAV_MAX_RANGE
std::vector< PositionedID > PositionedIDVec
std::vector< FGPositionedRef > FGPositionedList