Skip to content

Commit db07e91

Browse files
authoredApr 25, 2023
added transit level to connectivity map (valhalla#4082)
1 parent 6e0db89 commit db07e91

File tree

6 files changed

+79
-66
lines changed

6 files changed

+79
-66
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
* CHANGED: baldr directory: remove warnings and C++17 adjustments [#4011](https://github.com/valhalla/valhalla/pull/4011)
5050
* UPDATED: `vcpkg` to latest master, iconv wasn't building anymore [#4066](https://github.com/valhalla/valhalla/pull/4066)
5151
* CHANGED: pybind11 upgrade for python 3.11 [#4067](https://github.com/valhalla/valhalla/pull/4067)
52+
* CHANGED: added transit level to connectivity map [#4082](https://github.com/valhalla/valhalla/pull/4082)
5253

5354
## Release Date: 2023-01-03 Valhalla 3.3.0
5455
* **Removed**

‎src/baldr/connectivity_map.cc

+13-12
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ connectivity_map_t::connectivity_map_t(const boost::property_tree::ptree& pt,
137137
}
138138

139139
// All tiles have color 0 (not connected), go through and connect
140-
// (build the ColorMap). Transit level uses local hierarchy tiles
140+
// (build the ColorMap).
141141
for (auto& color : colors) {
142142
if (color.first == transit_level) {
143143
TileHierarchy::GetTransitLevel().tiles.ColorMap(color.second, not_neighbors);
@@ -162,16 +162,15 @@ size_t connectivity_map_t::get_color(const GraphId& id) const {
162162
return color->second;
163163
}
164164

165-
std::unordered_set<size_t> connectivity_map_t::get_colors(uint32_t hierarchy_level,
165+
std::unordered_set<size_t> connectivity_map_t::get_colors(const baldr::TileLevel& hierarchy_level,
166166
const baldr::PathLocation& location,
167167
float radius) const {
168168

169169
std::unordered_set<size_t> result;
170-
auto level = colors.find(hierarchy_level);
170+
auto level = colors.find(hierarchy_level.level);
171171
if (level == colors.cend()) {
172172
return result;
173173
}
174-
const auto& tiles = TileHierarchy::levels()[hierarchy_level].tiles;
175174
std::vector<const decltype(location.edges)*> edge_sets{&location.edges, &location.filtered_edges};
176175
for (const auto* edges : edge_sets) {
177176
for (const auto& edge : *edges) {
@@ -182,7 +181,7 @@ std::unordered_set<size_t> connectivity_map_t::get_colors(uint32_t hierarchy_lev
182181
float lngdeg = (radius / DistanceApproximator<PointLL>::MetersPerLngDegree(ll.lat()));
183182
AABB2<PointLL> bbox(Point2(ll.lng() - lngdeg, ll.lat() - latdeg),
184183
Point2(ll.lng() + lngdeg, ll.lat() + latdeg));
185-
std::vector<int32_t> tilelist = tiles.TileList(bbox);
184+
std::vector<int32_t> tilelist = hierarchy_level.tiles.TileList(bbox);
186185
for (const auto& id : tilelist) {
187186
auto color = level->second.find(id);
188187
if (color != level->second.cend()) {
@@ -196,11 +195,12 @@ std::unordered_set<size_t> connectivity_map_t::get_colors(uint32_t hierarchy_lev
196195

197196
std::string connectivity_map_t::to_geojson(const uint32_t hierarchy_level) const {
198197
// bail if we dont have the level
199-
uint32_t tile_level = (hierarchy_level == transit_level) ? transit_level - 1 : hierarchy_level;
200-
if (tile_level >= TileHierarchy::levels().size()) {
198+
if (hierarchy_level > TileHierarchy::GetTransitLevel().level) {
201199
throw std::runtime_error("hierarchy level not found");
202200
}
203-
const auto& tiles = TileHierarchy::levels()[tile_level].tiles;
201+
const auto& tiles = hierarchy_level == transit_level
202+
? TileHierarchy::GetTransitLevel().tiles
203+
: TileHierarchy::levels()[hierarchy_level].tiles;
204204

205205
// make a region map (inverse mapping of color to lists of tiles)
206206
// could cache this but shouldnt need to call it much
@@ -236,13 +236,14 @@ std::string connectivity_map_t::to_geojson(const uint32_t hierarchy_level) const
236236
}
237237

238238
std::vector<size_t> connectivity_map_t::to_image(const uint32_t hierarchy_level) const {
239-
uint32_t tile_level = (hierarchy_level == transit_level) ? transit_level - 1 : hierarchy_level;
240-
if (tile_level >= TileHierarchy::levels().size()) {
239+
if (hierarchy_level > TileHierarchy::GetTransitLevel().level) {
241240
throw std::runtime_error("hierarchy level not found");
242241
}
243-
const auto& level_tiles = TileHierarchy::levels()[tile_level];
242+
const auto& level_tiles = hierarchy_level == transit_level
243+
? TileHierarchy::GetTransitLevel().tiles
244+
: TileHierarchy::levels()[hierarchy_level].tiles;
244245

245-
std::vector<size_t> tiles(level_tiles.tiles.nrows() * level_tiles.tiles.ncolumns(), 0);
246+
std::vector<size_t> tiles(level_tiles.nrows() * level_tiles.ncolumns(), 0);
246247
auto level = colors.find(hierarchy_level);
247248
if (level != colors.cend()) {
248249
for (size_t i = 0; i < tiles.size(); ++i) {

‎src/loki/matrix_action.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void loki_worker_t::matrix(Api& request) {
145145
if (!connectivity_map) {
146146
continue;
147147
}
148-
auto colors = connectivity_map->get_colors(TileHierarchy::levels().back().level, projection, 0);
148+
auto colors = connectivity_map->get_colors(TileHierarchy::levels().back(), projection, 0);
149149
for (auto& color : colors) {
150150
auto itr = color_counts.find(color);
151151
if (itr == color_counts.cend()) {

‎src/loki/route_action.cc

+5-3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ void loki_worker_t::route(Api& request) {
7171
// check distance for hierarchy pruning
7272
check_hierarchy_distance(request);
7373

74+
auto connectivity_level = TileHierarchy::levels().back();
75+
uint32_t connectivity_radius = 0;
7476
// Validate walking distances (make sure they are in the accepted range)
7577
if (costing_name == "multimodal" || costing_name == "transit") {
7678
auto& ped_opts = *options.mutable_costings()->find(Costing::pedestrian)->second.mutable_options();
@@ -92,6 +94,8 @@ void loki_worker_t::route(Api& request) {
9294
throw valhalla_exception_t{156, " Min: " + std::to_string(min_transit_walking_dis) + " Max: " +
9395
std::to_string(max_transit_walking_dis) + " (Meters)"};
9496
}
97+
connectivity_level = TileHierarchy::GetTransitLevel();
98+
connectivity_radius = ped_opts.transit_start_end_max_distance();
9599
}
96100

97101
// correlate the various locations to the underlying graph
@@ -102,12 +106,10 @@ void loki_worker_t::route(Api& request) {
102106
for (size_t i = 0; i < locations.size(); ++i) {
103107
const auto& correlated = projections.at(locations[i]);
104108
PathLocation::toPBF(correlated, options.mutable_locations(i), *reader);
105-
// TODO: get transit level for transit costing
106-
// TODO: if transit send a non zero radius
107109
if (!connectivity_map) {
108110
continue;
109111
}
110-
auto colors = connectivity_map->get_colors(TileHierarchy::levels().back().level, correlated, 0);
112+
auto colors = connectivity_map->get_colors(connectivity_level, correlated, connectivity_radius);
111113
for (auto color : colors) {
112114
auto itr = color_counts.find(color);
113115
if (itr == color_counts.cend()) {

‎test/graphreader.cc

+56-48
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ TEST(SimpleCache, CacheLimitsNoOvercommitAfterClear) {
6464
EXPECT_FALSE(cache.OverCommitted());
6565
}
6666

67-
void touch_tile(const uint32_t tile_id, const std::string& tile_dir) {
68-
auto suffix = GraphTile::FileSuffix({tile_id, 2, 0});
67+
void touch_tile(const uint32_t tile_id, const std::string& tile_dir, uint8_t level) {
68+
auto suffix = GraphTile::FileSuffix({tile_id, level, 0});
6969
auto fullpath = tile_dir + filesystem::path::preferred_separator + suffix;
7070
filesystem::create_directories(filesystem::path(fullpath).parent_path());
7171
int fd = open(fullpath.c_str(), O_CREAT | O_WRONLY, 0644);
@@ -78,52 +78,60 @@ TEST(ConnectivityMap, Basic) {
7878
boost::property_tree::ptree pt;
7979
pt.put("tile_dir", "test/gphrdr_test");
8080
std::string tile_dir = pt.get<std::string>("tile_dir");
81-
const auto& level = TileHierarchy::levels()[2];
82-
filesystem::remove_all(tile_dir);
83-
84-
// looks like this (XX) means no tile there:
85-
/*
86-
* XX d1 XX XX
87-
* XX d0 XX XX
88-
* a2 XX c0 XX
89-
* a0 a1 XX b0
90-
*
91-
*/
92-
93-
// create some empty files with tile names
94-
uint32_t a0 = 0;
95-
touch_tile(a0, tile_dir);
96-
97-
uint32_t a1 = level.tiles.RightNeighbor(a0);
98-
touch_tile(a1, tile_dir);
99-
100-
uint32_t a2 = level.tiles.TopNeighbor(a0);
101-
touch_tile(a2, tile_dir);
102-
103-
uint32_t b0 = level.tiles.RightNeighbor(level.tiles.RightNeighbor(a1));
104-
touch_tile(b0, tile_dir);
105-
106-
uint32_t c0 = level.tiles.TopNeighbor(level.tiles.RightNeighbor(a1));
107-
touch_tile(c0, tile_dir);
108-
109-
uint32_t d0 = level.tiles.TopNeighbor(level.tiles.RightNeighbor(a2));
110-
touch_tile(d0, tile_dir);
111-
112-
uint32_t d1 = level.tiles.TopNeighbor(d0);
113-
touch_tile(d1, tile_dir);
114-
115-
// check that it looks right
116-
connectivity_map_t conn(pt);
117-
118-
EXPECT_EQ(conn.get_color({a0, 2, 0}), conn.get_color({a1, 2, 0})) << "a's should be connected";
119-
EXPECT_EQ(conn.get_color({a0, 2, 0}), conn.get_color({a2, 2, 0})) << "a's should be connected";
120-
EXPECT_EQ(conn.get_color({a1, 2, 0}), conn.get_color({a2, 2, 0})) << "a's should be connected";
121-
EXPECT_EQ(conn.get_color({d0, 2, 0}), conn.get_color({d1, 2, 0})) << "d's should be connected";
122-
EXPECT_NE(conn.get_color({c0, 2, 0}), conn.get_color({a1, 2, 0})) << "c is disjoint";
123-
EXPECT_NE(conn.get_color({b0, 2, 0}), conn.get_color({a0, 2, 0})) << "b is disjoint";
124-
EXPECT_NE(conn.get_color({a2, 2, 0}), conn.get_color({d0, 2, 0})) << "a is disjoint from d";
125-
126-
filesystem::remove_all(tile_dir);
81+
for (const auto& level : {TileHierarchy::levels()[2], TileHierarchy::GetTransitLevel()}) {
82+
filesystem::remove_all(tile_dir);
83+
84+
// looks like this (XX) means no tile there:
85+
/*
86+
* XX d1 XX XX
87+
* XX d0 XX XX
88+
* a2 XX c0 XX
89+
* a0 a1 XX b0
90+
*
91+
*/
92+
93+
// create some empty files with tile names
94+
uint32_t a0 = 0;
95+
touch_tile(a0, tile_dir, level.level);
96+
97+
uint32_t a1 = level.tiles.RightNeighbor(a0);
98+
touch_tile(a1, tile_dir, level.level);
99+
100+
uint32_t a2 = level.tiles.TopNeighbor(a0);
101+
touch_tile(a2, tile_dir, level.level);
102+
103+
uint32_t b0 = level.tiles.RightNeighbor(level.tiles.RightNeighbor(a1));
104+
touch_tile(b0, tile_dir, level.level);
105+
106+
uint32_t c0 = level.tiles.TopNeighbor(level.tiles.RightNeighbor(a1));
107+
touch_tile(c0, tile_dir, level.level);
108+
109+
uint32_t d0 = level.tiles.TopNeighbor(level.tiles.RightNeighbor(a2));
110+
touch_tile(d0, tile_dir, level.level);
111+
112+
uint32_t d1 = level.tiles.TopNeighbor(d0);
113+
touch_tile(d1, tile_dir, level.level);
114+
115+
// check that it looks right
116+
connectivity_map_t conn(pt);
117+
118+
EXPECT_EQ(conn.get_color({a0, level.level, 0}), conn.get_color({a1, level.level, 0}))
119+
<< "a's should be connected";
120+
EXPECT_EQ(conn.get_color({a0, level.level, 0}), conn.get_color({a2, level.level, 0}))
121+
<< "a's should be connected";
122+
EXPECT_EQ(conn.get_color({a1, level.level, 0}), conn.get_color({a2, level.level, 0}))
123+
<< "a's should be connected";
124+
EXPECT_EQ(conn.get_color({d0, level.level, 0}), conn.get_color({d1, level.level, 0}))
125+
<< "d's should be connected";
126+
EXPECT_NE(conn.get_color({c0, level.level, 0}), conn.get_color({a1, level.level, 0}))
127+
<< "c is disjoint";
128+
EXPECT_NE(conn.get_color({b0, level.level, 0}), conn.get_color({a0, level.level, 0}))
129+
<< "b is disjoint";
130+
EXPECT_NE(conn.get_color({a2, level.level, 0}), conn.get_color({d0, level.level, 0}))
131+
<< "a is disjoint from d";
132+
133+
filesystem::remove_all(tile_dir);
134+
}
127135
}
128136

129137
class TestGraphMemory final : public GraphMemory {

‎valhalla/baldr/connectivity_map.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ class connectivity_map_t {
3939
* @param radius the radius of the circle
4040
* @return colors the colors of the tiles that intersect this circle at this level
4141
*/
42-
std::unordered_set<size_t>
43-
get_colors(uint32_t hierarchy_level, const baldr::PathLocation& location, float radius) const;
42+
std::unordered_set<size_t> get_colors(const baldr::TileLevel& hierarchy_level,
43+
const baldr::PathLocation& location,
44+
float radius) const;
4445

4546
/**
4647
* Returns the geojson representing the connectivity map

0 commit comments

Comments
 (0)
Please sign in to comment.