2012-08-29 12:33:18 -04:00
|
|
|
/*
|
|
|
|
|
2013-10-14 07:42:28 -04:00
|
|
|
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
Redistributions of source code must retain the above copyright notice, this list
|
|
|
|
of conditions and the following disclaimer.
|
|
|
|
Redistributions in binary form must reproduce the above copyright notice, this
|
|
|
|
list of conditions and the following disclaimer in the documentation and/or
|
|
|
|
other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
|
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
2012-08-29 12:33:18 -04:00
|
|
|
|
2014-04-16 10:59:40 -04:00
|
|
|
#include "ExtractorCallbacks.h"
|
2013-12-16 05:29:38 -05:00
|
|
|
#include "ExtractionContainers.h"
|
2014-08-26 11:50:34 -04:00
|
|
|
#include "ExtractionNode.h"
|
2014-01-09 10:13:35 -05:00
|
|
|
#include "ExtractionWay.h"
|
2012-08-29 12:33:18 -04:00
|
|
|
|
2014-01-09 10:13:35 -05:00
|
|
|
#include "../DataStructures/Restriction.h"
|
2014-03-06 12:07:55 -05:00
|
|
|
#include "../DataStructures/ImportNode.h"
|
2014-08-26 11:50:34 -04:00
|
|
|
#include "../Util/container.hpp"
|
2014-10-10 13:31:43 -04:00
|
|
|
#include "../Util/simple_logger.hpp"
|
2014-01-09 10:13:35 -05:00
|
|
|
|
2013-12-20 07:12:56 -05:00
|
|
|
#include <osrm/Coordinate.h>
|
2013-12-16 05:29:38 -05:00
|
|
|
|
2014-05-09 13:35:09 -04:00
|
|
|
#include <limits>
|
2013-12-16 05:29:38 -05:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2014-05-09 10:17:31 -04:00
|
|
|
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers,
|
2014-05-09 12:40:07 -04:00
|
|
|
std::unordered_map<std::string, NodeID> &string_map)
|
2014-05-09 10:17:31 -04:00
|
|
|
: string_map(string_map), external_memory(extraction_containers)
|
|
|
|
{
|
|
|
|
}
|
2012-08-29 12:33:18 -04:00
|
|
|
|
|
|
|
/** warning: caller needs to take care of synchronization! */
|
2014-08-27 10:24:40 -04:00
|
|
|
void ExtractorCallbacks::ProcessNode(const osmium::Node &osm_input_node,
|
|
|
|
const ExtractionNode &result_node)
|
2014-05-09 10:17:31 -04:00
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
// TODO: use in-place c'tion
|
2014-08-26 11:50:34 -04:00
|
|
|
ExternalMemoryNode node;
|
|
|
|
node.bollard = result_node.barrier;
|
|
|
|
node.trafficLight = result_node.traffic_lights;
|
|
|
|
node.lat = osm_input_node.location().lat() * COORDINATE_PRECISION;
|
|
|
|
node.lon = osm_input_node.location().lon() * COORDINATE_PRECISION;
|
|
|
|
node.node_id = osm_input_node.id();
|
|
|
|
external_memory.all_nodes_list.push_back(node);
|
2012-08-29 12:33:18 -04:00
|
|
|
}
|
|
|
|
|
2014-08-27 10:24:40 -04:00
|
|
|
void ExtractorCallbacks::ProcessRestriction(
|
|
|
|
const boost::optional<InputRestrictionContainer> &restriction)
|
2014-05-09 10:17:31 -04:00
|
|
|
{
|
2014-08-26 11:50:34 -04:00
|
|
|
if (!restriction.is_initialized())
|
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
return;
|
2014-08-26 11:50:34 -04:00
|
|
|
}
|
|
|
|
external_memory.restrictions_list.push_back(restriction.get());
|
2012-08-29 12:33:18 -04:00
|
|
|
}
|
|
|
|
/** warning: caller needs to take care of synchronization! */
|
2014-08-27 10:24:40 -04:00
|
|
|
void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, ExtractionWay &parsed_way)
|
2014-05-09 10:17:31 -04:00
|
|
|
{
|
2014-09-29 05:37:36 -04:00
|
|
|
if (((0 >= parsed_way.forward_speed) ||
|
2014-08-27 10:24:40 -04:00
|
|
|
(TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) &&
|
2014-08-20 11:05:39 -04:00
|
|
|
((0 >= parsed_way.backward_speed) ||
|
2014-08-27 10:24:40 -04:00
|
|
|
(TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) &&
|
2014-08-20 11:05:39 -04:00
|
|
|
(0 >= parsed_way.duration))
|
2014-05-09 10:17:31 -04:00
|
|
|
{ // Only true if the way is specified by the speed profile
|
2014-05-18 16:44:19 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-08-29 12:33:18 -04:00
|
|
|
|
2014-08-27 10:24:40 -04:00
|
|
|
if (input_way.nodes().size() <= 1)
|
2014-06-02 13:23:50 -04:00
|
|
|
{ // safe-guard against broken data
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-27 10:24:40 -04:00
|
|
|
if (std::numeric_limits<decltype(input_way.id())>::max() == input_way.id())
|
2014-05-18 16:44:19 -04:00
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << input_way.id()
|
|
|
|
<< " of size " << input_way.nodes().size();
|
2014-05-18 16:44:19 -04:00
|
|
|
return;
|
|
|
|
}
|
2013-01-27 17:06:23 -05:00
|
|
|
|
2014-05-18 16:44:19 -04:00
|
|
|
if (0 < parsed_way.duration)
|
|
|
|
{
|
|
|
|
// TODO: iterate all way segments and set duration corresponding to the length of each
|
|
|
|
// segment
|
2014-08-27 10:24:40 -04:00
|
|
|
parsed_way.forward_speed = parsed_way.duration / (input_way.nodes().size() - 1);
|
|
|
|
parsed_way.backward_speed = parsed_way.duration / (input_way.nodes().size() - 1);
|
2014-05-18 16:44:19 -04:00
|
|
|
}
|
2013-02-27 11:36:44 -05:00
|
|
|
|
2014-08-18 09:38:07 -04:00
|
|
|
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.forward_speed))
|
2014-05-18 16:44:19 -04:00
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << input_way.id();
|
2014-05-18 16:44:19 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-08-29 12:33:18 -04:00
|
|
|
|
2014-05-18 16:44:19 -04:00
|
|
|
// Get the unique identifier for the street name
|
|
|
|
const auto &string_map_iterator = string_map.find(parsed_way.name);
|
2014-08-26 11:50:34 -04:00
|
|
|
unsigned name_id = external_memory.name_list.size();
|
2014-05-18 16:44:19 -04:00
|
|
|
if (string_map.end() == string_map_iterator)
|
|
|
|
{
|
|
|
|
external_memory.name_list.push_back(parsed_way.name);
|
2014-08-26 11:50:34 -04:00
|
|
|
string_map.insert(std::make_pair(parsed_way.name, name_id));
|
2014-05-18 16:44:19 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-26 11:50:34 -04:00
|
|
|
name_id = string_map_iterator->second;
|
2014-05-18 16:44:19 -04:00
|
|
|
}
|
|
|
|
|
2014-08-27 10:24:40 -04:00
|
|
|
const bool split_edge = (parsed_way.forward_speed > 0) &&
|
|
|
|
(TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) &&
|
|
|
|
(parsed_way.backward_speed > 0) &&
|
|
|
|
(TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) &&
|
|
|
|
((parsed_way.forward_speed != parsed_way.backward_speed) ||
|
|
|
|
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode));
|
2014-08-12 08:18:02 -04:00
|
|
|
|
2014-08-26 11:50:34 -04:00
|
|
|
auto pair_wise_segment_split = [&](const osmium::NodeRef &first_node,
|
2014-08-27 10:24:40 -04:00
|
|
|
const osmium::NodeRef &last_node)
|
|
|
|
{
|
2014-08-26 11:50:34 -04:00
|
|
|
// SimpleLogger().Write() << "adding edge (" << first_node.ref() << "," <<
|
2014-08-27 10:24:40 -04:00
|
|
|
// last_node.ref() << "), fwd speed: " << parsed_way.forward_speed;
|
|
|
|
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
|
|
|
first_node.ref(),
|
|
|
|
last_node.ref(),
|
|
|
|
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)
|
|
|
|
? ExtractionWay::oneway
|
|
|
|
: ExtractionWay::bidirectional),
|
2014-08-18 09:38:07 -04:00
|
|
|
parsed_way.forward_speed,
|
2014-08-26 11:50:34 -04:00
|
|
|
name_id,
|
2014-05-18 16:44:19 -04:00
|
|
|
parsed_way.roundabout,
|
2014-08-26 11:50:34 -04:00
|
|
|
parsed_way.ignore_in_grid,
|
2014-05-18 16:44:19 -04:00
|
|
|
(0 < parsed_way.duration),
|
2014-08-26 11:50:34 -04:00
|
|
|
parsed_way.is_access_restricted,
|
2014-08-18 09:38:07 -04:00
|
|
|
parsed_way.forward_travel_mode,
|
2014-06-03 04:44:09 -04:00
|
|
|
split_edge));
|
2014-08-26 11:50:34 -04:00
|
|
|
external_memory.used_node_id_list.push_back(first_node.ref());
|
|
|
|
};
|
|
|
|
|
|
|
|
const bool is_opposite_way = TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode;
|
|
|
|
if (is_opposite_way)
|
|
|
|
{
|
|
|
|
parsed_way.forward_travel_mode = parsed_way.backward_travel_mode;
|
|
|
|
parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
2014-08-27 10:24:40 -04:00
|
|
|
osrm::for_each_pair(
|
|
|
|
input_way.nodes().crbegin(), input_way.nodes().crend(), pair_wise_segment_split);
|
|
|
|
external_memory.used_node_id_list.push_back(input_way.nodes().front().ref());
|
2014-08-26 11:50:34 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
osrm::for_each_pair(
|
|
|
|
input_way.nodes().cbegin(), input_way.nodes().cend(), pair_wise_segment_split);
|
|
|
|
external_memory.used_node_id_list.push_back(input_way.nodes().back().ref());
|
2014-05-18 16:44:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// The following information is needed to identify start and end segments of restrictions
|
2014-08-27 10:24:40 -04:00
|
|
|
// The following information is needed to identify start and end segments of restrictions
|
2014-05-18 16:44:19 -04:00
|
|
|
external_memory.way_start_end_id_list.push_back(
|
2014-08-27 10:24:40 -04:00
|
|
|
{(EdgeID)input_way.id(),
|
|
|
|
(NodeID)input_way.nodes()[0].ref(),
|
|
|
|
(NodeID)input_way.nodes()[1].ref(),
|
|
|
|
(NodeID)input_way.nodes()[input_way.nodes().size() - 2].ref(),
|
|
|
|
(NodeID)input_way.nodes().back().ref()});
|
2014-05-18 16:44:19 -04:00
|
|
|
|
2014-06-03 04:44:09 -04:00
|
|
|
if (split_edge)
|
2014-05-18 16:44:19 -04:00
|
|
|
{ // Only true if the way should be split
|
2014-08-13 05:28:41 -04:00
|
|
|
BOOST_ASSERT(parsed_way.backward_travel_mode>0);
|
2014-08-26 11:50:34 -04:00
|
|
|
auto pair_wise_segment_split_2 = [&](const osmium::NodeRef &first_node,
|
|
|
|
const osmium::NodeRef &last_node)
|
2014-05-09 10:17:31 -04:00
|
|
|
{
|
2014-08-26 11:50:34 -04:00
|
|
|
// SimpleLogger().Write() << "adding edge (" << last_node.ref() << "," <<
|
2014-08-27 10:24:40 -04:00
|
|
|
// first_node.ref() << "), bwd speed: " << parsed_way.backward_speed;
|
2014-05-18 16:44:19 -04:00
|
|
|
external_memory.all_edges_list.push_back(
|
2014-08-26 11:50:34 -04:00
|
|
|
InternalExtractorEdge(last_node.ref(),
|
|
|
|
first_node.ref(),
|
2014-05-18 16:44:19 -04:00
|
|
|
ExtractionWay::oneway,
|
|
|
|
parsed_way.backward_speed,
|
2014-08-26 11:50:34 -04:00
|
|
|
name_id,
|
2014-05-18 16:44:19 -04:00
|
|
|
parsed_way.roundabout,
|
2014-08-26 11:50:34 -04:00
|
|
|
parsed_way.ignore_in_grid,
|
2014-05-18 16:44:19 -04:00
|
|
|
(0 < parsed_way.duration),
|
2014-08-26 11:50:34 -04:00
|
|
|
parsed_way.is_access_restricted,
|
2014-08-09 09:13:04 -04:00
|
|
|
parsed_way.backward_travel_mode,
|
2014-06-03 04:44:09 -04:00
|
|
|
split_edge));
|
2014-08-26 11:50:34 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
if (is_opposite_way)
|
|
|
|
{
|
|
|
|
// SimpleLogger().Write() << "opposite2";
|
2014-08-27 10:24:40 -04:00
|
|
|
osrm::for_each_pair(input_way.nodes().crbegin(),
|
|
|
|
input_way.nodes().crend(),
|
|
|
|
pair_wise_segment_split_2);
|
|
|
|
external_memory.used_node_id_list.push_back(input_way.nodes().front().ref());
|
2014-08-26 11:50:34 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-27 10:24:40 -04:00
|
|
|
osrm::for_each_pair(input_way.nodes().cbegin(),
|
|
|
|
input_way.nodes().cend(),
|
|
|
|
pair_wise_segment_split_2);
|
|
|
|
external_memory.used_node_id_list.push_back(input_way.nodes().back().ref());
|
2012-08-29 12:33:18 -04:00
|
|
|
}
|
2014-08-26 11:50:34 -04:00
|
|
|
|
2014-05-09 10:17:31 -04:00
|
|
|
external_memory.way_start_end_id_list.push_back(
|
2014-08-27 10:24:40 -04:00
|
|
|
{(EdgeID)input_way.id(),
|
|
|
|
(NodeID)input_way.nodes()[1].ref(),
|
|
|
|
(NodeID)input_way.nodes()[0].ref(),
|
|
|
|
(NodeID)input_way.nodes().back().ref(),
|
|
|
|
(NodeID)input_way.nodes()[input_way.nodes().size() - 2].ref()});
|
2012-08-29 12:33:18 -04:00
|
|
|
}
|
|
|
|
}
|