diff --git a/src/engine/plugins/tile.cpp b/src/engine/plugins/tile.cpp index e4054c6dd..a838c9dae 100644 --- a/src/engine/plugins/tile.cpp +++ b/src/engine/plugins/tile.cpp @@ -357,6 +357,26 @@ Status TilePlugin::HandleRequest(const std::shared_ptr sorted_edge_indexes(edges.size(), 0); + std::iota(sorted_edge_indexes.begin(), sorted_edge_indexes.end(), 0); // fill with 1,2,3,...N + + // Now, sort that array based on the edges list, using the u/v node IDs + // as the sort condition + std::sort(sorted_edge_indexes.begin(), + sorted_edge_indexes.end(), + [edges](const std::size_t &left, const std::size_t &right) -> bool { + return (edges[left].u != edges[right].u) ? edges[left].u < edges[right].u + : edges[left].v < edges[right].v; + }); + // From here on, we'll iterate over the sorted_edge_indexes instead of `edges` directly. + // Note, that we do this because ` + // If we're zooming into 16 or higher, include turn data. Why? Because turns make the map // really cramped, so we don't bother including the data for tiles that span a large area. if (parameters.z >= MIN_ZOOM_FOR_TURNS) @@ -386,8 +406,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptr unpacked_shortcut; std::vector approach_weight_vector; - // Look at every node in the directed graph we created + + // Make sure we traverse the startnodes in a consistent order + // to ensure identical PBF encoding on all platforms. + std::vector sorted_startnodes; + sorted_startnodes.reserve(directed_graph.size()); for (const auto &startnode : directed_graph) + sorted_startnodes.push_back(startnode.first); + std::sort(sorted_startnodes.begin(), sorted_startnodes.end()); + + // Look at every node in the directed graph we created + for (const auto &startnode : sorted_startnodes) { + const auto &nodedata = directed_graph[startnode]; // For all the outgoing edges from the node - for (const auto &approachedge : startnode.second) + for (const auto &approachedge : nodedata) { // If the target of this edge doesn't exist in our directed // graph, it's probably outside the tile, so we can skip it @@ -455,7 +486,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedForwardDatasources(edge.packed_geometry_id); @@ -636,8 +668,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedForwardWeights(edge.packed_geometry_id); const auto reverse_weight_vector = @@ -653,8 +686,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetCoordinateOfNode(edge.u); const auto b = facade->GetCoordinateOfNode(edge.v); diff --git a/unit_tests/library/tile.cpp b/unit_tests/library/tile.cpp index 6d6ea8a33..0f204e5dc 100644 --- a/unit_tests/library/tile.cpp +++ b/unit_tests/library/tile.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(test_tile) const auto rc = osrm.Tile(params, result); BOOST_CHECK(rc == Status::Ok); - BOOST_CHECK_GT(result.size(), 128); + BOOST_CHECK_EQUAL(result.size(), 114091); protozero::pbf_reader tile_message(result); tile_message.next();