Skip to content

Commit 1142a9e

Browse files
danpatTheMarex
authored andcommitted
Add layer to debug tiles to expose all OSM nodes in that area.
1 parent b168eca commit 1142a9e

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed

src/engine/plugins/tile.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,51 @@ void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &
831831
values_writer.add_float(util::vector_tile::VARIANT_TYPE_FLOAT, value);
832832
}
833833
}
834+
835+
// OSM Node tile layer
836+
{
837+
protozero::pbf_writer point_layer_writer(tile_writer, util::vector_tile::LAYER_TAG);
838+
point_layer_writer.add_uint32(util::vector_tile::VERSION_TAG, 2); // version
839+
point_layer_writer.add_string(util::vector_tile::NAME_TAG, "osmnodes"); // name
840+
point_layer_writer.add_uint32(util::vector_tile::EXTENT_TAG,
841+
util::vector_tile::EXTENT); // extent
842+
843+
std::vector<NodeID> internal_nodes;
844+
internal_nodes.reserve(edges.size() * 2);
845+
for (const auto &edge : edges)
846+
{
847+
internal_nodes.push_back(edge.u);
848+
internal_nodes.push_back(edge.v);
849+
}
850+
std::sort(internal_nodes.begin(), internal_nodes.end());
851+
auto new_end = std::unique(internal_nodes.begin(), internal_nodes.end());
852+
internal_nodes.resize(new_end - internal_nodes.begin());
853+
854+
for (const auto &internal_node : internal_nodes)
855+
{
856+
const auto coord = facade.GetCoordinateOfNode(internal_node);
857+
const auto tile_point = coordinatesToTilePoint(coord, tile_bbox);
858+
if (!boost::geometry::within(point_t(tile_point.x, tile_point.y), clip_box))
859+
{
860+
continue;
861+
}
862+
protozero::pbf_writer feature_writer(point_layer_writer,
863+
util::vector_tile::FEATURE_TAG);
864+
// Field 3 is the "geometry type" field. Value 1 is "point"
865+
feature_writer.add_enum(util::vector_tile::GEOMETRY_TAG,
866+
util::vector_tile::GEOMETRY_TYPE_POINT); // geometry type
867+
const auto osmid =
868+
static_cast<OSMNodeID::value_type>(facade.GetOSMNodeIDOfNode(internal_node));
869+
feature_writer.add_uint64(util::vector_tile::ID_TAG, osmid); // id
870+
// There are no additional properties, just the ID and the geometry
871+
{
872+
// Add the geometry as the last field in this feature
873+
protozero::packed_field_uint32 geometry(
874+
feature_writer, util::vector_tile::FEATURE_GEOMETRIES_TAG);
875+
encodePoint(tile_point, geometry);
876+
}
877+
}
878+
}
834879
}
835880
// protozero serializes data during object destructors, so once the scope closes,
836881
// our result buffer will have all the tile data encoded into it.

unit_tests/library/tile.cpp

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "osrm/osrm.hpp"
1212
#include "osrm/status.hpp"
1313

14+
#include "util/typedefs.hpp"
1415
#include "util/vector_tile.hpp"
1516

1617
#include <protozero/pbf_reader.hpp>
@@ -212,6 +213,58 @@ template <typename algorithm> void test_tile(algorithm &osrm)
212213

213214
BOOST_CHECK_EQUAL(number_of_turn_keys, 4);
214215
BOOST_CHECK(number_of_turns_found > 700);
216+
217+
tile_message.next();
218+
layer_message = tile_message.get_message();
219+
220+
auto number_of_nodes_found = 0u;
221+
222+
const auto check_osmnode_feature = [](protozero::pbf_reader feature_message) {
223+
feature_message.next(); // advance parser to first entry
224+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG);
225+
BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_POINT);
226+
227+
feature_message.next(); // advance to next entry
228+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG);
229+
feature_message.get_uint64(); // id
230+
231+
feature_message.next(); // advance to next entry
232+
// Note - on this layer, there should be no feature attributes, the next thing
233+
// we get should be the geometry
234+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_GEOMETRIES_TAG);
235+
auto geometry_iter_pair = feature_message.get_packed_uint32();
236+
BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1);
237+
};
238+
239+
while (layer_message.next())
240+
{
241+
switch (layer_message.tag())
242+
{
243+
case util::vector_tile::VERSION_TAG:
244+
BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2);
245+
break;
246+
case util::vector_tile::NAME_TAG:
247+
BOOST_CHECK_EQUAL(layer_message.get_string(), "osmnodes");
248+
break;
249+
case util::vector_tile::EXTENT_TAG:
250+
BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT);
251+
break;
252+
case util::vector_tile::FEATURE_TAG:
253+
check_osmnode_feature(layer_message.get_message());
254+
number_of_nodes_found++;
255+
break;
256+
case util::vector_tile::KEY_TAG:
257+
BOOST_CHECK(false); // There should be no properties on node features
258+
break;
259+
case util::vector_tile::VARIANT_TAG:
260+
BOOST_CHECK(false); // There should be no properties on node features
261+
break;
262+
default:
263+
BOOST_CHECK(false); // invalid tag
264+
break;
265+
}
266+
}
267+
BOOST_CHECK_EQUAL(number_of_nodes_found, 1791);
215268
}
216269

