Add datafacade factory to select avoid flags

This commit is contained in:
Patrick Niklaus 2017-07-21 21:55:19 +00:00 committed by Patrick Niklaus
parent c8b142a676
commit 21686ee8a9
14 changed files with 183 additions and 71 deletions

View File

@ -68,6 +68,7 @@ struct BaseParameters
std::vector<boost::optional<double>> radiuses;
std::vector<boost::optional<Bearing>> bearings;
std::vector<boost::optional<Approach>> approaches;
std::vector<std::string> avoid;
// Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true;
@ -77,9 +78,10 @@ struct BaseParameters
std::vector<boost::optional<double>> radiuses_ = {},
std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true)
bool generate_hints_ = true,
std::vector<std::string> avoid = {})
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
approaches(approaches_), generate_hints(generate_hints_)
approaches(approaches_), avoid(std::move(avoid)), generate_hints(generate_hints_)
{
}

View File

@ -87,24 +87,8 @@ struct RouteParameters : public BaseParameters
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::string> avoid_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}, avoid{std::move(avoid_)}
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below.
{
}
// Without avoid flags
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
@ -154,7 +138,6 @@ struct RouteParameters : public BaseParameters
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight;
std::vector<std::string> avoid;
bool IsValid() const
{

View File

@ -3,6 +3,7 @@
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "engine/datafacade_factory.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
@ -36,8 +37,8 @@ template <typename AlgorithmT> class DataWatchdog final
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
facade = std::make_shared<const FacadeT>(
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.data().region));
facade_factory = DataFacadeFactory<const FacadeT>(
std::make_shared<datafacade::SharedMemoryAllocator>(barrier.data().region));
timestamp = barrier.data().timestamp;
}
@ -51,7 +52,8 @@ template <typename AlgorithmT> class DataWatchdog final
watcher.join();
}
std::shared_ptr<const FacadeT> Get() const { return facade; }
std::shared_ptr<const FacadeT> Get(const api::BaseParameters &params) const { return facade_factory.Get(params); }
std::shared_ptr<const FacadeT> Get(const api::TileParameters &params) const { return facade_factory.Get(params); }
private:
void Run()
@ -68,8 +70,8 @@ template <typename AlgorithmT> class DataWatchdog final
if (timestamp != barrier.data().timestamp)
{
auto region = barrier.data().region;
facade = std::make_shared<const FacadeT>(
std::make_unique<datafacade::SharedMemoryAllocator>(region));
facade_factory = DataFacadeFactory<const FacadeT>(
std::make_shared<datafacade::SharedMemoryAllocator>(region));
timestamp = barrier.data().timestamp;
util::Log() << "updated facade to region " << region << " with timestamp "
<< timestamp;
@ -83,7 +85,7 @@ template <typename AlgorithmT> class DataWatchdog final
std::thread watcher;
bool active;
unsigned timestamp;
std::shared_ptr<const FacadeT> facade;
DataFacadeFactory<const FacadeT> facade_factory;
};
}
}

View File

