Changed preferred language algorithm to the new one - now feature has two names:

- default "name"
- "name:<my native lang>" OR "int_name" OR "name:en"

Also houses names are drawn if house has a number and a name
This commit is contained in:
Alex Zolotarev 2011-11-23 03:19:09 +03:00 committed by Alex Zolotarev
parent 9e713f19df
commit 2f4102153d
10 changed files with 66 additions and 347 deletions

View file

@ -34,7 +34,9 @@ namespace feature
void operator()(FeatureType & f, uint32_t)
{
++m_totalCount;
if (!f.GetPreferredDrawableName().empty())
string s1, s2;
f.GetPreferredDrawableNames(s1, s2);
if (!s1.empty())
++m_namesCount;
m_currFeatureTypes.clear();

View file

@ -1,9 +1,9 @@
#include "../base/SRC_FIRST.hpp"
#include "feature.hpp"
#include "feature_visibility.hpp"
#include "feature_loader_base.hpp"
#include "../platform/preferred_languages.hpp"
#include "../defines.hpp" // just for file extensions
@ -204,53 +204,66 @@ FeatureType::geom_stat_t FeatureType::GetTrianglesSize(int scale) const
return geom_stat_t(sz, m_Triangles.size());
}
class BestMatchedLangName
struct BestMatchedLangNames
{
int8_t const * m_priorities;
string & m_result;
int m_minPriority;
public:
BestMatchedLangName(int8_t const * priorities, string & result)
: m_priorities(priorities), m_result(result), m_minPriority(256)
string & m_defaultName;
string m_nativeName;
string m_intName;
string m_englishName;
BestMatchedLangNames(string & defaultName) : m_defaultName(defaultName) {}
bool operator()(int8_t code, string const & name)
{
}
bool operator() (int8_t lang, string const & utf8s)
{
ASSERT(lang >= 0 && lang < MAX_SUPPORTED_LANGUAGES, ());
int8_t const priority = m_priorities[lang];
if (priority == 0)
{
m_result = utf8s;
return false; // stop foreach
}
if (priority < m_minPriority)
{
m_minPriority = priority;
m_result = utf8s;
}
static int8_t defaultCode = StringUtf8Multilang::GetLangIndex("default");
// @TODO support list of preferred languages
// We can get them also from input keyboard languages
static int8_t const nativeCode = StringUtf8Multilang::GetLangIndex(languages::CurrentLanguage());
static int8_t const intCode = StringUtf8Multilang::GetLangIndex("int_name");
static int8_t const englishCode = StringUtf8Multilang::GetLangIndex("en");
if (code == defaultCode)
m_defaultName = name;
else if (code == nativeCode)
m_nativeName = name;
else if (code == intCode)
m_intName = name;
else if (code == englishCode)
m_englishName = name;
return true;
}
};
string FeatureType::GetPreferredDrawableName(int8_t const * priorities) const
void FeatureType::GetPreferredDrawableNames(string & defaultName, string & intName) const
{
ParseCommon();
string res;
if (priorities)
if (GetFeatureType() == GEOM_AREA)
defaultName = m_Params.house.Get();
if (defaultName.empty())
{
BestMatchedLangName matcher(priorities, res);
BestMatchedLangNames matcher(defaultName);
ForEachNameRef(matcher);
// match intName
if (!matcher.m_nativeName.empty())
intName.swap(matcher.m_nativeName);
else if (!matcher.m_intName.empty())
intName.swap(matcher.m_intName);
else
intName.swap(matcher.m_englishName);
if (defaultName.empty())
defaultName.swap(intName);
else
{ // filter out similar intName
if (!intName.empty() && defaultName.find(intName) != string::npos)
intName.clear();
}
}
else
m_Params.name.GetString(0, res);
if (res.empty() && GetFeatureType() == GEOM_AREA)
res = m_Params.house.Get();
return res;
{
BestMatchedLangNames matcher(intName);
ForEachNameRef(matcher);
}
}
uint32_t FeatureType::GetPopulation() const

View file

@ -229,9 +229,10 @@ public:
/// For test cases only.
string DebugString(int scale) const;
/// @param priorities optional array of languages priorities
/// if NULL, default (0) lang will be used
string GetPreferredDrawableName(int8_t const * priorities = NULL) const;
/// @param[out] defaultName corresponds to osm tag "name"
/// @param[out] intName optionally choosen from tags "name:<lang_code>" by the algorithm
/// @return true if at least defaultName is filled
void GetPreferredDrawableNames(string & defaultName, string & intName) const;
uint32_t GetPopulation() const;
double GetPopulationDrawRank() const;

