forked from organicmaps/organicmaps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopular_places_section_builder.cpp
122 lines (98 loc) · 3.41 KB
/
popular_places_section_builder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "generator/popular_places_section_builder.hpp"
#include "generator/gen_mwm_info.hpp"
#include "generator/ugc_translator.hpp"
#include "generator/utils.hpp"
#include "ugc/binary/index_ugc.hpp"
#include "ugc/binary/serdes.hpp"
#include "indexer/feature_data.hpp"
#include "indexer/feature_processor.hpp"
#include "indexer/ftraits.hpp"
#include "indexer/rank_table.hpp"
#include "base/geo_object_id.hpp"
#include "base/string_utils.hpp"
#include <cstdint>
#include <limits>
#include <unordered_map>
#include <utility>
#include <vector>
namespace
{
using PopularityIndex = uint8_t;
using PopularPlaces = std::unordered_map<base::GeoObjectId, PopularityIndex>;
void LoadPopularPlaces(std::string const & srcFilename, PopularPlaces & places)
{
coding::CSVReader reader;
auto const fileReader = FileReader(srcFilename);
reader.Read(fileReader, [&places, &srcFilename](coding::CSVReader::Row const & row)
{
size_t constexpr kOsmIdPos = 0;
size_t constexpr kPopularityIndexPos = 1;
ASSERT_EQUAL(row.size(), 2, ());
uint64_t osmId;
if (!strings::to_uint64(row[kOsmIdPos], osmId))
{
LOG(LERROR, ("Incorrect OSM id in file:", srcFilename, "parsed row:", row));
return;
}
uint32_t popularityIndex;
if (!strings::to_uint(row[kPopularityIndexPos], popularityIndex))
{
LOG(LERROR, ("Incorrect popularity index in file:", srcFilename, "parsed row:", row));
return;
}
if (popularityIndex > std::numeric_limits<PopularityIndex>::max())
{
LOG(LERROR, ("The popularity index value is higher than max supported value:", srcFilename,
"parsed row:", row));
return;
}
base::GeoObjectId id(osmId);
auto const result = places.emplace(std::move(id), static_cast<PopularityIndex>(popularityIndex));
if (!result.second)
{
LOG(LERROR, ("Popular place duplication in file:", srcFilename, "parsed row:", row));
return;
}
});
}
} // namespace
namespace generator
{
bool BuildPopularPlacesMwmSection(std::string const & srcFilename, std::string const & mwmFile,
std::string const & osmToFeatureFilename)
{
using ugc::binary::IndexUGC;
LOG(LINFO, ("Build Popular Places section"));
std::unordered_map<uint32_t, base::GeoObjectId> featureIdToOsmId;
ForEachOsmId2FeatureId(osmToFeatureFilename,
[&featureIdToOsmId](base::GeoObjectId const & osmId, uint32_t fId) {
featureIdToOsmId.emplace(fId, osmId);
});
PopularPlaces places;
LoadPopularPlaces(srcFilename, places);
bool popularPlaceFound = false;
std::vector<PopularityIndex> content;
feature::ForEachFromDat(mwmFile, [&](FeatureType const & f, uint32_t featureId)
{
ASSERT_EQUAL(content.size(), featureId, ());
PopularityIndex rank = 0;
auto const it = featureIdToOsmId.find(featureId);
// Non-OSM features (coastlines, sponsored objects) are not used.
if (it != featureIdToOsmId.cend())
{
auto const placesIt = places.find(it->second);
if (placesIt != places.cend())
{
popularPlaceFound = true;
rank = placesIt->second;
}
}
content.emplace_back(rank);
});
if (!popularPlaceFound)
return true;
FilesContainerW cont(mwmFile, FileWriter::OP_WRITE_EXISTING);
search::RankTableBuilder::Create(content, cont, POPULARITY_RANKS_FILE_TAG);
return true;
}
} // namespace generator