@ -212,6 +212,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
extractor::ClassData avoid_mask;
std::string m_timestamp;
extractor::ProfileProperties *m_profile_properties;
extractor::Datasources *m_datasources;
@ -246,10 +247,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout, char *memory_block)
void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout, char *memory_block, const std::size_t avoid_index)
{
m_profile_properties = data_layout.GetBlockPtr<extractor::ProfileProperties>(
memory_block, storage::DataLayout::PROPERTIES);
avoid_mask = m_profile_properties->avoidable_classes[avoid_index];
}
void InitializeTimestampPointer(storage::DataLayout &data_layout, char *memory_block)
@ -539,7 +542,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_entry_class_table = std::move(entry_class_table);
}
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block, const std::size_t avoid_index)
{
InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block);
@ -550,7 +553,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
InitializeTimestampPointer(data_layout, memory_block);
InitializeNamePointers(data_layout, memory_block);
InitializeTurnLaneDescriptionsPointers(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block, avoid_index);
InitializeRTreePointers(data_layout, memory_block);
InitializeIntersectionClassPointers(data_layout, memory_block);
}
@ -558,10 +561,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
public:
// allows switching between process_memory/shared_memory datafacade, based on the type of
// allocator
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_)
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::size_t avoid_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), avoid_index);
}
// node and edge information access
@ -802,6 +805,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return edge_based_node_data.GetClassData(id);
}
bool AvoidNode(const NodeID id) const override final
{
return (edge_based_node_data.GetClassData(id) & avoid_mask) > 0;
}
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
{
auto indexes = extractor::getClassIndexes(class_data);
@ -916,6 +924,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
return m_profile_properties->left_hand_driving;
}
};
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
@ -926,8 +935,9 @@ class ContiguousInternalMemoryDataFacade<CH>
public ContiguousInternalMemoryAlgorithmDataFacade<CH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacadeBase(allocator),
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<CH>(allocator)
{
@ -940,8 +950,9 @@ class ContiguousInternalMemoryDataFacade<CoreCH> final
public ContiguousInternalMemoryAlgorithmDataFacade<CoreCH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacade<CH>(allocator),
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacade<CH>(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<CoreCH>(allocator)
{
@ -959,14 +970,23 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
QueryGraph query_graph;
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeInternalPointers(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t avoid_index)
{
InitializeMLDDataPointers(data_layout, memory_block);
InitializeMLDDataPointers(data_layout, memory_block, avoid_index);
InitializeGraphPointer(data_layout, memory_block);
}
void InitializeMLDDataPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeMLDDataPointers(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t avoid_index)
{
const auto weights_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_WEIGHTS_0 + avoid_index);
const auto durations_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_DURATIONS_0 + avoid_index);
if (data_layout.GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_LEVEL_DATA) > 0);
@ -992,15 +1012,15 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
partition::MultiLevelPartitionView{level_data, partition, cell_to_children};
}
if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_WEIGHTS_0) > 0)
if (data_layout.GetBlockSize(weights_block_id) > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELLS) > 0);
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS) > 0);
auto mld_cell_weights_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::MLD_CELL_WEIGHTS_0);
auto mld_cell_durations_ptr = data_layout.GetBlockPtr<EdgeDuration>(
memory_block, storage::DataLayout::MLD_CELL_DURATIONS_0);
auto mld_cell_weights_ptr =
data_layout.GetBlockPtr<EdgeWeight>(memory_block, weights_block_id);
auto mld_cell_durations_ptr =
data_layout.GetBlockPtr<EdgeDuration>(memory_block, durations_block_id);
auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
@ -1072,10 +1092,10 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_)
std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::size_t avoid_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), avoid_index);
}
const partition::MultiLevelPartitionView &GetMultiLevelPartition() const override
@ -1130,9 +1150,10 @@ class ContiguousInternalMemoryDataFacade<MLD> final
{
private:
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacadeBase(allocator),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator)
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, avoid_index)
{
}

View File

@ -94,6 +94,8 @@ class BaseDataFacade
virtual extractor::ClassData GetClassData(const NodeID id) const = 0;
virtual bool AvoidNode(const NodeID id) const = 0;
virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,

View File