View file

@ -1,7 +1,7 @@
#include "draw_processor.hpp"
#include "drawer_yg.hpp"
#include "../platform/languages.hpp"
#include "../platform/preferred_languages.hpp"
#include "../geometry/screenbase.hpp"
#include "../geometry/rect_intersect.hpp"
@ -267,7 +267,9 @@ namespace fwork
if (type.second)
{
// Draw coastlines features only once.
if (!m_coasts.insert(f.GetPreferredDrawableName(0)).second)
string s1, s2;
f.GetPreferredDrawableNames(s1, s2);
if (!m_coasts.insert(s1).second)
return true;
}
@ -302,11 +304,13 @@ namespace fwork
sort(rules.begin(), rules.end(), less_depth());
string defaultName, intName;
f.GetPreferredDrawableNames(defaultName, intName);
shared_ptr<di::DrawInfo> ptr(new di::DrawInfo(
f.GetPreferredDrawableName(languages::GetCurrentPriorities()),
f.GetPreferredDrawableName(0),
f.GetRoadNumber(),
(m_zoom > 5) ? f.GetPopulationDrawRank() : 0.0));
defaultName,
intName,
f.GetRoadNumber(),
(m_zoom > 5) ? f.GetPopulationDrawRank() : 0.0));
DrawerYG * pDrawer = GetDrawer();

View file

@ -5,7 +5,6 @@
#include "../defines.hpp"
#include "../platform/languages.hpp"
#include "../platform/settings.hpp"
#include "../yg/rendercontext.hpp"
@ -130,11 +129,6 @@ Framework::Framework()
bind(&Framework::RemoveMap, this, _1),
bind(&Framework::InvalidateRect, this, _1, true));
LOG(LDEBUG, ("Storage initialized"));
// set language priorities
languages::CodesT langCodes;
languages::GetCurrentSettings(langCodes);
languages::SaveSettings(langCodes);
}
Framework::~Framework()

View file

@ -1,151 +0,0 @@
#include "languages.hpp"
#include "platform.hpp"
#include "preferred_languages.hpp"
#include "settings.hpp"
#include "../defines.hpp"
#include "../coding/file_reader.hpp"
#include "../coding/multilang_utf8_string.hpp"
#include "../base/logging.hpp"
#include "../base/string_utils.hpp"
#include "../std/algorithm.hpp"
#include "../std/sstream.hpp"
#define DEFAULT_LANGUAGES "default"
#define LANGUAGES_FILE "languages.txt"
#define LANG_DELIMETER "|"
#define SETTING_LANG_KEY "languages_priority"
namespace languages
{
static int8_t gDefaultPriorities[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63
};
int8_t const * GetCurrentPriorities()
{
return gDefaultPriorities;
}
static void SetPreferableLanguages(vector<string> const & langCodes)
{
size_t const size = langCodes.size();
CHECK_EQUAL(size, MAX_SUPPORTED_LANGUAGES, ());
CHECK_EQUAL(size, static_cast<int8_t>(size), ());
for (int8_t i = 0; i < static_cast<int8_t>(size); ++i)
{
int8_t const index = StringUtf8Multilang::GetLangIndex(langCodes[i]);
if (index >= 0)
gDefaultPriorities[index] = i;
else
{
ASSERT(false, ("Invalid language code"));
}
CHECK_GREATER_OR_EQUAL(gDefaultPriorities[i], 0, ("Unsupported language", langCodes[i]));
}
}
/// sorts outLanguages according to langCodes order
static void Sort(vector<string> const & codes, CodesAndNamesT & langs)
{
size_t ind = 0; // first unsorted position
// make selection sort
for (size_t code = 0; code < codes.size(); ++code)
{
for (size_t i = ind; i < langs.size(); ++i)
{
if (langs[i].first == codes[code])
{
if (ind != i) swap(langs[ind], langs[i]);
++ind;
break;
}
}
}
}
struct Collector
{
CodesT & m_out;
Collector(CodesT & out) : m_out(out) {}
void operator()(string const & str)
{
m_out.push_back(str);
}
};
void GetCurrentSettings(CodesT & outLangCodes)
{
CodesAndNamesT res;
GetCurrentSettings(res);
outLangCodes.clear();
for (CodesAndNamesT::iterator it = res.begin(); it != res.end(); ++it)
outLangCodes.push_back(it->first);
}
void GetCurrentSettings(CodesAndNamesT & outLanguages)
{
string settingsString;
// get preffered languages from the system
if (!Settings::Get(SETTING_LANG_KEY, settingsString))
settingsString = languages::PreferredLanguages();
CodesT currentCodes;
Collector c(currentCodes);
strings::Tokenize(settingsString, LANG_DELIMETER, c);
if (GetSupportedLanguages(outLanguages))
Sort(currentCodes, outLanguages);
}
void SaveSettings(CodesT const & langs)
{
CHECK_EQUAL(langs.size(), MAX_SUPPORTED_LANGUAGES, ());
string const saveString = strings::JoinStrings(langs.begin(), langs.end(), LANG_DELIMETER);
Settings::Set(SETTING_LANG_KEY, saveString);
// apply new settings
SetPreferableLanguages(langs);
}
bool GetSupportedLanguages(CodesAndNamesT & outLanguages)
{
outLanguages.clear();
string buffer;
try
{
ReaderPtr<Reader>(GetPlatform().GetReader(LANGUAGES_FILE)).ReadAsString(buffer);
}
catch (RootException const &)
{
return false;
}
istringstream stream(buffer);
for (size_t i = 0; (i < MAX_SUPPORTED_LANGUAGES) && stream.good(); ++i)
{
string line;
getline(stream, line);
size_t const delimIndex = line.find(LANG_DELIMETER);
if (delimIndex != string::npos)
outLanguages.push_back(make_pair(line.substr(0, delimIndex), line.substr(delimIndex + 1)));
}
return !outLanguages.empty();
}
}

