Add code to draw segregated nodes in a tile layer
This commit is contained in:
parent
37685dae73
commit
f460a9f17e
@ -191,6 +191,8 @@ class BaseDataFacade
|
|||||||
virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0;
|
virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0;
|
||||||
|
|
||||||
virtual bool IsLeftHandDriving(const NodeID id) const = 0;
|
virtual bool IsLeftHandDriving(const NodeID id) const = 0;
|
||||||
|
|
||||||
|
virtual bool IsSegregated(const NodeID) const { return false; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,60 @@ inline void encodePoint(const FixedPoint &pt, protozero::packed_field_uint32 &ge
|
|||||||
geometry.add_element(protozero::encode_zigzag32(dy));
|
geometry.add_element(protozero::encode_zigzag32(dy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<FixedLine> coordinatesToTileLine(const std::vector<util::Coordinate> &points,
|
||||||
|
const BBox &tile_bbox)
|
||||||
|
{
|
||||||
|
FloatLine geo_line;
|
||||||
|
for (auto const &c : points)
|
||||||
|
{
|
||||||
|
geo_line.emplace_back(static_cast<double>(util::toFloating(c.lon)),
|
||||||
|
static_cast<double>(util::toFloating(c.lat)));
|
||||||
|
}
|
||||||
|
|
||||||
|
linestring_t unclipped_line;
|
||||||
|
|
||||||
|
for (auto const &pt : geo_line)
|
||||||
|
{
|
||||||
|
double px_merc = pt.x * util::web_mercator::DEGREE_TO_PX;
|
||||||
|
double py_merc = util::web_mercator::latToY(util::FloatLatitude{pt.y}) *
|
||||||
|
util::web_mercator::DEGREE_TO_PX;
|
||||||
|
// convert lon/lat to tile coordinates
|
||||||
|
const auto px = std::round(
|
||||||
|
((px_merc - tile_bbox.minx) * util::web_mercator::TILE_SIZE / tile_bbox.width()) *
|
||||||
|
util::vector_tile::EXTENT / util::web_mercator::TILE_SIZE);
|
||||||
|
const auto py = std::round(
|
||||||
|
((tile_bbox.maxy - py_merc) * util::web_mercator::TILE_SIZE / tile_bbox.height()) *
|
||||||
|
util::vector_tile::EXTENT / util::web_mercator::TILE_SIZE);
|
||||||
|
|
||||||
|
boost::geometry::append(unclipped_line, point_t(px, py));
|
||||||
|
}
|
||||||
|
|
||||||
|
multi_linestring_t clipped_line;
|
||||||
|
|
||||||
|
boost::geometry::intersection(clip_box, unclipped_line, clipped_line);
|
||||||
|
|
||||||
|
std::vector<FixedLine> result;
|
||||||
|
|
||||||
|
// b::g::intersection might return a line with one point if the
|
||||||
|
// original line was very short and coords were dupes
|
||||||
|
if (!clipped_line.empty())
|
||||||
|
{
|
||||||
|
for (auto const &cl : clipped_line)
|
||||||
|
{
|
||||||
|
if (cl.size() < 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FixedLine tile_line;
|
||||||
|
for (const auto &p : cl)
|
||||||
|
tile_line.emplace_back(p.get<0>(), p.get<1>());
|
||||||
|
|
||||||
|
result.emplace_back(std::move(tile_line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returnx the x1,y1,x2,y2 pixel coordinates of a line in a given
|
* Returnx the x1,y1,x2,y2 pixel coordinates of a line in a given
|
||||||
* tile.
|
* tile.
|
||||||
@ -310,6 +364,20 @@ std::vector<std::size_t> getEdgeIndex(const std::vector<RTreeLeaf> &edges)
|
|||||||
return sorted_edge_indexes;
|
return sorted_edge_indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<NodeID> getSegregatedNodes(const DataFacadeBase &facade,
|
||||||
|
const std::vector<RTreeLeaf> &edges)
|
||||||
|
{
|
||||||
|
std::vector<NodeID> result;
|
||||||
|
|
||||||
|
for (RTreeLeaf const &e : edges)
|
||||||
|
{
|
||||||
|
if (e.forward_segment_id.enabled && facade.IsSegregated(e.forward_segment_id.id))
|
||||||
|
result.push_back(e.forward_segment_id.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void encodeVectorTile(const DataFacadeBase &facade,
|
void encodeVectorTile(const DataFacadeBase &facade,
|
||||||
unsigned x,
|
unsigned x,
|
||||||
unsigned y,
|
unsigned y,
|
||||||
@ -317,6 +385,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
const std::vector<RTreeLeaf> &edges,
|
const std::vector<RTreeLeaf> &edges,
|
||||||
const std::vector<std::size_t> &sorted_edge_indexes,
|
const std::vector<std::size_t> &sorted_edge_indexes,
|
||||||
const std::vector<routing_algorithms::TurnData> &all_turn_data,
|
const std::vector<routing_algorithms::TurnData> &all_turn_data,
|
||||||
|
const std::vector<NodeID> &segregated_nodes,
|
||||||
std::string &pbf_buffer)
|
std::string &pbf_buffer)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -867,6 +936,66 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
protozero::pbf_writer line_layer_writer(tile_writer, util::vector_tile::LAYER_TAG);
|
||||||
|
line_layer_writer.add_uint32(util::vector_tile::VERSION_TAG, 2); // version
|
||||||
|
line_layer_writer.add_string(util::vector_tile::NAME_TAG, "internal-nodes"); // name
|
||||||
|
line_layer_writer.add_uint32(util::vector_tile::EXTENT_TAG,
|
||||||
|
util::vector_tile::EXTENT); // extent
|
||||||
|
|
||||||
|
unsigned id = 0;
|
||||||
|
for (auto edgeNodeID : segregated_nodes)
|
||||||
|
{
|
||||||
|
auto const geomIndex = facade.GetGeometryIndex(edgeNodeID);
|
||||||
|
std::vector<NodeID> geometry;
|
||||||
|
|
||||||
|
if (geomIndex.forward)
|
||||||
|
geometry = facade.GetUncompressedForwardGeometry(geomIndex.id);
|
||||||
|
else
|
||||||
|
geometry = facade.GetUncompressedReverseGeometry(geomIndex.id);
|
||||||
|
|
||||||
|
std::vector<util::Coordinate> points;
|
||||||
|
for (auto const nodeID : geometry)
|
||||||
|
points.push_back(facade.GetCoordinateOfNode(nodeID));
|
||||||
|
|
||||||
|
const auto encode_tile_line = [&line_layer_writer, &id](
|
||||||
|
const FixedLine &tile_line, std::int32_t &start_x, std::int32_t &start_y) {
|
||||||
|
|
||||||
|
protozero::pbf_writer feature_writer(line_layer_writer,
|
||||||
|
util::vector_tile::FEATURE_TAG);
|
||||||
|
|
||||||
|
feature_writer.add_enum(util::vector_tile::GEOMETRY_TAG,
|
||||||
|
util::vector_tile::GEOMETRY_TYPE_LINE); // geometry type
|
||||||
|
|
||||||
|
feature_writer.add_uint64(util::vector_tile::ID_TAG, id++); // id
|
||||||
|
{
|
||||||
|
|
||||||
|
protozero::packed_field_uint32 field(
|
||||||
|
feature_writer, util::vector_tile::FEATURE_ATTRIBUTES_TAG);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
// Encode the geometry for the feature
|
||||||
|
protozero::packed_field_uint32 geometry(
|
||||||
|
feature_writer, util::vector_tile::FEATURE_GEOMETRIES_TAG);
|
||||||
|
encodeLinestring(tile_line, geometry, start_x, start_y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::int32_t start_x = 0;
|
||||||
|
std::int32_t start_y = 0;
|
||||||
|
|
||||||
|
auto tile_lines = coordinatesToTileLine(points, tile_bbox);
|
||||||
|
if (!tile_lines.empty())
|
||||||
|
{
|
||||||
|
for (auto const &tl : tile_lines)
|
||||||
|
{
|
||||||
|
encode_tile_line(tl, start_x, start_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// protozero serializes data during object destructors, so once the scope closes,
|
// protozero serializes data during object destructors, so once the scope closes,
|
||||||
// our result buffer will have all the tile data encoded into it.
|
// our result buffer will have all the tile data encoded into it.
|
||||||
@ -881,6 +1010,7 @@ Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
|
|
||||||
const auto &facade = algorithms.GetFacade();
|
const auto &facade = algorithms.GetFacade();
|
||||||
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
|
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
|
||||||
|
auto segregated_nodes = getSegregatedNodes(facade, edges);
|
||||||
|
|
||||||
auto edge_index = getEdgeIndex(edges);
|
auto edge_index = getEdgeIndex(edges);
|
||||||
|
|
||||||
@ -893,8 +1023,15 @@ Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
turns = algorithms.GetTileTurns(edges, edge_index);
|
turns = algorithms.GetTileTurns(edges, edge_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeVectorTile(
|
encodeVectorTile(facade,
|
||||||
facade, parameters.x, parameters.y, parameters.z, edges, edge_index, turns, pbf_buffer);
|
parameters.x,
|
||||||
|
parameters.y,
|
||||||
|
parameters.z,
|
||||||
|
edges,
|
||||||
|
edge_index,
|
||||||
|
turns,
|
||||||
|
segregated_nodes,
|
||||||
|
pbf_buffer);
|
||||||
|
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user