1
0
mirror of git://projects.qi-hardware.com/nanomap.git synced 2025-01-23 05:11:06 +02:00
nanomap/monav/unicodetournamenttrie/unicodetournamenttrieclient.cpp
Niels f1a2430393 Revert "first try to fix building with OpenWRT toolchain that does not include QtCore and QtGui in the include path"
This reverts commit da88ec21cdbda458d04368292008126c3ebe5715.

This was not the right solution
2010-11-17 22:05:12 +01:00

297 lines
8.3 KiB
C++

/*
Copyright 2010 Christian Vetter veaac.fdirct@gmail.com
This file is part of MoNav.
MoNav is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MoNav is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY
{
}
without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MoNav. If not, see <http://www.gnu.org/licenses/>.
*/
#include "unicodetournamenttrieclient.h"
#include "utils/qthelpers.h"
#include <QtDebug>
#include <algorithm>
#ifndef NOGUI
#include <QMessageBox>
#endif
UnicodeTournamentTrieClient::UnicodeTournamentTrieClient()
{
trieFile = NULL;
subTrieFile = NULL;
dataFile = NULL;
trieData = NULL;
subTrieData = NULL;
placeID = -1;
}
UnicodeTournamentTrieClient::~UnicodeTournamentTrieClient()
{
}
void UnicodeTournamentTrieClient::unload()
{
if ( trieFile != NULL )
delete trieFile;
trieFile = NULL;
if ( subTrieFile != NULL )
delete subTrieFile;
subTrieFile = NULL;
if ( dataFile != NULL )
delete dataFile;
dataFile = NULL;
}
QString UnicodeTournamentTrieClient::GetName()
{
return "Unicode Tournament Trie";
}
void UnicodeTournamentTrieClient::SetInputDirectory( const QString& dir )
{
directory = dir;
}
void UnicodeTournamentTrieClient::ShowSettings()
{
#ifndef NOGUI
QMessageBox::information( NULL, "Settings", "No settings available" );
#endif
}
bool UnicodeTournamentTrieClient::LoadData()
{
unload();
QString filename = fileInDirectory( directory, "Unicode Tournament Trie" );
trieFile = new QFile( filename + "_main" );
subTrieFile = new QFile( filename + "_sub" );
dataFile = new QFile( filename + "_ways" );
if ( !openQFile( trieFile, QIODevice::ReadOnly ) )
return false;
if ( !openQFile( subTrieFile, QIODevice::ReadOnly ) )
return false;
if ( !openQFile( dataFile, QIODevice::ReadOnly ) )
return false;
trieData = ( char* ) trieFile->map( 0, trieFile->size() );
subTrieData = ( char* ) subTrieFile->map( 0, subTrieFile->size() );
if ( trieData == NULL ) {
qDebug( "Failed to Memory Map trie data" );
return false;
}
if ( subTrieData == NULL ) {
qDebug( "Failed to Memory Map sub trie data" );
return false;
}
return true;
}
bool UnicodeTournamentTrieClient::find( const char* trie, unsigned* resultNode, QString* missingPrefix, QString prefix )
{
unsigned node = *resultNode;
for ( int i = 0; i < ( int ) prefix.length(); ) {
utt::Node element;
element.Read( trie + node );
bool found = false;
for ( int c = 0; c < ( int ) element.labelList.size(); c++ ) {
const utt::Label& label = element.labelList[c];
bool equal = true;
for ( int subIndex = 0; subIndex < ( int ) label.string.length(); ++subIndex ) {
if ( i + subIndex >= ( int ) prefix.length() ) {
*missingPrefix = label.string.mid( subIndex );
break;
}
if ( label.string[subIndex] != prefix[i + subIndex] ) {
equal = false;
break;
}
}
if ( !equal )
continue;
i += label.string.length();
node = label.index;
found = true;
break;
}
if ( !found )
return false;
}
*resultNode = node;
return true;
}
int UnicodeTournamentTrieClient::getSuggestion( const char* trie, QStringList* resultNames, unsigned node, int count, const QString prefix )
{
std::vector< Suggestion > candidates( 1 );
candidates[0].index = node;
candidates[0].prefix = prefix;
candidates[0].importance = std::numeric_limits< unsigned >::max();
while( count > 0 && candidates.size() > 0 ) {
const Suggestion next = candidates[0];
candidates[0] = candidates.back();
candidates.pop_back();
utt::Node element;
element.Read( trie + next.index );
bool isThis = true;
for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c ) {
assert( c->importance <= next.importance );
if ( c->importance == next.importance )
isThis = false;
}
if ( isThis && element.dataList.size() > 0 ) {
assert( next.prefix.length() > 0 );
QString suggestion = next.prefix[0].toUpper();
for ( int i = 1; i < ( int ) next.prefix.length(); ++i ) {
if ( suggestion[i - 1] == ' ' || suggestion[i - 1] == '-' )
suggestion += next.prefix[i].toUpper();
else
suggestion += next.prefix[i];
}
resultNames->push_back( suggestion );
count--;
}
for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c ) {
Suggestion nextEntry;
nextEntry.prefix = next.prefix + c->string;
nextEntry.index = c->index;
nextEntry.importance = c->importance;
candidates.push_back( nextEntry );
}
std::sort( candidates.begin(), candidates.end() );
if ( ( int ) candidates.size() > count )
candidates.resize( count );
}
return count;
}
bool UnicodeTournamentTrieClient::GetPlaceSuggestions( const QString& input, int amount, QStringList* suggestions, QStringList* inputSuggestions )
{
unsigned node = 0;
QString prefix;
QString name = input.toLower();
if ( !find( trieData, &node, &prefix, name ) )
return false;
if ( prefix.length() == 0 ) {
utt::Node element;
element.Read( trieData + node );
for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c )
inputSuggestions->push_back( input + c->string );
}
else {
inputSuggestions->push_back( input + prefix );
}
getSuggestion( trieData, suggestions, node, amount, name + prefix );
std::sort( inputSuggestions->begin(), inputSuggestions->end() );
return true;
}
bool UnicodeTournamentTrieClient::SelectPlace( int id )
{
placeID = id;
return true;
}
bool UnicodeTournamentTrieClient::GetStreetSuggestions( const QString& input, int amount, QStringList* suggestions, QStringList* inputSuggestions )
{
if ( placeID < 0 )
return false;
unsigned node = 0;
QString prefix;
QString name = input.toLower();
if ( !find( subTrieData + placeID, &node, &prefix, name ) )
return false;
if ( prefix.length() == 0 ) {
utt::Node element;
element.Read( subTrieData + placeID + node );
for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c )
inputSuggestions->push_back( input + c->string );
}
else {
inputSuggestions->push_back( input + prefix );
}
getSuggestion( subTrieData + placeID, suggestions, node, amount, name + prefix );
std::sort( inputSuggestions->begin(), inputSuggestions->end() );
return true;
}
bool UnicodeTournamentTrieClient::GetPlaceData( QString input, QVector< int >* placeIDs, QVector< UnsignedCoordinate >* placeCoordinates )
{
unsigned node = 0;
QString prefix;
QString name = input.toLower();
if ( !find( trieData, &node, &prefix, name ) )
return false;
utt::Node element;
element.Read( trieData + node );
for ( std::vector< utt::Data >::const_iterator i = element.dataList.begin(), e = element.dataList.end(); i != e; ++i ) {
utt::CityData data;
data.Read( subTrieData + i->start );
placeCoordinates->push_back( data.coordinate );
placeIDs->push_back( i->start + data.GetSize() );
}
return placeIDs->size() != 0;
}
bool UnicodeTournamentTrieClient::GetStreetData( QString input, QVector< int >* segmentLength, QVector< UnsignedCoordinate >* coordinates )
{
if ( placeID < 0 )
return false;
unsigned node = 0;
QString prefix;
QString name = input.toLower();
if ( !find( subTrieData + placeID, &node, &prefix, name ) )
return false;
utt::Node element;
element.Read( subTrieData + placeID + node );
for ( std::vector< utt::Data >::const_iterator i = element.dataList.begin(), e = element.dataList.end(); i != e; ++i ) {
unsigned* buffer = new unsigned[i->length * 2];
dataFile->seek( i->start * sizeof( unsigned ) * 2 );
dataFile->read( ( char* ) buffer, i->length * 2 * sizeof( unsigned ) );
for ( unsigned start = 0; start < i->length; ++start ) {
UnsignedCoordinate temp;
temp.x = buffer[start * 2];
temp.y = buffer[start * 2 + 1];
coordinates->push_back( temp );
}
delete[] buffer;
segmentLength->push_back( coordinates->size() );
}
return segmentLength->size() != 0;
}
Q_EXPORT_PLUGIN2(unicodetournamenttrieclient, UnicodeTournamentTrieClient)