View file

@ -1,21 +0,0 @@
#pragma once
#include "../std/vector.hpp"
#include "../std/string.hpp"
#include "../std/utility.hpp"
#include "../std/stdint.hpp"
namespace languages
{
typedef vector<pair<string, string> > CodesAndNamesT;
typedef vector<string> CodesT;
/// @return pointer to an array[MAX_SUPPORTED_LANGUAGES]
int8_t const * GetCurrentPriorities();
void GetCurrentSettings(CodesT & outLangCodes);
void GetCurrentSettings(CodesAndNamesT & outLanguages);
void SaveSettings(CodesT const & langs);
/// @return true if loaded default lang list which was used
/// for name:<lang> in features during world data generation
bool GetSupportedLanguages(CodesAndNamesT & outLanguages);
}

View file

@ -58,7 +58,6 @@ HEADERS += \
preferred_languages.hpp \
settings.hpp \
video_timer.hpp \
languages.hpp \
http_request.hpp \
http_thread_callback.hpp \
chunks_download_strategy.hpp \
@ -67,6 +66,5 @@ SOURCES += \
preferred_languages.cpp \
settings.cpp \
video_timer.cpp \
languages.cpp \
http_request.cpp \
chunks_download_strategy.cpp \

View file

@ -1,6 +1,5 @@
#include "preferences_dialog.hpp"
#include "../platform/languages.hpp"
#include "../platform/settings.hpp"
#include <QtGui/QIcon>
@ -24,27 +23,6 @@ namespace qt
setWindowIcon(icon);
setWindowTitle(tr("Preferences"));
m_pTable = new QTableWidget(0, 2, this);
m_pTable->setAlternatingRowColors(true);
m_pTable->setShowGrid(false);
m_pTable->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pTable->verticalHeader()->setVisible(false);
m_pTable->horizontalHeader()->setVisible(false);
m_pTable->horizontalHeader()->setStretchLastSection(true);
languages::CodesAndNamesT langList;
languages::GetCurrentSettings(langList);
for (size_t i = 0; i < langList.size(); ++i)
{
m_pTable->insertRow(i);
QTableWidgetItem * c1 = new QTableWidgetItem(langList[i].first.c_str());
c1->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_pTable->setItem(i, 0, c1);
QTableWidgetItem * c2 = new QTableWidgetItem(QString::fromUtf8(langList[i].second.c_str()));
c2->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_pTable->setItem(i, 1, c2);
}
m_pUnits = new QButtonGroup(this);
QGroupBox * radioBox = new QGroupBox("System of measurement");
{
@ -80,27 +58,6 @@ namespace qt
connect(m_pUnits, SIGNAL(buttonClicked(int)), this, SLOT(OnUnitsChanged(int)));
}
QHBoxLayout * tableLayout = new QHBoxLayout();
{
QPushButton * upButton = new QPushButton();
upButton->setIcon(QIcon(":/navig64/up.png"));
upButton->setToolTip(tr("Move up"));
upButton->setDefault(false);
connect(upButton, SIGNAL(clicked()), this, SLOT(OnUpClick()));
QPushButton * downButton = new QPushButton();
downButton->setIcon(QIcon(":/navig64/down.png"));
downButton->setToolTip(tr("Move down"));
downButton->setDefault(false);
connect(downButton, SIGNAL(clicked()), this, SLOT(OnDownClick()));
QVBoxLayout * vBox = new QVBoxLayout();
vBox->addWidget(upButton);
vBox->addWidget(downButton);
tableLayout->addLayout(vBox);
tableLayout->addWidget(m_pTable);
}
QHBoxLayout * bottomLayout = new QHBoxLayout();
{
@ -116,12 +73,8 @@ namespace qt
QVBoxLayout * finalLayout = new QVBoxLayout();
finalLayout->addWidget(radioBox);
finalLayout->addLayout(tableLayout);
finalLayout->addLayout(bottomLayout);
setLayout(finalLayout);
if (m_pTable->rowCount() > 0)
m_pTable->selectRow(0);
}
void PreferencesDialog::OnCloseClick()
@ -129,76 +82,6 @@ namespace qt
done(0);
}
static void SwapRows(QTableWidget & widget, int row1, int row2)
{
QTableWidgetItem * c0 = widget.takeItem(row1, 0);
QTableWidgetItem * c1 = widget.takeItem(row1, 1);
widget.setItem(row1, 0, widget.takeItem(row2, 0));
widget.setItem(row1, 1, widget.takeItem(row2, 1));
widget.setItem(row2, 0, c0);
widget.setItem(row2, 1, c1);
}
static void ShiftSelectionRange(QList<QTableWidgetSelectionRange> & range, int offset)
{
QList<QTableWidgetSelectionRange> newRange;
for (int i = 0; i < range.size(); ++i)
newRange.append(QTableWidgetSelectionRange(range[i].topRow() + offset,
range[i].leftColumn(),
range[i].bottomRow() + offset,
range[i].rightColumn()));
range = newRange;
}
void PreferencesDialog::OnUpClick()
{
QList<QTableWidgetSelectionRange> selection = m_pTable->selectedRanges();
int const selSize = selection.size();
if (selSize && selection[0].topRow() > 0)
{
for (int i = 0; i < selSize; ++i)
{
m_pTable->setRangeSelected(selection[i], false);
for (int j = selection[i].topRow(); j < selection[i].topRow() + selection[i].rowCount(); ++j)
SwapRows(*m_pTable, j, j - 1);
}
ShiftSelectionRange(selection, -1);
for (int i = 0; i < selSize; ++i)
m_pTable->setRangeSelected(selection[i], true);
m_pTable->scrollToItem(m_pTable->item(selection[0].topRow(), 0));
}
}
void PreferencesDialog::OnDownClick()
{
QList<QTableWidgetSelectionRange> selection = m_pTable->selectedRanges();
int const selSize = selection.size();
if (selSize && selection[selSize - 1].bottomRow() < m_pTable->rowCount() - 1)
{
for (int i = selSize - 1; i >= 0; --i)
{
m_pTable->setRangeSelected(selection[i], false);
for (int j = selection[i].bottomRow(); j > selection[i].bottomRow() - selection[i].rowCount(); --j)
SwapRows(*m_pTable, j, j + 1);
}
ShiftSelectionRange(selection, +1);
for (int i = 0; i < selSize; ++i)
m_pTable->setRangeSelected(selection[i], true);
m_pTable->scrollToItem(m_pTable->item(selection[selSize - 1].bottomRow(), 0));
}
}
void PreferencesDialog::done(int code)
{
languages::CodesT langCodes;
for (int i = 0; i < m_pTable->rowCount(); ++i)
langCodes.push_back(m_pTable->item(i, 0)->text().toUtf8().constData());
languages::SaveSettings(langCodes);
base_t::done(code);
}
void PreferencesDialog::OnUnitsChanged(int i)
{
using namespace Settings;

View file

@ -14,19 +14,15 @@ namespace qt
Q_OBJECT
virtual QSize sizeHint () const { return QSize(400, 400); }
virtual void done(int);
public:
explicit PreferencesDialog(QWidget * parent);
private slots:
void OnCloseClick();
void OnUpClick();
void OnDownClick();
void OnUnitsChanged(int i);
private:
QTableWidget * m_pTable;
QButtonGroup * m_pUnits;
};
} // namespace qt