217270
BOOST_AUTO_TEST_CASE(test_tile_ch)
@@ -613,4 +666,109 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds_mld)
613666
test_tile_speeds(osrm);
614667
}
615668

669+
template <typename algorithm> void test_tile_nodes(algorithm &osrm)
670+
{
671+
using namespace osrm;
672+
673+
// Small tile so we can test all the values
674+
// TileParameters params{272953, 191177, 19};
675+
// TileParameters params{136477, 95580, 18};
676+
// Small tile where we can test all the values
677+
TileParameters params{272953, 191177, 19};
678+
679+
std::string result;
680+
const auto rc = osrm.Tile(params, result);
681+
BOOST_CHECK(rc == Status::Ok);
682+
683+
BOOST_CHECK_GT(result.size(), 128);
684+
685+
protozero::pbf_reader tile_message(result);
686+
tile_message.next();
687+
BOOST_CHECK_EQUAL(tile_message.tag(), util::vector_tile::LAYER_TAG); // must be a layer
688+
689+
// Skip the segments and turns layers
690+
tile_message.skip();
691+
tile_message.next();
692+
tile_message.skip();
693+
694+
// Get the osmnodes layer
695+
tile_message.next();
696+
protozero::pbf_reader layer_message = tile_message.get_message();
697+
698+
std::vector<OSMNodeID::value_type> found_node_ids;
699+
700+
const auto check_feature = [&](protozero::pbf_reader feature_message) {
701+
feature_message.next(); // advance parser to first entry
702+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG);
703+
BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_POINT);
704+
705+
feature_message.next(); // advance to next entry
706+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG);
707+
found_node_ids.push_back(feature_message.get_uint64()); // id
708+
709+
feature_message.next(); // advance to next entry
710+
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_GEOMETRIES_TAG);
711+
auto geometry_iter_pair = feature_message.get_packed_uint32();
712+
BOOST_CHECK_GT(std::distance(geometry_iter_pair.begin(), geometry_iter_pair.end()), 1);
713+
};
714+
715+
while (layer_message.next())
716+
{
717+
switch (layer_message.tag())
718+
{
719+
case util::vector_tile::VERSION_TAG:
720+
BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2);
721+
break;
722+
case util::vector_tile::NAME_TAG:
723+
BOOST_CHECK_EQUAL(layer_message.get_string(), "osmnodes");
724+
break;
725+
case util::vector_tile::EXTENT_TAG:
726+
BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT);
727+
break;
728+
case util::vector_tile::FEATURE_TAG:
729+
check_feature(layer_message.get_message());
730+
break;
731+
case util::vector_tile::KEY_TAG:
732+
BOOST_CHECK(false); // There should be no keys
733+
break;
734+
case util::vector_tile::VARIANT_TAG:
735+
BOOST_CHECK(false); // There should be no values
736+
break;
737+
default:
738+
BOOST_CHECK(false); // invalid tag
739+
break;
740+
}
741+
}
742+
743+
std::sort(found_node_ids.begin(), found_node_ids.end());
744+
const std::vector<OSMNodeID::value_type> expected_node_ids = {
745+
25191722, 25191725, 357300400, 1737389138, 1737389140, 2241375220};
746+
BOOST_CHECK(found_node_ids == expected_node_ids);
747+
}
748+
749+
BOOST_AUTO_TEST_CASE(test_tile_nodes_ch)
750+
{
751+
using namespace osrm;
752+
753+
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm", osrm::EngineConfig::Algorithm::CH);
754+
test_tile_nodes(osrm);
755+
}
756+
757+
BOOST_AUTO_TEST_CASE(test_tile_nodes_corech)
758+
{
759+
using namespace osrm;
760+
761+
auto osrm =
762+
getOSRM(OSRM_TEST_DATA_DIR "/corech/monaco.osrm", osrm::EngineConfig::Algorithm::CoreCH);
763+
test_tile_nodes(osrm);
764+
}
765+
766+
BOOST_AUTO_TEST_CASE(test_tile_nodes_mld)
767+
{
768+
using namespace osrm;
769+
770+
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/mld/monaco.osrm", osrm::EngineConfig::Algorithm::MLD);
771+
test_tile_nodes(osrm);
772+
}
773+
616774
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)