Root/monav/unicodetournamenttrie/unicodetournamenttrieclient.cpp

1/*
2Copyright 2010 Christian Vetter veaac.fdirct@gmail.com
3
4This file is part of MoNav.
5
6MoNav is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11MoNav is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY
13{
14
15}
16 without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with MoNav. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include "unicodetournamenttrieclient.h"
25#include "utils/qthelpers.h"
26#include <QtDebug>
27#include <algorithm>
28#ifndef NOGUI
29 #include <QMessageBox>
30#endif
31
32UnicodeTournamentTrieClient::UnicodeTournamentTrieClient()
33{
34    trieFile = NULL;
35    subTrieFile = NULL;
36    dataFile = NULL;
37    trieData = NULL;
38    subTrieData = NULL;
39    placeID = -1;
40}
41
42UnicodeTournamentTrieClient::~UnicodeTournamentTrieClient()
43{
44
45}
46
47void UnicodeTournamentTrieClient::unload()
48{
49    if ( trieFile != NULL )
50        delete trieFile;
51    trieFile = NULL;
52    if ( subTrieFile != NULL )
53        delete subTrieFile;
54    subTrieFile = NULL;
55    if ( dataFile != NULL )
56        delete dataFile;
57    dataFile = NULL;
58}
59
60QString UnicodeTournamentTrieClient::GetName()
61{
62    return "Unicode Tournament Trie";
63}
64
65void UnicodeTournamentTrieClient::SetInputDirectory( const QString& dir )
66{
67    directory = dir;
68}
69
70void UnicodeTournamentTrieClient::ShowSettings()
71{
72#ifndef NOGUI
73    QMessageBox::information( NULL, "Settings", "No settings available" );
74#endif
75}
76
77bool UnicodeTournamentTrieClient::LoadData()
78{
79    unload();
80    QString filename = fileInDirectory( directory, "Unicode Tournament Trie" );
81    trieFile = new QFile( filename + "_main" );
82    subTrieFile = new QFile( filename + "_sub" );
83    dataFile = new QFile( filename + "_ways" );
84
85    if ( !openQFile( trieFile, QIODevice::ReadOnly ) )
86        return false;
87    if ( !openQFile( subTrieFile, QIODevice::ReadOnly ) )
88        return false;
89    if ( !openQFile( dataFile, QIODevice::ReadOnly ) )
90        return false;
91
92    trieData = ( char* ) trieFile->map( 0, trieFile->size() );
93    subTrieData = ( char* ) subTrieFile->map( 0, subTrieFile->size() );
94
95    if ( trieData == NULL ) {
96        qDebug( "Failed to Memory Map trie data" );
97        return false;
98    }
99    if ( subTrieData == NULL ) {
100        qDebug( "Failed to Memory Map sub trie data" );
101        return false;
102    }
103
104    return true;
105}
106
107bool UnicodeTournamentTrieClient::find( const char* trie, unsigned* resultNode, QString* missingPrefix, QString prefix )
108{
109    unsigned node = *resultNode;
110    for ( int i = 0; i < ( int ) prefix.length(); ) {
111        utt::Node element;
112        element.Read( trie + node );
113        bool found = false;
114        for ( int c = 0; c < ( int ) element.labelList.size(); c++ ) {
115            const utt::Label& label = element.labelList[c];
116            bool equal = true;
117            for ( int subIndex = 0; subIndex < ( int ) label.string.length(); ++subIndex ) {
118                if ( i + subIndex >= ( int ) prefix.length() ) {
119                    *missingPrefix = label.string.mid( subIndex );
120                    break;
121                }
122                if ( label.string[subIndex] != prefix[i + subIndex] ) {
123                    equal = false;
124                    break;
125                }
126            }
127            if ( !equal )
128                continue;
129
130            i += label.string.length();
131            node = label.index;
132            found = true;
133            break;
134
135        }
136        if ( !found )
137            return false;
138    }
139
140    *resultNode = node;
141    return true;
142}
143
144int UnicodeTournamentTrieClient::getSuggestion( const char* trie, QStringList* resultNames, unsigned node, int count, const QString prefix )
145{
146    std::vector< Suggestion > candidates( 1 );
147    candidates[0].index = node;
148    candidates[0].prefix = prefix;
149    candidates[0].importance = std::numeric_limits< unsigned >::max();
150
151    while( count > 0 && candidates.size() > 0 ) {
152        const Suggestion next = candidates[0];
153        candidates[0] = candidates.back();
154        candidates.pop_back();
155
156        utt::Node element;
157        element.Read( trie + next.index );
158        bool isThis = true;
159        for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c ) {
160            assert( c->importance <= next.importance );
161            if ( c->importance == next.importance )
162                isThis = false;
163        }
164        if ( isThis && element.dataList.size() > 0 ) {
165            assert( next.prefix.length() > 0 );
166            QString suggestion = next.prefix[0].toUpper();
167            for ( int i = 1; i < ( int ) next.prefix.length(); ++i ) {
168                if ( suggestion[i - 1] == ' ' || suggestion[i - 1] == '-' )
169                    suggestion += next.prefix[i].toUpper();
170                else
171                    suggestion += next.prefix[i];
172            }
173            resultNames->push_back( suggestion );
174            count--;
175        }
176        for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c ) {
177            Suggestion nextEntry;
178            nextEntry.prefix = next.prefix + c->string;
179            nextEntry.index = c->index;
180            nextEntry.importance = c->importance;
181            candidates.push_back( nextEntry );
182        }
183        std::sort( candidates.begin(), candidates.end() );
184        if ( ( int ) candidates.size() > count )
185            candidates.resize( count );
186    }
187
188    return count;
189}
190
191bool UnicodeTournamentTrieClient::GetPlaceSuggestions( const QString& input, int amount, QStringList* suggestions, QStringList* inputSuggestions )
192{
193    unsigned node = 0;
194    QString prefix;
195    QString name = input.toLower();
196
197    if ( !find( trieData, &node, &prefix, name ) )
198        return false;
199
200    if ( prefix.length() == 0 ) {
201        utt::Node element;
202        element.Read( trieData + node );
203        for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c )
204            inputSuggestions->push_back( input + c->string );
205    }
206    else {
207        inputSuggestions->push_back( input + prefix );
208    }
209    getSuggestion( trieData, suggestions, node, amount, name + prefix );
210    std::sort( inputSuggestions->begin(), inputSuggestions->end() );
211    return true;
212}
213
214bool UnicodeTournamentTrieClient::SelectPlace( int id )
215{
216    placeID = id;
217    return true;
218}
219
220bool UnicodeTournamentTrieClient::GetStreetSuggestions( const QString& input, int amount, QStringList* suggestions, QStringList* inputSuggestions )
221{
222    if ( placeID < 0 )
223        return false;
224    unsigned node = 0;
225    QString prefix;
226    QString name = input.toLower();
227
228    if ( !find( subTrieData + placeID, &node, &prefix, name ) )
229        return false;
230
231    if ( prefix.length() == 0 ) {
232        utt::Node element;
233        element.Read( subTrieData + placeID + node );
234        for ( std::vector< utt::Label >::const_iterator c = element.labelList.begin(), e = element.labelList.end(); c != e; ++c )
235            inputSuggestions->push_back( input + c->string );
236    }
237    else {
238        inputSuggestions->push_back( input + prefix );
239    }
240    getSuggestion( subTrieData + placeID, suggestions, node, amount, name + prefix );
241    std::sort( inputSuggestions->begin(), inputSuggestions->end() );
242    return true;
243}
244
245bool UnicodeTournamentTrieClient::GetPlaceData( QString input, QVector< int >* placeIDs, QVector< UnsignedCoordinate >* placeCoordinates )
246{
247    unsigned node = 0;
248    QString prefix;
249    QString name = input.toLower();
250    if ( !find( trieData, &node, &prefix, name ) )
251        return false;
252
253    utt::Node element;
254    element.Read( trieData + node );
255
256    for ( std::vector< utt::Data >::const_iterator i = element.dataList.begin(), e = element.dataList.end(); i != e; ++i ) {
257        utt::CityData data;
258        data.Read( subTrieData + i->start );
259        placeCoordinates->push_back( data.coordinate );
260        placeIDs->push_back( i->start + data.GetSize() );
261    }
262
263    return placeIDs->size() != 0;
264}
265
266bool UnicodeTournamentTrieClient::GetStreetData( QString input, QVector< int >* segmentLength, QVector< UnsignedCoordinate >* coordinates )
267{
268    if ( placeID < 0 )
269        return false;
270    unsigned node = 0;
271    QString prefix;
272    QString name = input.toLower();
273    if ( !find( subTrieData + placeID, &node, &prefix, name ) )
274        return false;
275
276    utt::Node element;
277    element.Read( subTrieData + placeID + node );
278
279    for ( std::vector< utt::Data >::const_iterator i = element.dataList.begin(), e = element.dataList.end(); i != e; ++i ) {
280        unsigned* buffer = new unsigned[i->length * 2];
281        dataFile->seek( i->start * sizeof( unsigned ) * 2 );
282        dataFile->read( ( char* ) buffer, i->length * 2 * sizeof( unsigned ) );
283        for ( unsigned start = 0; start < i->length; ++start ) {
284            UnsignedCoordinate temp;
285            temp.x = buffer[start * 2];
286            temp.y = buffer[start * 2 + 1];
287            coordinates->push_back( temp );
288        }
289        delete[] buffer;
290        segmentLength->push_back( coordinates->size() );
291    }
292
293    return segmentLength->size() != 0;
294}
295
296Q_EXPORT_PLUGIN2(unicodetournamenttrieclient, UnicodeTournamentTrieClient)
297

Archive Download this file

Branches:
master



interactive