Merge branch 'master' into navigation-refactoring

This commit is contained in:
Anton Makouski 2022-05-16 10:56:50 +03:00 committed by GitHub
commit be8f4e064e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
86 changed files with 1175 additions and 1288 deletions

View file

@ -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()

View file

@ -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 -->

View file

@ -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>

View file

@ -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 Mapsi 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 Mapsi 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>

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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!

View file

@ -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,

View file

@ -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);

View file

@ -4,6 +4,7 @@ set(SRC
features_tests.cpp
helpers.cpp
helpers.hpp
mwm_playground.cpp
)
omim_add_test(${PROJECT_NAME} ${SRC})

View 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()));
}

View file

@ -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)

View file

@ -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"

View file

@ -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

View file

@ -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))

View file

@ -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)
{
}

View file

@ -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;
}
};

View file

@ -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

View file

@ -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);

View file

@ -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))
{
}

View file

@ -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;

View file

@ -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();

View file

@ -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
{
}

View file

@ -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

View file

@ -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,

View file

@ -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);
}
};

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -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];

View file

@ -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";

View file

@ -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";

View file

@ -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)]);

View file

@ -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>

View file

@ -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)
{
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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

View file

@ -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)
{

View file

@ -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."));

View file

@ -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

View file

@ -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))
{
}

View file

@ -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,

View file

@ -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

View file

@ -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;
};

View file

@ -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

View file

@ -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;

View file

@ -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
View 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

View file

@ -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;

View file

@ -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:

View file

@ -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, ());

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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());
};

View file

@ -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()));
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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))
{
}

View file

@ -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,

View file

@ -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)

View file

@ -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);

View file

@ -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>>();

View file

@ -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>>();

View file

@ -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);

View file

@ -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);

View file

@ -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(

View file

@ -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();

View file

@ -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)
{

View file

@ -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);

View file

@ -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(), ());

View file

@ -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

View file

@ -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

View file

@ -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));
}
};

View file

@ -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;

View file

@ -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);
};

View file

@ -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 */));

View file

@ -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)

View file

@ -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 */,