Реализовать систему хранения картографических данных, с использованием паттерна фабричный метод.
Картографическая информация хранится в формате аналогичном OpenStreetMap и опирается на 3 базовых класса:
Node — узел (точка) на карте
Way — путь (линия) на карте
Relation — отношение (группа узлов и линий)
Данные хранятся в файле в простом текстовом TSV (tab-separated values) формате в кодировке UTF-8. Каждая строка содержит информацию об одном элементе.
Примеры записи:
узел
n676312584 54.8419441 83.1128523 #historic="memorial" #int_name="M. A. Lavrentyev" #name="М. А. Лаврентьев" #name:en="M. A. Lavrentyev" #name:ru="М. А. Лаврентьев"
// n{id} {lat} {lon} #{key1}="{value1}" ...
путь
w23328568 n252613842 n252613843 n910721898 n252613876 #addr:postcode="630090" #cladr:code="54000001000071400" #cladr:name="Академика Лаврентьева" #cladr:suffix="Проспект" #highway="secondary" #lanes="4" #lit="yes" #name="проспект Академика Лаврентьева" #name:en="Lavrentyev Ave" #surface="asphalt"
// w{id} n{id1} ... n{idN} #{key1}="{value1}" ...
отношение
r366519 w46676881="outer" n46676881="outer" w124965071="outer" n124965071="outer" w88178918="outer" n88178918="outer" w88178923="outer" n88178923="outer" w310614929="outer" n310614929="outer" w46677631="outer" n46677631="outer" #admin_level="9" #boundary="administrative" #name="Советский район" #type="boundary"
// r{id} w{id1}="{role1}" n{id2}="{role2}" ... w{N}="{roleN}" #{key1}="{value1}" ...
Для сохранения и восстановления связей между различными объектами использовать поля id. Например, в строке с записью об отношении можно сохранить список id а после загрузки всего файла создать связи с реальными объектами.
В данных содержатся названия на разных языках, поэтому в задаче необходимо использовать wstring, wofstream, wifstream.
Пример работы с файлами в кодировке UTF-8:
#include <locale> // locale
#include <string> // wstring
#include <codecvt> // codecvt_utf8_utf16, codecvt_utf8
#include <fstream> // wifstream, wofstream
template <size_t bits, std::codecvt_mode mode>
struct codecvt_utf8_wchar_impl;
// реализация для Windows: wchar_t - 16-бит, UTF-16
template <std::codecvt_mode mode>
struct codecvt_utf8_wchar_impl<16, mode> {
using type = std::codecvt_utf8_utf16<wchar_t, 0x10FFFF, mode>;
};
// реализация для Linux/Unix-подобных OS: wchar_t - 32-бит, UCS-32
template <std::codecvt_mode mode>
struct codecvt_utf8_wchar_impl<32, mode> {
using type = std::codecvt_utf8<wchar_t, 0x10FFFF, mode>;
};
// реализация для текущей OS
template <std::codecvt_mode mode>
using codecvt_utf8_wchar = typename codecvt_utf8_wchar_impl<sizeof(wchar_t) * 8, mode>::type;
void main(void) {
std::wifstream wifs("w-RU-NVS-1.uft8.txt", std::ios::binary);
wifs.imbue(std::locale(wifs.getloc(), new codecvt_utf8_wchar<std::consume_header>));
std::wofstream wofs("w-test.txt", std::ios::binary);
wofs.imbue(std::locale(wofs.getloc(), new codecvt_utf8_wchar<std::generate_header>));
while ( wifs ) {
std::wstring wstr;
std::getline(wifs, wstr);
wofs << L"test € тест" << std::endl;
wofs << wstr << std::endl;
}
}
Архив с примерами карт ~ 65 MB.