2010-11-03 22:39:06 +02:00
|
|
|
/*
|
|
|
|
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"
|
2010-11-17 15:11:42 +02:00
|
|
|
#include <QtCore/QtDebug>
|
2010-11-03 22:39:06 +02:00
|
|
|
#include <algorithm>
|
|
|
|
#ifndef NOGUI
|
2010-11-17 15:11:42 +02:00
|
|
|
#include <QtGui/QMessageBox>
|
2010-11-03 22:39:06 +02:00
|
|
|
#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)
|