Make ident/name searches on FGPositioned case-insensitive (for the GPS, especially)
This commit is contained in:
parent
ae7342ebe7
commit
8d5021f670
1 changed files with 47 additions and 39 deletions
|
@ -357,13 +357,17 @@ addToIndices(FGPositioned* aPos)
|
||||||
{
|
{
|
||||||
assert(aPos);
|
assert(aPos);
|
||||||
if (!aPos->ident().empty()) {
|
if (!aPos->ident().empty()) {
|
||||||
|
std::string u(boost::to_upper_copy(aPos->ident()));
|
||||||
|
|
||||||
global_identIndex.insert(global_identIndex.begin(),
|
global_identIndex.insert(global_identIndex.begin(),
|
||||||
std::make_pair(aPos->ident(), aPos));
|
std::make_pair(u, aPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aPos->name().empty()) {
|
if (!aPos->name().empty()) {
|
||||||
|
std::string u(boost::to_upper_copy(aPos->name()));
|
||||||
|
|
||||||
global_nameIndex.insert(global_nameIndex.begin(),
|
global_nameIndex.insert(global_nameIndex.begin(),
|
||||||
std::make_pair(aPos->name(), aPos));
|
std::make_pair(u, aPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Octree::global_spatialOctree) {
|
if (!Octree::global_spatialOctree) {
|
||||||
|
@ -380,8 +384,9 @@ removeFromIndices(FGPositioned* aPos)
|
||||||
assert(aPos);
|
assert(aPos);
|
||||||
|
|
||||||
if (!aPos->ident().empty()) {
|
if (!aPos->ident().empty()) {
|
||||||
NamedPositionedIndex::iterator it = global_identIndex.find(aPos->ident());
|
std::string u(boost::to_upper_copy(aPos->ident()));
|
||||||
while (it != global_identIndex.end() && (it->first == aPos->ident())) {
|
NamedPositionedIndex::iterator it = global_identIndex.find(u);
|
||||||
|
while (it != global_identIndex.end() && (it->first == u)) {
|
||||||
if (it->second == aPos) {
|
if (it->second == aPos) {
|
||||||
global_identIndex.erase(it);
|
global_identIndex.erase(it);
|
||||||
break;
|
break;
|
||||||
|
@ -392,8 +397,9 @@ removeFromIndices(FGPositioned* aPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aPos->name().empty()) {
|
if (!aPos->name().empty()) {
|
||||||
NamedPositionedIndex::iterator it = global_nameIndex.find(aPos->name());
|
std::string u(boost::to_upper_copy(aPos->name()));
|
||||||
while (it != global_nameIndex.end() && (it->first == aPos->name())) {
|
NamedPositionedIndex::iterator it = global_nameIndex.find(u);
|
||||||
|
while (it != global_nameIndex.end() && (it->first == u)) {
|
||||||
if (it->second == aPos) {
|
if (it->second == aPos) {
|
||||||
global_nameIndex.erase(it);
|
global_nameIndex.erase(it);
|
||||||
break;
|
break;
|
||||||
|
@ -415,6 +421,27 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void findInIndex(NamedPositionedIndex& aIndex, const std::string& aFind, std::vector<FGPositioned*>& aResult)
|
||||||
|
{
|
||||||
|
NamedPositionedIndex::const_iterator it = aIndex.begin();
|
||||||
|
NamedPositionedIndex::const_iterator end = aIndex.end();
|
||||||
|
|
||||||
|
bool haveFilter = !aFind.empty();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
FGPositioned::Type ty = it->second->type();
|
||||||
|
if ((ty < FGPositioned::AIRPORT) || (ty > FGPositioned::SEAPORT)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (haveFilter && it->first.find(aFind) == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult.push_back(it->second);
|
||||||
|
} // of index iteration
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
|
* A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
|
||||||
* implement the AirportList dialog. It's unfortunate that it needs to reside
|
* implement the AirportList dialog. It's unfortunate that it needs to reside
|
||||||
|
@ -422,43 +449,23 @@ public:
|
||||||
*/
|
*/
|
||||||
char** searchAirportNamesAndIdents(const std::string& aFilter)
|
char** searchAirportNamesAndIdents(const std::string& aFilter)
|
||||||
{
|
{
|
||||||
const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(std::locale());
|
// note this is a vector of raw pointers, not smart pointers, because it
|
||||||
std::string filter(aFilter);
|
// may get very large and smart-pointer-atomicity-locking then becomes a
|
||||||
bool hasFilter = !filter.empty();
|
// bottleneck for this case.
|
||||||
if (hasFilter) {
|
|
||||||
ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
NamedPositionedIndex::const_iterator it = global_identIndex.begin();
|
|
||||||
NamedPositionedIndex::const_iterator end = global_identIndex.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::vector<FGPositioned*> matches;
|
||||||
std::string upper;
|
if (!aFilter.empty()) {
|
||||||
|
std::string filter = boost::to_upper_copy(aFilter);
|
||||||
for (; it != end; ++it) {
|
findInIndex(global_identIndex, filter, matches);
|
||||||
FGPositioned::Type ty = it->second->type();
|
findInIndex(global_nameIndex, filter, matches);
|
||||||
if ((ty < FGPositioned::AIRPORT) || (ty > FGPositioned::SEAPORT)) {
|
} else {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasFilter && (it->second->ident().find(aFilter) == std::string::npos)) {
|
findInIndex(global_identIndex, std::string(), matches);
|
||||||
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
|
// sort alphabetically on name
|
||||||
std::sort(matches.begin(), matches.end(), OrderByName());
|
std::sort(matches.begin(), matches.end(), OrderByName());
|
||||||
|
|
||||||
// convert results to format comptible with puaList
|
// convert results to format comptible with puaList
|
||||||
unsigned int numMatches = matches.size();
|
unsigned int numMatches = matches.size();
|
||||||
char** result = new char*[numMatches + 1];
|
char** result = new char*[numMatches + 1];
|
||||||
result[numMatches] = NULL; // end-of-list marker
|
result[numMatches] = NULL; // end-of-list marker
|
||||||
|
@ -518,10 +525,11 @@ findAll(const NamedPositionedIndex& aIndex,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string upperBoundId = aName;
|
std::string name = boost::to_upper_copy(aName);
|
||||||
|
std::string upperBoundId = name;
|
||||||
upperBoundId[upperBoundId.size()-1]++;
|
upperBoundId[upperBoundId.size()-1]++;
|
||||||
NamedPositionedIndex::const_iterator upperBound = aIndex.lower_bound(upperBoundId);
|
NamedPositionedIndex::const_iterator upperBound = aIndex.lower_bound(upperBoundId);
|
||||||
NamedPositionedIndex::const_iterator it = aIndex.lower_bound(aName);
|
NamedPositionedIndex::const_iterator it = aIndex.lower_bound(name);
|
||||||
|
|
||||||
for (; it != upperBound; ++it) {
|
for (; it != upperBound; ++it) {
|
||||||
FGPositionedRef candidate = it->second;
|
FGPositionedRef candidate = it->second;
|
||||||
|
|
Loading…
Reference in a new issue