- return result;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-class OrderByName
-{
-public:
- bool operator()(FGPositioned* a, FGPositioned* b) const
- {
- return a->name() < b->name();
- }
-};
-
-/**
- * A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
- * implement the AirportList dialog. It's unfortunate that it needs to reside
- * here, but for now it's least ugly solution.
- */
-char** searchAirportNamesAndIdents(const std::string& aFilter)
-{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(std::locale());
- std::string filter(aFilter);
- bool hasFilter = !filter.empty();
- if (hasFilter) {
- ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size());
- }
-
- NamedPositionedIndex::const_iterator it = global_namedIndex.begin();
- NamedPositionedIndex::const_iterator end = global_namedIndex.end();
-
- // note this is a vector of raw pointers, not smart pointers, because it
- // may get very large and smart-pointer-atomicity-locking then becomes a
- // bottleneck for this case.
- std::vector<FGPositioned*> matches;
- std::string upper;
-
- for (; it != end; ++it) {
- FGPositioned::Type ty = it->second->type();
- if ((ty < FGPositioned::AIRPORT) || (ty > FGPositioned::SEAPORT)) {
- continue;
- }
-
- if (hasFilter && (it->second->ident().find(aFilter) == std::string::npos)) {
- upper = it->second->name(); // string copy, sadly
- ct.toupper((char *)upper.data(), (char *)upper.data() + upper.size());
- if (upper.find(aFilter) == std::string::npos) {
- continue;
- }
- }
-
- matches.push_back(it->second);
- }
-
- // sort alphabetically on name
- std::sort(matches.begin(), matches.end(), OrderByName());
-
- // convert results to format comptible with puaList
- unsigned int numMatches = matches.size();
- char** result = new char*[numMatches + 1];
- result[numMatches] = NULL; // end-of-list marker
-
- // nasty code to avoid excessive string copying and allocations.
- // We format results as follows (note whitespace!):
- // ' name-of-airport-chars (ident)'
- // so the total length is:
- // 1 + strlen(name) + 4 + 4 (for the ident) + 1 + 1 (for the null)
- // which gives a grand total of 11 + the length of the name.
- // note the ident is sometimes only three letters for non-ICAO small strips
- for (unsigned int i=0; i<numMatches; ++i) {
- int nameLength = matches[i]->name().size();
- int icaoLength = matches[i]->ident().size();
- char* entry = new char[nameLength + 11];
- char* dst = entry;
- *dst++ = ' ';
- memcpy(dst, matches[i]->name().c_str(), nameLength);
- dst += nameLength;
- *dst++ = ' ';
- *dst++ = ' ';
- *dst++ = ' ';
- *dst++ = '(';
- memcpy(dst, matches[i]->ident().c_str(), icaoLength);
- dst += icaoLength;
- *dst++ = ')';
- *dst++ = 0;
- result[i] = entry;
- }
-
- return result;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool
-FGPositioned::Filter::hasTypeRange() const
-{
- assert(minType() <= maxType());
- return (minType() != INVALID) && (maxType() != INVALID);
-}
-
-bool
-FGPositioned::Filter::passType(Type aTy) const
-{
- assert(hasTypeRange());
- return (minType() <= aTy) && (maxType() >= aTy);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndexed) :
- mType(ty),
- mPosition(aPos),
- mIdent(aIdent)
-{
- SGReferenced::get(this); // hold an owning ref, for the moment
-
- if (aIndexed) {
- assert(ty != TAXIWAY && ty != PAVEMENT);
- addToIndices(this);
- }
-}
-
-FGPositioned::~FGPositioned()
-{
- //std::cout << "destroying:" << mIdent << "/" << nameForType(mType) << std::endl;
- removeFromIndices(this);
-}
-
-SGBucket
-FGPositioned::bucket() const
-{
- return SGBucket(mPosition);
-}
-
-SGVec3d
-FGPositioned::cart() const
-{
- return SGVec3d::fromGeod(mPosition);