Add data structure to allow identification of via-way turns during creation of edge-based-graph
initial version of handling via-way turn restrictions (this is dirty) - requires update of data structures - requires clean-up - requires optimisation
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "extractor/way_restriction_map.hpp"
|
||||
|
||||
#include "util/concurrent_id_map.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
@@ -78,7 +79,6 @@ class EdgeBasedGraphFactory
|
||||
CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const extractor::PackedOSMIDs &osm_node_ids,
|
||||
ProfileProperties profile_properties,
|
||||
@@ -91,7 +91,9 @@ class EdgeBasedGraphFactory
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path);
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const RestrictionMap &restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
||||
@@ -106,7 +108,7 @@ class EdgeBasedGraphFactory
|
||||
std::vector<util::guidance::BearingClass> GetBearingClasses() const;
|
||||
std::vector<util::guidance::EntryClass> GetEntryClasses() const;
|
||||
|
||||
unsigned GetHighestEdgeID();
|
||||
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
||||
|
||||
// Basic analysis of a turn (u --(e1)-- v --(e2)-- w)
|
||||
// with known angle.
|
||||
@@ -134,12 +136,15 @@ class EdgeBasedGraphFactory
|
||||
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
||||
EdgeBasedNodeDataContainer m_edge_based_node_container;
|
||||
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
EdgeID m_max_edge_id;
|
||||
|
||||
// the number of edge-based nodes is mostly made up out of the edges in the node-based graph.
|
||||
// Any edge in the node-based graph represents a node in the edge-based graph. In addition, we
|
||||
// add a set of artificial edge-based nodes into the mix to model via-way turn restrictions.
|
||||
std::uint64_t m_number_of_edge_based_nodes;
|
||||
|
||||
const std::vector<util::Coordinate> &m_coordinates;
|
||||
const extractor::PackedOSMIDs &m_osm_node_ids;
|
||||
std::shared_ptr<util::NodeBasedDynamicGraph> m_node_based_graph;
|
||||
std::shared_ptr<RestrictionMap const> m_restriction_map;
|
||||
|
||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||
const std::unordered_set<NodeID> &m_traffic_lights;
|
||||
@@ -152,14 +157,16 @@ class EdgeBasedGraphFactory
|
||||
|
||||
unsigned RenumberEdges();
|
||||
|
||||
std::vector<NBGToEBG> GenerateEdgeExpandedNodes();
|
||||
std::vector<NBGToEBG> GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename);
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const RestrictionMap &restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
|
||||
@@ -104,6 +104,16 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
util::inplacePermutation(classes.begin(), classes.end(), permutation);
|
||||
}
|
||||
|
||||
// all containers have the exact same size
|
||||
std::size_t Size() const
|
||||
{
|
||||
BOOST_ASSERT(geometry_ids.size() == name_ids.size());
|
||||
BOOST_ASSERT(geometry_ids.size() == component_ids.size());
|
||||
BOOST_ASSERT(geometry_ids.size() == travel_modes.size());
|
||||
BOOST_ASSERT(geometry_ids.size() == classes.size());
|
||||
return geometry_ids.size();
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<GeometryID> geometry_ids;
|
||||
Vector<NameID> name_ids;
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace extractor
|
||||
// ab via b to bd
|
||||
struct InputNodeRestriction
|
||||
{
|
||||
OSMEdgeID_weak from;
|
||||
OSMNodeID_weak via;
|
||||
OSMEdgeID_weak to;
|
||||
OSMWayID from;
|
||||
OSMNodeID via;
|
||||
OSMWayID to;
|
||||
};
|
||||
|
||||
// A restriction that uses a single via-way in between
|
||||
@@ -39,9 +39,9 @@ struct InputNodeRestriction
|
||||
// ab via be to ef -- no u turn
|
||||
struct InputWayRestriction
|
||||
{
|
||||
OSMEdgeID_weak from;
|
||||
OSMEdgeID_weak via;
|
||||
OSMEdgeID_weak to;
|
||||
OSMWayID from;
|
||||
OSMWayID via;
|
||||
OSMWayID to;
|
||||
};
|
||||
|
||||
// Outside view of the variant, these are equal to the `which()` results
|
||||
@@ -52,35 +52,20 @@ enum RestrictionType
|
||||
NUM_RESTRICTION_TYPES = 2
|
||||
};
|
||||
|
||||
namespace restriction_details
|
||||
{
|
||||
|
||||
// currently these bits only hold an `is_only` value.
|
||||
struct Bits
|
||||
{ // mostly unused, initialised to false by default
|
||||
Bits() : is_only(false) {}
|
||||
|
||||
bool is_only;
|
||||
// when adding more bits, consider using bitfields just as in
|
||||
// bool unused : 7;
|
||||
};
|
||||
|
||||
} // namespace restriction
|
||||
|
||||
struct InputTurnRestriction
|
||||
{
|
||||
// keep in the same order as the turn restrictions below
|
||||
boost::variant<InputNodeRestriction, InputWayRestriction> node_or_way;
|
||||
restriction_details::Bits flags;
|
||||
bool is_only;
|
||||
|
||||
OSMEdgeID_weak From() const
|
||||
OSMWayID From() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).from
|
||||
: boost::get<InputWayRestriction>(node_or_way).from;
|
||||
}
|
||||
|
||||
OSMEdgeID_weak To() const
|
||||
OSMWayID To() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).to
|
||||
@@ -141,6 +126,11 @@ struct NodeRestriction
|
||||
return "From " + std::to_string(from) + " via " + std::to_string(via) + " to " +
|
||||
std::to_string(to);
|
||||
}
|
||||
|
||||
bool operator==(const NodeRestriction &other) const
|
||||
{
|
||||
return std::tie(from, via, to) == std::tie(other.from, other.via, other.to);
|
||||
}
|
||||
};
|
||||
|
||||
// A way restriction in the context of OSRM requires translation into NodeIDs. This is due to the
|
||||
@@ -165,6 +155,12 @@ struct WayRestriction
|
||||
// case a way restrction is not fully collapsed
|
||||
NodeRestriction in_restriction;
|
||||
NodeRestriction out_restriction;
|
||||
|
||||
bool operator==(const WayRestriction &other) const
|
||||
{
|
||||
return std::tie(in_restriction, out_restriction) ==
|
||||
std::tie(other.in_restriction, other.out_restriction);
|
||||
}
|
||||
};
|
||||
|
||||
// Wrapper for turn restrictions that gives more information on its type / handles the switch
|
||||
@@ -173,20 +169,18 @@ struct TurnRestriction
|
||||
{
|
||||
// keep in the same order as the turn restrictions above
|
||||
boost::variant<NodeRestriction, WayRestriction> node_or_way;
|
||||
restriction_details::Bits flags;
|
||||
bool is_only;
|
||||
|
||||
// construction for NodeRestrictions
|
||||
explicit TurnRestriction(NodeRestriction node_restriction, bool is_only = false)
|
||||
: node_or_way(node_restriction)
|
||||
: node_or_way(node_restriction), is_only(is_only)
|
||||
{
|
||||
flags.is_only = is_only;
|
||||
}
|
||||
|
||||
// construction for WayRestrictions
|
||||
explicit TurnRestriction(WayRestriction way_restriction, bool is_only = false)
|
||||
: node_or_way(way_restriction)
|
||||
: node_or_way(way_restriction), is_only(is_only)
|
||||
{
|
||||
flags.is_only = is_only;
|
||||
}
|
||||
|
||||
explicit TurnRestriction()
|
||||
@@ -239,6 +233,24 @@ struct TurnRestriction
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const TurnRestriction &other) const
|
||||
{
|
||||
if (is_only != other.is_only)
|
||||
return false;
|
||||
|
||||
if (Type() != other.Type())
|
||||
return false;
|
||||
|
||||
if (Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
return AsWayRestriction() == other.AsWayRestriction();
|
||||
}
|
||||
else
|
||||
{
|
||||
return AsNodeRestriction() == other.AsNodeRestriction();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string representation;
|
||||
@@ -253,7 +265,7 @@ struct TurnRestriction
|
||||
auto const &node = AsNodeRestriction();
|
||||
representation = node.ToString();
|
||||
}
|
||||
representation += " is_only: " + std::to_string(flags.is_only);
|
||||
representation += " is_only: " + std::to_string(is_only);
|
||||
return representation;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -69,7 +69,6 @@ namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
/**
|
||||
\brief Efficent look up if an edge is the start + via node of a TurnRestriction
|
||||
EdgeBasedEdgeFactory decides by it if edges are inserted or geometry is compressed
|
||||
@@ -80,61 +79,8 @@ class RestrictionMap
|
||||
RestrictionMap() : m_count(0) {}
|
||||
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
|
||||
|
||||
// Replace end v with w in each turn restriction containing u as via node
|
||||
template <class GraphT>
|
||||
void FixupArrivingTurnRestriction(const NodeID node_u,
|
||||
const NodeID node_v,
|
||||
const NodeID node_w,
|
||||
const GraphT &graph)
|
||||
{
|
||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
||||
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
||||
|
||||
if (!IsViaNode(node_u))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find all potential start edges. It is more efficient to get a (small) list
|
||||
// of potential start edges than iterating over all buckets
|
||||
std::vector<NodeID> predecessors;
|
||||
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
|
||||
{
|
||||
const NodeID target = graph.GetTarget(current_edge_id);
|
||||
if (node_v != target)
|
||||
{
|
||||
predecessors.push_back(target);
|
||||
}
|
||||
}
|
||||
|
||||
for (const NodeID node_x : predecessors)
|
||||
{
|
||||
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
|
||||
if (restriction_iterator == m_restriction_map.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const unsigned index = restriction_iterator->second;
|
||||
auto &bucket = m_restriction_bucket_list.at(index);
|
||||
|
||||
for (RestrictionTarget &restriction_target : bucket)
|
||||
{
|
||||
if (node_v == restriction_target.target_node)
|
||||
{
|
||||
restriction_target.target_node = node_w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsViaNode(const NodeID node) const;
|
||||
|
||||
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
||||
void
|
||||
FixupStartingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w);
|
||||
|
||||
// Check if edge (u, v) is the start of any turn restriction.
|
||||
// If so returns id of first target node.
|
||||
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -37,7 +38,6 @@ class ScriptingEnvironment;
|
||||
* ...----(a)-----(via)------(b)----...
|
||||
* So it can be represented by the tripe (a, via, b).
|
||||
*/
|
||||
|
||||
class RestrictionParser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -165,7 +165,7 @@ inline void write(storage::io::FileWriter &writer, const WayRestriction &restric
|
||||
|
||||
inline void read(storage::io::FileReader &reader, TurnRestriction &restriction)
|
||||
{
|
||||
reader.ReadInto(restriction.flags);
|
||||
reader.ReadInto(restriction.is_only);
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
WayRestriction way_restriction;
|
||||
@@ -183,7 +183,7 @@ inline void read(storage::io::FileReader &reader, TurnRestriction &restriction)
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const TurnRestriction &restriction)
|
||||
{
|
||||
writer.WriteOne(restriction.flags);
|
||||
writer.WriteOne(restriction.is_only);
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
write(writer, boost::get<WayRestriction>(restriction.node_or_way));
|
||||
@@ -213,7 +213,7 @@ inline void read(storage::io::FileReader &reader, ConditionalTurnRestriction &re
|
||||
TurnRestriction base;
|
||||
read(reader, base);
|
||||
reinterpret_cast<TurnRestriction &>(restriction) = std::move(base);
|
||||
auto num_conditions = reader.ReadElementCount64();
|
||||
const auto num_conditions = reader.ReadElementCount64();
|
||||
restriction.condition.resize(num_conditions);
|
||||
for (uint64_t i = 0; i < num_conditions; i++)
|
||||
{
|
||||
@@ -230,19 +230,18 @@ inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &
|
||||
auto num_indices = reader.ReadElementCount64();
|
||||
restrictions.reserve(num_indices);
|
||||
TurnRestriction restriction;
|
||||
while (num_indices > 0)
|
||||
while (num_indices-- > 0)
|
||||
{
|
||||
read(reader, restriction);
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
std::uint64_t num_indices = restrictions.size();
|
||||
const auto num_indices = restrictions.size();
|
||||
writer.WriteElementCount64(num_indices);
|
||||
auto const write_restriction = [&writer](const auto &restriction) {
|
||||
const auto write_restriction = [&writer](const auto &restriction) {
|
||||
write(writer, restriction);
|
||||
};
|
||||
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
|
||||
@@ -255,20 +254,19 @@ inline void read(storage::io::FileReader &reader,
|
||||
auto num_indices = reader.ReadElementCount64();
|
||||
restrictions.reserve(num_indices);
|
||||
ConditionalTurnRestriction restriction;
|
||||
while (num_indices > 0)
|
||||
while (num_indices-- > 0)
|
||||
{
|
||||
read(reader, restriction);
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer,
|
||||
const std::vector<ConditionalTurnRestriction> &restrictions)
|
||||
{
|
||||
std::uint64_t num_indices = restrictions.size();
|
||||
const auto num_indices = restrictions.size();
|
||||
writer.WriteElementCount64(num_indices);
|
||||
auto const write_restriction = [&writer](const auto &restriction) {
|
||||
const auto write_restriction = [&writer](const auto &restriction) {
|
||||
write(writer, restriction);
|
||||
};
|
||||
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
||||
#define OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// to access the turn restrictions
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
// Given the compressed representation of via-way turn restrictions, we provide a fast access into
|
||||
// the restrictions to indicate which turns may be restricted due to a way in between
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
class WayRestrictionMap
|
||||
{
|
||||
public:
|
||||
struct ViaWay
|
||||
{
|
||||
std::size_t id;
|
||||
NodeID from;
|
||||
NodeID to;
|
||||
};
|
||||
WayRestrictionMap(const std::vector<TurnRestriction> &turn_restrictions);
|
||||
|
||||
// check if an edge between two nodes is a restricted turn. The check needs to be performed
|
||||
bool IsViaWay(const NodeID from, const NodeID to) const;
|
||||
|
||||
// number of duplicated nodes
|
||||
std::size_t NumberOfDuplicatedNodes() const;
|
||||
|
||||
// returns a representative for the duplicated way, consisting of the representative ID (first
|
||||
// ID of the nodes restrictions) and the from/to vertices of the via-way
|
||||
// This is used to construct edge based nodes that act as intermediate nodes.
|
||||
std::vector<ViaWay> DuplicatedNodeRepresentatives() const;
|
||||
|
||||
// Access all duplicated NodeIDs for a set of nodes indicating a via way
|
||||
util::range<std::size_t> DuplicatedNodeIDs(const NodeID from, const NodeID to) const;
|
||||
|
||||
// check whether a turn onto a given node is restricted, when coming from a duplicated node
|
||||
bool IsRestricted(std::size_t duplicated_node, const NodeID to) const;
|
||||
|
||||
TurnRestriction const &GetRestriction(std::size_t) const;
|
||||
|
||||
// changes edge_based_node to the correct duplicated_node_id in case node_based_from,
|
||||
// node_based_via, node_based_to can be identified with a restriction group
|
||||
NodeID RemapIfRestricted(const NodeID edge_based_node,
|
||||
const NodeID node_based_from,
|
||||
const NodeID node_based_via,
|
||||
const NodeID node_based_to,
|
||||
const NodeID number_of_edge_based_nodes) const;
|
||||
|
||||
private:
|
||||
std::size_t AsDuplicatedNodeID(const std::size_t restriction_id) const;
|
||||
|
||||
// access all restrictions that have the same starting way and via way. Any duplicated node
|
||||
// represents the same in-way + via-way combination. This vector contains data about all
|
||||
// restrictions and their assigned duplicated nodes. It indicates the minimum restriciton ID
|
||||
// that is represented by the next node. The ID of a node is defined as the position of the
|
||||
// lower bound of the restrictions ID within this array
|
||||
//
|
||||
// a - b
|
||||
// |
|
||||
// y - c - x
|
||||
//
|
||||
// restriction nodes | restriction id
|
||||
// a - b - c - x : 5
|
||||
// a - b - c - y : 6
|
||||
//
|
||||
// EBN: 0 . | 2 | 3 | 4 ...
|
||||
// duplicated node groups: ... | 5 | 7 | ...
|
||||
std::vector<std::size_t> duplicated_node_groups;
|
||||
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, std::size_t> restriction_starts;
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, std::size_t> restriction_ends;
|
||||
|
||||
std::vector<TurnRestriction> restriction_data;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
||||
@@ -66,7 +66,7 @@ template <typename EdgeDataT>
|
||||
inline void read(storage::io::FileReader &reader, DynamicGraph<EdgeDataT> &graph)
|
||||
{
|
||||
storage::serialization::read(reader, graph.node_array);
|
||||
auto num_edges = reader.ReadElementCount64();
|
||||
const auto num_edges = reader.ReadElementCount64();
|
||||
graph.edge_list.resize(num_edges);
|
||||
for (auto index : irange<std::size_t>(0, num_edges))
|
||||
{
|
||||
|
||||
@@ -51,16 +51,17 @@ static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
|
||||
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
|
||||
static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias");
|
||||
|
||||
static const OSMNodeID SPECIAL_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMWayID SPECIAL_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMNodeID SPECIAL_OSM_NODEID =
|
||||
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
|
||||
static const OSMWayID SPECIAL_OSM_WAYID =
|
||||
OSMWayID{std::numeric_limits<OSMWayID::value_type>::max()};
|
||||
|
||||
static const OSMNodeID MAX_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMNodeID MIN_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::min()};
|
||||
static const OSMWayID MAX_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint64_t>::min()};
|
||||
|
||||
using OSMNodeID_weak = std::uint64_t;
|
||||
using OSMEdgeID_weak = std::uint64_t;
|
||||
static const OSMNodeID MAX_OSM_NODEID =
|
||||
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
|
||||
static const OSMNodeID MIN_OSM_NODEID =
|
||||
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::min()};
|
||||
static const OSMWayID MAX_OSM_WAYID = OSMWayID{std::numeric_limits<OSMWayID::value_type>::max()};
|
||||
static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<OSMWayID::value_type>::min()};
|
||||
|
||||
using NodeID = std::uint32_t;
|
||||
using EdgeID = std::uint32_t;
|
||||
|
||||
Reference in New Issue
Block a user