Merge branch 'master' into navigation-refactoring
This commit is contained in:
commit
be8f4e064e
86 changed files with 1175 additions and 1288 deletions
|
@ -186,18 +186,6 @@ if (PLATFORM_LINUX OR PLATFORM_ANDROID)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (DEFINED ENV{QT_PATH})
|
||||
message("Qt path is set to: " $ENV{QT_PATH})
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_PATH})
|
||||
else()
|
||||
file(GLOB QT_PATH_LIST "/usr/local/opt/qt*" "/usr/lib/x86_64-linux-gnu/qt*")
|
||||
if (QT_PATH_LIST)
|
||||
list(GET QT_PATH_LIST 0 QT_PATH)
|
||||
message("Found Qt path: " ${QT_PATH})
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_PATH})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT SKIP_TESTS)
|
||||
set(SKIP_TESTS FALSE)
|
||||
endif()
|
||||
|
@ -232,7 +220,7 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
|
|||
list(APPEND qt_components Gui Xml Svg)
|
||||
endif()
|
||||
# PATHS are hard-coded hints where to look for qt5 in addition to other places.
|
||||
find_package(Qt5 COMPONENTS REQUIRED ${qt_components} PATHS /usr/local/opt/qt@5)
|
||||
find_package(Qt5 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} /opt/homebrew/opt/qt@5 /usr/local/opt/qt@5 /usr/lib/x86_64-linux-gnu/qt5)
|
||||
if (Qt5_VERSION VERSION_LESS 5.5.0)
|
||||
message(FATAL_ERROR "Minimum supported Qt5 version is 5.5")
|
||||
endif()
|
||||
|
|
|
@ -672,7 +672,7 @@
|
|||
<string name="elevation_profile_distance">Distance :</string>
|
||||
<string name="elevation_profile_time">Temps:</string>
|
||||
<string name="isolines_toast_zooms_1_10">Zoomez pour voir les courbes de niveaux</string>
|
||||
<string name="download_map_title">Télécharcher la carte du monde</string>
|
||||
<string name="download_map_title">Télécharger la carte du monde</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="connection_failure">Erreur de connexion</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
|
|
|
@ -518,11 +518,13 @@
|
|||
<string name="setting_emulate_bad_storage">Slechte opslag emuleren</string>
|
||||
<string name="core_entrance">Ingang</string>
|
||||
<string name="error_enter_correct_name">Voer een juiste naam in</string>
|
||||
<string name="bookmark_lists">lijsten</string>
|
||||
<string name="bookmark_lists">Lijsten</string>
|
||||
<!-- Do not display all bookmark lists on the map -->
|
||||
<string name="bookmark_lists_hide_all">Alles verbergen</string>
|
||||
<string name="bookmark_lists_show_all">Alles weergeven</string>
|
||||
<string name="bookmarks_create_new_group">Nieuwe lijst maken</string>
|
||||
<!-- Bookmark categories screen -->
|
||||
<string name="bookmarks_import">Bladwijzers importeren</string>
|
||||
<string name="bookmarks_error_message_share_general">Delen is onmogelijk wegens een toepassingsfout</string>
|
||||
<string name="bookmarks_error_title_share_empty">Deelfout</string>
|
||||
<string name="bookmarks_error_message_share_empty">Een lege lijst kan niet gedeeld worden</string>
|
||||
|
@ -556,7 +558,7 @@
|
|||
<string name="terms_of_use">Gebruiksvoorwaarden</string>
|
||||
<string name="button_layer_traffic">Verkeer</string>
|
||||
<string name="button_layer_subway">Metro</string>
|
||||
<string name="layers_title">Map layers</string>
|
||||
<string name="layers_title">Kaartweergave</string>
|
||||
<string name="subway_data_unavailable">Metrokaart is niet beschikbaar</string>
|
||||
<string name="bookmarks_empty_list_title">Deze lijst is leeg</string>
|
||||
<string name="bookmarks_empty_list_message">Om een bladwijzer toe te voegen, tikt u op een plaats op de kaart en vervolgens op het sterpictogram</string>
|
||||
|
@ -582,12 +584,12 @@
|
|||
<string name="power_managment_setting_manual_max">Maximale energiebesparing</string>
|
||||
<string name="enable_logging_warning_message">Deze optie is ingeschakeld voor logboekregistraties voor diagnostische doeleinden. Het helpt bij het identificeren van problemen met de applicatie. Schakel de optie alleen in op verzoek van Organic Maps-ondersteuning.</string>
|
||||
<string name="access_rules_author_only">Wordt online bewerkt</string>
|
||||
<string name="driving_options_title">Omweginstellingen</string>
|
||||
<string name="driving_options_title">Route instellingen</string>
|
||||
<string name="driving_options_subheader">Vermijden op elke route</string>
|
||||
<string name="avoid_tolls">Tolwegen</string>
|
||||
<string name="avoid_unpaved">Aardewegen</string>
|
||||
<string name="avoid_ferry">Ferries</string>
|
||||
<string name="avoid_motorways">Hoofdverkeerswegen</string>
|
||||
<string name="avoid_unpaved">Onverharde wegen</string>
|
||||
<string name="avoid_ferry">Veerdiensten</string>
|
||||
<string name="avoid_motorways">Autosnelwegen</string>
|
||||
<string name="unable_to_calc_alert_title">Kan route niet opbouwen</string>
|
||||
<string name="unable_to_calc_alert_subtitle">Helaas konden we geen route opbouwen met de gekozen opties. Wijzig de instellingen en probeer het opnieuw</string>
|
||||
<string name="define_to_avoid_btn">Omwegen configureren</string>
|
||||
|
@ -661,6 +663,10 @@
|
|||
<string name="enable_screen_sleep">Laat het scherm slapen</string>
|
||||
<!-- Description in preferences -->
|
||||
<string name="enable_screen_sleep_description">Indien ingeschakeld, mag het scherm slapen na een periode van inactiviteit.</string>
|
||||
<!-- A preference title; keep short! -->
|
||||
<string name="enable_show_on_lock_screen">Toon op vergrendelscherm</string>
|
||||
<!-- Description in preferences -->
|
||||
<string name="enable_show_on_lock_screen_description">Indien ingeschakeld, hoeft het scherm niet te worden ontgrendeld wanneer de app actief is.</string>
|
||||
|
||||
<!-- SECTION: Types -->
|
||||
<string name="type.aerialway.station">Kabelwagenstation</string>
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
<string name="unsupported_phone">Hızlı donanıma sahip bir OpenGL gerekli. Ne yazık ki cihazınız desteklenmiyor.</string>
|
||||
<string name="download">İndir</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="disconnect_usb_cable">Organic Maps’i kullanabilmeniz için lütfen USB kablosunun bağlantısını kesin veya hafıza kartı takın</string>
|
||||
<string name="disconnect_usb_cable">Organic Maps’i kullanabilmek için lütfen USB kablosunun bağlantısını kesin veya hafıza kartı takın</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="not_enough_free_space_on_sdcard">Uygulamayı kullanabilmeniz için lütfen SD kart/USB depolama aygıtında biraz alan boşaltın</string>
|
||||
<string name="not_enough_free_space_on_sdcard">Uygulamayı kullanabilmek için lütfen SD kart/USB depolama aygıtında biraz alan boşaltın</string>
|
||||
<string name="download_resources">Başlamadan önce cihazınıza genel dünya haritasını indirelim.\n%s alan gerekli.</string>
|
||||
<string name="download_resources_continue">Haritaya Git</string>
|
||||
<string name="downloading_country_can_proceed">%s indiriliyor. Şimdi haritaya\ngidebilirsiniz.</string>
|
||||
|
@ -680,6 +680,10 @@
|
|||
<string name="isolines_toast_zooms_1_10">İzohipsleri görmek için haritayı büyütün</string>
|
||||
<string name="download_map_title">Dünya haritasını indir</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="disk_error">Dahili aygıtın belleğinde veya SD kartta klasör oluşturulamıyor ve dosyalar taşınamıyor</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="disk_error_title">Disk hatası</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="connection_failure">Bağlantı hatası</string>
|
||||
<!-- Used in DownloadResources startup screen -->
|
||||
<string name="disconnect_usb_cable_title">USB kablosunu çıkarın</string>
|
||||
|
@ -784,7 +788,7 @@
|
|||
<string name="type.amenity.post_box">Posta Kutusu</string>
|
||||
<string name="type.amenity.post_office">Postane</string>
|
||||
<string name="type.amenity.prison">Hapishane</string>
|
||||
<string name="type.amenity.pub">Bar</string>
|
||||
<string name="type.amenity.pub">Meyhane</string>
|
||||
<string name="type.amenity.public_bookcase">Kitap Değişimi</string>
|
||||
|
||||
<!-- SECTION: Types: Recycling -->
|
||||
|
@ -821,11 +825,11 @@
|
|||
<string name="type.amenity.vending_machine.parking_tickets">Otopark Fişi</string>
|
||||
<string name="type.amenity.vending_machine.public_transport_tickets">Toplu Taşıma Biletleri için Otomatlar</string>
|
||||
<string name="type.amenity.vending_machine.excrement_bags">Dışkı Torbası Dağıtıcı</string>
|
||||
<string name="type.amenity.parcel_locker">Posta Kutusu</string>
|
||||
<string name="type.amenity.parcel_locker">Kilitlenebilen Kutu Dolaplar</string>
|
||||
<string name="type.amenity.vending_machine.fuel">Yakıt Dağıtıcı</string>
|
||||
<string name="type.amenity.veterinary">Veteriner</string>
|
||||
<string name="type.amenity.waste_basket">Çöp Kutusu</string>
|
||||
<string name="type.amenity.waste_disposal">Çöp Kutusu</string>
|
||||
<string name="type.amenity.waste_disposal">Çöp Konteyneri</string>
|
||||
<string name="type.amenity.waste_transfer_station">Atık Transfer İstasyonu</string>
|
||||
<string name="type.amenity.water_point">Karavanlar için Su Noktası</string>
|
||||
<string name="type.barrier">Bariyer</string>
|
||||
|
@ -1157,7 +1161,7 @@
|
|||
<string name="type.historic.castle.stately">Kale</string>
|
||||
<string name="type.historic.citywalls">Şehir Duvarı</string>
|
||||
<string name="type.historic.fort">Hisar</string>
|
||||
<string name="type.historic.memorial">Anıt</string>
|
||||
<string name="type.historic.memorial">Abide</string>
|
||||
<string name="type.historic.memorial.plaque">Hatıra Plaketi</string>
|
||||
<string name="type.historic.memorial.sculpture">Heykel</string>
|
||||
<string name="type.historic.memorial.statue">Heykel</string>
|
||||
|
@ -1256,7 +1260,7 @@
|
|||
<string name="type.man_made.surveillance">Güvenlik Kamerası</string>
|
||||
<string name="type.man_made.tower">Kule</string>
|
||||
<string name="type.man_made.wastewater_plant">Atıksu Tesisi</string>
|
||||
<string name="type.man_made.water_tap">Çeşme Suyu</string>
|
||||
<string name="type.man_made.water_tap">Su Musluğu</string>
|
||||
<string name="type.man_made.water_tower">Su Kulesi</string>
|
||||
<string name="type.man_made.water_well">Su Kuyusu</string>
|
||||
<string name="type.man_made.windmill">Yel Değirmeni</string>
|
||||
|
@ -1303,13 +1307,13 @@
|
|||
<string name="type.natural.wetland.marsh">Sulak Alan</string>
|
||||
<string name="type.noexit">Çıkmaz</string>
|
||||
<string name="type.office">Ofis</string>
|
||||
<string name="type.office.company">Şirket bürosu</string>
|
||||
<string name="type.office.company">Şirket Bürosu</string>
|
||||
<string name="type.office.estate_agent">Emlakçı</string>
|
||||
<string name="type.office.government">Devlet dairesi</string>
|
||||
<string name="type.office.insurance">Sigorta Acentası</string>
|
||||
<string name="type.office.lawyer">Avukatlık bürosu</string>
|
||||
<string name="type.office.government">Devlet Dairesi</string>
|
||||
<string name="type.office.insurance">Sigorta Acentesi</string>
|
||||
<string name="type.office.lawyer">Avukatlık Bürosu</string>
|
||||
<string name="type.office.ngo">STK Binası</string>
|
||||
<string name="type.office.telecommunication">Cep telefonu operatörü</string>
|
||||
<string name="type.office.telecommunication">Cep Telefonu Operatörü</string>
|
||||
<string name="type.place">Yer</string>
|
||||
<string name="type.place.city">Şehir</string>
|
||||
<string name="type.place.city.capital">Başkent</string>
|
||||
|
@ -1433,7 +1437,7 @@
|
|||
<string name="type.shop.alcohol">İçki dükkanı</string>
|
||||
<string name="type.shop.bakery">Fırın</string>
|
||||
<string name="type.shop.beauty">Güzellik Salonu</string>
|
||||
<string name="type.shop.beverages">İçecek</string>
|
||||
<string name="type.shop.beverages">İçecekler</string>
|
||||
<string name="type.shop.bicycle">Bisikletçi</string>
|
||||
<string name="type.shop.bookmaker">Bahisçi</string>
|
||||
<string name="type.shop.books">Kitapçı</string>
|
||||
|
@ -1521,7 +1525,7 @@
|
|||
<string name="type.sport.tennis">Tenis Kortu</string>
|
||||
<string name="type.tourism">Turizm</string>
|
||||
<string name="type.tourism.alpine_hut">Dağda Konaklama</string>
|
||||
<string name="type.tourism.apartment">Apart otel</string>
|
||||
<string name="type.tourism.apartment">Apart Otel</string>
|
||||
<string name="type.tourism.artwork">Sanat</string>
|
||||
<string name="type.tourism.artwork.architecture">Sanatsal Mimari</string>
|
||||
<string name="type.tourism.artwork.painting">Sanat Eserleri</string>
|
||||
|
|
|
@ -8,11 +8,61 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace map_uint32_tests
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
using Buffer = vector<uint8_t>;
|
||||
using BufferT = vector<uint8_t>;
|
||||
using ValuesT = vector<uint32_t>;
|
||||
using BuilderT = MapUint32ToValueBuilder<uint32_t>;
|
||||
using MapT = MapUint32ToValue<uint32_t>;
|
||||
|
||||
UNIT_TEST(MapUint32ValTest)
|
||||
UNIT_TEST(MapUint32Val_Small)
|
||||
{
|
||||
{
|
||||
BuilderT builder;
|
||||
BufferT buffer;
|
||||
MemWriter writer(buffer);
|
||||
builder.Freeze(writer, [](Writer &, auto, auto) {});
|
||||
|
||||
LOG(LINFO, ("Empty map size =", buffer.size()));
|
||||
|
||||
MemReader reader(buffer.data(), buffer.size());
|
||||
auto map = MapT::Load(reader, [](NonOwningReaderSource &, uint32_t, ValuesT &) {});
|
||||
|
||||
TEST_EQUAL(map->Count(), 0, ());
|
||||
uint32_t dummy;
|
||||
TEST(!map->Get(1, dummy), ());
|
||||
}
|
||||
|
||||
{
|
||||
BuilderT builder;
|
||||
builder.Put(1, 777);
|
||||
BufferT buffer;
|
||||
MemWriter writer(buffer);
|
||||
builder.Freeze(writer, [](Writer & writer, auto b, auto e)
|
||||
{
|
||||
WriteVarUint(writer, *b++);
|
||||
TEST(b == e, ());
|
||||
});
|
||||
|
||||
MemReader reader(buffer.data(), buffer.size());
|
||||
auto map = MapT::Load(reader, [](NonOwningReaderSource & source, uint32_t blockSize, ValuesT & values)
|
||||
{
|
||||
TEST_EQUAL(blockSize, 1, ("GetThreadsafe should pass optimal blockSize"));
|
||||
while (source.Size() > 0)
|
||||
values.push_back(ReadVarUint<uint32_t>(source));
|
||||
TEST_EQUAL(values.size(), 1, ());
|
||||
});
|
||||
|
||||
TEST_EQUAL(map->Count(), 1, ());
|
||||
uint32_t val;
|
||||
TEST(map->GetThreadsafe(1, val), ());
|
||||
TEST_EQUAL(val, 777, ());
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(MapUint32Val_Smoke)
|
||||
{
|
||||
vector<pair<uint32_t, uint32_t>> data;
|
||||
size_t const dataSize = 227;
|
||||
|
@ -20,34 +70,29 @@ UNIT_TEST(MapUint32ValTest)
|
|||
for (size_t i = 0; i < data.size(); ++i)
|
||||
data[i] = make_pair(static_cast<uint32_t>(i), static_cast<uint32_t>(i));
|
||||
|
||||
Buffer buffer;
|
||||
BufferT buffer;
|
||||
{
|
||||
MapUint32ToValueBuilder<uint32_t> builder;
|
||||
|
||||
BuilderT builder;
|
||||
for (auto const & d : data)
|
||||
builder.Put(d.first, d.second);
|
||||
|
||||
MemWriter<Buffer> writer(buffer);
|
||||
|
||||
auto const trivialWriteBlockCallback = [](Writer & w, vector<uint32_t>::const_iterator begin,
|
||||
vector<uint32_t>::const_iterator end) {
|
||||
MemWriter writer(buffer);
|
||||
builder.Freeze(writer, [](Writer & w, BuilderT::Iter begin, BuilderT::Iter end)
|
||||
{
|
||||
for (auto it = begin; it != end; ++it)
|
||||
WriteToSink(w, *it);
|
||||
};
|
||||
builder.Freeze(writer, trivialWriteBlockCallback);
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
MemReader reader(buffer.data(), buffer.size());
|
||||
auto const trivialReadBlockCallback = [](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
vector<uint32_t> & values) {
|
||||
values.resize(blockSize);
|
||||
for (size_t i = 0; i < blockSize && source.Size() > 0; ++i)
|
||||
{
|
||||
values[i] = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
}
|
||||
};
|
||||
auto table = MapUint32ToValue<uint32_t>::Load(reader, trivialReadBlockCallback);
|
||||
auto table = MapUint32ToValue<uint32_t>::Load(reader, [](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
ValuesT & values)
|
||||
{
|
||||
values.reserve(blockSize);
|
||||
while (source.Size() > 0)
|
||||
values.push_back(ReadPrimitiveFromSource<uint32_t>(source));
|
||||
});
|
||||
TEST(table.get(), ());
|
||||
|
||||
for (auto const & d : data)
|
||||
|
@ -60,3 +105,4 @@ UNIT_TEST(MapUint32ValTest)
|
|||
}
|
||||
}
|
||||
}
|
||||
} // namespace map_uint32_tests
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
// Format:
|
||||
// File offset (bytes) Field name Field size (bytes)
|
||||
// 0 version 2
|
||||
// 2 endianness 2
|
||||
// 2 block size 2
|
||||
// 4 positions offset 4
|
||||
// 8 variables offset 4
|
||||
// 12 end of section 4
|
||||
|
@ -48,158 +48,106 @@
|
|||
// positions offset positions table variables offset - positions offset
|
||||
// variables offset variables blocks end of section - variables offset
|
||||
//
|
||||
// Version and endianness are always stored in the little-endian format.
|
||||
// 0 value of endianness means little-endian, whereas 1 means big-endian.
|
||||
//
|
||||
// All offsets are in the little-endian format.
|
||||
//
|
||||
// Identifiers table is a bit-vector with rank-select table, where set
|
||||
// bits denote that values for the corresponding features are in the
|
||||
// table. Identifiers table is stored in the native endianness.
|
||||
//
|
||||
// Positions table is an Elias-Fano table where each entry corresponds
|
||||
// to the start position of the variables block. Positions table is
|
||||
// stored in the native endianness.
|
||||
// to the start position of the variables block.
|
||||
//
|
||||
// Variables is a sequence of blocks, where each block (with the
|
||||
// exception of the last one) is a sequence of kBlockSize variables
|
||||
// encoded by block encoding callback.
|
||||
//
|
||||
// On Get call kBlockSize consecutive variables are decoded and cached in RAM. Get is not
|
||||
// threadsafe.
|
||||
//
|
||||
// GetThreadsafe does not use cache.
|
||||
// On Get call m_blockSize consecutive variables are decoded and cached in RAM.
|
||||
|
||||
template <typename Value>
|
||||
class MapUint32ToValue
|
||||
{
|
||||
public:
|
||||
using ReadBlockCallback =
|
||||
std::function<void(NonOwningReaderSource &, uint32_t, std::vector<Value> &)>;
|
||||
// 0 - initial version.
|
||||
// 1 - added m_blockSize instead of m_endianess.
|
||||
static uint16_t constexpr kLastVersion = 1;
|
||||
|
||||
static uint32_t constexpr kBlockSize = 64;
|
||||
public:
|
||||
using ReadBlockCallback = std::function<void(NonOwningReaderSource &, uint32_t, std::vector<Value> &)>;
|
||||
|
||||
struct Header
|
||||
{
|
||||
void Read(Reader & reader)
|
||||
uint16_t Read(Reader & reader)
|
||||
{
|
||||
NonOwningReaderSource source(reader);
|
||||
m_version = ReadPrimitiveFromSource<uint16_t>(source);
|
||||
m_endianness = ReadPrimitiveFromSource<uint16_t>(source);
|
||||
auto const version = ReadPrimitiveFromSource<uint16_t>(source);
|
||||
m_blockSize = ReadPrimitiveFromSource<uint16_t>(source);
|
||||
if (version == 0)
|
||||
m_blockSize = 64;
|
||||
|
||||
m_positionsOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_variablesOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_endOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
return version;
|
||||
}
|
||||
|
||||
void Write(Writer & writer)
|
||||
{
|
||||
WriteToSink(writer, m_version);
|
||||
WriteToSink(writer, m_endianness);
|
||||
WriteToSink(writer, kLastVersion);
|
||||
WriteToSink(writer, m_blockSize);
|
||||
WriteToSink(writer, m_positionsOffset);
|
||||
WriteToSink(writer, m_variablesOffset);
|
||||
WriteToSink(writer, m_endOffset);
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
if (m_version != 0)
|
||||
{
|
||||
LOG(LERROR, ("Unknown version."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_endianness > 1)
|
||||
{
|
||||
LOG(LERROR, ("Wrong endianness value."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_positionsOffset < sizeof(m_header))
|
||||
{
|
||||
LOG(LERROR, ("Positions before header:", m_positionsOffset, sizeof(m_header)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_variablesOffset < m_positionsOffset)
|
||||
{
|
||||
LOG(LERROR, ("Deltas before positions:", m_variablesOffset, m_positionsOffset));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_endOffset < m_variablesOffset)
|
||||
{
|
||||
LOG(LERROR, ("End of section before variables:", m_endOffset, m_variablesOffset));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t m_version = 0;
|
||||
uint16_t m_endianness = 0;
|
||||
uint16_t m_blockSize = 0;
|
||||
uint32_t m_positionsOffset = 0;
|
||||
uint32_t m_variablesOffset = 0;
|
||||
uint32_t m_endOffset = 0;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Header) == 16, "Wrong header size");
|
||||
|
||||
MapUint32ToValue(Reader & reader, ReadBlockCallback const & readBlockCallback)
|
||||
: m_reader(reader), m_readBlockCallback(readBlockCallback)
|
||||
{
|
||||
}
|
||||
|
||||
~MapUint32ToValue() = default;
|
||||
|
||||
// Tries to get |value| for key identified by |id|. Returns
|
||||
// false if table does not have entry for this id.
|
||||
/// @name Tries to get |value| for key identified by |id|.
|
||||
/// @returns false if table does not have entry for this id.
|
||||
/// @{
|
||||
[[nodiscard]] bool Get(uint32_t id, Value & value)
|
||||
{
|
||||
if (id >= m_ids.size() || !m_ids[id])
|
||||
return false;
|
||||
|
||||
uint32_t const rank = static_cast<uint32_t>(m_ids.rank(id));
|
||||
uint32_t const base = rank / kBlockSize;
|
||||
uint32_t const offset = rank % kBlockSize;
|
||||
uint32_t const base = rank / m_header.m_blockSize;
|
||||
uint32_t const offset = rank % m_header.m_blockSize;
|
||||
|
||||
auto & entry = m_cache[base];
|
||||
if (entry.empty())
|
||||
entry = GetImpl(rank);
|
||||
entry = GetImpl(rank, m_header.m_blockSize);
|
||||
|
||||
value = entry[offset];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tries to get |value| for key identified by |id|. Returns
|
||||
// false if table does not have entry for this id.
|
||||
[[nodiscard]] bool GetThreadsafe(uint32_t id, Value & value) const
|
||||
{
|
||||
if (id >= m_ids.size() || !m_ids[id])
|
||||
return false;
|
||||
|
||||
uint32_t const rank = static_cast<uint32_t>(m_ids.rank(id));
|
||||
uint32_t const offset = rank % kBlockSize;
|
||||
uint32_t const offset = rank % m_header.m_blockSize;
|
||||
|
||||
auto const entry = GetImpl(rank);
|
||||
auto const entry = GetImpl(rank, offset + 1);
|
||||
|
||||
value = entry[offset];
|
||||
return true;
|
||||
}
|
||||
/// @}
|
||||
|
||||
// Loads MapUint32ToValue instance. Note that |reader| must be alive
|
||||
// until the destruction of loaded table. Returns nullptr if
|
||||
// MapUint32ToValue can't be loaded.
|
||||
// It's guaranteed that |readBlockCallback| will not be called for empty block.
|
||||
static std::unique_ptr<MapUint32ToValue> Load(Reader & reader,
|
||||
ReadBlockCallback const & readBlockCallback)
|
||||
static std::unique_ptr<MapUint32ToValue> Load(Reader & reader, ReadBlockCallback const & readBlockCallback)
|
||||
{
|
||||
uint16_t const version = ReadPrimitiveFromPos<uint16_t>(reader, 0 /* pos */);
|
||||
if (version != 0)
|
||||
return {};
|
||||
|
||||
// Only single version of centers table is supported now. If you need to implement new
|
||||
// versions, implement dispatching based on first-four-bytes version.
|
||||
auto table = std::make_unique<MapUint32ToValue>(reader, readBlockCallback);
|
||||
if (!table->Init())
|
||||
return {};
|
||||
|
@ -221,39 +169,40 @@ public:
|
|||
uint64_t Count() const { return m_ids.num_ones(); }
|
||||
|
||||
private:
|
||||
std::vector<Value> GetImpl(uint32_t rank) const
|
||||
/// @param[in] upperSize Read until this size. Can be one of: \n
|
||||
/// - m_header.m_blockSize for the regular Get version with cache \n
|
||||
/// - index + 1 for the GetThreadsafe version without cache, to break when needed element is readed \n
|
||||
std::vector<Value> GetImpl(uint32_t rank, uint32_t upperSize) const
|
||||
{
|
||||
uint32_t const base = rank / kBlockSize;
|
||||
|
||||
std::vector<Value> values(kBlockSize);
|
||||
|
||||
uint32_t const base = rank / m_header.m_blockSize;
|
||||
auto const start = m_offsets.select(base);
|
||||
auto const end = base + 1 < m_offsets.num_ones() ? m_offsets.select(base + 1) + m_header.m_variablesOffset
|
||||
: m_header.m_endOffset;
|
||||
|
||||
NonOwningReaderSource src(m_reader, m_header.m_variablesOffset + start, end);
|
||||
m_readBlockCallback(src, kBlockSize, values);
|
||||
|
||||
// Important! Client should read while src.Size() > 0 and max |upperSize| number of elements.
|
||||
std::vector<Value> values;
|
||||
m_readBlockCallback(src, upperSize, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
bool Init()
|
||||
{
|
||||
m_header.Read(m_reader);
|
||||
|
||||
if (!m_header.IsValid())
|
||||
auto const version = m_header.Read(m_reader);
|
||||
if (version > kLastVersion)
|
||||
{
|
||||
LOG(LERROR, ("Unsupported version =", version, "Last known version =", kLastVersion));
|
||||
return false;
|
||||
|
||||
bool const isHostBigEndian = IsBigEndianMacroBased();
|
||||
bool const isDataBigEndian = m_header.m_endianness == 1;
|
||||
bool const endiannesMismatch = isHostBigEndian != isDataBigEndian;
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t const idsSize = m_header.m_positionsOffset - sizeof(m_header);
|
||||
std::vector<uint8_t> data(idsSize);
|
||||
m_reader.Read(sizeof(m_header), data.data(), data.size());
|
||||
m_idsRegion = std::make_unique<CopiedMemoryRegion>(move(data));
|
||||
EndiannessAwareMap(endiannesMismatch, *m_idsRegion, m_ids);
|
||||
|
||||
coding::MapVisitor visitor(m_idsRegion->ImmutableData());
|
||||
m_ids.map(visitor);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -261,30 +210,14 @@ private:
|
|||
std::vector<uint8_t> data(offsetsSize);
|
||||
m_reader.Read(m_header.m_positionsOffset, data.data(), data.size());
|
||||
m_offsetsRegion = std::make_unique<CopiedMemoryRegion>(move(data));
|
||||
EndiannessAwareMap(endiannesMismatch, *m_offsetsRegion, m_offsets);
|
||||
|
||||
coding::MapVisitor visitor(m_offsetsRegion->ImmutableData());
|
||||
m_offsets.map(visitor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Cont>
|
||||
void EndiannessAwareMap(bool endiannesMismatch, CopiedMemoryRegion & region, Cont & cont)
|
||||
{
|
||||
Cont c;
|
||||
if (endiannesMismatch)
|
||||
{
|
||||
coding::ReverseMapVisitor visitor(region.MutableData());
|
||||
c.map(visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
coding::MapVisitor visitor(region.ImmutableData());
|
||||
c.map(visitor);
|
||||
}
|
||||
|
||||
c.swap(cont);
|
||||
}
|
||||
|
||||
Header m_header;
|
||||
Reader & m_reader;
|
||||
|
||||
|
@ -317,9 +250,11 @@ public:
|
|||
}
|
||||
|
||||
// It's guaranteed that |writeBlockCallback| will not be called for empty block.
|
||||
void Freeze(Writer & writer, WriteBlockCallback const & writeBlockCallback) const
|
||||
template <class WriterT>
|
||||
void Freeze(WriterT & writer, WriteBlockCallback const & writeBlockCallback, uint16_t blockSize = 64) const
|
||||
{
|
||||
typename Map::Header header;
|
||||
header.m_blockSize = blockSize;
|
||||
|
||||
auto const startOffset = writer.Pos();
|
||||
header.Write(writer);
|
||||
|
@ -331,7 +266,7 @@ public:
|
|||
for (auto const & id : m_ids)
|
||||
builder.set(id, true);
|
||||
|
||||
coding::FreezeVisitor<Writer> visitor(writer);
|
||||
coding::FreezeVisitor<WriterT> visitor(writer);
|
||||
succinct::rs_bit_vector(&builder).map(visitor);
|
||||
}
|
||||
|
||||
|
@ -340,11 +275,11 @@ public:
|
|||
|
||||
{
|
||||
MemWriter<std::vector<uint8_t>> writer(variables);
|
||||
for (size_t i = 0; i < m_values.size(); i += Map::kBlockSize)
|
||||
for (size_t i = 0; i < m_values.size(); i += blockSize)
|
||||
{
|
||||
offsets.push_back(static_cast<uint32_t>(variables.size()));
|
||||
|
||||
auto const endOffset = std::min(i + Map::kBlockSize, m_values.size());
|
||||
auto const endOffset = std::min(i + blockSize, m_values.size());
|
||||
CHECK_GREATER(endOffset, i, ());
|
||||
writeBlockCallback(writer, m_values.cbegin() + i, m_values.cbegin() + endOffset);
|
||||
}
|
||||
|
@ -357,7 +292,7 @@ public:
|
|||
builder.push_back(offset);
|
||||
|
||||
header.m_positionsOffset = base::checked_cast<uint32_t>(writer.Pos() - startOffset);
|
||||
coding::FreezeVisitor<Writer> visitor(writer);
|
||||
coding::FreezeVisitor<WriterT> visitor(writer);
|
||||
succinct::elias_fano(&builder).map(visitor);
|
||||
}
|
||||
|
||||
|
@ -370,7 +305,6 @@ public:
|
|||
auto const endOffset = writer.Pos();
|
||||
|
||||
writer.Seek(startOffset);
|
||||
CHECK_EQUAL(header.m_endianness, 0, ("|m_endianness| should be set to little-endian."));
|
||||
header.Write(writer);
|
||||
writer.Seek(endOffset);
|
||||
}
|
||||
|
|
|
@ -22300,7 +22300,7 @@
|
|||
es = Descarga mapa mundial
|
||||
eu = Deskargatu munduko mapa
|
||||
fi = Lataa maailmankartta
|
||||
fr = Télécharcher la carte du monde
|
||||
fr = Télécharger la carte du monde
|
||||
it = Scarica la mappa del mondo
|
||||
pl = Pobierz mapę świata
|
||||
pt = Descarregar o mapa mundial
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Translations
|
||||
|
||||
Adding and updating translations is easy!
|
||||
1. Change the translation file you want, e.g. [strings.txt](../data/strings/strings.txt)
|
||||
1. Change the translation file you want, e.g. [strings.txt](../data/strings/strings.txt) ([raw text version](https://raw.githubusercontent.com/organicmaps/organicmaps/master/data/strings/strings.txt))
|
||||
2. Commit your changes
|
||||
3. Send a pull request!
|
||||
|
||||
|
|
|
@ -51,9 +51,8 @@ DrapeEngine::DrapeEngine(Params && params)
|
|||
mode = Follow;
|
||||
}
|
||||
|
||||
double timeInBackground = 0.0;
|
||||
if (settings::Get(kLastEnterBackground, timeInBackground))
|
||||
timeInBackground = base::Timer::LocalTime() - timeInBackground;
|
||||
if (!settings::Get(kLastEnterBackground, m_startBackgroundTime))
|
||||
m_startBackgroundTime = base::Timer::LocalTime();
|
||||
|
||||
std::vector<PostprocessRenderer::Effect> effects;
|
||||
|
||||
|
@ -69,7 +68,7 @@ DrapeEngine::DrapeEngine(Params && params)
|
|||
//}
|
||||
|
||||
MyPositionController::Params mpParams(mode,
|
||||
timeInBackground,
|
||||
base::Timer::LocalTime() - m_startBackgroundTime,
|
||||
params.m_hints,
|
||||
params.m_isRoutingActive,
|
||||
params.m_isAutozoomEnabled,
|
||||
|
|
|
@ -151,28 +151,26 @@ MyPositionController::MyPositionController(Params && params, ref_ptr<DrapeNotifi
|
|||
{
|
||||
using namespace location;
|
||||
|
||||
m_mode = PendingPosition;
|
||||
if (m_hints.m_isFirstLaunch)
|
||||
{
|
||||
m_mode = PendingPosition;
|
||||
m_desiredInitMode = Follow;
|
||||
}
|
||||
else if (m_hints.m_isLaunchByDeepLink)
|
||||
{
|
||||
m_mode = NotFollowNoPosition;
|
||||
m_desiredInitMode = NotFollow;
|
||||
}
|
||||
else if (params.m_timeInBackground >= kMaxTimeInBackgroundSec)
|
||||
{
|
||||
m_mode = PendingPosition;
|
||||
m_desiredInitMode = Follow;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore PendingPosition mode (and start location service on platform side accordingly)
|
||||
// if we have routing mode or FollowXXX desired mode (usually loaded from settings).
|
||||
m_desiredInitMode = params.m_initMode;
|
||||
m_mode = (params.m_isRoutingActive || df::IsModeChangeViewport(m_desiredInitMode)) ?
|
||||
PendingPosition : NotFollowNoPosition;
|
||||
|
||||
// Do not start position if we ended previous session without it.
|
||||
if (!params.m_isRoutingActive && m_desiredInitMode == NotFollowNoPosition)
|
||||
m_mode = NotFollowNoPosition;
|
||||
}
|
||||
|
||||
m_pendingStarted = (m_mode == PendingPosition);
|
||||
|
@ -333,7 +331,6 @@ void MyPositionController::ResetRenderShape()
|
|||
|
||||
void MyPositionController::NextMode(ScreenBase const & screen)
|
||||
{
|
||||
|
||||
// Skip switching to next mode while we are waiting for position.
|
||||
if (IsWaitingForLocation())
|
||||
{
|
||||
|
@ -341,12 +338,18 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start looking for location.
|
||||
if (m_mode == location::NotFollowNoPosition)
|
||||
{
|
||||
ResetNotification(m_locationWaitingNotifyId);
|
||||
ChangeMode(location::PendingPosition);
|
||||
|
||||
if (!m_isPositionAssigned)
|
||||
{
|
||||
// This is the first user location request (button touch) after controller's initialization
|
||||
// with some previous not Follow state. The new mode will be Follow to center on the position.
|
||||
m_desiredInitMode = location::Follow;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -455,12 +458,6 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
|||
ResetRoutingNotFollowTimer();
|
||||
newMode = location::NotFollow;
|
||||
}
|
||||
else if (m_mode == location::PendingPosition && newMode < location::Follow)
|
||||
{
|
||||
// This is the first user location request (button touch) after controller's initialization
|
||||
// with some previous not Follow state. New mode will be Follow to move on current position.
|
||||
newMode = location::Follow;
|
||||
}
|
||||
|
||||
ChangeMode(newMode);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ set(SRC
|
|||
features_tests.cpp
|
||||
helpers.cpp
|
||||
helpers.hpp
|
||||
mwm_playground.cpp
|
||||
)
|
||||
|
||||
omim_add_test(${PROJECT_NAME} ${SRC})
|
||||
|
|
90
generator/generator_integration_tests/mwm_playground.cpp
Normal file
90
generator/generator_integration_tests/mwm_playground.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/cross_mwm_connector_serialization.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "coding/map_uint32_to_val.hpp"
|
||||
|
||||
#include "base/scope_guard.hpp"
|
||||
|
||||
#include "3party/succinct/elias_fano_compressed_list.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
platform::LocalCountryFile MakeFile(std::string name, int64_t version)
|
||||
{
|
||||
return { GetPlatform().WritableDir() + std::to_string(version),
|
||||
platform::CountryFile(std::move(name)), version };
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(CrossMwmWeights)
|
||||
{
|
||||
classificator::Load();
|
||||
|
||||
FrozenDataSource dataSource;
|
||||
auto const res = dataSource.RegisterMap(MakeFile("Austria_Lower Austria_Wien", 220314));
|
||||
TEST_EQUAL(res.second, MwmSet::RegResult::Success, ());
|
||||
|
||||
auto const handle = dataSource.GetMwmHandleById(res.first);
|
||||
auto reader = handle.GetValue()->m_cont.GetReader(CROSS_MWM_FILE_TAG);
|
||||
LOG(LINFO, ("Section size =", reader.Size()));
|
||||
|
||||
using CrossMwmID = base::GeoObjectId;
|
||||
using namespace routing;
|
||||
CrossMwmConnector<CrossMwmID> connector;
|
||||
CrossMwmConnectorBuilder<CrossMwmID> builder(connector);
|
||||
|
||||
builder.DeserializeTransitions(VehicleType::Car, reader);
|
||||
builder.DeserializeWeights(reader);
|
||||
|
||||
//std::vector<connector::Weight> weights(connector.GetNumEnters() * connector.GetNumExits());
|
||||
|
||||
using IdxWeightT = std::pair<uint32_t, uint32_t>;
|
||||
std::vector<IdxWeightT> idx2weight;
|
||||
|
||||
connector.ForEachEnter([&](uint32_t enterIdx, Segment const & enter)
|
||||
{
|
||||
connector.ForEachExit([&](uint32_t exitIdx, Segment const & exit)
|
||||
{
|
||||
uint32_t const idx = connector.GetWeightIndex(enterIdx, exitIdx);
|
||||
uint32_t const weight = connector.GetWeight(enterIdx, exitIdx);
|
||||
//weights[idx] = weight;
|
||||
|
||||
if (weight > 0)
|
||||
idx2weight.emplace_back(idx, weight);
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
std::string const filePath = "cross_mwm_weights.ef";
|
||||
SCOPE_GUARD(deleteFile, [&filePath]() { base::DeleteFileX(filePath); });
|
||||
|
||||
{
|
||||
succinct::elias_fano_compressed_list efList(weights);
|
||||
succinct::mapper::freeze(efList, filePath.c_str());
|
||||
|
||||
LOG(LINFO, ("EF list size =", FileReader(filePath).Size()));
|
||||
}
|
||||
|
||||
base::EraseIf(weights, [](connector::Weight w) { return w == 0; });
|
||||
LOG(LINFO, ("Raw no-zeroes size =", weights.size() * sizeof(connector::Weight)));
|
||||
|
||||
{
|
||||
succinct::elias_fano_compressed_list efList(weights);
|
||||
succinct::mapper::freeze(efList, filePath.c_str());
|
||||
|
||||
LOG(LINFO, ("EF list no-zeroes size =", FileReader(filePath).Size()));
|
||||
}
|
||||
*/
|
||||
|
||||
CrossMwmConnectorBuilderEx<CrossMwmID> builder1;
|
||||
std::vector<uint8_t> buffer;
|
||||
builder1.SetAndWriteWeights(std::move(idx2weight), buffer);
|
||||
LOG(LINFO, ("Map size =", buffer.size()));
|
||||
}
|
|
@ -134,7 +134,9 @@ void TestAltitudes(DataSource const & dataSource, MwmSet::MwmId const & mwmId,
|
|||
std::string const & mwmPath, bool hasAltitudeExpected,
|
||||
AltitudeGetter & expectedAltitudes)
|
||||
{
|
||||
AltitudeLoaderCached loader(dataSource, mwmId);
|
||||
auto const handle = dataSource.GetMwmHandleById(mwmId);
|
||||
TEST(handle.IsAlive(), ());
|
||||
AltitudeLoaderCached loader(*handle.GetValue());
|
||||
TEST_EQUAL(loader.HasAltitudes(), hasAltitudeExpected, ());
|
||||
|
||||
auto processor = [&expectedAltitudes, &loader](FeatureType & f, uint32_t const & id)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "routing_common/maxspeed_conversion.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
#include "indexer/index_builder.hpp"
|
||||
#include "indexer/map_style_reader.hpp"
|
||||
|
||||
|
|
|
@ -99,8 +99,6 @@ set(SRC
|
|||
metadata_serdes.hpp
|
||||
mwm_set.cpp
|
||||
mwm_set.hpp
|
||||
postcodes.cpp
|
||||
postcodes.hpp
|
||||
postcodes_matcher.cpp # it's in indexer due to editor which is in indexer and depends on postcodes_marcher
|
||||
postcodes_matcher.hpp # it's in indexer due to editor which is in indexer and depends on postcodes_marcher
|
||||
rank_table.cpp
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "indexer/altitude_loader.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/succinct_mapper.hpp"
|
||||
|
@ -32,14 +32,8 @@ void LoadAndMap(size_t dataSize, ReaderSource<FilesContainerR::TReader> & src, T
|
|||
}
|
||||
} // namespace
|
||||
|
||||
AltitudeLoaderBase::AltitudeLoaderBase(DataSource const & dataSource, MwmSet::MwmId const & mwmId)
|
||||
: m_handle(dataSource.GetMwmHandleById(mwmId))
|
||||
AltitudeLoaderBase::AltitudeLoaderBase(MwmValue const & mwmValue)
|
||||
{
|
||||
if (!m_handle.IsAlive())
|
||||
return;
|
||||
|
||||
auto const & mwmValue = *m_handle.GetValue();
|
||||
|
||||
m_countryFileName = mwmValue.GetCountryFileName();
|
||||
|
||||
if (!mwmValue.m_cont.IsExist(ALTITUDES_FILE_TAG))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include "indexer/feature_altitude.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "coding/memory_region.hpp"
|
||||
|
||||
|
@ -10,16 +9,17 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "3party/succinct/elias_fano.hpp"
|
||||
#include "3party/succinct/rs_bit_vector.hpp"
|
||||
|
||||
class DataSource;
|
||||
class MwmValue;
|
||||
|
||||
namespace feature
|
||||
{
|
||||
class AltitudeLoaderBase
|
||||
{
|
||||
public:
|
||||
AltitudeLoaderBase(DataSource const & dataSource, MwmSet::MwmId const & mwmId);
|
||||
explicit AltitudeLoaderBase(MwmValue const & mwmValue);
|
||||
|
||||
/// \returns altitude of feature with |featureId|. All items of the returned vector are valid
|
||||
/// or the returned vector is empty.
|
||||
|
@ -37,14 +37,13 @@ private:
|
|||
std::unique_ptr<FilesContainerR::TReader> m_reader;
|
||||
AltitudeHeader m_header;
|
||||
std::string m_countryFileName;
|
||||
MwmSet::MwmHandle m_handle;
|
||||
};
|
||||
|
||||
class AltitudeLoaderCached : public AltitudeLoaderBase
|
||||
{
|
||||
public:
|
||||
AltitudeLoaderCached(DataSource const & dataSource, MwmSet::MwmId const & mwmId)
|
||||
: AltitudeLoaderBase(dataSource, mwmId)
|
||||
explicit AltitudeLoaderCached(MwmValue const & mwmValue)
|
||||
: AltitudeLoaderBase(mwmValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -73,17 +73,15 @@ unique_ptr<CentersTable> CentersTable::LoadV1(Reader & reader)
|
|||
Header header;
|
||||
header.Read(reader);
|
||||
|
||||
auto geometryParamsSubreader =
|
||||
reader.CreateSubReader(header.m_geometryParamsOffset, header.m_geometryParamsSize);
|
||||
if (!geometryParamsSubreader)
|
||||
return {};
|
||||
NonOwningReaderSource geometryParamsSource(*geometryParamsSubreader);
|
||||
NonOwningReaderSource src(reader, header.m_geometryParamsOffset,
|
||||
header.m_geometryParamsOffset + header.m_geometryParamsSize);
|
||||
|
||||
serial::GeometryCodingParams codingParams;
|
||||
codingParams.Load(geometryParamsSource);
|
||||
auto minX = ReadPrimitiveFromSource<uint32_t>(geometryParamsSource);
|
||||
auto minY = ReadPrimitiveFromSource<uint32_t>(geometryParamsSource);
|
||||
auto maxX = ReadPrimitiveFromSource<uint32_t>(geometryParamsSource);
|
||||
auto maxY = ReadPrimitiveFromSource<uint32_t>(geometryParamsSource);
|
||||
codingParams.Load(src);
|
||||
auto minX = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto minY = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto maxX = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto maxY = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
m2::RectD limitRect(PointUToPointD({minX, minY}, kPointCoordBits),
|
||||
PointUToPointD({maxX, maxY}, kPointCoordBits));
|
||||
|
||||
|
@ -102,15 +100,16 @@ bool CentersTable::Init(Reader & reader, serial::GeometryCodingParams const & co
|
|||
m_limitRect = limitRect;
|
||||
// Decodes block encoded by writeBlockCallback from CentersTableBuilder::Freeze.
|
||||
auto const readBlockCallback = [&](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
vector<m2::PointU> & values) {
|
||||
values.resize(blockSize);
|
||||
uint64_t delta = ReadVarUint<uint64_t>(source);
|
||||
values[0] = coding::DecodePointDeltaFromUint(delta, m_codingParams.GetBasePoint());
|
||||
vector<m2::PointU> & values)
|
||||
{
|
||||
values.reserve(blockSize);
|
||||
|
||||
for (size_t i = 1; i < blockSize && source.Size() > 0; ++i)
|
||||
auto prev = m_codingParams.GetBasePoint();
|
||||
while (source.Size() > 0)
|
||||
{
|
||||
delta = ReadVarUint<uint64_t>(source);
|
||||
values[i] = coding::DecodePointDeltaFromUint(delta, values[i - 1]);
|
||||
auto const pt = coding::DecodePointDeltaFromUint(ReadVarUint<uint64_t>(source), prev);
|
||||
values.push_back(pt);
|
||||
prev = pt;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <memory>
|
||||
|
||||
class FilesContainerR;
|
||||
class IntervalIndexIFace;
|
||||
|
||||
class IndexFactory
|
||||
{
|
||||
|
@ -22,6 +21,7 @@ public:
|
|||
inline version::MwmVersion const & GetMwmVersion() const { return m_version; }
|
||||
inline feature::DataHeader const & GetHeader() const { return m_header; }
|
||||
inline feature::RegionData const & GetRegionData() const { return m_regionData; }
|
||||
inline void MoveRegionData(feature::RegionData & data) { data = std::move(m_regionData); }
|
||||
|
||||
template <typename Reader>
|
||||
std::unique_ptr<IntervalIndex<Reader, uint32_t>> CreateIndex(Reader const & reader) const
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/scale_index.hpp"
|
||||
#include "indexer/unique_index.hpp"
|
||||
|
||||
#include "platform/mwm_version.hpp"
|
||||
|
||||
|
@ -57,15 +59,16 @@ public:
|
|||
// iterate through intervals
|
||||
for (auto const & i : intervals)
|
||||
{
|
||||
index.ForEachInIntervalAndScale(i.first, i.second, scale, [&](uint64_t /* key */, uint32_t value) {
|
||||
if (!checkUnique(value))
|
||||
return;
|
||||
m_fn(value, *src);
|
||||
index.ForEachInIntervalAndScale(i.first, i.second, scale, [&](uint64_t /* key */, uint32_t value)
|
||||
{
|
||||
if (checkUnique(value))
|
||||
m_fn(value, *src);
|
||||
});
|
||||
if (m_stop())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check created features container.
|
||||
// Need to do it on a per-mwm basis, because Drape relies on features in a sorted order.
|
||||
// Touched (created, edited) features reading.
|
||||
|
@ -165,15 +168,13 @@ unique_ptr<MwmInfo> DataSource::CreateInfo(platform::LocalCountryFile const & lo
|
|||
auto info = make_unique<MwmInfoEx>();
|
||||
info->m_bordersRect = h.GetBounds();
|
||||
|
||||
pair<int, int> const scaleR = h.GetScaleRange();
|
||||
auto const scaleR = h.GetScaleRange();
|
||||
info->m_minScale = static_cast<uint8_t>(scaleR.first);
|
||||
info->m_maxScale = static_cast<uint8_t>(scaleR.second);
|
||||
info->m_version = value.GetMwmVersion();
|
||||
// Copying to drop the const qualifier.
|
||||
feature::RegionData regionData(value.GetRegionData());
|
||||
info->m_data = regionData;
|
||||
value.m_factory.MoveRegionData(info->m_data);
|
||||
|
||||
return unique_ptr<MwmInfo>(move(info));
|
||||
return info;
|
||||
}
|
||||
|
||||
unique_ptr<MwmValue> DataSource::CreateValue(MwmInfo & info) const
|
||||
|
@ -186,7 +187,7 @@ unique_ptr<MwmValue> DataSource::CreateValue(MwmInfo & info) const
|
|||
|
||||
p->SetTable(dynamic_cast<MwmInfoEx &>(info));
|
||||
ASSERT(p->GetHeader().IsMWMSuitable(), ());
|
||||
return unique_ptr<MwmValue>(move(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
pair<MwmSet::MwmId, MwmSet::RegResult> DataSource::RegisterMap(LocalCountryFile const & localFile)
|
||||
|
@ -231,9 +232,10 @@ void DataSource::ForEachInIntervals(ReaderCallback const & fn, covering::Coverin
|
|||
void DataSource::ForEachFeatureIDInRect(FeatureIdCallback const & f, m2::RectD const & rect,
|
||||
int scale) const
|
||||
{
|
||||
auto readFeatureId = [&f](uint32_t index, FeatureSource & src) {
|
||||
auto readFeatureId = [&f](uint32_t index, FeatureSource & src)
|
||||
{
|
||||
if (src.GetFeatureStatus(index) != FeatureStatus::Deleted)
|
||||
f(src.GetFeatureId(index));
|
||||
f({ src.GetMwmId(), index });
|
||||
};
|
||||
|
||||
ReadMWMFunctor readFunctor(*m_factory, readFeatureId);
|
||||
|
@ -313,6 +315,7 @@ void DataSource::ReadFeatures(FeatureCallback const & fn, vector<FeatureID> cons
|
|||
ft = src->GetModifiedFeature(fidIter->m_index);
|
||||
else
|
||||
ft = src->GetOriginalFeature(fidIter->m_index);
|
||||
|
||||
CHECK(ft, ());
|
||||
fn(*ft);
|
||||
} while (++fidIter != endIter && id == fidIter->m_mwmId);
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "indexer/cell_id.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/feature_covering.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
#include "indexer/feature_source.hpp"
|
||||
#include "indexer/features_vector.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
#include "indexer/scale_index.hpp"
|
||||
#include "indexer/unique_index.hpp"
|
||||
|
||||
#include "coding/files_container.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
@ -20,8 +10,6 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
class DataSource : public MwmSet
|
||||
{
|
||||
public:
|
||||
|
@ -58,6 +46,11 @@ public:
|
|||
return ReadFeatures(fn, {feature});
|
||||
}
|
||||
|
||||
std::unique_ptr<FeatureSource> CreateFeatureSource(DataSource::MwmHandle const & handle) const
|
||||
{
|
||||
return (*m_factory)(handle);
|
||||
}
|
||||
|
||||
protected:
|
||||
using ReaderCallback = std::function<void(MwmSet::MwmHandle const & handle,
|
||||
covering::CoveringGetter & cov, int scale)>;
|
||||
|
@ -67,13 +60,13 @@ protected:
|
|||
void ForEachInIntervals(ReaderCallback const & fn, covering::CoveringMode mode,
|
||||
m2::RectD const & rect, int scale) const;
|
||||
|
||||
/// MwmSet overrides:
|
||||
/// @name MwmSet overrides
|
||||
/// @{
|
||||
std::unique_ptr<MwmInfo> CreateInfo(platform::LocalCountryFile const & localFile) const override;
|
||||
std::unique_ptr<MwmValue> CreateValue(MwmInfo & info) const override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
friend class FeaturesLoaderGuard;
|
||||
|
||||
std::unique_ptr<FeatureSourceFactory> m_factory;
|
||||
};
|
||||
|
||||
|
@ -86,16 +79,14 @@ public:
|
|||
};
|
||||
|
||||
/// Guard for loading features from particular MWM by demand.
|
||||
/// @note This guard is suitable when mwm is loaded.
|
||||
/// @note If you need to work with FeatureType from different threads you need to use
|
||||
/// a unique FeaturesLoaderGuard instance for every thread. But construction of instances of
|
||||
/// FeaturesLoaderGuard should be serialized. For an example of concurrent extracting feature
|
||||
/// details please see ConcurrentFeatureParsingTest.
|
||||
/// a unique FeaturesLoaderGuard instance for every thread.
|
||||
/// For an example of concurrent extracting feature details please see ConcurrentFeatureParsingTest.
|
||||
class FeaturesLoaderGuard
|
||||
{
|
||||
public:
|
||||
FeaturesLoaderGuard(DataSource const & dataSource, DataSource::MwmId const & id)
|
||||
: m_handle(dataSource.GetMwmHandleById(id)), m_source((*dataSource.m_factory)(m_handle))
|
||||
: m_handle(dataSource.GetMwmHandleById(id)), m_source(dataSource.CreateFeatureSource(m_handle))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "indexer/feature_utils.hpp"
|
||||
#include "indexer/feature_visibility.hpp"
|
||||
#include "indexer/map_object.hpp"
|
||||
#include "indexer/postcodes.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
#include "indexer/shared_load_info.hpp"
|
||||
|
||||
|
@ -188,13 +187,10 @@ uint8_t ReadByte(TSource & src)
|
|||
FeatureType::FeatureType(SharedLoadInfo const * loadInfo, vector<uint8_t> && buffer,
|
||||
indexer::MetadataDeserializer * metadataDeserializer)
|
||||
: m_loadInfo(loadInfo)
|
||||
, m_data(buffer)
|
||||
, m_data(std::move(buffer))
|
||||
, m_metadataDeserializer(metadataDeserializer)
|
||||
{
|
||||
CHECK(m_loadInfo, ());
|
||||
|
||||
ASSERT(m_loadInfo->GetMWMFormat() >= version::Format::v11 && m_metadataDeserializer,
|
||||
(m_loadInfo->GetMWMFormat()));
|
||||
CHECK(m_loadInfo && m_metadataDeserializer, ());
|
||||
|
||||
m_header = Header(m_data);
|
||||
}
|
||||
|
@ -522,23 +518,10 @@ void FeatureType::ParseMetadata()
|
|||
try
|
||||
{
|
||||
UNUSED_VALUE(m_metadataDeserializer->Get(m_id.m_index, m_metadata));
|
||||
|
||||
// December 19 - September 20 mwm compatibility
|
||||
auto postcodesReader = m_loadInfo->GetPostcodesReader();
|
||||
if (postcodesReader)
|
||||
{
|
||||
auto postcodes = indexer::Postcodes::Load(*postcodesReader->GetPtr());
|
||||
CHECK(postcodes, ());
|
||||
string postcode;
|
||||
auto const havePostcode = postcodes->Get(m_id.m_index, postcode);
|
||||
CHECK(!havePostcode || !postcode.empty(), (havePostcode, postcode));
|
||||
if (havePostcode)
|
||||
m_metadata.Set(feature::Metadata::FMD_POSTCODE, postcode);
|
||||
}
|
||||
}
|
||||
catch (Reader::OpenException const &)
|
||||
{
|
||||
// now ignore exception because not all mwm have needed sections
|
||||
LOG(LERROR, ("Error reading metadata", m_id));
|
||||
}
|
||||
|
||||
m_parsed.m_metadata = true;
|
||||
|
@ -556,7 +539,7 @@ void FeatureType::ParseMetaIds()
|
|||
}
|
||||
catch (Reader::OpenException const &)
|
||||
{
|
||||
// now ignore exception because not all mwm have needed sections
|
||||
LOG(LERROR, ("Error reading metadata", m_id));
|
||||
}
|
||||
|
||||
m_parsed.m_metaIds = true;
|
||||
|
@ -717,7 +700,7 @@ void FeatureType::GetPreferredNames(bool allowTranslit, int8_t deviceLang, featu
|
|||
if (!HasName())
|
||||
return;
|
||||
|
||||
auto const mwmInfo = GetID().m_mwmId.GetInfo();
|
||||
auto const & mwmInfo = m_id.m_mwmId.GetInfo();
|
||||
if (!mwmInfo)
|
||||
return;
|
||||
|
||||
|
@ -738,7 +721,7 @@ void FeatureType::GetReadableName(bool allowTranslit, int8_t deviceLang, feature
|
|||
if (!HasName())
|
||||
return;
|
||||
|
||||
auto const mwmInfo = GetID().m_mwmId.GetInfo();
|
||||
auto const & mwmInfo = m_id.m_mwmId.GetInfo();
|
||||
if (!mwmInfo)
|
||||
return;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
|
||||
std::vector<m2::PointD> GetTrianglesAsPoints(int scale);
|
||||
|
||||
void SetID(FeatureID const & id) { m_id = id; }
|
||||
void SetID(FeatureID id) { m_id = std::move(id); }
|
||||
FeatureID const & GetID() const { return m_id; }
|
||||
|
||||
void ResetGeometry();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#include "indexer/feature_source.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string ToString(FeatureStatus fs)
|
||||
std::string ToString(FeatureStatus fs)
|
||||
{
|
||||
switch (fs)
|
||||
{
|
||||
|
@ -21,7 +19,7 @@ FeatureSource::FeatureSource(MwmSet::MwmHandle const & handle) : m_handle(handle
|
|||
return;
|
||||
|
||||
auto const & value = *m_handle.GetValue();
|
||||
m_vector = make_unique<FeaturesVector>(value.m_cont, value.GetHeader(), value.m_table.get());
|
||||
m_vector = std::make_unique<FeaturesVector>(value.m_cont, value.GetHeader(), value.m_table.get());
|
||||
}
|
||||
|
||||
size_t FeatureSource::GetNumFeatures() const
|
||||
|
@ -29,16 +27,16 @@ size_t FeatureSource::GetNumFeatures() const
|
|||
if (!m_handle.IsAlive())
|
||||
return 0;
|
||||
|
||||
ASSERT(m_vector.get(), ());
|
||||
ASSERT(m_vector, ());
|
||||
return m_vector->GetNumFeatures();
|
||||
}
|
||||
|
||||
unique_ptr<FeatureType> FeatureSource::GetOriginalFeature(uint32_t index) const
|
||||
std::unique_ptr<FeatureType> FeatureSource::GetOriginalFeature(uint32_t index) const
|
||||
{
|
||||
ASSERT(m_handle.IsAlive(), ());
|
||||
ASSERT(m_vector != nullptr, ());
|
||||
ASSERT(m_vector, ());
|
||||
auto ft = m_vector->GetByIndex(index);
|
||||
ft->SetID(FeatureID(m_handle.GetId(), index));
|
||||
ft->SetID({ GetMwmId(), index });
|
||||
return ft;
|
||||
}
|
||||
|
||||
|
@ -47,9 +45,9 @@ FeatureStatus FeatureSource::GetFeatureStatus(uint32_t index) const
|
|||
return FeatureStatus::Untouched;
|
||||
}
|
||||
|
||||
unique_ptr<FeatureType> FeatureSource::GetModifiedFeature(uint32_t index) const { return {}; }
|
||||
std::unique_ptr<FeatureType> FeatureSource::GetModifiedFeature(uint32_t index) const { return {}; }
|
||||
|
||||
void FeatureSource::ForEachAdditionalFeature(m2::RectD const & rect, int scale,
|
||||
function<void(uint32_t)> const & fn) const
|
||||
std::function<void(uint32_t)> const & fn) const
|
||||
{
|
||||
}
|
||||
|
|
|
@ -29,26 +29,26 @@ class FeatureSource
|
|||
{
|
||||
public:
|
||||
explicit FeatureSource(MwmSet::MwmHandle const & handle);
|
||||
virtual ~FeatureSource() {}
|
||||
virtual ~FeatureSource() = default;
|
||||
|
||||
size_t GetNumFeatures() const;
|
||||
|
||||
std::unique_ptr<FeatureType> GetOriginalFeature(uint32_t index) const;
|
||||
|
||||
FeatureID GetFeatureId(uint32_t index) const { return FeatureID(m_handle.GetId(), index); }
|
||||
MwmSet::MwmId const & GetMwmId() const { return m_handle.GetId(); }
|
||||
|
||||
virtual FeatureStatus GetFeatureStatus(uint32_t index) const;
|
||||
|
||||
virtual std::unique_ptr<FeatureType> GetModifiedFeature(uint32_t index) const;
|
||||
|
||||
// Runs |fn| for each feature, that is not present in the mwm.
|
||||
// Runs |fn| for each feature, that is not present in the mwm.
|
||||
virtual void ForEachAdditionalFeature(m2::RectD const & rect, int scale,
|
||||
std::function<void(uint32_t)> const & fn) const;
|
||||
|
||||
protected:
|
||||
MwmSet::MwmHandle const & m_handle;
|
||||
std::unique_ptr<FeaturesVector> m_vector;
|
||||
}; // class FeatureSource
|
||||
};
|
||||
|
||||
// Lightweight FeatureSource factory. Each DataSource owns factory object.
|
||||
class FeatureSourceFactory
|
||||
|
|
|
@ -69,14 +69,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
using Id2OsmMapT = MapUint32ToValue<uint64_t>;
|
||||
private:
|
||||
DataSource const & m_dataSource;
|
||||
MwmSet::MwmId m_mwmId;
|
||||
FilesContainerR::TReader m_reader;
|
||||
|
||||
std::unique_ptr<MapUint32ToValue<uint64_t>> m_mapNodes;
|
||||
std::unique_ptr<MapUint32ToValue<uint64_t>> m_mapWays;
|
||||
std::unique_ptr<MapUint32ToValue<uint64_t>> m_mapRelations;
|
||||
std::unique_ptr<Id2OsmMapT> m_mapNodes;
|
||||
std::unique_ptr<Id2OsmMapT> m_mapWays;
|
||||
std::unique_ptr<Id2OsmMapT> m_mapRelations;
|
||||
|
||||
std::unique_ptr<Reader> m_nodesReader;
|
||||
std::unique_ptr<Reader> m_waysReader;
|
||||
|
@ -285,6 +286,8 @@ public:
|
|||
EnsurePadding(sink, offset);
|
||||
}
|
||||
|
||||
using Id2OsmMapT = FeatureIdToGeoObjectIdOneWay::Id2OsmMapT;
|
||||
|
||||
template <typename Reader>
|
||||
static void DeserializeV0(Reader & reader, HeaderV0 const & header,
|
||||
FeatureIdToGeoObjectIdOneWay & map)
|
||||
|
@ -297,10 +300,9 @@ public:
|
|||
map.m_waysReader = reader.CreateSubReader(header.m_waysOffset, waysSize);
|
||||
map.m_relationsReader = reader.CreateSubReader(header.m_relationsOffset, relationsSize);
|
||||
|
||||
map.m_mapNodes = MapUint32ToValue<uint64_t>::Load(*map.m_nodesReader, ReadBlockCallback);
|
||||
map.m_mapWays = MapUint32ToValue<uint64_t>::Load(*map.m_waysReader, ReadBlockCallback);
|
||||
map.m_mapRelations =
|
||||
MapUint32ToValue<uint64_t>::Load(*map.m_relationsReader, ReadBlockCallback);
|
||||
map.m_mapNodes = Id2OsmMapT::Load(*map.m_nodesReader, ReadBlockCallback);
|
||||
map.m_mapWays = Id2OsmMapT::Load(*map.m_waysReader, ReadBlockCallback);
|
||||
map.m_mapRelations = Id2OsmMapT::Load(*map.m_relationsReader, ReadBlockCallback);
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
|
@ -357,10 +359,9 @@ private:
|
|||
static void ReadBlockCallback(NonOwningReaderSource & src, uint32_t blockSize,
|
||||
std::vector<uint64_t> & values)
|
||||
{
|
||||
values.clear();
|
||||
values.reserve(blockSize);
|
||||
for (size_t i = 0; i < blockSize && src.Size() > 0; ++i)
|
||||
values.emplace_back(ReadVarUint<uint64_t>(src));
|
||||
while (src.Size() > 0)
|
||||
values.push_back(ReadVarUint<uint64_t>(src));
|
||||
}
|
||||
|
||||
static void WriteBlockCallback(Writer & writer, std::vector<uint64_t>::const_iterator begin,
|
||||
|
|
|
@ -28,7 +28,7 @@ void MetadataDeserializer::Header::Read(Reader & reader)
|
|||
bool MetadataDeserializer::Get(uint32_t featureId, feature::MetadataBase & meta)
|
||||
{
|
||||
MetaIds metaIds;
|
||||
if (!m_map->GetThreadsafe(featureId, metaIds))
|
||||
if (!GetIds(featureId, metaIds))
|
||||
return false;
|
||||
|
||||
lock_guard<mutex> guard(m_stringsMutex);
|
||||
|
@ -73,23 +73,21 @@ unique_ptr<MetadataDeserializer> MetadataDeserializer::Load(Reader & reader)
|
|||
|
||||
// Decodes block encoded by writeBlockCallback from MetadataBuilder::Freeze.
|
||||
auto const readBlockCallback = [&](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
vector<MetaIds> & values) {
|
||||
// We may have some unused values it the tail of the last block but it's ok because
|
||||
// default block size is 64.
|
||||
vector<MetaIds> & values)
|
||||
{
|
||||
values.resize(blockSize);
|
||||
for (size_t i = 0; i < blockSize && source.Size() > 0; ++i)
|
||||
{
|
||||
auto const size = ReadVarUint<uint32_t>(source);
|
||||
values[i].resize(size);
|
||||
CHECK_GREATER(size, 0, ());
|
||||
|
||||
for (auto & value : values[i])
|
||||
value.first = ReadPrimitiveFromSource<uint8_t>(source);
|
||||
|
||||
values[i][0].second = ReadVarUint<uint32_t>(source);
|
||||
for (size_t j = 1; j < values[i].size(); ++j)
|
||||
{
|
||||
int32_t delta = ReadVarInt<int32_t>(source);
|
||||
values[i][j].second = values[i][j - 1].second + delta;
|
||||
}
|
||||
values[i][j].second = values[i][j - 1].second + ReadVarInt<int32_t>(source);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
#include "indexer/data_factory.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
#include "platform/mwm_version.hpp"
|
||||
|
||||
|
@ -115,7 +114,7 @@ public:
|
|||
friend class MwmSet;
|
||||
|
||||
MwmId() = default;
|
||||
MwmId(std::shared_ptr<MwmInfo> const & info) : m_info(info) {}
|
||||
explicit MwmId(std::shared_ptr<MwmInfo> const & info) : m_info(info) {}
|
||||
|
||||
void Reset() { m_info.reset(); }
|
||||
bool IsAlive() const { return (m_info && m_info->GetStatus() != MwmInfo::STATUS_DEREGISTERED); }
|
||||
|
@ -155,14 +154,11 @@ public:
|
|||
|
||||
MwmHandle & operator=(MwmHandle && handle);
|
||||
|
||||
protected:
|
||||
MwmId m_mwmId;
|
||||
|
||||
private:
|
||||
friend class MwmSet;
|
||||
|
||||
MwmHandle(MwmSet & mwmSet, MwmId const & mwmId, std::unique_ptr<MwmValue> && value);
|
||||
|
||||
MwmId m_mwmId;
|
||||
MwmSet * m_mwmSet;
|
||||
std::unique_ptr<MwmValue> m_value;
|
||||
|
||||
|
@ -286,6 +282,7 @@ public:
|
|||
|
||||
/// Get ids of all mwms. Some of them may be with not active status.
|
||||
/// In that case, LockValue returns NULL.
|
||||
/// @todo In fact, std::shared_ptr<MwmInfo> is a MwmId. Seems like better to make vector<MwmId> interface.
|
||||
void GetMwmsInfo(std::vector<std::shared_ptr<MwmInfo>> & info) const;
|
||||
|
||||
// Clears caches and mwm's registry. All known mwms won't be marked as DEREGISTERED.
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
#include "indexer/postcodes.hpp"
|
||||
|
||||
#include "coding/varint.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/checked_cast.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace indexer
|
||||
{
|
||||
void Postcodes::Header::Read(Reader & reader)
|
||||
{
|
||||
static_assert(is_same<underlying_type_t<Version>, uint8_t>::value, "");
|
||||
NonOwningReaderSource source(reader);
|
||||
m_version = static_cast<Version>(ReadPrimitiveFromSource<uint8_t>(source));
|
||||
CHECK_EQUAL(base::Underlying(m_version), base::Underlying(Version::V0), ());
|
||||
m_stringsOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_stringsSize = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_postcodesMapOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_postcodesMapSize = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
}
|
||||
|
||||
bool Postcodes::Get(uint32_t id, std::string & postcode)
|
||||
{
|
||||
uint32_t postcodeId;
|
||||
if (!m_map->Get(id, postcodeId))
|
||||
return false;
|
||||
|
||||
CHECK_LESS_OR_EQUAL(postcodeId, m_strings.GetNumStrings(), ());
|
||||
postcode = m_strings.ExtractString(*m_stringsSubreader, postcodeId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
unique_ptr<Postcodes> Postcodes::Load(Reader & reader)
|
||||
{
|
||||
auto postcodes = make_unique<Postcodes>();
|
||||
postcodes->m_version = Version::V0;
|
||||
|
||||
Header header;
|
||||
header.Read(reader);
|
||||
|
||||
postcodes->m_stringsSubreader =
|
||||
reader.CreateSubReader(header.m_stringsOffset, header.m_stringsSize);
|
||||
if (!postcodes->m_stringsSubreader)
|
||||
return {};
|
||||
postcodes->m_strings.InitializeIfNeeded(*postcodes->m_stringsSubreader);
|
||||
|
||||
postcodes->m_mapSubreader =
|
||||
reader.CreateSubReader(header.m_postcodesMapOffset, header.m_postcodesMapSize);
|
||||
if (!postcodes->m_mapSubreader)
|
||||
return {};
|
||||
|
||||
// Decodes block encoded by writeBlockCallback from PostcodesBuilder::Freeze.
|
||||
auto const readBlockCallback = [&](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
vector<uint32_t> & values) {
|
||||
// We may have some unused values it the tail of the last block but it's ok because
|
||||
// default block size is 64.
|
||||
values.resize(blockSize);
|
||||
for (size_t i = 0; i < blockSize && source.Size() > 0; ++i)
|
||||
values[i] = ReadVarUint<uint32_t>(source);
|
||||
};
|
||||
|
||||
postcodes->m_map = Map::Load(*postcodes->m_mapSubreader, readBlockCallback);
|
||||
if (!postcodes->m_map)
|
||||
return {};
|
||||
|
||||
return postcodes;
|
||||
}
|
||||
} // namespace indexer
|
|
@ -1,55 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "coding/map_uint32_to_val.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/text_storage.hpp"
|
||||
#include "coding/write_to_sink.hpp"
|
||||
#include "coding/writer.hpp"
|
||||
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace indexer
|
||||
{
|
||||
// December 2019 - September 2020 mwm compatibility
|
||||
class Postcodes
|
||||
{
|
||||
public:
|
||||
enum class Version : uint8_t
|
||||
{
|
||||
V0 = 0,
|
||||
Latest = V0
|
||||
};
|
||||
|
||||
struct Header
|
||||
{
|
||||
void Read(Reader & reader);
|
||||
|
||||
Version m_version = Version::Latest;
|
||||
// All offsets are relative to the start of the section (offset of header is zero).
|
||||
uint32_t m_stringsOffset = 0;
|
||||
uint32_t m_stringsSize = 0;
|
||||
uint32_t m_postcodesMapOffset = 0;
|
||||
uint32_t m_postcodesMapSize = 0;
|
||||
};
|
||||
|
||||
static std::unique_ptr<Postcodes> Load(Reader & reader);
|
||||
|
||||
// Tries to get |postcode| of the feature with id |featureId|. Returns false if table
|
||||
// does not have entry for the feature.
|
||||
[[nodiscard]] bool Get(uint32_t featureId, std::string & postcode);
|
||||
|
||||
private:
|
||||
using Map = MapUint32ToValue<uint32_t>;
|
||||
|
||||
std::unique_ptr<Reader> m_stringsSubreader;
|
||||
coding::BlockedTextStorageReader m_strings;
|
||||
std::unique_ptr<Map> m_map;
|
||||
std::unique_ptr<Reader> m_mapSubreader;
|
||||
Version m_version = Version::Latest;
|
||||
};
|
||||
} // namespace indexer
|
|
@ -1,9 +1,9 @@
|
|||
#include "indexer/utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace indexer
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
MwmSet::MwmHandle FindWorld(DataSource const & dataSource,
|
||||
vector<shared_ptr<MwmInfo>> const & infos)
|
||||
{
|
||||
|
|
|
@ -176,19 +176,17 @@
|
|||
|
||||
- (BOOL)openUrl:(NSString *)urlString inSafari:(BOOL)safari
|
||||
{
|
||||
NSURL * url = [[NSURL alloc] initWithString:urlString];
|
||||
if (!url)
|
||||
NSURLComponents * urlc = [NSURLComponents componentsWithString:urlString];
|
||||
if (!urlc)
|
||||
{
|
||||
NSAssert(false, @"Invalid URL %@", urlString);
|
||||
return NO;
|
||||
}
|
||||
NSString * scheme = url.scheme;
|
||||
if (!([scheme isEqualToString:@"https"] || [scheme isEqualToString:@"http"]))
|
||||
{
|
||||
NSAssert(false, @"Incorrect url scheme %@", scheme);
|
||||
return NO;
|
||||
}
|
||||
// Some links in OSM do not have a scheme: www.some.link
|
||||
if (!urlc.scheme)
|
||||
urlc.scheme = @"http";
|
||||
|
||||
NSURL * url = urlc.URL;
|
||||
if (safari)
|
||||
{
|
||||
[UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil];
|
||||
|
|
|
@ -885,7 +885,7 @@
|
|||
|
||||
"error_enter_correct_name" = "Voer een juiste naam in";
|
||||
|
||||
"bookmark_lists" = "lijsten";
|
||||
"bookmark_lists" = "Lijsten";
|
||||
|
||||
/* Do not display all bookmark lists on the map */
|
||||
"bookmark_lists_hide_all" = "Alles verbergen";
|
||||
|
@ -938,7 +938,7 @@
|
|||
|
||||
"button_layer_subway" = "Metro";
|
||||
|
||||
"layers_title" = "Map layers";
|
||||
"layers_title" = "Kaartweergave";
|
||||
|
||||
"subway_data_unavailable" = "Metrokaart is niet beschikbaar";
|
||||
|
||||
|
@ -982,17 +982,17 @@
|
|||
|
||||
"power_managment_setting_manual_max" = "Maximale energiebesparing";
|
||||
|
||||
"driving_options_title" = "Omweginstellingen";
|
||||
"driving_options_title" = "Route instellingen";
|
||||
|
||||
"driving_options_subheader" = "Vermijden op elke route";
|
||||
|
||||
"avoid_tolls" = "Tolwegen";
|
||||
|
||||
"avoid_unpaved" = "Aardewegen";
|
||||
"avoid_unpaved" = "Onverharde wegen";
|
||||
|
||||
"avoid_ferry" = "Ferries";
|
||||
"avoid_ferry" = "Veerdiensten";
|
||||
|
||||
"avoid_motorways" = "Hoofdverkeerswegen";
|
||||
"avoid_motorways" = "Autosnelwegen";
|
||||
|
||||
"unable_to_calc_alert_title" = "Kan route niet opbouwen";
|
||||
|
||||
|
|
|
@ -1386,7 +1386,7 @@
|
|||
|
||||
"type.amenity.prison" = "Hapishane";
|
||||
|
||||
"type.amenity.pub" = "Bar";
|
||||
"type.amenity.pub" = "Meyhane";
|
||||
|
||||
"type.amenity.public_bookcase" = "Kitap Değişimi";
|
||||
|
||||
|
@ -1469,7 +1469,7 @@
|
|||
|
||||
"type.amenity.vending_machine.excrement_bags" = "Dışkı Torbası Dağıtıcı";
|
||||
|
||||
"type.amenity.parcel_locker" = "Posta Kutusu";
|
||||
"type.amenity.parcel_locker" = "Kilitlenebilen Kutu Dolaplar";
|
||||
|
||||
"type.amenity.vending_machine.fuel" = "Yakıt Dağıtıcı";
|
||||
|
||||
|
@ -1477,7 +1477,7 @@
|
|||
|
||||
"type.amenity.waste_basket" = "Çöp Kutusu";
|
||||
|
||||
"type.amenity.waste_disposal" = "Çöp Kutusu";
|
||||
"type.amenity.waste_disposal" = "Çöp Konteyneri";
|
||||
|
||||
"type.amenity.waste_transfer_station" = "Atık Transfer İstasyonu";
|
||||
|
||||
|
@ -2101,7 +2101,7 @@
|
|||
|
||||
"type.historic.fort" = "Hisar";
|
||||
|
||||
"type.historic.memorial" = "Anıt";
|
||||
"type.historic.memorial" = "Abide";
|
||||
|
||||
"type.historic.memorial.plaque" = "Hatıra Plaketi";
|
||||
|
||||
|
@ -2327,7 +2327,7 @@
|
|||
|
||||
"type.man_made.wastewater_plant" = "Atıksu Tesisi";
|
||||
|
||||
"type.man_made.water_tap" = "Çeşme Suyu";
|
||||
"type.man_made.water_tap" = "Su Musluğu";
|
||||
|
||||
"type.man_made.water_tower" = "Su Kulesi";
|
||||
|
||||
|
@ -2425,19 +2425,19 @@
|
|||
|
||||
"type.office" = "Ofis";
|
||||
|
||||
"type.office.company" = "Şirket bürosu";
|
||||
"type.office.company" = "Şirket Bürosu";
|
||||
|
||||
"type.office.estate_agent" = "Emlakçı";
|
||||
|
||||
"type.office.government" = "Devlet dairesi";
|
||||
"type.office.government" = "Devlet Dairesi";
|
||||
|
||||
"type.office.insurance" = "Sigorta Acentası";
|
||||
"type.office.insurance" = "Sigorta Acentesi";
|
||||
|
||||
"type.office.lawyer" = "Avukatlık bürosu";
|
||||
"type.office.lawyer" = "Avukatlık Bürosu";
|
||||
|
||||
"type.office.ngo" = "STK Binası";
|
||||
|
||||
"type.office.telecommunication" = "Cep telefonu operatörü";
|
||||
"type.office.telecommunication" = "Cep Telefonu Operatörü";
|
||||
|
||||
"type.organic.only" = "Organic";
|
||||
|
||||
|
@ -2699,7 +2699,7 @@
|
|||
|
||||
"type.shop.beauty" = "Güzellik Salonu";
|
||||
|
||||
"type.shop.beverages" = "İçecek";
|
||||
"type.shop.beverages" = "İçecekler";
|
||||
|
||||
"type.shop.bicycle" = "Bisikletçi";
|
||||
|
||||
|
@ -2875,7 +2875,7 @@
|
|||
|
||||
"type.tourism.alpine_hut" = "Dağda Konaklama";
|
||||
|
||||
"type.tourism.apartment" = "Apart otel";
|
||||
"type.tourism.apartment" = "Apart Otel";
|
||||
|
||||
"type.tourism.artwork" = "Sanat";
|
||||
|
||||
|
|
|
@ -144,10 +144,9 @@ void Framework::VisualizeCrossMwmTransitionsInRect(m2::RectD const & rect)
|
|||
MwmSet::MwmHandle handle = m_featuresFetcher.GetDataSource().GetMwmHandleById(mwmId);
|
||||
CHECK(handle.IsAlive(), ());
|
||||
|
||||
FilesContainerR::TReader reader(routing::connector::GetReader<CrossMwmID>(handle.GetValue()->m_cont));
|
||||
ReaderSource src(reader);
|
||||
auto reader = routing::connector::GetReader<CrossMwmID>(handle.GetValue()->m_cont);
|
||||
routing::CrossMwmConnectorBuilder<CrossMwmID> builder(connector);
|
||||
builder.DeserializeTransitions(routing::VehicleType::Car, src);
|
||||
builder.DeserializeTransitions(routing::VehicleType::Car, reader);
|
||||
|
||||
static uint32_t counter = 0;
|
||||
colors.emplace(mwmId, colorList[counter++ % std::size(colorList)]);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "platform/local_country_file_utils.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "coding/var_serial_vector.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
|
|
@ -38,8 +38,8 @@ void GetRegularEdges(geometry::PointWithAltitude const & junction, IRoadGraph co
|
|||
}
|
||||
} // namespace
|
||||
|
||||
Graph::Graph(DataSource const & dataSource, shared_ptr<CarModelFactory> carModelFactory)
|
||||
: m_graph(dataSource, IRoadGraph::Mode::ObeyOnewayTag, carModelFactory)
|
||||
Graph::Graph(DataSource & dataSource, shared_ptr<CarModelFactory> carModelFactory)
|
||||
: m_dataSource(dataSource, nullptr /* numMwmIDs */), m_graph(m_dataSource, IRoadGraph::Mode::ObeyOnewayTag, carModelFactory)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/features_road_graph.hpp"
|
||||
#include "routing/road_graph.hpp"
|
||||
|
||||
|
@ -16,8 +17,6 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class DataSource;
|
||||
|
||||
namespace openlr
|
||||
{
|
||||
// TODO(mgsergio): Inherit from FeaturesRoadGraph.
|
||||
|
@ -29,7 +28,7 @@ public:
|
|||
using EdgeVector = routing::FeaturesRoadGraph::EdgeVector;
|
||||
using Junction = geometry::PointWithAltitude;
|
||||
|
||||
Graph(DataSource const & dataSource, std::shared_ptr<routing::CarModelFactory> carModelFactory);
|
||||
Graph(DataSource & dataSource, std::shared_ptr<routing::CarModelFactory> carModelFactory);
|
||||
|
||||
// Appends edges such as that edge.GetStartJunction() == junction to the |edges|.
|
||||
void GetOutgoingEdges(geometry::PointWithAltitude const & junction, EdgeListT & edges);
|
||||
|
@ -55,6 +54,7 @@ public:
|
|||
|
||||
using EdgeCacheT = std::map<Junction, EdgeListT>;
|
||||
private:
|
||||
routing::MwmDataSource m_dataSource;
|
||||
routing::FeaturesRoadGraph m_graph;
|
||||
EdgeCacheT m_outgoingCache, m_ingoingCache;
|
||||
};
|
||||
|
|
|
@ -216,79 +216,11 @@ void CopyWithoutOffsets(InputIterator start, InputIterator stop, OutputIterator
|
|||
copy(from, to, out);
|
||||
}
|
||||
|
||||
class SegmentsDecoderV1
|
||||
{
|
||||
public:
|
||||
SegmentsDecoderV1(DataSource const & dataSource, unique_ptr<CarModelFactory> cmf)
|
||||
: m_roadGraph(dataSource, IRoadGraph::Mode::ObeyOnewayTag, move(cmf))
|
||||
, m_infoGetter(dataSource)
|
||||
, m_router(m_roadGraph, m_infoGetter)
|
||||
{
|
||||
}
|
||||
|
||||
bool DecodeSegment(LinearSegment const & segment, DecodedPath & path, Stats & stat)
|
||||
{
|
||||
double const kOffsetToleranceM = 10;
|
||||
|
||||
auto const & ref = segment.m_locationReference;
|
||||
|
||||
path.m_segmentId.Set(segment.m_segmentId);
|
||||
|
||||
m_points.clear();
|
||||
for (auto const & point : ref.m_points)
|
||||
m_points.emplace_back(point);
|
||||
|
||||
auto positiveOffsetM = ref.m_positiveOffsetMeters;
|
||||
if (positiveOffsetM >= m_points[0].m_distanceToNextPointM)
|
||||
{
|
||||
LOG(LWARNING, ("Wrong positive offset for segment:", segment.m_segmentId));
|
||||
positiveOffsetM = 0;
|
||||
}
|
||||
|
||||
auto negativeOffsetM = ref.m_negativeOffsetMeters;
|
||||
if (negativeOffsetM >= m_points[m_points.size() - 2].m_distanceToNextPointM)
|
||||
{
|
||||
LOG(LWARNING, ("Wrong negative offset for segment:", segment.m_segmentId));
|
||||
negativeOffsetM = 0;
|
||||
}
|
||||
|
||||
{
|
||||
double expectedLength = 0;
|
||||
for (size_t i = 0; i + 1 < m_points.size(); ++i)
|
||||
expectedLength += m_points[i].m_distanceToNextPointM;
|
||||
|
||||
if (positiveOffsetM + negativeOffsetM >= expectedLength)
|
||||
{
|
||||
LOG(LINFO, ("Skipping", segment.m_segmentId, "due to wrong positive/negative offsets."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (positiveOffsetM + negativeOffsetM + kOffsetToleranceM >= expectedLength)
|
||||
{
|
||||
LOG(LINFO, ("Too tight positive and negative offsets, setting them to zero."));
|
||||
positiveOffsetM = 0;
|
||||
negativeOffsetM = 0;
|
||||
++stat.m_tightOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_router.Go(m_points, positiveOffsetM, negativeOffsetM, path.m_path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
FeaturesRoadGraph m_roadGraph;
|
||||
RoadInfoGetter m_infoGetter;
|
||||
Router m_router;
|
||||
vector<WayPoint> m_points;
|
||||
};
|
||||
|
||||
class SegmentsDecoderV2
|
||||
{
|
||||
public:
|
||||
SegmentsDecoderV2(DataSource const & dataSource, unique_ptr<CarModelFactory> cmf)
|
||||
SegmentsDecoderV2(DataSource & dataSource, unique_ptr<CarModelFactory> cmf)
|
||||
: m_dataSource(dataSource), m_graph(dataSource, move(cmf)), m_infoGetter(dataSource)
|
||||
{
|
||||
}
|
||||
|
@ -377,7 +309,7 @@ private:
|
|||
class SegmentsDecoderV3
|
||||
{
|
||||
public:
|
||||
SegmentsDecoderV3(DataSource const & dataSource, unique_ptr<CarModelFactory> carModelFactory)
|
||||
SegmentsDecoderV3(DataSource & dataSource, unique_ptr<CarModelFactory> carModelFactory)
|
||||
: m_dataSource(dataSource), m_graph(dataSource, move(carModelFactory)), m_infoGetter(dataSource)
|
||||
{
|
||||
}
|
||||
|
@ -503,18 +435,12 @@ bool OpenLRDecoder::SegmentsFilter::Matches(LinearSegment const & segment) const
|
|||
}
|
||||
|
||||
// OpenLRDecoder -----------------------------------------------------------------------------
|
||||
OpenLRDecoder::OpenLRDecoder(vector<FrozenDataSource> const & dataSources,
|
||||
OpenLRDecoder::OpenLRDecoder(vector<FrozenDataSource> & dataSources,
|
||||
CountryParentNameGetter const & countryParentNameGetter)
|
||||
: m_dataSources(dataSources), m_countryParentNameGetter(countryParentNameGetter)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenLRDecoder::DecodeV1(vector<LinearSegment> const & segments, uint32_t const numThreads,
|
||||
vector<DecodedPath> & paths)
|
||||
{
|
||||
Decode<SegmentsDecoderV1, Stats>(segments, numThreads, paths);
|
||||
}
|
||||
|
||||
void OpenLRDecoder::DecodeV2(vector<LinearSegment> const & segments, uint32_t const numThreads,
|
||||
vector<DecodedPath> & paths)
|
||||
{
|
||||
|
@ -531,8 +457,8 @@ template <typename Decoder, typename Stats>
|
|||
void OpenLRDecoder::Decode(vector<LinearSegment> const & segments,
|
||||
uint32_t const numThreads, vector<DecodedPath> & paths)
|
||||
{
|
||||
auto const worker = [&segments, &paths, numThreads, this](size_t threadNum, DataSource const & dataSource,
|
||||
Stats & stat) {
|
||||
auto const worker = [&](size_t threadNum, DataSource & dataSource, Stats & stat)
|
||||
{
|
||||
size_t constexpr kBatchSize = GetOptimalBatchSize();
|
||||
size_t constexpr kProgressFrequency = 100;
|
||||
|
||||
|
|
|
@ -40,13 +40,10 @@ public:
|
|||
bool const m_multipointsOnly;
|
||||
};
|
||||
|
||||
OpenLRDecoder(std::vector<FrozenDataSource> const & dataSources,
|
||||
OpenLRDecoder(std::vector<FrozenDataSource> & dataSources,
|
||||
CountryParentNameGetter const & countryParentNameGetter);
|
||||
|
||||
// Maps partner segments to mwm paths. |segments| should be sorted by partner id.
|
||||
void DecodeV1(std::vector<LinearSegment> const & segments, uint32_t const numThreads,
|
||||
std::vector<DecodedPath> & paths);
|
||||
|
||||
void DecodeV2(std::vector<LinearSegment> const & segments, uint32_t const numThreads,
|
||||
std::vector<DecodedPath> & paths);
|
||||
|
||||
|
@ -58,7 +55,7 @@ private:
|
|||
void Decode(std::vector<LinearSegment> const & segments, uint32_t const numThreads,
|
||||
std::vector<DecodedPath> & paths);
|
||||
|
||||
std::vector<FrozenDataSource> const & m_dataSources;
|
||||
std::vector<FrozenDataSource> & m_dataSources;
|
||||
CountryParentNameGetter m_countryParentNameGetter;
|
||||
};
|
||||
} // namespace openlr
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "drape_frontend/drape_api.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/features_road_graph.hpp"
|
||||
#include "routing/road_graph.hpp"
|
||||
|
||||
|
@ -37,8 +38,8 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using namespace openlr;
|
||||
|
||||
namespace openlr
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class TrafficDrawerDelegate : public TrafficDrawerDelegateBase
|
||||
|
@ -125,7 +126,7 @@ class PointsControllerDelegate : public PointsControllerDelegateBase
|
|||
public:
|
||||
explicit PointsControllerDelegate(Framework & framework)
|
||||
: m_framework(framework)
|
||||
, m_dataSource(framework.GetDataSource())
|
||||
, m_dataSource(const_cast<DataSource &>(GetDataSource()), nullptr /* numMwmIDs */)
|
||||
, m_roadGraph(m_dataSource, routing::IRoadGraph::Mode::ObeyOnewayTag,
|
||||
std::make_unique<routing::CarModelFactory>(storage::CountryParentGetter{}))
|
||||
{
|
||||
|
@ -135,7 +136,8 @@ public:
|
|||
{
|
||||
std::vector<m2::PointD> points;
|
||||
auto const & rect = m_framework.GetCurrentViewport();
|
||||
auto const pushPoint = [&points, &rect](m2::PointD const & point) {
|
||||
auto const pushPoint = [&points, &rect](m2::PointD const & point)
|
||||
{
|
||||
if (!rect.IsPointInside(point))
|
||||
return;
|
||||
for (auto const & p : points)
|
||||
|
@ -146,7 +148,8 @@ public:
|
|||
points.push_back(point);
|
||||
};
|
||||
|
||||
auto const pushFeaturePoints = [&pushPoint](FeatureType & ft) {
|
||||
auto const pushFeaturePoints = [&pushPoint](FeatureType & ft)
|
||||
{
|
||||
if (ft.GetGeomType() != feature::GeomType::Line)
|
||||
return;
|
||||
auto const roadClass = ftypes::GetHighwayClass(feature::TypesHolder(ft));
|
||||
|
@ -158,7 +161,7 @@ public:
|
|||
ft.ForEachPoint(pushPoint, scales::GetUpperScale());
|
||||
};
|
||||
|
||||
m_dataSource.ForEachInRect(pushFeaturePoints, rect, scales::GetUpperScale());
|
||||
GetDataSource().ForEachInRect(pushFeaturePoints, rect, scales::GetUpperScale());
|
||||
return points;
|
||||
}
|
||||
|
||||
|
@ -169,34 +172,34 @@ public:
|
|||
|
||||
std::vector<FeaturePoint> points;
|
||||
m2::PointD pointOnFt;
|
||||
indexer::ForEachFeatureAtPoint(m_dataSource, [&points, &p, &pointOnFt](FeatureType & ft) {
|
||||
if (ft.GetGeomType() != feature::GeomType::Line)
|
||||
return;
|
||||
indexer::ForEachFeatureAtPoint(GetDataSource(), [&points, &p, &pointOnFt](FeatureType & ft)
|
||||
{
|
||||
if (ft.GetGeomType() != feature::GeomType::Line)
|
||||
return;
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
auto minDistance = std::numeric_limits<double>::max();
|
||||
auto bestPointIndex = kInvalidIndex;
|
||||
for (size_t i = 0; i < ft.GetPointsCount(); ++i)
|
||||
auto minDistance = std::numeric_limits<double>::max();
|
||||
auto bestPointIndex = kInvalidIndex;
|
||||
for (size_t i = 0; i < ft.GetPointsCount(); ++i)
|
||||
{
|
||||
auto const & fp = ft.GetPoint(i);
|
||||
auto const distance = mercator::DistanceOnEarth(fp, p);
|
||||
if (PointsMatch(fp, p) && distance < minDistance)
|
||||
{
|
||||
auto const & fp = ft.GetPoint(i);
|
||||
auto const distance = mercator::DistanceOnEarth(fp, p);
|
||||
if (PointsMatch(fp, p) && distance < minDistance)
|
||||
{
|
||||
bestPointIndex = i;
|
||||
minDistance = distance;
|
||||
}
|
||||
bestPointIndex = i;
|
||||
minDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestPointIndex != kInvalidIndex)
|
||||
{
|
||||
points.emplace_back(ft.GetID(), bestPointIndex);
|
||||
pointOnFt = ft.GetPoint(bestPointIndex);
|
||||
}
|
||||
}, p);
|
||||
|
||||
if (bestPointIndex != kInvalidIndex)
|
||||
{
|
||||
points.emplace_back(ft.GetID(), bestPointIndex);
|
||||
pointOnFt = ft.GetPoint(bestPointIndex);
|
||||
}
|
||||
},
|
||||
p);
|
||||
return std::make_pair(points, pointOnFt);
|
||||
|
||||
}
|
||||
|
||||
std::vector<m2::PointD> GetReachablePoints(m2::PointD const & p) const override
|
||||
|
@ -228,14 +231,15 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
DataSource const & GetDataSource() const { return m_framework.GetDataSource(); }
|
||||
|
||||
Framework & m_framework;
|
||||
DataSource const & m_dataSource;
|
||||
routing::MwmDataSource m_dataSource;
|
||||
routing::FeaturesRoadGraph m_roadGraph;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openlr
|
||||
{
|
||||
|
||||
MainWindow::MainWindow(Framework & framework)
|
||||
: m_framework(framework)
|
||||
{
|
||||
|
|
|
@ -278,7 +278,6 @@ int main(int argc, char * argv[])
|
|||
std::vector<DecodedPath> paths(segments.size());
|
||||
switch (FLAGS_algo_version)
|
||||
{
|
||||
case 1: decoder.DecodeV1(segments, numThreads, paths); break;
|
||||
case 2: decoder.DecodeV2(segments, numThreads, paths); break;
|
||||
case 3: decoder.DecodeV3(segments, numThreads, paths); break;
|
||||
default: CHECK(false, ("Wrong algorithm version."));
|
||||
|
|
|
@ -35,6 +35,7 @@ set(SRC
|
|||
cross_mwm_graph.hpp
|
||||
cross_mwm_ids.hpp
|
||||
cross_mwm_index_graph.hpp
|
||||
data_source.hpp
|
||||
directions_engine.cpp
|
||||
directions_engine.hpp
|
||||
directions_engine_helpers.cpp
|
||||
|
|
|
@ -12,8 +12,7 @@ using namespace std;
|
|||
using namespace turns;
|
||||
using namespace ftypes;
|
||||
|
||||
CarDirectionsEngine::CarDirectionsEngine(DataSource const & dataSource,
|
||||
shared_ptr<NumMwmIds> numMwmIds)
|
||||
CarDirectionsEngine::CarDirectionsEngine(MwmDataSource & dataSource, shared_ptr<NumMwmIds> numMwmIds)
|
||||
: DirectionsEngine(dataSource, move(numMwmIds))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace routing
|
|||
class CarDirectionsEngine : public DirectionsEngine
|
||||
{
|
||||
public:
|
||||
CarDirectionsEngine(DataSource const & dataSource, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
CarDirectionsEngine(MwmDataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
protected:
|
||||
virtual size_t GetTurnDirection(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include "coding/map_uint32_to_val.hpp"
|
||||
#include "coding/sparse_vector.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
@ -23,7 +24,10 @@ namespace connector
|
|||
{
|
||||
double constexpr kNoRoute = 0.0;
|
||||
|
||||
/// @todo Can we make cross-mwm Weight in minutes and store it as uint16_t?
|
||||
/// Will get 2x less memory without quality loss (minutes is fine granularity for cross-mwm routing).
|
||||
using Weight = uint32_t;
|
||||
Weight constexpr kNoRouteStored = 0;
|
||||
|
||||
enum class WeightsLoadState
|
||||
{
|
||||
|
@ -164,7 +168,7 @@ public:
|
|||
|
||||
bool WeightsWereLoaded() const
|
||||
{
|
||||
switch (m_weightsLoadState)
|
||||
switch (m_weights.m_loadState)
|
||||
{
|
||||
case connector::WeightsLoadState::Unknown:
|
||||
case connector::WeightsLoadState::ReadyToLoad: return false;
|
||||
|
@ -184,8 +188,8 @@ public:
|
|||
using WeightT = connector::Weight;
|
||||
WeightT GetWeight(size_t enterIdx, size_t exitIdx) const
|
||||
{
|
||||
auto const idx = GetWeightIndex(enterIdx, exitIdx);
|
||||
return (m_weights.Has(idx) ? m_weights.Get(idx) : connector::kNoRoute);
|
||||
WeightT weight;
|
||||
return (m_weights.Get(GetWeightIndex(enterIdx, exitIdx), weight) ? weight : connector::kNoRouteStored);
|
||||
}
|
||||
|
||||
size_t GetMemorySize() const
|
||||
|
@ -244,7 +248,7 @@ private:
|
|||
void AddEdge(Segment const & segment, uint32_t enterIdx, uint32_t exitIdx, EdgeListT & edges) const
|
||||
{
|
||||
auto const weight = GetWeight(enterIdx, exitIdx);
|
||||
if (weight != connector::kNoRoute)
|
||||
if (weight != connector::kNoRouteStored)
|
||||
edges.emplace_back(segment, RouteWeight::FromCrossMwmWeight(weight));
|
||||
}
|
||||
|
||||
|
@ -289,14 +293,45 @@ private:
|
|||
using MwmID2FeatureIDMapT = std::unordered_map<CrossMwmId, uint32_t, connector::HashKey>;
|
||||
MwmID2FeatureIDMapT m_crossMwmIdToFeatureId;
|
||||
|
||||
/// @name Used for lazy weights loading.
|
||||
/// @{
|
||||
connector::WeightsLoadState m_weightsLoadState = connector::WeightsLoadState::Unknown;
|
||||
uint64_t m_weightsOffset = 0;
|
||||
WeightT m_granularity = 0;
|
||||
/// @}
|
||||
|
||||
// Weight is the time required for the route to pass edge, measured in seconds rounded upwards.
|
||||
coding::SparseVector<WeightT> m_weights;
|
||||
struct Weights
|
||||
{
|
||||
connector::WeightsLoadState m_loadState = connector::WeightsLoadState::Unknown;
|
||||
uint64_t m_offset = 0;
|
||||
WeightT m_granularity = 0;
|
||||
uint16_t m_version;
|
||||
|
||||
coding::SparseVector<WeightT> m_v1;
|
||||
|
||||
std::unique_ptr<MapUint32ToValue<WeightT>> m_v2;
|
||||
std::unique_ptr<Reader> m_reader;
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
if (m_version < 2)
|
||||
return m_v1.Empty();
|
||||
else
|
||||
return m_v2 == nullptr;
|
||||
}
|
||||
|
||||
bool Get(uint32_t idx, WeightT & weight) const
|
||||
{
|
||||
if (m_version < 2)
|
||||
{
|
||||
if (m_v1.Has(idx))
|
||||
{
|
||||
weight = m_v1.Get(idx);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_v2->Get(idx, weight);
|
||||
}
|
||||
}
|
||||
|
||||
} m_weights;
|
||||
};
|
||||
} // namespace routing
|
||||
|
|
|
@ -210,11 +210,17 @@ protected:
|
|||
void CheckBitsPerCrossMwmId(uint32_t bitsPerCrossMwmId) const;
|
||||
|
||||
public:
|
||||
template <class Source>
|
||||
void DeserializeTransitions(VehicleType requiredVehicle, Source & src)
|
||||
void DeserializeTransitions(VehicleType requiredVehicle, FilesContainerR::TReader & reader)
|
||||
{
|
||||
CHECK(m_c.m_weightsLoadState == connector::WeightsLoadState::Unknown, ());
|
||||
DeserializeTransitions(requiredVehicle, *(reader.GetPtr()));
|
||||
}
|
||||
|
||||
template <class Reader>
|
||||
void DeserializeTransitions(VehicleType requiredVehicle, Reader & reader)
|
||||
{
|
||||
CHECK(m_c.m_weights.m_loadState == connector::WeightsLoadState::Unknown, ());
|
||||
|
||||
NonOwningReaderSource src(reader);
|
||||
Header header;
|
||||
header.Deserialize(src);
|
||||
CheckBitsPerCrossMwmId(header.GetBitsPerCrossMwmId());
|
||||
|
@ -259,46 +265,77 @@ public:
|
|||
", connector:", numExits));
|
||||
}
|
||||
|
||||
m_c.m_weightsOffset = weightsOffset;
|
||||
m_c.m_granularity = header.GetGranularity();
|
||||
m_c.m_weightsLoadState = connector::WeightsLoadState::ReadyToLoad;
|
||||
m_c.m_weights.m_offset = weightsOffset;
|
||||
m_c.m_weights.m_granularity = header.GetGranularity();
|
||||
m_c.m_weights.m_version = header.GetVersion();
|
||||
m_c.m_weights.m_loadState = connector::WeightsLoadState::ReadyToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
m_c.m_weightsLoadState = connector::WeightsLoadState::NotExists;
|
||||
m_c.m_weights.m_loadState = connector::WeightsLoadState::NotExists;
|
||||
}
|
||||
|
||||
template <class Source>
|
||||
void DeserializeWeights(Source & src)
|
||||
void DeserializeWeights(FilesContainerR::TReader & reader)
|
||||
{
|
||||
CHECK(m_c.m_weightsLoadState == connector::WeightsLoadState::ReadyToLoad, ());
|
||||
CHECK_GREATER(m_c.m_granularity, 0, ());
|
||||
DeserializeWeights(*(reader.GetPtr()));
|
||||
}
|
||||
|
||||
src.Skip(m_c.m_weightsOffset);
|
||||
/// @param[in] reader Initialized reader for the whole section (makes Skip inside).
|
||||
template <class Reader>
|
||||
void DeserializeWeights(Reader & reader)
|
||||
{
|
||||
CHECK(m_c.m_weights.m_loadState == connector::WeightsLoadState::ReadyToLoad, ());
|
||||
CHECK_GREATER(m_c.m_weights.m_granularity, 0, ());
|
||||
|
||||
size_t const amount = m_c.GetNumEnters() * m_c.GetNumExits();
|
||||
|
||||
// Do reserve memory here to avoid a lot of reallocations.
|
||||
// SparseVector will shrink final vector if needed.
|
||||
coding::SparseVectorBuilder<Weight> builder(amount);
|
||||
BitReader<Source> reader(src);
|
||||
|
||||
Weight prev = 1;
|
||||
for (size_t i = 0; i < amount; ++i)
|
||||
if (m_c.m_weights.m_version < 2)
|
||||
{
|
||||
if (reader.Read(1) != kNoRouteBit)
|
||||
NonOwningReaderSource src(reader);
|
||||
src.Skip(m_c.m_weights.m_offset);
|
||||
|
||||
// Do reserve memory here to avoid a lot of reallocations.
|
||||
// SparseVector will shrink final vector if needed.
|
||||
coding::SparseVectorBuilder<Weight> builder(amount);
|
||||
BitReader bitReader(src);
|
||||
|
||||
Weight prev = 1;
|
||||
for (size_t i = 0; i < amount; ++i)
|
||||
{
|
||||
Weight const delta = ReadDelta<Weight>(reader) - 1;
|
||||
Weight const current = DecodeZigZagDelta(prev, delta);
|
||||
builder.PushValue(current * m_c.m_granularity);
|
||||
prev = current;
|
||||
if (bitReader.Read(1) != kNoRouteBit)
|
||||
{
|
||||
Weight const delta = ReadDelta<Weight>(bitReader) - 1;
|
||||
Weight const current = DecodeZigZagDelta(prev, delta);
|
||||
builder.PushValue(current * m_c.m_weights.m_granularity);
|
||||
prev = current;
|
||||
}
|
||||
else
|
||||
builder.PushEmpty();
|
||||
}
|
||||
else
|
||||
builder.PushEmpty();
|
||||
|
||||
m_c.m_weights.m_v1 = builder.Build();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_c.m_weights.m_reader = reader.CreateSubReader(m_c.m_weights.m_offset, reader.Size() - m_c.m_weights.m_offset);
|
||||
m_c.m_weights.m_v2 = MapUint32ToValue<Weight>::Load(*(m_c.m_weights.m_reader),
|
||||
[granularity = m_c.m_weights.m_granularity](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
std::vector<Weight> & values)
|
||||
{
|
||||
values.resize(blockSize);
|
||||
|
||||
uint32_t prev = ReadVarUint<uint32_t>(source);
|
||||
values[0] = granularity * prev;
|
||||
|
||||
for (size_t i = 1; i < blockSize && source.Size() > 0; ++i)
|
||||
{
|
||||
prev += ReadVarInt<int32_t>(source);
|
||||
values[i] = granularity * prev;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
m_c.m_weights = builder.Build();
|
||||
m_c.m_weightsLoadState = connector::WeightsLoadState::Loaded;
|
||||
m_c.m_weights.m_loadState = connector::WeightsLoadState::Loaded;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -316,7 +353,10 @@ protected:
|
|||
using Weight = connector::Weight;
|
||||
using WeightsLoadState = connector::WeightsLoadState;
|
||||
|
||||
static uint32_t constexpr kLastVersion = 1;
|
||||
// 0 - initial version
|
||||
// 1 - removed dummy GeometryCodingParams
|
||||
// 2 - store weights as MapUint32ToValue
|
||||
static uint32_t constexpr kLastVersion = 2;
|
||||
static uint8_t constexpr kNoRouteBit = 0;
|
||||
static uint8_t constexpr kRouteBit = 1;
|
||||
|
||||
|
@ -420,6 +460,7 @@ protected:
|
|||
|
||||
void AddSection(Section const & section) { m_sections.push_back(section); }
|
||||
|
||||
uint32_t GetVersion() const { return m_version; }
|
||||
uint32_t GetNumTransitions() const { return m_numTransitions; }
|
||||
uint64_t GetSizeTransitions() const { return m_sizeTransitions; }
|
||||
Weight GetGranularity() const { return m_granularity; }
|
||||
|
@ -467,24 +508,34 @@ private:
|
|||
transition.Serialize(bitsPerOsmId, bitsPerMask, memWriter);
|
||||
}
|
||||
|
||||
static uint16_t constexpr kBlockSize = 256;
|
||||
|
||||
using Weight = typename BaseT::Weight;
|
||||
using IdxWeightT = std::pair<uint32_t, Weight>;
|
||||
|
||||
void WriteWeights(std::vector<uint8_t> & buffer) const
|
||||
{
|
||||
MemWriter<std::vector<uint8_t>> memWriter(buffer);
|
||||
BitWriter<MemWriter<std::vector<uint8_t>>> writer(memWriter);
|
||||
|
||||
connector::Weight prevWeight = 1;
|
||||
MapUint32ToValueBuilder<Weight> builder;
|
||||
for (auto const & w : m_weights)
|
||||
builder.Put(w.first, w.second);
|
||||
|
||||
MemWriter writer(buffer);
|
||||
builder.Freeze(writer, [](auto & writer, auto beg, auto end)
|
||||
{
|
||||
if (w != connector::kNoRoute)
|
||||
auto const NextStoredValue = [&beg]()
|
||||
{
|
||||
writer.Write(BaseT::kRouteBit, 1);
|
||||
auto const storedWeight = (w + BaseT::kGranularity - 1) / BaseT::kGranularity;
|
||||
WriteDelta(writer, EncodeZigZagDelta(prevWeight, storedWeight) + 1);
|
||||
prevWeight = storedWeight;
|
||||
return (*beg++ + BaseT::kGranularity - 1) / BaseT::kGranularity;
|
||||
};
|
||||
|
||||
Weight prev = NextStoredValue();
|
||||
WriteVarUint(writer, prev);
|
||||
while (beg != end)
|
||||
{
|
||||
Weight const storedWeight = NextStoredValue();
|
||||
WriteVarInt(writer, static_cast<int32_t>(storedWeight) - static_cast<int32_t>(prev));
|
||||
prev = storedWeight;
|
||||
}
|
||||
else
|
||||
writer.Write(BaseT::kNoRouteBit, 1);
|
||||
}
|
||||
}, kBlockSize);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -513,11 +564,15 @@ public:
|
|||
std::vector<uint8_t> weightsBuf;
|
||||
if (!m_weights.empty())
|
||||
{
|
||||
std::sort(m_weights.begin(), m_weights.end(), base::LessBy(&IdxWeightT::first));
|
||||
WriteWeights(weightsBuf);
|
||||
|
||||
header.AddSection(typename BaseT::Section(
|
||||
weightsBuf.size(), m_connector.GetNumEnters(), m_connector.GetNumExits(), m_vehicleType));
|
||||
}
|
||||
|
||||
// Use buffer serialization above, because BaseT::Header is not plain (vector<Section>)
|
||||
// and we are not able to calculate its final size.
|
||||
header.Serialize(sink);
|
||||
sink.Write(transitionsBuf.data(), transitionsBuf.size());
|
||||
sink.Write(weightsBuf.data(), weightsBuf.size());
|
||||
|
@ -538,25 +593,36 @@ public:
|
|||
{
|
||||
CHECK(m_vehicleType != VehicleType::Count, ("PrepareConnector should be called"));
|
||||
|
||||
m_weights.resize(m_connector.GetNumEnters() * m_connector.GetNumExits());
|
||||
m_weights.reserve(m_connector.GetNumEnters() * m_connector.GetNumExits());
|
||||
m_connector.ForEachEnter([&](uint32_t enterIdx, Segment const & enter)
|
||||
{
|
||||
m_connector.ForEachExit([&](uint32_t exitIdx, Segment const & exit)
|
||||
{
|
||||
auto const weight = calcWeight(enter, exit);
|
||||
auto const w = calcWeight(enter, exit);
|
||||
CHECK_LESS(w, std::numeric_limits<Weight>::max(), ());
|
||||
|
||||
// Edges weights should be >= astar heuristic, so use std::ceil.
|
||||
m_weights[m_connector.GetWeightIndex(enterIdx, exitIdx)] = static_cast<connector::Weight>(std::ceil(weight));
|
||||
if (w != connector::kNoRoute)
|
||||
m_weights.emplace_back(m_connector.GetWeightIndex(enterIdx, exitIdx), static_cast<Weight>(std::ceil(w)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Used in tests only.
|
||||
void SetAndWriteWeights(std::vector<IdxWeightT> && weights, std::vector<uint8_t> & buffer)
|
||||
{
|
||||
m_weights = std::move(weights);
|
||||
std::sort(m_weights.begin(), m_weights.end(), base::LessBy(&IdxWeightT::first));
|
||||
WriteWeights(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
// All accumulated transitions with road-mask inside.
|
||||
std::vector<typename BaseT::Transition> m_transitions;
|
||||
|
||||
// Weights for the current prepared connector. Used for VehicleType::Car only now.
|
||||
typename BaseT::ConnectorT m_connector;
|
||||
std::vector<typename BaseT::Weight> m_weights;
|
||||
std::vector<IdxWeightT> m_weights;
|
||||
VehicleType m_vehicleType = VehicleType::Count;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "routing/cross_mwm_graph.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/transit_graph.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
@ -22,14 +22,14 @@ CrossMwmGraph::CrossMwmGraph(shared_ptr<NumMwmIds> numMwmIds,
|
|||
shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn,
|
||||
DataSource & dataSource)
|
||||
MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource)
|
||||
, m_numMwmIds(numMwmIds)
|
||||
, m_numMwmTree(numMwmTree)
|
||||
, m_vehicleModelFactory(vehicleModelFactory)
|
||||
, m_countryRectFn(countryRectFn)
|
||||
, m_crossMwmIndexGraph(dataSource, numMwmIds, vehicleType)
|
||||
, m_crossMwmTransitGraph(dataSource, numMwmIds, VehicleType::Transit)
|
||||
, m_crossMwmIndexGraph(m_dataSource, vehicleType)
|
||||
, m_crossMwmTransitGraph(m_dataSource, VehicleType::Transit)
|
||||
{
|
||||
CHECK(m_numMwmIds, ());
|
||||
CHECK(m_vehicleModelFactory, ());
|
||||
|
@ -205,16 +205,14 @@ void CrossMwmGraph::GetTwinFeature(Segment const & segment, bool isOutgoing, vec
|
|||
});
|
||||
}
|
||||
|
||||
CrossMwmGraph::MwmStatus CrossMwmGraph::GetMwmStatus(NumMwmId numMwmId,
|
||||
string const & sectionName) const
|
||||
CrossMwmGraph::MwmStatus CrossMwmGraph::GetMwmStatus(NumMwmId numMwmId, string const & sectionName) const
|
||||
{
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(m_numMwmIds->GetFile(numMwmId));
|
||||
if (!handle.IsAlive())
|
||||
return MwmStatus::NotLoaded;
|
||||
|
||||
MwmValue const * value = handle.GetValue();
|
||||
CHECK(value != nullptr, ("Country file:", m_numMwmIds->GetFile(numMwmId)));
|
||||
return value->m_cont.IsExist(sectionName) ? MwmStatus::SectionExists : MwmStatus::NoSection;
|
||||
switch (m_dataSource.GetSectionStatus(numMwmId, sectionName))
|
||||
{
|
||||
case MwmDataSource::MwmNotLoaded: return MwmStatus::NotLoaded;
|
||||
case MwmDataSource::SectionExists: return MwmStatus::SectionExists;
|
||||
case MwmDataSource::NoSection: return MwmStatus::NoSection;
|
||||
}
|
||||
}
|
||||
|
||||
CrossMwmGraph::MwmStatus CrossMwmGraph::GetCrossMwmStatus(NumMwmId numMwmId) const
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class DataSource;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class MwmDataSource;
|
||||
|
||||
/// \brief Getting information for cross mwm routing.
|
||||
class CrossMwmGraph final
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public:
|
|||
std::shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn,
|
||||
DataSource & dataSource);
|
||||
MwmDataSource & dataSource);
|
||||
|
||||
/// \brief Transition segment is a segment which is crossed by mwm border. That means
|
||||
/// start and finish of such segment have to lie in different mwms. If a segment is
|
||||
|
@ -121,7 +121,7 @@ private:
|
|||
void DeserializeTransitions(std::vector<NumMwmId> const & mwmIds);
|
||||
void DeserializeTransitTransitions(std::vector<NumMwmId> const & mwmIds);
|
||||
|
||||
DataSource & m_dataSource;
|
||||
MwmDataSource & m_dataSource;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
std::shared_ptr<m4::Tree<NumMwmId>> m_numMwmTree;
|
||||
std::shared_ptr<VehicleModelFactoryInterface> m_vehicleModelFactory;
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include "routing/cross_mwm_connector.hpp"
|
||||
#include "routing/cross_mwm_connector_serialization.hpp"
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/fake_feature_ids.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/vehicle_mask.hpp"
|
||||
|
||||
#include "routing_common/num_mwm_id.hpp"
|
||||
#include "routing_common/vehicle_model.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
|
@ -60,9 +60,8 @@ class CrossMwmIndexGraph final
|
|||
public:
|
||||
using ReaderSourceFile = ReaderSource<FilesContainerR::TReader>;
|
||||
|
||||
CrossMwmIndexGraph(DataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
VehicleType vehicleType)
|
||||
: m_dataSource(dataSource), m_numMwmIds(numMwmIds), m_vehicleType(vehicleType)
|
||||
CrossMwmIndexGraph(MwmDataSource & dataSource, VehicleType vehicleType)
|
||||
: m_dataSource(dataSource), m_vehicleType(vehicleType)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -122,9 +121,9 @@ public:
|
|||
// There are same in common, but in case of different version of mwms
|
||||
// their's geometry can differ from each other. Because of this we can not
|
||||
// build the route, because we fail in astar_algorithm.hpp CHECK(invariant) sometimes.
|
||||
auto const & sMwmId = m_dataSource.GetMwmIdByCountryFile(m_numMwmIds->GetFile(s.GetMwmId()));
|
||||
auto const & sMwmId = m_dataSource.GetMwmId(s.GetMwmId());
|
||||
CHECK(sMwmId.IsAlive(), (s));
|
||||
auto const & twinSegMwmId = m_dataSource.GetMwmIdByCountryFile(m_numMwmIds->GetFile(twinSeg->GetMwmId()));
|
||||
auto const & twinSegMwmId = m_dataSource.GetMwmId(twinSeg->GetMwmId());
|
||||
CHECK(twinSegMwmId.IsAlive(), (*twinSeg));
|
||||
|
||||
if (sMwmId.GetInfo()->GetVersion() == twinSegMwmId.GetInfo()->GetVersion() ||
|
||||
|
@ -195,23 +194,18 @@ private:
|
|||
{
|
||||
std::vector<m2::PointD> geometry;
|
||||
|
||||
auto const & handle = m_dataSource.GetMwmHandleByCountryFile(m_numMwmIds->GetFile(segment.GetMwmId()));
|
||||
if (!handle.IsAlive())
|
||||
auto const mwmId = m_dataSource.GetMwmId(segment.GetMwmId());
|
||||
if (!mwmId.IsAlive())
|
||||
return geometry;
|
||||
|
||||
auto const & mwmId = handle.GetId();
|
||||
auto ft = m_dataSource.GetFeature({ mwmId, segment.GetFeatureId() });
|
||||
ft->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
auto const & featureId = FeatureID(mwmId, segment.GetFeatureId());
|
||||
size_t const count = ft->GetPointsCount();
|
||||
geometry.reserve(count);
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
geometry.emplace_back(ft->GetPoint(i));
|
||||
|
||||
auto const fillGeometry = [&geometry](FeatureType & ftype)
|
||||
{
|
||||
ftype.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
geometry.reserve(ftype.GetPointsCount());
|
||||
for (uint32_t i = 0; i < ftype.GetPointsCount(); ++i)
|
||||
geometry.emplace_back(ftype.GetPoint(i));
|
||||
};
|
||||
|
||||
m_dataSource.ReadFeature(fillGeometry, featureId);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
@ -262,27 +256,19 @@ private:
|
|||
template <typename Fn>
|
||||
CrossMwmConnector<CrossMwmId> const & Deserialize(NumMwmId numMwmId, Fn && fn)
|
||||
{
|
||||
auto const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Mwm", file, "cannot be loaded."));
|
||||
MwmValue const & mwmValue = m_dataSource.GetMwmValue(numMwmId);
|
||||
|
||||
MwmValue const * value = handle.GetValue();
|
||||
CHECK(value != nullptr, ("Country file:", file));
|
||||
|
||||
FilesContainerR::TReader reader(connector::GetReader<CrossMwmId>(value->m_cont));
|
||||
ReaderSourceFile src(reader);
|
||||
auto it = m_connectors.emplace(numMwmId, CrossMwmConnector<CrossMwmId>(numMwmId)).first;
|
||||
|
||||
CrossMwmConnectorBuilder<CrossMwmId> builder(it->second);
|
||||
builder.ApplyNumerationOffset();
|
||||
|
||||
fn(builder, src);
|
||||
auto reader = connector::GetReader<CrossMwmId>(mwmValue.m_cont);
|
||||
fn(builder, reader);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
DataSource & m_dataSource;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
MwmDataSource & m_dataSource;
|
||||
VehicleType m_vehicleType;
|
||||
|
||||
/// \note |m_connectors| contains cache with transition segments and leap edges.
|
||||
|
|
128
routing/data_source.hpp
Normal file
128
routing/data_source.hpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
#pragma once
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
|
||||
#include "routing_common/num_mwm_id.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
// Main purpose is to take and hold MwmHandle-s here (readers and caches).
|
||||
// Routing works in a separate threads and doesn't interfere within route calculation process.
|
||||
/// @note Should add additional thread's caches in case of concurrent routing process.
|
||||
class MwmDataSource
|
||||
{
|
||||
DataSource & m_dataSource;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIDs;
|
||||
std::unordered_map<NumMwmId, MwmSet::MwmHandle> m_handles;
|
||||
|
||||
// Used for FeaturesRoadGraph in openlr only.
|
||||
std::map<MwmSet::MwmId, MwmSet::MwmHandle> m_handles2;
|
||||
|
||||
// Last used FeatureType source.
|
||||
std::unique_ptr<FeatureSource> m_features;
|
||||
|
||||
MwmSet::MwmHandle const * GetHandleSafe(NumMwmId numMwmId)
|
||||
{
|
||||
ASSERT(m_numMwmIDs, ());
|
||||
auto it = m_handles.find(numMwmId);
|
||||
if (it == m_handles.end())
|
||||
{
|
||||
auto handle = m_dataSource.GetMwmHandleByCountryFile(m_numMwmIDs->GetFile(numMwmId));
|
||||
if (!handle.IsAlive())
|
||||
return nullptr;
|
||||
|
||||
it = m_handles.emplace(numMwmId, std::move(handle)).first;
|
||||
}
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
public:
|
||||
/// @param[in] numMwmIDs Cay be null, if don't call NumMwmId functions.
|
||||
MwmDataSource(DataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIDs)
|
||||
: m_dataSource(dataSource), m_numMwmIDs(std::move(numMwmIDs))
|
||||
{}
|
||||
|
||||
bool IsLoaded(platform::CountryFile const & file) const { return m_dataSource.IsLoaded(file); }
|
||||
|
||||
enum SectionStatus
|
||||
{
|
||||
MwmNotLoaded,
|
||||
SectionExists,
|
||||
NoSection,
|
||||
};
|
||||
|
||||
MwmSet::MwmHandle const & GetHandle(NumMwmId numMwmId)
|
||||
{
|
||||
ASSERT(m_numMwmIDs, ());
|
||||
auto it = m_handles.find(numMwmId);
|
||||
if (it == m_handles.end())
|
||||
{
|
||||
auto const file = m_numMwmIDs->GetFile(numMwmId);
|
||||
auto handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Mwm", file, "cannot be loaded."));
|
||||
|
||||
it = m_handles.emplace(numMwmId, std::move(handle)).first;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
MwmValue const & GetMwmValue(NumMwmId numMwmId)
|
||||
{
|
||||
return *GetHandle(numMwmId).GetValue();
|
||||
}
|
||||
|
||||
SectionStatus GetSectionStatus(NumMwmId numMwmId, std::string const & section)
|
||||
{
|
||||
auto const * handle = GetHandleSafe(numMwmId);
|
||||
if (!handle)
|
||||
return MwmNotLoaded;
|
||||
return handle->GetValue()->m_cont.IsExist(section) ? SectionExists : NoSection;
|
||||
}
|
||||
|
||||
MwmSet::MwmId GetMwmId(NumMwmId numMwmId) const
|
||||
{
|
||||
ASSERT(m_numMwmIDs, ());
|
||||
return m_dataSource.GetMwmIdByCountryFile(m_numMwmIDs->GetFile(numMwmId));
|
||||
}
|
||||
|
||||
template <class FnT> void ForEachStreet(FnT && fn, m2::RectD const & rect)
|
||||
{
|
||||
m_dataSource.ForEachInRect(fn, rect, scales::GetUpperScale());
|
||||
}
|
||||
|
||||
MwmSet::MwmHandle const & GetHandle(MwmSet::MwmId const & mwmId)
|
||||
{
|
||||
if (m_numMwmIDs)
|
||||
{
|
||||
return GetHandle(m_numMwmIDs->GetId(mwmId.GetInfo()->GetLocalFile().GetCountryFile()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = m_handles2.find(mwmId);
|
||||
if (it == m_handles2.end())
|
||||
{
|
||||
auto handle = m_dataSource.GetMwmHandleById(mwmId);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Mwm", mwmId.GetInfo()->GetCountryName(), "cannot be loaded."));
|
||||
|
||||
it = m_handles2.emplace(mwmId, std::move(handle)).first;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<FeatureType> GetFeature(FeatureID const & id)
|
||||
{
|
||||
if (!m_features || id.m_mwmId != m_features->GetMwmId())
|
||||
m_features = m_dataSource.CreateFeatureSource(GetHandle(id.m_mwmId));
|
||||
|
||||
/// @todo Should we also retrieve "modified" features here?
|
||||
return m_features->GetOriginalFeature(id.m_index);
|
||||
}
|
||||
};
|
||||
} // namespace routing
|
|
@ -1,5 +1,6 @@
|
|||
#include "routing/directions_engine.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/fake_feature_ids.hpp"
|
||||
#include "routing/routing_helpers.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
@ -18,6 +19,8 @@
|
|||
#include <cstdlib>
|
||||
#include <utility>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsFakeFeature(uint32_t featureId)
|
||||
|
@ -27,8 +30,6 @@ bool IsFakeFeature(uint32_t featureId)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace routing
|
||||
{
|
||||
using namespace routing::turns;
|
||||
using namespace std;
|
||||
using namespace traffic;
|
||||
|
@ -37,14 +38,13 @@ void DirectionsEngine::Clear()
|
|||
{
|
||||
m_adjacentEdges.clear();
|
||||
m_pathSegments.clear();
|
||||
m_loader.reset();
|
||||
}
|
||||
|
||||
FeaturesLoaderGuard & DirectionsEngine::GetLoader(MwmSet::MwmId const & id)
|
||||
std::unique_ptr<FeatureType> DirectionsEngine::GetFeature(FeatureID const & featureId)
|
||||
{
|
||||
if (!m_loader || id != m_loader->GetId())
|
||||
m_loader = make_unique<FeaturesLoaderGuard>(m_dataSource, id);
|
||||
return *m_loader;
|
||||
if (IsFakeFeature(featureId.m_index))
|
||||
return nullptr;
|
||||
return m_dataSource.GetFeature(featureId);
|
||||
}
|
||||
|
||||
void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId,
|
||||
|
@ -53,10 +53,7 @@ void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId,
|
|||
if (!featureId.IsValid())
|
||||
return;
|
||||
|
||||
if (IsFakeFeature(featureId.m_index))
|
||||
return;
|
||||
|
||||
auto ft = GetLoader(featureId.m_mwmId).GetFeatureByIndex(featureId.m_index);
|
||||
auto ft = GetFeature(featureId);
|
||||
if (!ft)
|
||||
return;
|
||||
|
||||
|
@ -91,11 +88,7 @@ void DirectionsEngine::GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT con
|
|||
if (edge.IsFake())
|
||||
continue;
|
||||
|
||||
auto const & outFeatureId = edge.GetFeatureId();
|
||||
if (IsFakeFeature(outFeatureId.m_index))
|
||||
continue;
|
||||
|
||||
auto ft = GetLoader(outFeatureId.m_mwmId).GetFeatureByIndex(outFeatureId.m_index);
|
||||
auto ft = GetFeature(edge.GetFeatureId());
|
||||
if (!ft)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "routing/segment.hpp"
|
||||
#include "routing/vehicle_mask.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
|||
|
||||
namespace routing
|
||||
{
|
||||
|
||||
namespace turns
|
||||
{
|
||||
class IRoutingResult;
|
||||
|
@ -26,11 +25,12 @@ struct TurnItem;
|
|||
}
|
||||
|
||||
enum class RouterResultCode;
|
||||
class MwmDataSource;
|
||||
|
||||
class DirectionsEngine
|
||||
{
|
||||
public:
|
||||
DirectionsEngine(DataSource const & dataSource, std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
DirectionsEngine(MwmDataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
: m_dataSource(dataSource), m_numMwmIds(numMwmIds)
|
||||
{
|
||||
CHECK(m_numMwmIds, ());
|
||||
|
@ -64,8 +64,7 @@ protected:
|
|||
RoutingSettings const & vehicleSettings, turns::TurnItem & turn) = 0;
|
||||
virtual void FixupTurns(std::vector<geometry::PointWithAltitude> const & junctions,
|
||||
Route::TTurns & turnsDir) = 0;
|
||||
|
||||
FeaturesLoaderGuard & GetLoader(MwmSet::MwmId const & id);
|
||||
std::unique_ptr<FeatureType> GetFeature(FeatureID const & featureId);
|
||||
void LoadPathAttributes(FeatureID const & featureId, LoadedPathSegment & pathSegment);
|
||||
void GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT const & outgoingEdges,
|
||||
Edge const & inEdge, uint32_t startSegId, uint32_t endSegId,
|
||||
|
@ -85,9 +84,8 @@ protected:
|
|||
AdjacentEdgesMap m_adjacentEdges;
|
||||
TUnpackedPathSegments m_pathSegments;
|
||||
|
||||
DataSource const & m_dataSource;
|
||||
MwmDataSource & m_dataSource;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
std::unique_ptr<FeaturesLoaderGuard> m_loader;
|
||||
VehicleType m_vehicleType = VehicleType::Count;
|
||||
|
||||
private:
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
using namespace traffic;
|
||||
|
@ -69,8 +71,6 @@ double CalcClimbSegment(EdgeEstimator::Purpose purpose, Segment const & segment,
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace routing
|
||||
{
|
||||
double GetPedestrianClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
|
||||
geometry::Altitude altitudeM)
|
||||
{
|
||||
|
@ -119,11 +119,11 @@ double GetCarClimbPenalty(EdgeEstimator::Purpose /* purpose */, double /* tangen
|
|||
|
||||
// EdgeEstimator -----------------------------------------------------------------------------------
|
||||
EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
|
||||
DataSource * /*dataSourcePtr*/, std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
DataSource * /*dataSourcePtr*/, std::shared_ptr<NumMwmIds> /*numMwmIds*/)
|
||||
: m_maxWeightSpeedMpS(KMPH2MPS(maxWeightSpeedKMpH))
|
||||
, m_offroadSpeedKMpH(offroadSpeedKMpH)
|
||||
//, m_dataSourcePtr(dataSourcePtr)
|
||||
, m_numMwmIds(numMwmIds)
|
||||
//, m_numMwmIds(numMwmIds)
|
||||
{
|
||||
CHECK_GREATER(m_offroadSpeedKMpH.m_weight, 0.0, ());
|
||||
CHECK_GREATER(m_offroadSpeedKMpH.m_eta, 0.0, ());
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
};
|
||||
|
||||
EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
|
||||
DataSource * dataSourcePtr = nullptr, std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
|
||||
DataSource * dataSourcePtr = nullptr, std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
|
||||
virtual ~EdgeEstimator() = default;
|
||||
|
||||
double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const;
|
||||
|
@ -68,7 +68,7 @@ private:
|
|||
SpeedKMpH const m_offroadSpeedKMpH;
|
||||
|
||||
//DataSource * m_dataSourcePtr;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
//std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
//std::unordered_map<NumMwmId, double> m_leapWeightSpeedMpS;
|
||||
|
||||
double ComputeDefaultLeapWeightSpeed() const;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "routing/features_road_graph.hpp"
|
||||
|
||||
#include "routing/routing_helpers.hpp"
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/nearest_edge_finder.hpp"
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/routing_helpers.hpp"
|
||||
|
||||
#include "routing_common/vehicle_model.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
|
@ -35,63 +35,50 @@ auto constexpr kInvalidSpeedKMPH = numeric_limits<double>::max();
|
|||
|
||||
double GetRoadCrossingRadiusMeters() { return kMwmRoadCrossingRadiusMeters; }
|
||||
|
||||
FeaturesRoadGraph::Value::Value(DataSource const & dataSource, MwmSet::MwmHandle handle)
|
||||
: m_mwmHandle(move(handle))
|
||||
{
|
||||
if (!m_mwmHandle.IsAlive())
|
||||
return;
|
||||
|
||||
m_altitudeLoader = make_unique<feature::AltitudeLoaderCached>(dataSource, m_mwmHandle.GetId());
|
||||
}
|
||||
|
||||
FeaturesRoadGraph::CrossCountryVehicleModel::CrossCountryVehicleModel(
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory)
|
||||
: m_vehicleModelFactory(vehicleModelFactory)
|
||||
, m_maxSpeed(m_vehicleModelFactory->GetVehicleModel()->GetMaxWeightSpeed())
|
||||
, m_offroadSpeedKMpH(m_vehicleModelFactory->GetVehicleModel()->GetOffroadSpeed())
|
||||
FeaturesRoadGraphBase::CrossCountryVehicleModel::CrossCountryVehicleModel(VehicleModelFactoryPtrT modelFactory)
|
||||
: m_modelFactory(modelFactory)
|
||||
, m_maxSpeed(m_modelFactory->GetVehicleModel()->GetMaxWeightSpeed())
|
||||
, m_offroadSpeedKMpH(m_modelFactory->GetVehicleModel()->GetOffroadSpeed())
|
||||
{
|
||||
}
|
||||
|
||||
SpeedKMpH FeaturesRoadGraph::CrossCountryVehicleModel::GetSpeed(
|
||||
FeatureType & f, SpeedParams const & speedParams) const
|
||||
SpeedKMpH FeaturesRoadGraphBase::CrossCountryVehicleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->GetSpeed(f, speedParams);
|
||||
}
|
||||
|
||||
std::optional<HighwayType> FeaturesRoadGraph::CrossCountryVehicleModel::GetHighwayType(FeatureType & f) const
|
||||
std::optional<HighwayType> FeaturesRoadGraphBase::CrossCountryVehicleModel::GetHighwayType(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->GetHighwayType(f);
|
||||
}
|
||||
|
||||
SpeedKMpH const & FeaturesRoadGraph::CrossCountryVehicleModel::GetOffroadSpeed() const
|
||||
SpeedKMpH const & FeaturesRoadGraphBase::CrossCountryVehicleModel::GetOffroadSpeed() const
|
||||
{
|
||||
return m_offroadSpeedKMpH;
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsOneWay(FeatureType & f) const
|
||||
bool FeaturesRoadGraphBase::CrossCountryVehicleModel::IsOneWay(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsOneWay(f);
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsRoad(FeatureType & f) const
|
||||
bool FeaturesRoadGraphBase::CrossCountryVehicleModel::IsRoad(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsRoad(f);
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsPassThroughAllowed(FeatureType & f) const
|
||||
bool FeaturesRoadGraphBase::CrossCountryVehicleModel::IsPassThroughAllowed(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsPassThroughAllowed(f);
|
||||
}
|
||||
|
||||
VehicleModelInterface * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleModel(
|
||||
FeatureID const & featureId) const
|
||||
VehicleModelInterface * FeaturesRoadGraphBase::CrossCountryVehicleModel::GetVehicleModel(FeatureID const & featureId) const
|
||||
{
|
||||
auto itr = m_cache.find(featureId.m_mwmId);
|
||||
if (itr != m_cache.end())
|
||||
return itr->second.get();
|
||||
|
||||
auto const vehicleModel = m_vehicleModelFactory->GetVehicleModelForCountry(
|
||||
featureId.m_mwmId.GetInfo()->GetCountryName());
|
||||
auto vehicleModel = m_modelFactory->GetVehicleModelForCountry(featureId.m_mwmId.GetInfo()->GetCountryName());
|
||||
|
||||
ASSERT(vehicleModel, ());
|
||||
ASSERT_EQUAL(m_maxSpeed, vehicleModel->GetMaxWeightSpeed(), ());
|
||||
|
@ -100,12 +87,12 @@ VehicleModelInterface * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleM
|
|||
return itr->second.get();
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::CrossCountryVehicleModel::Clear()
|
||||
void FeaturesRoadGraphBase::CrossCountryVehicleModel::Clear()
|
||||
{
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo & FeaturesRoadGraph::RoadInfoCache::Find(FeatureID const & featureId, bool & found)
|
||||
IRoadGraph::RoadInfo & FeaturesRoadGraphBase::RoadInfoCache::Find(FeatureID const & featureId, bool & found)
|
||||
{
|
||||
std::lock_guard lock(m_mutexCache);
|
||||
auto res = m_cache.emplace(featureId.m_mwmId, TMwmFeatureCache());
|
||||
|
@ -120,18 +107,16 @@ void FeaturesRoadGraph::RoadInfoCache::Clear()
|
|||
m_cache.clear();
|
||||
}
|
||||
|
||||
FeaturesRoadGraph::FeaturesRoadGraph(DataSource const & dataSource, IRoadGraph::Mode mode,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory)
|
||||
FeaturesRoadGraphBase::FeaturesRoadGraphBase(MwmDataSource & dataSource, IRoadGraph::Mode mode,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory)
|
||||
: m_dataSource(dataSource), m_mode(mode), m_vehicleModel(vehicleModelFactory)
|
||||
{
|
||||
}
|
||||
|
||||
int FeaturesRoadGraph::GetStreetReadScale() { return scales::GetUpperScale(); }
|
||||
|
||||
class CrossFeaturesLoader
|
||||
{
|
||||
public:
|
||||
CrossFeaturesLoader(FeaturesRoadGraph const & graph, IRoadGraph::ICrossEdgesLoader & edgesLoader)
|
||||
CrossFeaturesLoader(FeaturesRoadGraphBase const & graph, IRoadGraph::ICrossEdgesLoader & edgesLoader)
|
||||
: m_graph(graph), m_edgesLoader(edgesLoader)
|
||||
{}
|
||||
|
||||
|
@ -142,51 +127,51 @@ public:
|
|||
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
|
||||
IRoadGraph::RoadInfo const & roadInfo =
|
||||
m_graph.GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
IRoadGraph::RoadInfo const & roadInfo = m_graph.GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
CHECK_EQUAL(roadInfo.m_speedKMPH, kInvalidSpeedKMPH, ());
|
||||
|
||||
m_edgesLoader(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional);
|
||||
}
|
||||
|
||||
private:
|
||||
FeaturesRoadGraph const & m_graph;
|
||||
FeaturesRoadGraphBase const & m_graph;
|
||||
IRoadGraph::ICrossEdgesLoader & m_edgesLoader;
|
||||
};
|
||||
|
||||
IRoadGraph::RoadInfo FeaturesRoadGraph::GetRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
IRoadGraph::RoadInfo FeaturesRoadGraphBase::GetRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
RoadInfo const & ri = GetCachedRoadInfo(featureId, speedParams);
|
||||
ASSERT_GREATER(ri.m_speedKMPH, 0.0, ());
|
||||
return ri;
|
||||
}
|
||||
|
||||
double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const
|
||||
double FeaturesRoadGraphBase::GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const
|
||||
{
|
||||
double const speedKMPH = GetCachedRoadInfo(featureId, speedParams).m_speedKMPH;
|
||||
ASSERT_GREATER(speedKMPH, 0.0, ());
|
||||
return speedKMPH;
|
||||
}
|
||||
|
||||
double FeaturesRoadGraph::GetMaxSpeedKMpH() const { return m_vehicleModel.GetMaxWeightSpeed(); }
|
||||
|
||||
void FeaturesRoadGraph::ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgesLoader) const
|
||||
double FeaturesRoadGraphBase::GetMaxSpeedKMpH() const
|
||||
{
|
||||
CrossFeaturesLoader featuresLoader(*this, edgesLoader);
|
||||
m2::RectD const rect =
|
||||
mercator::RectByCenterXYAndSizeInMeters(cross, kMwmRoadCrossingRadiusMeters);
|
||||
m_dataSource.ForEachInRect(featuresLoader, rect, GetStreetReadScale());
|
||||
return m_vehicleModel.GetMaxWeightSpeed();
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::FindClosestEdges(
|
||||
m2::RectD const & rect, uint32_t count,
|
||||
vector<pair<Edge, geometry::PointWithAltitude>> & vicinities) const
|
||||
void FeaturesRoadGraphBase::ForEachFeatureClosestToCross(
|
||||
m2::PointD const & cross, ICrossEdgesLoader & edgesLoader) const
|
||||
{
|
||||
CrossFeaturesLoader featuresLoader(*this, edgesLoader);
|
||||
m2::RectD const rect = mercator::RectByCenterXYAndSizeInMeters(cross, kMwmRoadCrossingRadiusMeters);
|
||||
m_dataSource.ForEachStreet(featuresLoader, rect);
|
||||
}
|
||||
|
||||
void FeaturesRoadGraphBase::FindClosestEdges(m2::RectD const & rect, uint32_t count,
|
||||
vector<pair<Edge, geometry::PointWithAltitude>> & vicinities) const
|
||||
{
|
||||
NearestEdgeFinder finder(rect.Center(), nullptr /* IsEdgeProjGood */);
|
||||
|
||||
auto const f = [&finder, this](FeatureType & ft)
|
||||
m_dataSource.ForEachStreet([&](FeatureType & ft)
|
||||
{
|
||||
if (!m_vehicleModel.IsRoad(ft))
|
||||
return;
|
||||
|
@ -195,18 +180,18 @@ void FeaturesRoadGraph::FindClosestEdges(
|
|||
|
||||
IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
finder.AddInformationSource(IRoadGraph::FullRoadInfo(featureId, roadInfo));
|
||||
};
|
||||
|
||||
m_dataSource.ForEachInRect(f, rect, GetStreetReadScale());
|
||||
}, rect);
|
||||
|
||||
finder.MakeResult(vicinities, count);
|
||||
}
|
||||
|
||||
vector<IRoadGraph::FullRoadInfo>
|
||||
FeaturesRoadGraph::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const
|
||||
FeaturesRoadGraphBase::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const
|
||||
{
|
||||
vector<IRoadGraph::FullRoadInfo> roads;
|
||||
auto const f = [&roads, &isGoodFeature, &rect, this](FeatureType & ft) {
|
||||
|
||||
m_dataSource.ForEachStreet([&](FeatureType & ft)
|
||||
{
|
||||
if (!m_vehicleModel.IsRoad(ft))
|
||||
return;
|
||||
|
||||
|
@ -221,16 +206,14 @@ FeaturesRoadGraph::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isG
|
|||
return;
|
||||
|
||||
roads.emplace_back(featureId, roadInfo);
|
||||
};
|
||||
}, rect);
|
||||
|
||||
m_dataSource.ForEachInRect(f, rect, GetStreetReadScale());
|
||||
return roads;
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const
|
||||
void FeaturesRoadGraphBase::GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const
|
||||
{
|
||||
FeaturesLoaderGuard loader(m_dataSource, featureId.m_mwmId);
|
||||
auto ft = loader.GetFeatureByIndex(featureId.m_index);
|
||||
auto ft = m_dataSource.GetFeature(featureId);
|
||||
if (!ft)
|
||||
return;
|
||||
|
||||
|
@ -238,48 +221,41 @@ void FeaturesRoadGraph::GetFeatureTypes(FeatureID const & featureId, feature::Ty
|
|||
types = feature::TypesHolder(*ft);
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const
|
||||
void FeaturesRoadGraphBase::GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const
|
||||
{
|
||||
types = feature::TypesHolder();
|
||||
|
||||
m2::PointD const & cross = junction.GetPoint();
|
||||
m2::RectD const rect = mercator::RectByCenterXYAndSizeInMeters(cross, kMwmRoadCrossingRadiusMeters);
|
||||
|
||||
auto const f = [&types, &cross](FeatureType & ft) {
|
||||
if (!types.Empty())
|
||||
return;
|
||||
|
||||
if (ft.GetGeomType() != feature::GeomType::Point)
|
||||
return;
|
||||
|
||||
if (!base::AlmostEqualAbs(ft.GetCenter(), cross, kMwmPointAccuracy))
|
||||
return;
|
||||
|
||||
feature::TypesHolder typesHolder(ft);
|
||||
if (!typesHolder.Empty())
|
||||
types = typesHolder;
|
||||
};
|
||||
|
||||
m2::RectD const rect =
|
||||
mercator::RectByCenterXYAndSizeInMeters(cross, kMwmRoadCrossingRadiusMeters);
|
||||
m_dataSource.ForEachInRect(f, rect, GetStreetReadScale());
|
||||
m_dataSource.ForEachStreet([&](FeatureType & ft)
|
||||
{
|
||||
if (types.Empty() && ft.GetGeomType() == feature::GeomType::Point &&
|
||||
base::AlmostEqualAbs(ft.GetCenter(), cross, kMwmPointAccuracy))
|
||||
{
|
||||
types = feature::TypesHolder(ft);
|
||||
}
|
||||
}, rect);
|
||||
}
|
||||
|
||||
IRoadGraph::Mode FeaturesRoadGraph::GetMode() const
|
||||
IRoadGraph::Mode FeaturesRoadGraphBase::GetMode() const
|
||||
{
|
||||
return m_mode;
|
||||
};
|
||||
|
||||
void FeaturesRoadGraph::ClearState()
|
||||
void FeaturesRoadGraphBase::ClearState()
|
||||
{
|
||||
m_cache.Clear();
|
||||
m_vehicleModel.Clear();
|
||||
m_mwmLocks.clear();
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::IsRoad(FeatureType & ft) const { return m_vehicleModel.IsRoad(ft); }
|
||||
bool FeaturesRoadGraphBase::IsRoad(FeatureType & ft) const
|
||||
{
|
||||
return m_vehicleModel.IsRoad(ft);
|
||||
}
|
||||
|
||||
IRoadGraph::PointWithAltitudeVec FeaturesRoadGraph::GetRoadGeom(FeatureType & ft) const
|
||||
IRoadGraph::PointWithAltitudeVec FeaturesRoadGraphBase::GetRoadGeom(FeatureType & ft) const
|
||||
{
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
|
@ -287,49 +263,41 @@ IRoadGraph::PointWithAltitudeVec FeaturesRoadGraph::GetRoadGeom(FeatureType & ft
|
|||
return roadInfo.m_junctions;
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::IsOneWay(FeatureType & ft) const { return m_vehicleModel.IsOneWay(ft); }
|
||||
bool FeaturesRoadGraphBase::IsOneWay(FeatureType & ft) const
|
||||
{
|
||||
return m_vehicleModel.IsOneWay(ft);
|
||||
}
|
||||
|
||||
double FeaturesRoadGraph::GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams const & speedParams) const
|
||||
double FeaturesRoadGraphBase::GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams const & speedParams) const
|
||||
{
|
||||
return m_vehicleModel.GetSpeed(ft, speedParams).m_weight;
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMpH, RoadInfo & ri) const
|
||||
void FeaturesRoadGraphBase::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMpH, RoadInfo & ri) const
|
||||
{
|
||||
ri.m_speedKMPH = speedKMpH;
|
||||
|
||||
Value const & value = LockMwm(featureId.m_mwmId);
|
||||
if (!value.IsAlive())
|
||||
return;
|
||||
|
||||
ri.m_bidirectional = !IsOneWay(ft);
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
size_t const pointsCount = ft.GetPointsCount();
|
||||
|
||||
geometry::Altitudes altitudes;
|
||||
if (value.m_altitudeLoader)
|
||||
{
|
||||
altitudes = value.m_altitudeLoader->GetAltitudes(featureId.m_index, ft.GetPointsCount());
|
||||
}
|
||||
auto const loader = GetAltitudesLoader(featureId.m_mwmId);
|
||||
if (loader)
|
||||
altitudes = loader->GetAltitudes(featureId.m_index, pointsCount);
|
||||
else
|
||||
{
|
||||
ASSERT(false, ());
|
||||
altitudes = geometry::Altitudes(ft.GetPointsCount(), geometry::kDefaultAltitudeMeters);
|
||||
}
|
||||
altitudes = geometry::Altitudes(pointsCount, geometry::kDefaultAltitudeMeters);
|
||||
|
||||
CHECK_EQUAL(altitudes.size(), pointsCount,
|
||||
("altitudeLoader->GetAltitudes(", featureId.m_index, "...) returns wrong altitudes:",
|
||||
altitudes));
|
||||
CHECK_EQUAL(altitudes.size(), pointsCount, ("GetAltitudes for", featureId, "returns wrong altitudes:", altitudes));
|
||||
|
||||
ri.m_junctions.resize(pointsCount);
|
||||
ri.m_junctions.resize_no_init(pointsCount);
|
||||
for (size_t i = 0; i < pointsCount; ++i)
|
||||
ri.m_junctions[i] = geometry::PointWithAltitude(ft.GetPoint(i), altitudes[i]);
|
||||
ri.m_junctions[i] = { ft.GetPoint(i), altitudes[i] };
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(
|
||||
FeatureID const & featureId, SpeedParams const & speedParams) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
|
@ -337,9 +305,7 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons
|
|||
if (found)
|
||||
return ri;
|
||||
|
||||
FeaturesLoaderGuard loader(m_dataSource, featureId.m_mwmId);
|
||||
|
||||
auto ft = loader.GetFeatureByIndex(featureId.m_index);
|
||||
auto ft = m_dataSource.GetFeature(featureId);
|
||||
if (!ft)
|
||||
return ri;
|
||||
|
||||
|
@ -349,31 +315,34 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons
|
|||
return ri;
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId,
|
||||
FeatureType & ft,
|
||||
double speedKMPH) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(
|
||||
FeatureID const & featureId, FeatureType & ft, double speedKMPH) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
|
||||
if (found)
|
||||
return ri;
|
||||
|
||||
// ft must be set
|
||||
ASSERT_EQUAL(featureId, ft.GetID(), ());
|
||||
ExtractRoadInfo(featureId, ft, speedKMPH, ri);
|
||||
return ri;
|
||||
}
|
||||
|
||||
FeaturesRoadGraph::Value const & FeaturesRoadGraph::LockMwm(MwmSet::MwmId const & mwmId) const
|
||||
feature::AltitudeLoaderCached * FeaturesRoadGraph::GetAltitudesLoader(MwmSet::MwmId const & mwmId) const
|
||||
{
|
||||
ASSERT(mwmId.IsAlive(), ());
|
||||
|
||||
auto const itr = m_mwmLocks.find(mwmId);
|
||||
if (itr != m_mwmLocks.end())
|
||||
return itr->second;
|
||||
|
||||
return m_mwmLocks.emplace(move(mwmId), Value(m_dataSource, m_dataSource.GetMwmHandleById(mwmId)))
|
||||
.first->second;
|
||||
auto it = m_altitudes.find(mwmId);
|
||||
if (it == m_altitudes.end())
|
||||
{
|
||||
auto const & handle = m_dataSource.GetHandle(mwmId);
|
||||
it = m_altitudes.emplace(mwmId, *handle.GetValue()).first;
|
||||
}
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::ClearState()
|
||||
{
|
||||
FeaturesRoadGraphBase::ClearState();
|
||||
m_altitudes.clear();
|
||||
}
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -20,18 +20,22 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class DataSource;
|
||||
class FeatureType;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class FeaturesRoadGraph : public IRoadGraph
|
||||
class MwmDataSource;
|
||||
|
||||
class FeaturesRoadGraphBase : public IRoadGraph
|
||||
{
|
||||
protected:
|
||||
using VehicleModelFactoryPtrT = std::shared_ptr<VehicleModelFactoryInterface>;
|
||||
|
||||
private:
|
||||
class CrossCountryVehicleModel : public VehicleModelInterface
|
||||
{
|
||||
public:
|
||||
CrossCountryVehicleModel(std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory);
|
||||
explicit CrossCountryVehicleModel(VehicleModelFactoryPtrT modelFactory);
|
||||
|
||||
// VehicleModelInterface overrides:
|
||||
SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override;
|
||||
|
@ -47,7 +51,7 @@ private:
|
|||
private:
|
||||
VehicleModelInterface * GetVehicleModel(FeatureID const & featureId) const;
|
||||
|
||||
std::shared_ptr<VehicleModelFactoryInterface> const m_vehicleModelFactory;
|
||||
VehicleModelFactoryPtrT const m_modelFactory;
|
||||
double const m_maxSpeed;
|
||||
SpeedKMpH const m_offroadSpeedKMpH;
|
||||
|
||||
|
@ -71,45 +75,44 @@ private:
|
|||
public:
|
||||
static double constexpr kClosestEdgesRadiusM = 150.0;
|
||||
|
||||
FeaturesRoadGraph(DataSource const & dataSource, IRoadGraph::Mode mode,
|
||||
std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory);
|
||||
FeaturesRoadGraphBase(MwmDataSource & dataSource, IRoadGraph::Mode mode, VehicleModelFactoryPtrT modelFactory);
|
||||
|
||||
static int GetStreetReadScale();
|
||||
|
||||
// IRoadGraph overrides:
|
||||
/// @name IRoadGraph overrides
|
||||
/// @{
|
||||
RoadInfo GetRoadInfo(FeatureID const & featureId, SpeedParams const & speedParams) const override;
|
||||
double GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const override;
|
||||
double GetMaxSpeedKMpH() const override;
|
||||
void ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgesLoader) const override;
|
||||
void FindClosestEdges(
|
||||
m2::RectD const & rect, uint32_t count,
|
||||
std::vector<std::pair<Edge, geometry::PointWithAltitude>> & vicinities) const override;
|
||||
std::vector<IRoadGraph::FullRoadInfo>
|
||||
FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const override;
|
||||
void FindClosestEdges(m2::RectD const & rect, uint32_t count,
|
||||
std::vector<std::pair<Edge, geometry::PointWithAltitude>> & vicinities) const override;
|
||||
std::vector<IRoadGraph::FullRoadInfo> FindRoads(
|
||||
m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const override;
|
||||
void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const override;
|
||||
void GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const override;
|
||||
IRoadGraph::Mode GetMode() const override;
|
||||
void ClearState() override;
|
||||
/// @}
|
||||
|
||||
bool IsRoad(FeatureType & ft) const;
|
||||
IRoadGraph::PointWithAltitudeVec GetRoadGeom(FeatureType & ft) const;
|
||||
|
||||
protected:
|
||||
MwmDataSource & m_dataSource;
|
||||
|
||||
virtual feature::AltitudeLoaderBase * GetAltitudesLoader(MwmSet::MwmId const & mwmId) const
|
||||
{
|
||||
// Don't retrieve altitudes here because FeaturesRoadGraphBase is used in IndexRouter for
|
||||
// IndexRouter::FindClosestProjectionToRoad and IndexRouter::FindBestEdges only.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CrossFeaturesLoader;
|
||||
|
||||
struct Value
|
||||
{
|
||||
Value() = default;
|
||||
Value(DataSource const & dataSource, MwmSet::MwmHandle handle);
|
||||
|
||||
bool IsAlive() const { return m_mwmHandle.IsAlive(); }
|
||||
|
||||
MwmSet::MwmHandle m_mwmHandle;
|
||||
std::unique_ptr<feature::AltitudeLoaderCached> m_altitudeLoader;
|
||||
};
|
||||
|
||||
bool IsOneWay(FeatureType & ft) const;
|
||||
double GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams const & speedParams) const;
|
||||
|
||||
|
@ -118,18 +121,27 @@ private:
|
|||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, SpeedParams const & speedParams) const;
|
||||
// Searches a feature RoadInfo in the cache, and if does not find then takes passed feature and speed.
|
||||
// This version is used to prevent redundant feature loading when feature speed is known.
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMPH) const;
|
||||
void ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, double speedKMpH,
|
||||
RoadInfo & ri) const;
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft, double speedKMPH) const;
|
||||
void ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, double speedKMpH, RoadInfo & ri) const;
|
||||
|
||||
Value const & LockMwm(MwmSet::MwmId const & mwmId) const;
|
||||
|
||||
DataSource const & m_dataSource;
|
||||
IRoadGraph::Mode const m_mode;
|
||||
mutable RoadInfoCache m_cache;
|
||||
mutable CrossCountryVehicleModel m_vehicleModel;
|
||||
mutable std::map<MwmSet::MwmId, Value> m_mwmLocks;
|
||||
};
|
||||
|
||||
class FeaturesRoadGraph : public FeaturesRoadGraphBase
|
||||
{
|
||||
mutable std::map<MwmSet::MwmId, feature::AltitudeLoaderCached> m_altitudes;
|
||||
|
||||
public:
|
||||
FeaturesRoadGraph(MwmDataSource & dataSource, IRoadGraph::Mode mode, VehicleModelFactoryPtrT modelFactory)
|
||||
: FeaturesRoadGraphBase(dataSource, mode, modelFactory)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
feature::AltitudeLoaderCached * GetAltitudesLoader(MwmSet::MwmId const & mwmId) const override;
|
||||
void ClearState() override;
|
||||
};
|
||||
|
||||
// @returns a distance d such as that for a given point p any edge
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "routing/geometry.hpp"
|
||||
|
||||
#include "routing/city_roads.hpp"
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/maxspeeds.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
|
||||
#include "indexer/altitude_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
|
@ -74,90 +74,67 @@ public:
|
|||
CityRoads m_cityRoads;
|
||||
};
|
||||
|
||||
// GeometryLoaderImpl ------------------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
class GeometryLoaderImpl final : public GeometryLoader
|
||||
{
|
||||
public:
|
||||
GeometryLoaderImpl(DataSource const & dataSource, MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel, bool loadAltitudes);
|
||||
GeometryLoaderImpl(MwmSet::MwmHandle const & handle, VehicleModelPtrT const & vehicleModel, bool loadAltitudes)
|
||||
: m_vehicleModel(vehicleModel)
|
||||
, m_source(handle)
|
||||
, m_altitudeLoader(*handle.GetValue())
|
||||
, m_loadAltitudes(loadAltitudes)
|
||||
{
|
||||
m_attrsGetter.Load(handle.GetValue()->m_cont);
|
||||
}
|
||||
|
||||
// GeometryLoader overrides:
|
||||
void Load(uint32_t featureId, RoadGeometry & road) override;
|
||||
void Load(uint32_t featureId, RoadGeometry & road) override
|
||||
{
|
||||
auto feature = m_source.GetOriginalFeature(featureId);
|
||||
feature->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
geometry::Altitudes altitudes;
|
||||
if (m_loadAltitudes)
|
||||
altitudes = m_altitudeLoader.GetAltitudes(featureId, feature->GetPointsCount());
|
||||
|
||||
road.Load(*m_vehicleModel, *feature, altitudes.empty() ? nullptr : &altitudes, m_attrsGetter);
|
||||
}
|
||||
|
||||
private:
|
||||
VehicleModelPtrT m_vehicleModel;
|
||||
RoadAttrsGetter m_attrsGetter;
|
||||
FeaturesLoaderGuard m_guard;
|
||||
string const m_country;
|
||||
FeatureSource m_source;
|
||||
feature::AltitudeLoaderBase m_altitudeLoader;
|
||||
bool const m_loadAltitudes;
|
||||
};
|
||||
|
||||
GeometryLoaderImpl::GeometryLoaderImpl(DataSource const & dataSource,
|
||||
MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel,
|
||||
bool loadAltitudes)
|
||||
: m_vehicleModel(move(vehicleModel))
|
||||
, m_guard(dataSource, handle.GetId())
|
||||
, m_country(handle.GetInfo()->GetCountryName())
|
||||
, m_altitudeLoader(dataSource, handle.GetId())
|
||||
, m_loadAltitudes(loadAltitudes)
|
||||
{
|
||||
CHECK(handle.IsAlive(), ());
|
||||
CHECK(m_vehicleModel, ());
|
||||
|
||||
m_attrsGetter.Load(handle.GetValue()->m_cont);
|
||||
}
|
||||
|
||||
void GeometryLoaderImpl::Load(uint32_t featureId, RoadGeometry & road)
|
||||
{
|
||||
auto feature = m_guard.GetFeatureByIndex(featureId);
|
||||
if (!feature)
|
||||
MYTHROW(RoutingException, ("Feature", featureId, "not found in", m_country));
|
||||
ASSERT_EQUAL(feature->GetID().m_index, featureId, ());
|
||||
|
||||
feature->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
geometry::Altitudes altitudes;
|
||||
if (m_loadAltitudes)
|
||||
altitudes = m_altitudeLoader.GetAltitudes(featureId, feature->GetPointsCount());
|
||||
|
||||
road.Load(*m_vehicleModel, *feature, altitudes.empty() ? nullptr : &altitudes, m_attrsGetter);
|
||||
}
|
||||
|
||||
// FileGeometryLoader ------------------------------------------------------------------------------
|
||||
class FileGeometryLoader final : public GeometryLoader
|
||||
{
|
||||
public:
|
||||
FileGeometryLoader(string const & fileName, VehicleModelPtrT const & vehicleModel);
|
||||
FileGeometryLoader(string const & fileName, VehicleModelPtrT const & vehicleModel)
|
||||
: m_featuresVector(fileName)
|
||||
, m_vehicleModel(vehicleModel)
|
||||
{
|
||||
m_attrsGetter.Load(m_featuresVector.GetContainer());
|
||||
}
|
||||
|
||||
// GeometryLoader overrides:
|
||||
void Load(uint32_t featureId, RoadGeometry & road) override;
|
||||
void Load(uint32_t featureId, RoadGeometry & road) override
|
||||
{
|
||||
auto feature = m_featuresVector.GetVector().GetByIndex(featureId);
|
||||
feature->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
// Note. If FileGeometryLoader is used for generation cross mwm section for bicycle or
|
||||
// pedestrian routing |altitudes| should be used here.
|
||||
road.Load(*m_vehicleModel, *feature, nullptr /* altitudes */, m_attrsGetter);
|
||||
}
|
||||
|
||||
private:
|
||||
FeaturesVectorTest m_featuresVector;
|
||||
RoadAttrsGetter m_attrsGetter;
|
||||
shared_ptr<VehicleModelInterface> m_vehicleModel;
|
||||
VehicleModelPtrT m_vehicleModel;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
FileGeometryLoader::FileGeometryLoader(string const & fileName, VehicleModelPtrT const & vehicleModel)
|
||||
: m_featuresVector(fileName)
|
||||
, m_vehicleModel(vehicleModel)
|
||||
{
|
||||
CHECK(m_vehicleModel, ());
|
||||
|
||||
m_attrsGetter.Load(m_featuresVector.GetContainer());
|
||||
}
|
||||
|
||||
void FileGeometryLoader::Load(uint32_t featureId, RoadGeometry & road)
|
||||
{
|
||||
auto feature = m_featuresVector.GetVector().GetByIndex(featureId);
|
||||
CHECK(feature, ());
|
||||
feature->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
// Note. If FileGeometryLoader is used for generation cross mwm section for bicycle or
|
||||
// pedestrian routing |altitudes| should be used here.
|
||||
road.Load(*m_vehicleModel, *feature, nullptr /* altitudes */, m_attrsGetter);
|
||||
}
|
||||
|
||||
// RoadGeometry ------------------------------------------------------------------------------------
|
||||
RoadGeometry::RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedKMpH, Points const & points)
|
||||
|
@ -273,19 +250,20 @@ RoadGeometry const & Geometry::GetRoad(uint32_t featureId)
|
|||
}
|
||||
|
||||
// static
|
||||
unique_ptr<GeometryLoader> GeometryLoader::Create(DataSource const & dataSource,
|
||||
MwmSet::MwmHandle const & handle,
|
||||
unique_ptr<GeometryLoader> GeometryLoader::Create(MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel,
|
||||
bool loadAltitudes)
|
||||
{
|
||||
CHECK(handle.IsAlive(), ());
|
||||
return make_unique<GeometryLoaderImpl>(dataSource, handle, vehicleModel, loadAltitudes);
|
||||
CHECK(vehicleModel, ());
|
||||
return make_unique<GeometryLoaderImpl>(handle, vehicleModel, loadAltitudes);
|
||||
}
|
||||
|
||||
// static
|
||||
unique_ptr<GeometryLoader> GeometryLoader::CreateFromFile(
|
||||
string const & fileName, VehicleModelPtrT const & vehicleModel)
|
||||
{
|
||||
CHECK(vehicleModel, ());
|
||||
return make_unique<FileGeometryLoader>(fileName, vehicleModel);
|
||||
}
|
||||
} // namespace routing
|
||||
|
|
|
@ -108,8 +108,7 @@ public:
|
|||
using VehicleModelPtrT = std::shared_ptr<VehicleModelInterface>;
|
||||
|
||||
/// @param[in] handle should be alive, its caller responsibility to check it.
|
||||
static std::unique_ptr<GeometryLoader> Create(DataSource const & dataSource,
|
||||
MwmSet::MwmHandle const & handle,
|
||||
static std::unique_ptr<GeometryLoader> Create(MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel,
|
||||
bool loadAltitudes);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "routing/index_graph_loader.hpp"
|
||||
|
||||
#include "routing/city_roads.hpp"
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/index_graph_serialization.hpp"
|
||||
#include "routing/restriction_loader.hpp"
|
||||
#include "routing/road_access.hpp"
|
||||
|
@ -9,8 +10,6 @@
|
|||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/speed_camera_ser_des.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
#include "platform/country_defines.hpp"
|
||||
|
||||
#include "coding/files_container.hpp"
|
||||
|
@ -31,10 +30,20 @@ using namespace std;
|
|||
class IndexGraphLoaderImpl final : public IndexGraphLoader
|
||||
{
|
||||
public:
|
||||
IndexGraphLoaderImpl(VehicleType vehicleType, bool loadAltitudes, shared_ptr<NumMwmIds> numMwmIds,
|
||||
IndexGraphLoaderImpl(VehicleType vehicleType, bool loadAltitudes,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
shared_ptr<EdgeEstimator> estimator, DataSource & dataSource,
|
||||
RoutingOptions routingOptions = RoutingOptions());
|
||||
shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions = RoutingOptions())
|
||||
: m_vehicleType(vehicleType)
|
||||
, m_loadAltitudes(loadAltitudes)
|
||||
, m_dataSource(dataSource)
|
||||
, m_vehicleModelFactory(move(vehicleModelFactory))
|
||||
, m_estimator(move(estimator))
|
||||
, m_avoidRoutingOptions(routingOptions)
|
||||
{
|
||||
CHECK(m_vehicleModelFactory, ());
|
||||
CHECK(m_estimator, ());
|
||||
}
|
||||
|
||||
// IndexGraphLoader overrides:
|
||||
IndexGraph & GetIndexGraph(NumMwmId numMwmId) override;
|
||||
|
@ -50,8 +59,7 @@ private:
|
|||
|
||||
VehicleType m_vehicleType;
|
||||
bool m_loadAltitudes;
|
||||
DataSource & m_dataSource;
|
||||
shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
MwmDataSource & m_dataSource;
|
||||
shared_ptr<VehicleModelFactoryInterface> m_vehicleModelFactory;
|
||||
shared_ptr<EdgeEstimator> m_estimator;
|
||||
|
||||
|
@ -73,24 +81,6 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
IndexGraphLoaderImpl::IndexGraphLoaderImpl(
|
||||
VehicleType vehicleType, bool loadAltitudes, shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
shared_ptr<EdgeEstimator> estimator, DataSource & dataSource,
|
||||
RoutingOptions routingOptions)
|
||||
: m_vehicleType(vehicleType)
|
||||
, m_loadAltitudes(loadAltitudes)
|
||||
, m_dataSource(dataSource)
|
||||
, m_numMwmIds(move(numMwmIds))
|
||||
, m_vehicleModelFactory(move(vehicleModelFactory))
|
||||
, m_estimator(move(estimator))
|
||||
, m_avoidRoutingOptions(routingOptions)
|
||||
{
|
||||
CHECK(m_numMwmIds, ());
|
||||
CHECK(m_vehicleModelFactory, ());
|
||||
CHECK(m_estimator, ());
|
||||
}
|
||||
|
||||
IndexGraph & IndexGraphLoaderImpl::GetIndexGraph(NumMwmId numMwmId)
|
||||
{
|
||||
auto res = m_graphs.try_emplace(numMwmId, GraphAttrs());
|
||||
|
@ -118,12 +108,7 @@ IndexGraphLoaderImpl::CamerasMapT const & IndexGraphLoaderImpl::ReceiveSpeedCams
|
|||
auto res = m_cachedCameras.try_emplace(numMwmId, CamerasMapT{});
|
||||
if (res.second)
|
||||
{
|
||||
auto const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
auto handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Can't get mwm handle for", file));
|
||||
|
||||
MwmValue const & mwmValue = *handle.GetValue();
|
||||
MwmValue const & mwmValue = m_dataSource.GetMwmValue(numMwmId);
|
||||
try
|
||||
{
|
||||
FilesContainerR::TReader reader(mwmValue.m_cont.GetReader(CAMERAS_INFO_FILE_TAG));
|
||||
|
@ -175,39 +160,34 @@ vector<RouteSegment::SpeedCamera> IndexGraphLoaderImpl::GetSpeedCameraInfo(Segme
|
|||
|
||||
IndexGraphLoaderImpl::GraphPtrT IndexGraphLoaderImpl::CreateIndexGraph(NumMwmId numMwmId, GeometryPtrT & geometry)
|
||||
{
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Can't get mwm handle for", file));
|
||||
MwmSet::MwmHandle const & handle = m_dataSource.GetHandle(numMwmId);
|
||||
MwmValue const * value = handle.GetValue();
|
||||
|
||||
shared_ptr<VehicleModelInterface> vehicleModel =
|
||||
m_vehicleModelFactory->GetVehicleModelForCountry(file.GetName());
|
||||
m_vehicleModelFactory->GetVehicleModelForCountry(value->GetCountryFileName());
|
||||
|
||||
if (!geometry)
|
||||
geometry = make_shared<Geometry>(GeometryLoader::Create(m_dataSource, handle, vehicleModel, m_loadAltitudes));
|
||||
geometry = make_shared<Geometry>(GeometryLoader::Create(handle, vehicleModel, m_loadAltitudes));
|
||||
|
||||
auto graph = make_unique<IndexGraph>(geometry, m_estimator, m_avoidRoutingOptions);
|
||||
graph->SetCurrentTimeGetter(m_currentTimeGetter);
|
||||
|
||||
base::Timer timer;
|
||||
MwmValue const & mwmValue = *handle.GetValue();
|
||||
DeserializeIndexGraph(mwmValue, m_vehicleType, *graph);
|
||||
LOG(LINFO, (ROUTING_FILE_TAG, "section for", file.GetName(), "loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
DeserializeIndexGraph(*value, m_vehicleType, *graph);
|
||||
LOG(LINFO, (ROUTING_FILE_TAG, "section for", value->GetCountryFileName(), "loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
IndexGraphLoaderImpl::GeometryPtrT IndexGraphLoaderImpl::CreateGeometry(NumMwmId numMwmId)
|
||||
{
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Can't get mwm handle for", file));
|
||||
MwmSet::MwmHandle const & handle = m_dataSource.GetHandle(numMwmId);
|
||||
MwmValue const * value = handle.GetValue();
|
||||
|
||||
shared_ptr<VehicleModelInterface> vehicleModel =
|
||||
m_vehicleModelFactory->GetVehicleModelForCountry(file.GetName());
|
||||
m_vehicleModelFactory->GetVehicleModelForCountry(value->GetCountryFileName());
|
||||
|
||||
return make_shared<Geometry>(GeometryLoader::Create(m_dataSource, handle, vehicleModel, m_loadAltitudes));
|
||||
return make_shared<Geometry>(GeometryLoader::Create(handle, vehicleModel, m_loadAltitudes));
|
||||
}
|
||||
|
||||
void IndexGraphLoaderImpl::Clear() { m_graphs.clear(); }
|
||||
|
@ -239,12 +219,12 @@ namespace routing
|
|||
{
|
||||
// static
|
||||
unique_ptr<IndexGraphLoader> IndexGraphLoader::Create(
|
||||
VehicleType vehicleType, bool loadAltitudes, shared_ptr<NumMwmIds> numMwmIds,
|
||||
VehicleType vehicleType, bool loadAltitudes,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
shared_ptr<EdgeEstimator> estimator, DataSource & dataSource,
|
||||
shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions)
|
||||
{
|
||||
return make_unique<IndexGraphLoaderImpl>(vehicleType, loadAltitudes, numMwmIds, vehicleModelFactory,
|
||||
return make_unique<IndexGraphLoaderImpl>(vehicleType, loadAltitudes, vehicleModelFactory,
|
||||
estimator, dataSource, routingOptions);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
#include <vector>
|
||||
|
||||
class MwmValue;
|
||||
class DataSource;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class MwmDataSource;
|
||||
|
||||
class IndexGraphLoader
|
||||
{
|
||||
public:
|
||||
|
@ -29,9 +30,9 @@ public:
|
|||
virtual void Clear() = 0;
|
||||
|
||||
static std::unique_ptr<IndexGraphLoader> Create(
|
||||
VehicleType vehicleType, bool loadAltitudes, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
VehicleType vehicleType, bool loadAltitudes,
|
||||
std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
std::shared_ptr<EdgeEstimator> estimator, DataSource & dataSource,
|
||||
std::shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions = RoutingOptions());
|
||||
};
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#include "routing/index_road_graph.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/fake_feature_ids.hpp"
|
||||
#include "routing/index_graph_starter.hpp"
|
||||
#include "routing/latlon_with_altitude.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/transit_graph.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
|
@ -15,11 +14,10 @@ using namespace std;
|
|||
|
||||
namespace routing
|
||||
{
|
||||
IndexRoadGraph::IndexRoadGraph(shared_ptr<NumMwmIds> numMwmIds, IndexGraphStarter & starter,
|
||||
vector<Segment> const & segments,
|
||||
IndexRoadGraph::IndexRoadGraph(IndexGraphStarter & starter, vector<Segment> const & segments,
|
||||
vector<geometry::PointWithAltitude> const & junctions,
|
||||
DataSource & dataSource)
|
||||
: m_dataSource(dataSource), m_numMwmIds(move(numMwmIds)), m_starter(starter), m_segments(segments)
|
||||
MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource), m_starter(starter), m_segments(segments)
|
||||
{
|
||||
// j0 j1 j2 j3
|
||||
// *--s0--*--s1--*--s2--*
|
||||
|
@ -72,8 +70,7 @@ void IndexRoadGraph::GetEdgeTypes(Edge const & edge, feature::TypesHolder & type
|
|||
return;
|
||||
}
|
||||
|
||||
FeaturesLoaderGuard loader(m_dataSource, featureId.m_mwmId);
|
||||
auto ft = loader.GetFeatureByIndex(featureId.m_index);
|
||||
auto ft = m_dataSource.GetFeature(featureId);
|
||||
if (!ft)
|
||||
{
|
||||
LOG(LERROR, ("Can't load types for feature", featureId));
|
||||
|
@ -107,9 +104,7 @@ void IndexRoadGraph::GetRouteEdges(EdgeVector & edges) const
|
|||
Segment real = segment;
|
||||
if (m_starter.ConvertToReal(real))
|
||||
{
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(real.GetMwmId());
|
||||
MwmSet::MwmId const mwmId = m_dataSource.GetMwmIdByCountryFile(file);
|
||||
edges.push_back(Edge::MakeFakeWithRealPart(FeatureID(mwmId, real.GetFeatureId()),
|
||||
edges.push_back(Edge::MakeFakeWithRealPart({ m_dataSource.GetMwmId(real.GetMwmId()), real.GetFeatureId() },
|
||||
segment.GetSegmentIdx(),
|
||||
real.IsForward(), real.GetSegmentIdx(),
|
||||
junctionFrom, junctionTo));
|
||||
|
@ -121,10 +116,8 @@ void IndexRoadGraph::GetRouteEdges(EdgeVector & edges) const
|
|||
}
|
||||
else
|
||||
{
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(segment.GetMwmId());
|
||||
MwmSet::MwmId const mwmId = m_dataSource.GetMwmIdByCountryFile(file);
|
||||
edges.push_back(Edge::MakeReal(FeatureID(mwmId, segment.GetFeatureId()), segment.IsForward(),
|
||||
segment.GetSegmentIdx(), junctionFrom, junctionTo));
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
segment.IsForward(), segment.GetSegmentIdx(), junctionFrom, junctionTo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,11 +143,8 @@ void IndexRoadGraph::GetEdges(geometry::PointWithAltitude const & junction, bool
|
|||
if (IndexGraphStarter::IsFakeSegment(segment))
|
||||
continue;
|
||||
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(segment.GetMwmId());
|
||||
MwmSet::MwmId const mwmId = m_dataSource.GetMwmIdByCountryFile(file);
|
||||
|
||||
edges.push_back(Edge::MakeReal(
|
||||
FeatureID(mwmId, segment.GetFeatureId()), segment.IsForward(), segment.GetSegmentIdx(),
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
segment.IsForward(), segment.GetSegmentIdx(),
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude(),
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude()));
|
||||
}
|
||||
|
|
|
@ -11,19 +11,17 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class DataSource;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class MwmDataSource;
|
||||
class IndexGraphStarter;
|
||||
|
||||
class IndexRoadGraph : public RoadGraphBase
|
||||
{
|
||||
public:
|
||||
IndexRoadGraph(std::shared_ptr<NumMwmIds> numMwmIds, IndexGraphStarter & starter,
|
||||
std::vector<Segment> const & segments,
|
||||
IndexRoadGraph(IndexGraphStarter & starter, std::vector<Segment> const & segments,
|
||||
std::vector<geometry::PointWithAltitude> const & junctions,
|
||||
DataSource & dataSource);
|
||||
MwmDataSource & dataSource);
|
||||
|
||||
// IRoadGraphBase overrides:
|
||||
virtual void GetOutgoingEdges(geometry::PointWithAltitude const & junction,
|
||||
|
@ -43,8 +41,7 @@ private:
|
|||
using SegmentListT = SmallList<Segment>;
|
||||
SegmentListT const & GetSegments(geometry::PointWithAltitude const & junction, bool isOutgoing) const;
|
||||
|
||||
DataSource & m_dataSource;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
MwmDataSource & m_dataSource;
|
||||
IndexGraphStarter & m_starter;
|
||||
std::vector<Segment> m_segments;
|
||||
std::map<geometry::PointWithAltitude, SegmentListT> m_beginToSegment;
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
|
||||
|
@ -116,7 +118,7 @@ shared_ptr<VehicleModelFactoryInterface> CreateVehicleModelFactory(
|
|||
|
||||
unique_ptr<DirectionsEngine> CreateDirectionsEngine(VehicleType vehicleType,
|
||||
shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource)
|
||||
MwmDataSource & dataSource)
|
||||
{
|
||||
switch (vehicleType)
|
||||
{
|
||||
|
@ -196,8 +198,7 @@ bool IsDeadEndCached(Segment const & segment, bool isOutgoing, bool useRoutingOp
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace routing
|
||||
{
|
||||
|
||||
// IndexRouter::BestEdgeComparator ----------------------------------------------------------------
|
||||
IndexRouter::BestEdgeComparator::BestEdgeComparator(m2::PointD const & point, m2::PointD const & direction)
|
||||
: m_point(point), m_direction(direction)
|
||||
|
@ -251,7 +252,7 @@ IndexRouter::IndexRouter(VehicleType vehicleType, bool loadAltitudes,
|
|||
: m_vehicleType(vehicleType)
|
||||
, m_loadAltitudes(loadAltitudes)
|
||||
, m_name("astar-bidirectional-" + ToString(m_vehicleType))
|
||||
, m_dataSource(dataSource)
|
||||
, m_dataSource(dataSource, numMwmIds)
|
||||
, m_vehicleModelFactory(CreateVehicleModelFactory(m_vehicleType, countryParentNameGetterFn))
|
||||
, m_countryFileFn(countryFileFn)
|
||||
, m_countryRectFn(countryRectFn)
|
||||
|
@ -366,8 +367,8 @@ RouterResultCode IndexRouter::CalculateRoute(Checkpoints const & checkpoints,
|
|||
if (code != RouterResultCode::RouteNotFound)
|
||||
return code;
|
||||
|
||||
LOG(LWARNING, ("Can't adjust route, do full rebuild, prev start:",
|
||||
mercator::ToLatLon(m_lastRoute->GetStart()), ", start:", mercator::ToLatLon(startPoint), ", finish:", mercator::ToLatLon(finalPoint)));
|
||||
LOG(LWARNING, ("Can't adjust route, do full rebuild, prev start:", mercator::ToLatLon(m_lastRoute->GetStart()),
|
||||
"start:", mercator::ToLatLon(startPoint), "finish:", mercator::ToLatLon(finalPoint)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,8 +972,7 @@ unique_ptr<WorldGraph> IndexRouter::MakeWorldGraph()
|
|||
|
||||
auto indexGraphLoader = IndexGraphLoader::Create(
|
||||
m_vehicleType == VehicleType::Transit ? VehicleType::Pedestrian : m_vehicleType,
|
||||
m_loadAltitudes, m_numMwmIds, m_vehicleModelFactory, m_estimator, m_dataSource,
|
||||
routingOptions);
|
||||
m_loadAltitudes, m_vehicleModelFactory, m_estimator, m_dataSource, routingOptions);
|
||||
|
||||
if (m_vehicleType != VehicleType::Transit)
|
||||
{
|
||||
|
@ -983,7 +983,7 @@ unique_ptr<WorldGraph> IndexRouter::MakeWorldGraph()
|
|||
return graph;
|
||||
}
|
||||
|
||||
auto transitGraphLoader = TransitGraphLoader::Create(m_dataSource, m_numMwmIds, m_estimator);
|
||||
auto transitGraphLoader = TransitGraphLoader::Create(m_dataSource, m_estimator);
|
||||
return make_unique<TransitWorldGraph>(move(crossMwmGraph), move(indexGraphLoader),
|
||||
move(transitGraphLoader), m_estimator);
|
||||
}
|
||||
|
@ -1137,9 +1137,6 @@ bool IndexRouter::FindBestEdges(m2::PointD const & checkpoint,
|
|||
bool & bestSegmentIsAlmostCodirectional) const
|
||||
{
|
||||
CHECK(m_vehicleModelFactory, ());
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(pointCountryFile);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(MwmIsNotAliveException, ("Can't get mwm handle for", pointCountryFile));
|
||||
|
||||
auto const rect = mercator::RectByCenterXYAndSizeInMeters(checkpoint, closestEdgesRadiusM);
|
||||
auto closestRoads = m_roadGraph.FindRoads(rect, [this](FeatureID const & fid)
|
||||
|
@ -1474,7 +1471,7 @@ RouterResultCode IndexRouter::ProcessLeapsJoints(vector<Segment> const & input,
|
|||
|
||||
RouterResultCode IndexRouter::RedressRoute(vector<Segment> const & segments,
|
||||
base::Cancellable const & cancellable,
|
||||
IndexGraphStarter & starter, Route & route) const
|
||||
IndexGraphStarter & starter, Route & route)
|
||||
{
|
||||
CHECK(!segments.empty(), ());
|
||||
vector<geometry::PointWithAltitude> junctions;
|
||||
|
@ -1484,7 +1481,7 @@ RouterResultCode IndexRouter::RedressRoute(vector<Segment> const & segments,
|
|||
for (size_t i = 0; i < numPoints; ++i)
|
||||
junctions.emplace_back(starter.GetRouteJunction(segments, i).ToPointWithAltitude());
|
||||
|
||||
IndexRoadGraph roadGraph(m_numMwmIds, starter, segments, junctions, m_dataSource);
|
||||
IndexRoadGraph roadGraph(starter, segments, junctions, m_dataSource);
|
||||
starter.GetGraph().SetMode(WorldGraphMode::NoLeaps);
|
||||
|
||||
Route::TTimes times;
|
||||
|
@ -1542,7 +1539,7 @@ RouterResultCode IndexRouter::RedressRoute(vector<Segment> const & segments,
|
|||
|
||||
bool IndexRouter::AreSpeedCamerasProhibited(NumMwmId mwmID) const
|
||||
{
|
||||
if (::AreSpeedCamerasProhibited(m_numMwmIds->GetFile(mwmID)))
|
||||
if (routing::AreSpeedCamerasProhibited(m_numMwmIds->GetFile(mwmID)))
|
||||
{
|
||||
// Not a big overhead here, but can cache flag in IndexRouter and reset it via
|
||||
// Framework -> RoutingSession -> IndexRouter.
|
||||
|
@ -1561,11 +1558,11 @@ bool IndexRouter::AreMwmsNear(IndexGraphStarter const & starter) const
|
|||
{
|
||||
m2::RectD const & rect = m_countryRectFn(m_numMwmIds->GetFile(startMwmId).GetName());
|
||||
bool found = false;
|
||||
m_numMwmTree->ForEachInRect(rect,
|
||||
[&finishMwmIds, &found](NumMwmId id) {
|
||||
if (!found && finishMwmIds.count(id) > 0)
|
||||
found = true;
|
||||
});
|
||||
m_numMwmTree->ForEachInRect(rect, [&finishMwmIds, &found](NumMwmId id)
|
||||
{
|
||||
if (!found && finishMwmIds.count(id) > 0)
|
||||
found = true;
|
||||
});
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
|
@ -1573,21 +1570,13 @@ bool IndexRouter::AreMwmsNear(IndexGraphStarter const & starter) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IndexRouter::DoesTransitSectionExist(NumMwmId numMwmId) const
|
||||
bool IndexRouter::DoesTransitSectionExist(NumMwmId numMwmId)
|
||||
{
|
||||
CHECK(m_numMwmIds, ());
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Can't get mwm handle for", file));
|
||||
|
||||
MwmValue const & mwmValue = *handle.GetValue();
|
||||
return mwmValue.m_cont.IsExist(TRANSIT_FILE_TAG);
|
||||
return m_dataSource.GetSectionStatus(numMwmId, TRANSIT_FILE_TAG) == MwmDataSource::SectionExists;
|
||||
}
|
||||
|
||||
RouterResultCode IndexRouter::ConvertTransitResult(set<NumMwmId> const & mwmIds,
|
||||
RouterResultCode resultCode) const
|
||||
RouterResultCode resultCode)
|
||||
{
|
||||
if (m_vehicleType != VehicleType::Transit || resultCode != RouterResultCode::RouteNotFound)
|
||||
return resultCode;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "routing/base/astar_progress.hpp"
|
||||
#include "routing/base/routing_result.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/directions_engine.hpp"
|
||||
#include "routing/edge_estimator.hpp"
|
||||
#include "routing/fake_edges_container.hpp"
|
||||
|
@ -35,8 +36,6 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class DataSource;
|
||||
|
||||
namespace traffic { class TrafficCache; }
|
||||
|
||||
namespace routing
|
||||
|
@ -182,14 +181,14 @@ private:
|
|||
std::vector<Segment> & output);
|
||||
RouterResultCode RedressRoute(std::vector<Segment> const & segments,
|
||||
base::Cancellable const & cancellable, IndexGraphStarter & starter,
|
||||
Route & route) const;
|
||||
Route & route);
|
||||
|
||||
bool AreSpeedCamerasProhibited(NumMwmId mwmID) const;
|
||||
bool AreMwmsNear(IndexGraphStarter const & starter) const;
|
||||
bool DoesTransitSectionExist(NumMwmId numMwmId) const;
|
||||
bool DoesTransitSectionExist(NumMwmId numMwmId);
|
||||
|
||||
RouterResultCode ConvertTransitResult(std::set<NumMwmId> const & mwmIds,
|
||||
RouterResultCode resultCode) const;
|
||||
RouterResultCode resultCode);
|
||||
|
||||
/// \brief Fills |speedcamProhibitedMwms| with mwms which are crossed by |segments|
|
||||
/// where speed cameras are prohibited.
|
||||
|
@ -210,7 +209,7 @@ private:
|
|||
|
||||
template <typename Vertex, typename Edge, typename Weight, typename AStarParams>
|
||||
RouterResultCode FindPath(AStarParams & params, std::set<NumMwmId> const & mwmIds,
|
||||
RoutingResult<Vertex, Weight> & routingResult) const
|
||||
RoutingResult<Vertex, Weight> & routingResult)
|
||||
{
|
||||
AStarAlgorithm<Vertex, Edge, Weight> algorithm;
|
||||
return ConvertTransitResult(
|
||||
|
@ -235,7 +234,7 @@ private:
|
|||
VehicleType m_vehicleType;
|
||||
bool m_loadAltitudes;
|
||||
std::string const m_name;
|
||||
DataSource & m_dataSource;
|
||||
MwmDataSource m_dataSource;
|
||||
std::shared_ptr<VehicleModelFactoryInterface> m_vehicleModelFactory;
|
||||
|
||||
TCountryFileFn const m_countryFileFn;
|
||||
|
@ -243,7 +242,7 @@ private:
|
|||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
std::shared_ptr<m4::Tree<NumMwmId>> m_numMwmTree;
|
||||
std::shared_ptr<TrafficStash> m_trafficStash;
|
||||
FeaturesRoadGraph m_roadGraph;
|
||||
FeaturesRoadGraphBase m_roadGraph;
|
||||
|
||||
std::shared_ptr<EdgeEstimator> m_estimator;
|
||||
std::unique_ptr<DirectionsEngine> m_directionsEngine;
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
namespace routing
|
||||
{
|
||||
PedestrianDirectionsEngine::PedestrianDirectionsEngine(DataSource const & dataSource,
|
||||
shared_ptr<NumMwmIds> numMwmIds)
|
||||
PedestrianDirectionsEngine::PedestrianDirectionsEngine(MwmDataSource & dataSource, shared_ptr<NumMwmIds> numMwmIds)
|
||||
: DirectionsEngine(dataSource, move(numMwmIds))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace routing
|
|||
class PedestrianDirectionsEngine : public DirectionsEngine
|
||||
{
|
||||
public:
|
||||
PedestrianDirectionsEngine(DataSource const & dataSource, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
PedestrianDirectionsEngine(MwmDataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
protected:
|
||||
virtual size_t GetTurnDirection(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
|
|
|
@ -44,20 +44,19 @@ void SplitEdge(Edge const & ab, geometry::PointWithAltitude const & p, vector<Ed
|
|||
|
||||
// Edge ------------------------------------------------------------------------
|
||||
// static
|
||||
Edge Edge::MakeReal(FeatureID const & featureId, bool forward, uint32_t segId,
|
||||
Edge Edge::MakeReal(FeatureID featureId, bool forward, uint32_t segId,
|
||||
JunctionPointT const & startJunction,
|
||||
JunctionPointT const & endJunction)
|
||||
{
|
||||
return {Type::Real, featureId, kInvalidFakeSegmentId, forward, segId, startJunction, endJunction};
|
||||
return {Type::Real, std::move(featureId), kInvalidFakeSegmentId, forward, segId, startJunction, endJunction};
|
||||
}
|
||||
|
||||
// static
|
||||
Edge Edge::MakeFakeWithRealPart(FeatureID const & featureId, uint32_t fakeSegmentId, bool forward,
|
||||
Edge Edge::MakeFakeWithRealPart(FeatureID featureId, uint32_t fakeSegmentId, bool forward,
|
||||
uint32_t segId, JunctionPointT const & startJunction,
|
||||
JunctionPointT const & endJunction)
|
||||
{
|
||||
return {Type::FakeWithRealPart, featureId, fakeSegmentId, forward,
|
||||
segId, startJunction, endJunction};
|
||||
return {Type::FakeWithRealPart, std::move(featureId), fakeSegmentId, forward, segId, startJunction, endJunction};
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -79,10 +78,10 @@ Edge Edge::MakeFake(JunctionPointT const & startJunction,
|
|||
return e;
|
||||
}
|
||||
|
||||
Edge::Edge(Type type, FeatureID const & featureId, uint32_t fakeSegmentId, bool forward, uint32_t segId,
|
||||
Edge::Edge(Type type, FeatureID featureId, uint32_t fakeSegmentId, bool forward, uint32_t segId,
|
||||
JunctionPointT const & startJunction, JunctionPointT const & endJunction)
|
||||
: m_type(type)
|
||||
, m_featureId(featureId)
|
||||
, m_featureId(std::move(featureId))
|
||||
, m_forward(forward)
|
||||
, m_segId(segId)
|
||||
, m_startJunction(startJunction)
|
||||
|
|
|
@ -37,10 +37,10 @@ public:
|
|||
|
||||
using JunctionPointT = geometry::PointWithAltitude;
|
||||
|
||||
static Edge MakeReal(FeatureID const & featureId, bool forward, uint32_t segId,
|
||||
static Edge MakeReal(FeatureID featureId, bool forward, uint32_t segId,
|
||||
JunctionPointT const & startJunction,
|
||||
JunctionPointT const & endJunction);
|
||||
static Edge MakeFakeWithRealPart(FeatureID const & featureId, uint32_t fakeSegmentId,
|
||||
static Edge MakeFakeWithRealPart(FeatureID featureId, uint32_t fakeSegmentId,
|
||||
bool forward, uint32_t segId,
|
||||
JunctionPointT const & startJunction,
|
||||
JunctionPointT const & endJunction);
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
bool operator<(Edge const & r) const;
|
||||
|
||||
private:
|
||||
Edge(Type type, FeatureID const & featureId, uint32_t fakeSegmentId, bool forward, uint32_t segId,
|
||||
Edge(Type type, FeatureID featureId, uint32_t fakeSegmentId, bool forward, uint32_t segId,
|
||||
JunctionPointT const & startJunction, JunctionPointT const & endJunction);
|
||||
|
||||
friend std::string DebugPrint(Edge const & r);
|
||||
|
|
|
@ -28,13 +28,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
// RoutingTest overrides:
|
||||
std::unique_ptr<routing::DirectionsEngine> CreateDirectionsEngine(
|
||||
std::shared_ptr<routing::NumMwmIds> numMwmIds) override
|
||||
{
|
||||
return std::make_unique<routing::CarDirectionsEngine>(m_dataSource, numMwmIds);
|
||||
}
|
||||
|
||||
std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
|
||||
{
|
||||
return std::make_unique<SimplifiedModelFactory<routing::BicycleModel>>();
|
||||
|
|
|
@ -38,13 +38,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
// RoutingTest overrides:
|
||||
std::unique_ptr<routing::DirectionsEngine> CreateDirectionsEngine(
|
||||
std::shared_ptr<routing::NumMwmIds> numMwmIds) override
|
||||
{
|
||||
return std::make_unique<routing::CarDirectionsEngine>(m_dataSource, numMwmIds);
|
||||
}
|
||||
|
||||
std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
|
||||
{
|
||||
return std::make_unique<SimplifiedModelFactory<routing::CarModel>>();
|
||||
|
|
|
@ -142,7 +142,8 @@ unique_ptr<routing::IRouter> RoutingTest::CreateRouter(string const & name)
|
|||
void RoutingTest::GetNearestEdges(m2::PointD const & pt,
|
||||
vector<pair<routing::Edge, geometry::PointWithAltitude>> & edges)
|
||||
{
|
||||
routing::FeaturesRoadGraph graph(m_dataSource, m_mode, CreateModelFactory());
|
||||
MwmDataSource dataSource(m_dataSource, nullptr /* numMwmIDs */);
|
||||
routing::FeaturesRoadGraph graph(dataSource, m_mode, CreateModelFactory());
|
||||
graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(
|
||||
pt, routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
|
||||
1 /* count */, edges);
|
||||
|
|
|
@ -36,8 +36,6 @@ public:
|
|||
void TestTwoPointsOnFeature(m2::PointD const & startPos, m2::PointD const & finalPos);
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<routing::DirectionsEngine> CreateDirectionsEngine(
|
||||
std::shared_ptr<routing::NumMwmIds> numMwmIds) = 0;
|
||||
virtual std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() = 0;
|
||||
|
||||
std::unique_ptr<routing::IRouter> CreateRouter(std::string const & name);
|
||||
|
|
|
@ -45,13 +45,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
// RoutingTest overrides:
|
||||
unique_ptr<routing::DirectionsEngine> CreateDirectionsEngine(
|
||||
shared_ptr<routing::NumMwmIds> numMwmIds) override
|
||||
{
|
||||
return std::make_unique<routing::PedestrianDirectionsEngine>(m_dataSource, move(numMwmIds));
|
||||
}
|
||||
|
||||
unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
|
||||
{
|
||||
unique_ptr<routing::VehicleModelFactoryInterface> factory(
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
@ -50,8 +51,8 @@ void TestConcurrentAccessToFeatures(string const & mwm)
|
|||
"threads simultaneously.", local));
|
||||
|
||||
mutex guardCtorMtx;
|
||||
auto parseGeometries = [&guardCtorMtx, &featureNumber, &dataSource, &handle,
|
||||
&local](vector<m2::PointD> & points) {
|
||||
auto parseGeometries = [&](vector<m2::PointD> & points)
|
||||
{
|
||||
unique_lock<mutex> guardCtor(guardCtorMtx);
|
||||
FeaturesLoaderGuard guard(dataSource, handle.GetId());
|
||||
guardCtor.unlock();
|
||||
|
|
|
@ -40,11 +40,12 @@ void TestAltitudeOfAllMwmFeatures(string const & countryId,
|
|||
TEST_NOT_EQUAL(country, LocalCountryFile(), ());
|
||||
TEST(country.HasFiles(), (country));
|
||||
|
||||
pair<MwmSet::MwmId, MwmSet::RegResult> const regResult = dataSource.RegisterMap(country);
|
||||
TEST_EQUAL(regResult.second, MwmSet::RegResult::Success, ());
|
||||
TEST(regResult.first.IsAlive(), ());
|
||||
pair<MwmSet::MwmId, MwmSet::RegResult> const res = dataSource.RegisterMap(country);
|
||||
TEST_EQUAL(res.second, MwmSet::RegResult::Success, ());
|
||||
auto const handle = dataSource.GetMwmHandleById(res.first);
|
||||
TEST(handle.IsAlive(), ());
|
||||
|
||||
auto altitudeLoader = make_unique<AltitudeLoaderCached>(dataSource, regResult.first /* mwmId */);
|
||||
auto altitudeLoader = make_unique<AltitudeLoaderCached>(*handle.GetValue());
|
||||
|
||||
ForEachFeature(country.GetPath(MapFileType::Map), [&](FeatureType & f, uint32_t const & id)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,8 @@ UNIT_TEST(FakeEdgesCombinatorialExplosion)
|
|||
for (auto const & file : localFiles)
|
||||
dataSource.Register(file);
|
||||
|
||||
FeaturesRoadGraph graph(dataSource, IRoadGraph::Mode::ObeyOnewayTag,
|
||||
MwmDataSource routingSource(dataSource, nullptr /* numMwmIDs */);
|
||||
FeaturesRoadGraph graph(routingSource, IRoadGraph::Mode::ObeyOnewayTag,
|
||||
std::make_shared<CarModelFactory>(CountryParentNameGetterFn()));
|
||||
geometry::PointWithAltitude const j(m2::PointD(mercator::FromLatLon(50.73208, -1.21279)),
|
||||
geometry::kDefaultAltitudeMeters);
|
||||
|
|
|
@ -160,10 +160,7 @@ void TestSerialization(CrossMwmConnectorBuilderEx<CrossMwmId> & builder)
|
|||
|
||||
CrossMwmBuilderTestFixture<CrossMwmId> test;
|
||||
|
||||
{
|
||||
ReaderSource<MemReader> source(reader);
|
||||
test.builder.DeserializeTransitions(VehicleType::Car, source);
|
||||
}
|
||||
test.builder.DeserializeTransitions(VehicleType::Car, reader);
|
||||
|
||||
TestConnectorConsistency(test.connector);
|
||||
|
||||
|
@ -187,10 +184,7 @@ void TestSerialization(CrossMwmConnectorBuilderEx<CrossMwmId> & builder)
|
|||
TEST(!test.connector.WeightsWereLoaded(), ());
|
||||
TEST(!test.connector.HasWeights(), ());
|
||||
|
||||
{
|
||||
ReaderSource<MemReader> source(reader);
|
||||
test.builder.DeserializeWeights(source);
|
||||
}
|
||||
test.builder.DeserializeWeights(reader);
|
||||
|
||||
TEST(test.connector.WeightsWereLoaded(), ());
|
||||
TEST(test.connector.HasWeights(), ());
|
||||
|
@ -253,10 +247,7 @@ void TestWeightsSerialization()
|
|||
NumMwmId const mwmId = kGeneratorMwmId;
|
||||
CrossMwmBuilderTestFixture<CrossMwmId> test(mwmId);
|
||||
|
||||
{
|
||||
ReaderSource<MemReader> source(reader);
|
||||
test.builder.DeserializeTransitions(VehicleType::Car, source);
|
||||
}
|
||||
test.builder.DeserializeTransitions(VehicleType::Car, reader);
|
||||
|
||||
TestConnectorConsistency(test.connector);
|
||||
|
||||
|
@ -266,10 +257,7 @@ void TestWeightsSerialization()
|
|||
TEST(!test.connector.WeightsWereLoaded(), ());
|
||||
TEST(!test.connector.HasWeights(), ());
|
||||
|
||||
{
|
||||
ReaderSource<MemReader> source(reader);
|
||||
test.builder.DeserializeWeights(source);
|
||||
}
|
||||
test.builder.DeserializeWeights(reader);
|
||||
|
||||
TEST(test.connector.WeightsWereLoaded(), ());
|
||||
TEST(test.connector.HasWeights(), ());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "routing/transit_graph_loader.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/fake_ending.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
|
||||
|
@ -9,9 +10,6 @@
|
|||
#include "transit/transit_types.hpp"
|
||||
#include "transit/transit_version.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
|
||||
#include "coding/files_container.hpp"
|
||||
|
@ -29,122 +27,94 @@ namespace routing
|
|||
class TransitGraphLoaderImpl : public TransitGraphLoader
|
||||
{
|
||||
public:
|
||||
TransitGraphLoaderImpl(DataSource & dataSource, shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<EdgeEstimator> estimator);
|
||||
TransitGraphLoaderImpl(MwmDataSource & dataSource, shared_ptr<EdgeEstimator> estimator)
|
||||
: m_dataSource(dataSource), m_estimator(estimator)
|
||||
{
|
||||
}
|
||||
|
||||
// TransitGraphLoader overrides.
|
||||
~TransitGraphLoaderImpl() override = default;
|
||||
TransitGraph & GetTransitGraph(NumMwmId numMwmId, IndexGraph & indexGraph) override
|
||||
{
|
||||
auto const it = m_graphs.find(numMwmId);
|
||||
if (it != m_graphs.cend())
|
||||
return *it->second;
|
||||
|
||||
TransitGraph & GetTransitGraph(NumMwmId mwmId, IndexGraph & indexGraph) override;
|
||||
void Clear() override;
|
||||
auto const emplaceRes = m_graphs.emplace(numMwmId, CreateTransitGraph(numMwmId, indexGraph));
|
||||
ASSERT(emplaceRes.second, ("Failed to add TransitGraph for", numMwmId, "to TransitGraphLoader."));
|
||||
return *(emplaceRes.first)->second;
|
||||
}
|
||||
|
||||
void Clear() override { m_graphs.clear(); }
|
||||
|
||||
private:
|
||||
unique_ptr<TransitGraph> CreateTransitGraph(NumMwmId mwmId, IndexGraph & indexGraph) const;
|
||||
unique_ptr<TransitGraph> CreateTransitGraph(NumMwmId numMwmId, IndexGraph & indexGraph) const
|
||||
{
|
||||
base::Timer timer;
|
||||
|
||||
DataSource & m_dataSource;
|
||||
shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
MwmValue const & mwmValue = m_dataSource.GetMwmValue(numMwmId);
|
||||
|
||||
// By default we return empty transit graph with version OnlySubway.
|
||||
if (!mwmValue.m_cont.IsExist(TRANSIT_FILE_TAG))
|
||||
return make_unique<TransitGraph>(::transit::TransitVersion::OnlySubway, numMwmId, m_estimator);
|
||||
|
||||
try
|
||||
{
|
||||
FilesContainerR::TReader reader(mwmValue.m_cont.GetReader(TRANSIT_FILE_TAG));
|
||||
auto const transitHeaderVersion = ::transit::GetVersion(*reader.GetPtr());
|
||||
|
||||
unique_ptr<TransitGraph> graph;
|
||||
if (transitHeaderVersion == ::transit::TransitVersion::OnlySubway)
|
||||
{
|
||||
graph = make_unique<TransitGraph>(::transit::TransitVersion::OnlySubway, numMwmId, m_estimator);
|
||||
|
||||
transit::GraphData transitData;
|
||||
transitData.DeserializeForRouting(*reader.GetPtr());
|
||||
|
||||
TransitGraph::Endings gateEndings;
|
||||
MakeGateEndings(transitData.GetGates(), numMwmId, indexGraph, gateEndings);
|
||||
|
||||
graph->Fill(transitData, gateEndings);
|
||||
}
|
||||
else if (transitHeaderVersion == ::transit::TransitVersion::AllPublicTransport)
|
||||
{
|
||||
graph = make_unique<TransitGraph>(::transit::TransitVersion::AllPublicTransport, numMwmId, m_estimator);
|
||||
|
||||
::transit::experimental::TransitData transitData;
|
||||
transitData.DeserializeForRouting(*reader.GetPtr());
|
||||
|
||||
TransitGraph::Endings gateEndings;
|
||||
MakeGateEndings(transitData.GetGates(), numMwmId, indexGraph, gateEndings);
|
||||
|
||||
TransitGraph::Endings stopEndings;
|
||||
MakeStopEndings(transitData.GetStops(), numMwmId, indexGraph, stopEndings);
|
||||
|
||||
graph->Fill(transitData, stopEndings, gateEndings);
|
||||
}
|
||||
else
|
||||
CHECK(false, (transitHeaderVersion));
|
||||
|
||||
LOG(LINFO, (TRANSIT_FILE_TAG, "section, version", transitHeaderVersion, "for", mwmValue.GetCountryFileName(),
|
||||
"loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
|
||||
return graph;
|
||||
}
|
||||
catch (Reader::OpenException const & e)
|
||||
{
|
||||
LOG(LERROR, ("Error while reading", TRANSIT_FILE_TAG, "section.", e.Msg()));
|
||||
throw;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
MwmDataSource & m_dataSource;
|
||||
shared_ptr<EdgeEstimator> m_estimator;
|
||||
unordered_map<NumMwmId, unique_ptr<TransitGraph>> m_graphs;
|
||||
};
|
||||
|
||||
TransitGraphLoaderImpl::TransitGraphLoaderImpl(DataSource & dataSource,
|
||||
shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<EdgeEstimator> estimator)
|
||||
: m_dataSource(dataSource), m_numMwmIds(numMwmIds), m_estimator(estimator)
|
||||
{
|
||||
}
|
||||
|
||||
void TransitGraphLoaderImpl::Clear() { m_graphs.clear(); }
|
||||
|
||||
TransitGraph & TransitGraphLoaderImpl::GetTransitGraph(NumMwmId numMwmId, IndexGraph & indexGraph)
|
||||
{
|
||||
auto const it = m_graphs.find(numMwmId);
|
||||
if (it != m_graphs.cend())
|
||||
return *it->second;
|
||||
|
||||
auto const emplaceRes = m_graphs.emplace(numMwmId, CreateTransitGraph(numMwmId, indexGraph));
|
||||
ASSERT(emplaceRes.second, ("Failed to add TransitGraph for", numMwmId, "to TransitGraphLoader."));
|
||||
return *(emplaceRes.first)->second;
|
||||
}
|
||||
|
||||
unique_ptr<TransitGraph> TransitGraphLoaderImpl::CreateTransitGraph(NumMwmId numMwmId,
|
||||
IndexGraph & indexGraph) const
|
||||
{
|
||||
platform::CountryFile const & file = m_numMwmIds->GetFile(numMwmId);
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(file);
|
||||
if (!handle.IsAlive())
|
||||
MYTHROW(RoutingException, ("Can't get mwm handle for", file));
|
||||
|
||||
base::Timer timer;
|
||||
|
||||
MwmValue const & mwmValue = *handle.GetValue();
|
||||
|
||||
// By default we return empty transit graph with version OnlySubway.
|
||||
if (!mwmValue.m_cont.IsExist(TRANSIT_FILE_TAG))
|
||||
return make_unique<TransitGraph>(::transit::TransitVersion::OnlySubway, numMwmId, m_estimator);
|
||||
|
||||
try
|
||||
{
|
||||
FilesContainerR::TReader reader(mwmValue.m_cont.GetReader(TRANSIT_FILE_TAG));
|
||||
auto const transitHeaderVersion = ::transit::GetVersion(*reader.GetPtr());
|
||||
|
||||
if (transitHeaderVersion == ::transit::TransitVersion::OnlySubway)
|
||||
{
|
||||
auto graph =
|
||||
make_unique<TransitGraph>(::transit::TransitVersion::OnlySubway, numMwmId, m_estimator);
|
||||
|
||||
transit::GraphData transitData;
|
||||
transitData.DeserializeForRouting(*reader.GetPtr());
|
||||
|
||||
TransitGraph::Endings gateEndings;
|
||||
MakeGateEndings(transitData.GetGates(), numMwmId, indexGraph, gateEndings);
|
||||
|
||||
graph->Fill(transitData, gateEndings);
|
||||
|
||||
LOG(LINFO, (TRANSIT_FILE_TAG, "section, version", transitHeaderVersion, "for", file.GetName(),
|
||||
"loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
|
||||
return graph;
|
||||
}
|
||||
else if (transitHeaderVersion == ::transit::TransitVersion::AllPublicTransport)
|
||||
{
|
||||
auto graph = make_unique<TransitGraph>(::transit::TransitVersion::AllPublicTransport,
|
||||
numMwmId, m_estimator);
|
||||
|
||||
::transit::experimental::TransitData transitData;
|
||||
transitData.DeserializeForRouting(*reader.GetPtr());
|
||||
|
||||
TransitGraph::Endings gateEndings;
|
||||
MakeGateEndings(transitData.GetGates(), numMwmId, indexGraph, gateEndings);
|
||||
|
||||
TransitGraph::Endings stopEndings;
|
||||
MakeStopEndings(transitData.GetStops(), numMwmId, indexGraph, stopEndings);
|
||||
|
||||
graph->Fill(transitData, stopEndings, gateEndings);
|
||||
|
||||
LOG(LINFO, (TRANSIT_FILE_TAG, "section, version", transitHeaderVersion, "for", file.GetName(),
|
||||
"loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
CHECK(false, (transitHeaderVersion));
|
||||
}
|
||||
catch (Reader::OpenException const & e)
|
||||
{
|
||||
LOG(LERROR, ("Error while reading", TRANSIT_FILE_TAG, "section.", e.Msg()));
|
||||
throw;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// static
|
||||
unique_ptr<TransitGraphLoader> TransitGraphLoader::Create(DataSource & dataSource,
|
||||
shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<EdgeEstimator> estimator)
|
||||
unique_ptr<TransitGraphLoader> TransitGraphLoader::Create(MwmDataSource & dataSource, shared_ptr<EdgeEstimator> estimator)
|
||||
{
|
||||
return make_unique<TransitGraphLoaderImpl>(dataSource, numMwmIds, estimator);
|
||||
return make_unique<TransitGraphLoaderImpl>(dataSource, estimator);
|
||||
}
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
class DataSource;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class MwmDataSource;
|
||||
|
||||
class TransitGraphLoader
|
||||
{
|
||||
public:
|
||||
|
@ -20,8 +20,6 @@ public:
|
|||
virtual TransitGraph & GetTransitGraph(NumMwmId mwmId, IndexGraph & indexGraph) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
static std::unique_ptr<TransitGraphLoader> Create(DataSource & dataSource,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
std::shared_ptr<EdgeEstimator> estimator);
|
||||
static std::unique_ptr<TransitGraphLoader> Create(MwmDataSource & dataSource, std::shared_ptr<EdgeEstimator> estimator);
|
||||
};
|
||||
} // namespace routing
|
||||
|
|
|
@ -57,8 +57,8 @@ public:
|
|||
explicit EliasFanoMap(unique_ptr<Reader> && reader) : m_reader(move(reader))
|
||||
{
|
||||
ASSERT(m_reader, ());
|
||||
auto readBlockCallback = [](auto & source, uint32_t blockSize, vector<uint32_t> & values) {
|
||||
CHECK_GREATER(blockSize, 0, ());
|
||||
auto readBlockCallback = [](auto & source, uint32_t blockSize, vector<uint32_t> & values)
|
||||
{
|
||||
values.resize(blockSize);
|
||||
values[0] = ReadVarUint<uint32_t>(source);
|
||||
|
||||
|
@ -66,8 +66,7 @@ public:
|
|||
{
|
||||
// Feature ids for all real features are less than numeric_limits<int32_t>::max()
|
||||
// so we can use delta coding with int32_t difference type.
|
||||
auto const delta = ReadVarInt<int32_t>(source);
|
||||
values[i] = base::asserted_cast<uint32_t>(values[i - 1] + delta);
|
||||
values[i] = base::asserted_cast<uint32_t>(values[i - 1] + ReadVarInt<int32_t>(source));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -885,6 +885,23 @@ void Processor::InitPreRanker(Geocoder::Params const & geocoderParams,
|
|||
m_preRanker.Init(params);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class NotInPreffered : public ftypes::BaseChecker
|
||||
{
|
||||
NotInPreffered() : ftypes::BaseChecker(1)
|
||||
{
|
||||
base::StringIL const types[] = { {"organic"}, {"internet_access"} };
|
||||
auto const & c = classif();
|
||||
for (auto const & e : types)
|
||||
m_types.push_back(c.GetTypeByPath(e));
|
||||
}
|
||||
|
||||
public:
|
||||
DECLARE_CHECKER_INSTANCE(NotInPreffered);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void Processor::InitRanker(Geocoder::Params const & geocoderParams,
|
||||
SearchParams const & searchParams)
|
||||
{
|
||||
|
@ -901,12 +918,7 @@ void Processor::InitRanker(Geocoder::Params const & geocoderParams,
|
|||
|
||||
params.m_preferredTypes = m_preferredTypes;
|
||||
// Remove "secondary" category types from preferred.
|
||||
base::EraseIf(params.m_preferredTypes, [](uint32_t type)
|
||||
{
|
||||
static uint32_t const organic = classif().GetTypeByPath({"organic"});
|
||||
ftype::TruncValue(type, 1);
|
||||
return (organic == type);
|
||||
});
|
||||
base::EraseIf(params.m_preferredTypes, NotInPreffered::Instance());
|
||||
|
||||
params.m_suggestsEnabled = searchParams.m_suggestsEnabled;
|
||||
params.m_needAddress = searchParams.m_needAddress;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "track_analyzing/utils.hpp"
|
||||
|
||||
#include "routing/city_roads.hpp"
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/geometry.hpp"
|
||||
#include "routing/index_graph.hpp"
|
||||
#include "routing/index_graph_loader.hpp"
|
||||
|
@ -18,7 +19,6 @@
|
|||
#include "traffic/speed_groups.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/features_vector.hpp"
|
||||
|
@ -53,9 +53,10 @@
|
|||
|
||||
#include "defines.hpp"
|
||||
|
||||
namespace track_analyzing
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
using namespace track_analyzing;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -383,8 +384,7 @@ private:
|
|||
};
|
||||
} // namespace
|
||||
|
||||
namespace track_analyzing
|
||||
{
|
||||
|
||||
void CmdTagsTable(string const & filepath, string const & trackExtension, StringFilter mwmFilter,
|
||||
StringFilter userFilter)
|
||||
{
|
||||
|
@ -396,7 +396,8 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
|
|||
auto numMwmIds = CreateNumMwmIds(storage);
|
||||
|
||||
Stats stats;
|
||||
auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks) {
|
||||
auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks)
|
||||
{
|
||||
if (mwmFilter(mwmName))
|
||||
return;
|
||||
|
||||
|
@ -410,8 +411,10 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
|
|||
auto const vehicleType = VehicleType::Car;
|
||||
auto const edgeEstimator = EdgeEstimator::Create(vehicleType, *vehicleModel,
|
||||
nullptr /* trafficStash */, &dataSource, numMwmIds);
|
||||
auto indexGraphLoader = IndexGraphLoader::Create(vehicleType, false /* loadAltitudes */, numMwmIds,
|
||||
carModelFactory, edgeEstimator, dataSource);
|
||||
|
||||
MwmDataSource routingSource(dataSource, numMwmIds);
|
||||
auto indexGraphLoader = IndexGraphLoader::Create(vehicleType, false /* loadAltitudes */,
|
||||
carModelFactory, edgeEstimator, routingSource);
|
||||
|
||||
platform::CountryFile const countryFile(mwmName);
|
||||
auto localCountryFile = storage.GetLatestLocalFile(countryFile);
|
||||
|
@ -472,7 +475,8 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
|
|||
}
|
||||
};
|
||||
|
||||
auto processTrack = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks) {
|
||||
auto processTrack = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks)
|
||||
{
|
||||
LOG(LINFO, ("Processing", filename));
|
||||
ForTracksSortedByMwmName(mwmToMatchedTracks, *numMwmIds, processMwm);
|
||||
};
|
||||
|
|
|
@ -66,10 +66,10 @@ TrackMatcher::TrackMatcher(storage::Storage const & storage, NumMwmId mwmId,
|
|||
CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success,
|
||||
("Can't register mwm", countryFile.GetName()));
|
||||
|
||||
MwmSet::MwmHandle const handle = m_dataSource.GetMwmHandleByCountryFile(countryFile);
|
||||
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(countryFile);
|
||||
|
||||
m_graph = make_unique<IndexGraph>(
|
||||
make_shared<Geometry>(GeometryLoader::Create(m_dataSource, handle, m_vehicleModel,
|
||||
false /* loadAltitudes */)),
|
||||
make_shared<Geometry>(GeometryLoader::Create(handle, m_vehicleModel, false /* loadAltitudes */)),
|
||||
EdgeEstimator::Create(VehicleType::Car, *m_vehicleModel, nullptr /* trafficStash */,
|
||||
nullptr /* dataSource */, nullptr /* numMvmIds */));
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Paths
|
||||
OMIM_ROOT = $(PROJECT_DIR)/../..
|
||||
QT_PATH = /usr/local/opt/qt5
|
||||
QT_PATH[arch=x86_64] = /usr/local/opt/qt@5
|
||||
QT_PATH[arch=arm64] = /opt/homebrew/opt/qt@5
|
||||
BOOST_ROOT = $(OMIM_ROOT)/3party/boost
|
||||
|
||||
HEADER_SEARCH_PATHS = $(inherited) $(OMIM_ROOT) $(BOOST_ROOT)
|
||||
|
|
|
@ -63,8 +63,6 @@
|
|||
408FE47724FEB95600F5D06D /* metadata_serdes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 408FE47524FEB95600F5D06D /* metadata_serdes.cpp */; };
|
||||
4099F6491FC7142A002A7B05 /* fake_feature_ids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4099F6471FC71429002A7B05 /* fake_feature_ids.cpp */; };
|
||||
4099F64A1FC7142A002A7B05 /* fake_feature_ids.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4099F6481FC7142A002A7B05 /* fake_feature_ids.hpp */; };
|
||||
409EE3E3237E9AA700EA31A4 /* postcodes.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 409EE3E1237E9AA700EA31A4 /* postcodes.hpp */; };
|
||||
409EE3E4237E9AA700EA31A4 /* postcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 409EE3E2237E9AA700EA31A4 /* postcodes.cpp */; };
|
||||
40D62CEF23F2E8BE009A20F5 /* dat_section_header.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 40D62CEE23F2E8BE009A20F5 /* dat_section_header.hpp */; };
|
||||
456B3FB41EDEEB65009B3D1F /* scales_patch.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 456B3FB31EDEEB65009B3D1F /* scales_patch.hpp */; };
|
||||
456E1B181F90E5B7009C32E1 /* cities_boundaries_serdes.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 456E1B141F90E5B6009C32E1 /* cities_boundaries_serdes.hpp */; };
|
||||
|
@ -294,8 +292,6 @@
|
|||
408FE47524FEB95600F5D06D /* metadata_serdes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = metadata_serdes.cpp; sourceTree = "<group>"; };
|
||||
4099F6471FC71429002A7B05 /* fake_feature_ids.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fake_feature_ids.cpp; sourceTree = "<group>"; };
|
||||
4099F6481FC7142A002A7B05 /* fake_feature_ids.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = fake_feature_ids.hpp; sourceTree = "<group>"; };
|
||||
409EE3E1237E9AA700EA31A4 /* postcodes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = postcodes.hpp; sourceTree = "<group>"; };
|
||||
409EE3E2237E9AA700EA31A4 /* postcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = postcodes.cpp; sourceTree = "<group>"; };
|
||||
40C3C090205BF9F400CED188 /* bounds.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = bounds.hpp; sourceTree = "<group>"; };
|
||||
40D62CEE23F2E8BE009A20F5 /* dat_section_header.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = dat_section_header.hpp; sourceTree = "<group>"; };
|
||||
40DF582C2174979200E4E0FC /* classificator_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = classificator_tests.cpp; sourceTree = "<group>"; };
|
||||
|
@ -706,8 +702,6 @@
|
|||
675340E51A3F540F00A0A8C3 /* mwm_set.hpp */,
|
||||
E906DE391CF44934004C4F5E /* postcodes_matcher.cpp */,
|
||||
E906DE3A1CF44934004C4F5E /* postcodes_matcher.hpp */,
|
||||
409EE3E2237E9AA700EA31A4 /* postcodes.cpp */,
|
||||
409EE3E1237E9AA700EA31A4 /* postcodes.hpp */,
|
||||
347F33721C454242009758CC /* rank_table.cpp */,
|
||||
347F33731C454242009758CC /* rank_table.hpp */,
|
||||
F61F83041E4B187500B37B7A /* road_shields_parser.cpp */,
|
||||
|
@ -804,7 +798,6 @@
|
|||
6753413F1A3F540F00A0A8C3 /* scale_index.hpp in Headers */,
|
||||
6753410E1A3F540F00A0A8C3 /* drawing_rules.hpp in Headers */,
|
||||
FA7F9B84273F32680093EA08 /* validate_and_format_contacts.hpp in Headers */,
|
||||
409EE3E3237E9AA700EA31A4 /* postcodes.hpp in Headers */,
|
||||
670C615C1AB0691900C38A8C /* features_offsets_table.hpp in Headers */,
|
||||
6758AED41BB4413000C26E27 /* drules_selector.hpp in Headers */,
|
||||
6753412F1A3F540F00A0A8C3 /* index_builder.hpp in Headers */,
|
||||
|
@ -1001,7 +994,6 @@
|
|||
3D12E3D72111B4BE0015A9A9 /* caching_rank_table_loader.cpp in Sources */,
|
||||
6753414D1A3F540F00A0A8C3 /* types_mapping.cpp in Sources */,
|
||||
34583BC71C88552100F94664 /* cuisines.cpp in Sources */,
|
||||
409EE3E4237E9AA700EA31A4 /* postcodes.cpp in Sources */,
|
||||
675341121A3F540F00A0A8C3 /* feature_algo.cpp in Sources */,
|
||||
675341211A3F540F00A0A8C3 /* feature_utils.cpp in Sources */,
|
||||
4099F6491FC7142A002A7B05 /* fake_feature_ids.cpp in Sources */,
|
||||
|
|
Reference in a new issue