@ -0,0 +1,88 @@
#ifndef OSRM_ENGINE_DATAFACADE_FACTORY_HPP
#define OSRM_ENGINE_DATAFACADE_FACTORY_HPP
#include "extractor/class_data.hpp"
#include "extractor/profile_properties.hpp"
#include "engine/api/base_parameters.hpp"
#include "engine/api/tile_parameters.hpp"
#include "util/integer_range.hpp"
#include "storage/shared_datatype.hpp"
#include <array>
#include <memory>
#include <unordered_map>
namespace osrm
{
namespace engine
{
// This class selects the right facade for
template <typename FacadeT> class DataFacadeFactory
{
public:
DataFacadeFactory() = default;
template <typename AllocatorT> DataFacadeFactory(std::shared_ptr<AllocatorT> allocator)
{
for (const auto index : util::irange<std::size_t>(0, facades.size()))
{
facades[index] = std::make_shared<FacadeT>(allocator, index);
}
properties = allocator->GetLayout().template GetBlockPtr<extractor::ProfileProperties>(
allocator->GetMemory(), storage::DataLayout::PROPERTIES);
for (const auto index : util::irange<std::size_t>(0, properties->class_names.size()))
{
const std::string name = properties->GetClassName(index);
if (!name.empty())
{
name_to_class[name] = extractor::getClassData(index);
}
}
}
std::shared_ptr<FacadeT> Get(const api::TileParameters &) const
{
return facades[0];
}
std::shared_ptr<FacadeT> Get(const api::BaseParameters &params) const
{
if (params.avoid.empty())
return facades[0];
extractor::ClassData mask = 0;
for (const auto &name : params.avoid)
{
auto class_mask_iter = name_to_class.find(name);
if (class_mask_iter != name_to_class.end())
{
mask |= class_mask_iter->second;
}
}
auto avoid_iter = std::find(
properties->avoidable_classes.begin(), properties->avoidable_classes.end(), mask);
if (avoid_iter != properties->avoidable_classes.end())
{
auto avoid_index = std::distance(properties->avoidable_classes.begin(), avoid_iter);
return facades[avoid_index];
}
// FIXME We need proper error handling here
return {};
}
private:
std::array<std::shared_ptr<FacadeT>, extractor::MAX_AVOIDABLE_CLASSES> facades;
std::unordered_map<std::string, extractor::ClassData> name_to_class;
const extractor::ProfileProperties *properties = nullptr;
};
}
}
#endif

View File

@ -20,7 +20,8 @@ template <typename AlgorithmT, template <typename A> class FacadeT> class DataFa
virtual ~DataFacadeProvider() = default;
virtual std::shared_ptr<const Facade> Get() const = 0;
virtual std::shared_ptr<const Facade> Get(const api::BaseParameters&) const = 0;
virtual std::shared_ptr<const Facade> Get(const api::TileParameters&) const = 0;
};
template <typename AlgorithmT, template <typename A> class FacadeT>
@ -30,15 +31,15 @@ class ImmutableProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
ImmutableProvider(const storage::StorageConfig &config)
: immutable_data_facade(std::make_shared<Facade>(
std::make_shared<datafacade::ProcessMemoryAllocator>(config)))
: facade_factory(std::make_shared<datafacade::ProcessMemoryAllocator>(config))
{
}
std::shared_ptr<const Facade> Get() const override final { return immutable_data_facade; }
std::shared_ptr<const Facade> Get(const api::TileParameters &params) const override final { return facade_factory.Get(params); }
std::shared_ptr<const Facade> Get(const api::BaseParameters &params) const override final { return facade_factory.Get(params); }
private:
std::shared_ptr<const Facade> immutable_data_facade;
DataFacadeFactory<const Facade> facade_factory;
};
template <typename AlgorithmT, template <typename A> class FacadeT>
@ -49,7 +50,8 @@ class WatchingProvider : public DataFacadeProvider<AlgorithmT, FacadeT>
public:
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
std::shared_ptr<const Facade> Get() const override final { return watchdog.Get(); }
std::shared_ptr<const Facade> Get(const api::TileParameters &params) const override final { return watchdog.Get(params); }
std::shared_ptr<const Facade> Get(const api::BaseParameters &params) const override final { return watchdog.Get(params); }
};
}

View File

@ -85,40 +85,40 @@ template <typename Algorithm> class Engine final : public EngineInterface
Status Route(const api::RouteParameters &params,
util::json::Object &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return route_plugin.HandleRequest(algorithms, params, result);
}
Status Table(const api::TableParameters &params,
util::json::Object &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return table_plugin.HandleRequest(algorithms, params, result);
}
Status Nearest(const api::NearestParameters &params,
util::json::Object &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return nearest_plugin.HandleRequest(algorithms, params, result);
}
Status Trip(const api::TripParameters &params, util::json::Object &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return trip_plugin.HandleRequest(algorithms, params, result);
}
Status Match(const api::MatchParameters &params,
util::json::Object &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return match_plugin.HandleRequest(algorithms, params, result);
}
Status Tile(const api::TileParameters &params, std::string &result) const override final
{
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get(params)};
return tile_plugin.HandleRequest(algorithms, params, result);
}

View File

@ -17,6 +17,12 @@ static const std::uint8_t MAX_AVOIDABLE_CLASSES = 8;
inline bool isSubset(const ClassData lhs, const ClassData rhs) { return (lhs & rhs) == lhs; }
inline auto getClassIndexes(const ClassData data) { return util::makeBitRange<ClassData>(data); }
inline auto getClassData(const std::size_t index)
{
BOOST_ASSERT(index <= MAX_CLASS_INDEX);
return uint8_t{1} << index;
}
}
}

View File

@ -79,7 +79,7 @@ struct ProfileProperties
}
// Check if this classes are avoidable
boost::optional<std::size_t> ClassesAreAvoidable(ClassData classes)
boost::optional<std::size_t> ClassesAreAvoidable(ClassData classes) const
{
auto iter = std::find(avoidable_classes.begin(), avoidable_classes.end(), classes);
if (iter != avoidable_classes.end())

View File

@ -162,10 +162,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
(-approach_type %
';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1];
avoid_rule = qi::lit("avoid=") >
(qi::as_string[+qi::char_("a-zA-Z")] %
',')[ph::bind(&engine::api::BaseParameters::avoid, qi::_r1) = qi::_1];
base_rule = radiuses_rule(qi::_r1) //
| hints_rule(qi::_r1) //
| bearings_rule(qi::_r1) //
| generate_hints_rule(qi::_r1) | approach_rule(qi::_r1);
| generate_hints_rule(qi::_r1) //
| approach_rule(qi::_r1) //
| avoid_rule(qi::_r1);
}
protected:
@ -179,6 +185,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::rule<Iterator, Signature> generate_hints_rule;
qi::rule<Iterator, Signature> approach_rule;
qi::rule<Iterator, Signature> avoid_rule;
qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule;
qi::rule<Iterator, osrm::util::Coordinate()> location_rule;

View File

@ -70,8 +70,6 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
avoid_rule = qi::lit("avoid=") > (qi::as_string[+qi::char_("a-zA-Z")] % ',');
base_rule =
BaseGrammar::base_rule(qi::_r1) |
(qi::lit("steps=") >
@ -84,8 +82,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
(qi::lit("annotations=") >
(qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] |
qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] |
(annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ','))) |
avoid_rule[ph::bind(&engine::api::RouteParameters::avoid, qi::_r1) = qi::_1];
(annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',')));
query_rule = BaseGrammar::query_rule(qi::_r1);
}
@ -97,7 +94,6 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
private:
qi::rule<Iterator, Signature> root_rule;
qi::rule<Iterator, Signature> route_rule;
qi::rule<Iterator, std::vector<std::string>()> avoid_rule;
qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type;
qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type;

View File

@ -89,7 +89,10 @@ void SetAvoidableClasses(const ExtractorCallbacks::ClassesMap &classes_map,
throw util::exception("Only " + std::to_string(MAX_AVOIDABLE_CLASSES) + " avoidable combinations allowed.");
}
std::size_t combination_index = 0;
// The avoid index 0 is reserve for not avoiding anything
profile_properties.SetAvoidableClasses(0, 0);
std::size_t combination_index = 1;
for (const auto &combination : avoidable_classes)
{
ClassData mask = 0;

View File

@ -189,7 +189,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
throw util::exception("Maximum number of classes if " +
std::to_string(MAX_CLASS_INDEX + 1));
}
ClassData class_mask = 1u << classes_map.size();
ClassData class_mask = getClassData(classes_map.size());
classes_map[class_name] = class_mask;
return class_mask;
}