2012-06-15 12:47:27 -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-06-15 12:47:27 -04:00
|
|
|
|
|
|
|
#ifndef SHORTESTPATHROUTING_H_
|
|
|
|
#define SHORTESTPATHROUTING_H_
|
|
|
|
|
2013-09-21 16:18:27 -04:00
|
|
|
#include <boost/assert.hpp>
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-09-21 16:18:27 -04:00
|
|
|
#include "BasicRoutingInterface.h"
|
2013-09-19 12:53:34 -04:00
|
|
|
#include "../DataStructures/SearchEngineData.h"
|
2013-12-18 06:00:35 -05:00
|
|
|
#include "../typedefs.h"
|
2013-09-19 12:53:34 -04:00
|
|
|
|
2013-09-20 05:09:07 -04:00
|
|
|
template<class DataFacadeT>
|
|
|
|
class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>{
|
|
|
|
typedef BasicRoutingInterface<DataFacadeT> super;
|
|
|
|
typedef SearchEngineData::QueryHeap QueryHeap;
|
2013-09-19 12:53:34 -04:00
|
|
|
SearchEngineData & engine_working_data;
|
2013-09-21 16:10:41 -04:00
|
|
|
|
2012-06-15 12:47:27 -04:00
|
|
|
public:
|
2013-09-21 16:10:41 -04:00
|
|
|
ShortestPathRouting(
|
|
|
|
DataFacadeT * facade,
|
|
|
|
SearchEngineData & engine_working_data
|
|
|
|
) :
|
|
|
|
super(facade),
|
|
|
|
engine_working_data(engine_working_data)
|
2014-03-25 13:06:05 -04:00
|
|
|
{ }
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2014-03-25 13:06:05 -04:00
|
|
|
~ShortestPathRouting() { }
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-09-21 16:10:41 -04:00
|
|
|
void operator()(
|
2013-12-12 18:35:23 -05:00
|
|
|
const std::vector<PhantomNodes> & phantom_nodes_vector,
|
2013-09-21 16:10:41 -04:00
|
|
|
RawRouteData & raw_route_data
|
2014-03-25 13:06:05 -04:00
|
|
|
) const
|
|
|
|
{
|
2014-05-07 10:17:47 -04:00
|
|
|
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
|
|
|
|
{
|
2014-03-25 12:48:25 -04:00
|
|
|
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
|
2014-03-05 13:17:19 -05:00
|
|
|
// raw_route_data.lengthOfShortestPath = INT_MAX;
|
|
|
|
// raw_route_data.lengthOfAlternativePath = INT_MAX;
|
2012-06-19 11:26:34 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
int distance1 = 0;
|
|
|
|
int distance2 = 0;
|
2013-09-21 16:10:41 -04:00
|
|
|
bool search_from_1st_node = true;
|
|
|
|
bool search_from_2nd_node = true;
|
2013-02-03 10:47:32 -05:00
|
|
|
NodeID middle1 = UINT_MAX;
|
|
|
|
NodeID middle2 = UINT_MAX;
|
2013-12-12 18:35:23 -05:00
|
|
|
std::vector<std::vector<NodeID> > packed_legs1(phantom_nodes_vector.size());
|
|
|
|
std::vector<std::vector<NodeID> > packed_legs2(phantom_nodes_vector.size());
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-09-20 12:30:47 -04:00
|
|
|
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
|
|
|
|
super::facade->GetNumberOfNodes()
|
|
|
|
);
|
|
|
|
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
|
|
|
|
super::facade->GetNumberOfNodes()
|
|
|
|
);
|
|
|
|
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
|
|
|
|
super::facade->GetNumberOfNodes()
|
|
|
|
);
|
|
|
|
|
|
|
|
QueryHeap & forward_heap1 = *(engine_working_data.forwardHeap);
|
|
|
|
QueryHeap & reverse_heap1 = *(engine_working_data.backwardHeap);
|
|
|
|
QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
|
|
|
|
QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-12-12 18:35:23 -05:00
|
|
|
int current_leg = 0;
|
2012-06-15 12:47:27 -04:00
|
|
|
//Get distance to next pair of target nodes.
|
2014-05-07 10:17:47 -04:00
|
|
|
for(const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
|
|
|
|
{
|
2013-02-06 09:23:57 -05:00
|
|
|
forward_heap1.Clear(); forward_heap2.Clear();
|
|
|
|
reverse_heap1.Clear(); reverse_heap2.Clear();
|
2013-09-21 16:10:41 -04:00
|
|
|
int local_upper_bound1 = INT_MAX;
|
|
|
|
int local_upper_bound2 = INT_MAX;
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-02-06 09:23:57 -05:00
|
|
|
middle1 = UINT_MAX;
|
|
|
|
middle2 = UINT_MAX;
|
|
|
|
|
2012-06-15 12:47:27 -04:00
|
|
|
//insert new starting nodes into forward heap, adjusted by previous distances.
|
2014-03-05 13:17:19 -05:00
|
|
|
if(
|
|
|
|
search_from_1st_node &&
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID
|
2014-03-05 13:17:19 -05:00
|
|
|
) {
|
2014-04-10 17:47:39 -04:00
|
|
|
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
|
2013-09-21 16:21:33 -04:00
|
|
|
forward_heap1.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.forward_node_id,
|
|
|
|
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
|
|
|
|
phantom_node_pair.source_phantom.forward_node_id
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
|
|
|
forward_heap2.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.forward_node_id,
|
|
|
|
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
|
|
|
|
phantom_node_pair.source_phantom.forward_node_id
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
2013-12-12 18:35:23 -05:00
|
|
|
}
|
2014-03-05 13:17:19 -05:00
|
|
|
if(
|
|
|
|
search_from_2nd_node &&
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID
|
2014-03-05 13:17:19 -05:00
|
|
|
) {
|
2014-04-10 17:47:39 -04:00
|
|
|
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
|
2013-09-21 16:21:33 -04:00
|
|
|
forward_heap1.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.reverse_node_id,
|
|
|
|
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
|
|
|
|
phantom_node_pair.source_phantom.reverse_node_id
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
|
|
|
forward_heap2.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.source_phantom.reverse_node_id,
|
|
|
|
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
|
|
|
|
phantom_node_pair.source_phantom.reverse_node_id
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//insert new backward nodes into backward heap, unadjusted.
|
2014-03-25 13:06:05 -04:00
|
|
|
if( phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID ) {
|
2014-04-10 17:47:39 -04:00
|
|
|
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.forward_node_id << ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
|
2014-03-05 13:17:19 -05:00
|
|
|
reverse_heap1.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.target_phantom.forward_node_id,
|
|
|
|
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
|
|
|
|
phantom_node_pair.target_phantom.forward_node_id
|
2014-03-05 13:17:19 -05:00
|
|
|
);
|
|
|
|
}
|
2014-02-11 05:42:24 -05:00
|
|
|
|
2014-03-25 13:06:05 -04:00
|
|
|
if( phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID ) {
|
2014-04-10 17:47:39 -04:00
|
|
|
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.reverse_node_id << ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
|
2013-09-21 16:10:41 -04:00
|
|
|
reverse_heap2.Insert(
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.target_phantom.reverse_node_id,
|
|
|
|
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
|
|
|
|
phantom_node_pair.target_phantom.reverse_node_id
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
2013-12-12 18:35:23 -05:00
|
|
|
}
|
|
|
|
|
2014-04-09 16:09:35 -04:00
|
|
|
// const int forward_offset = phantom_node_pair.ComputeForwardQueueOffset();
|
2014-04-08 19:47:52 -04:00
|
|
|
// const int forward_offset = super::ComputeForwardOffset(
|
|
|
|
// phantom_node_pair.source_phantom
|
|
|
|
// );
|
2014-04-09 16:09:35 -04:00
|
|
|
// const int reverse_offset = -phantom_node_pair.ComputeReverseQueueOffset();
|
2014-04-08 19:47:52 -04:00
|
|
|
// const int reverse_offset = super::ComputeReverseOffset(
|
|
|
|
// phantom_node_pair.target_phantom
|
|
|
|
// );
|
2012-06-15 12:47:27 -04:00
|
|
|
|
|
|
|
//run two-Target Dijkstra routing step.
|
2013-02-06 09:23:57 -05:00
|
|
|
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){
|
2014-03-06 12:09:54 -05:00
|
|
|
if( 0 < forward_heap1.Size() ){
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RoutingStep(
|
|
|
|
forward_heap1,
|
|
|
|
reverse_heap1,
|
|
|
|
&middle1,
|
|
|
|
&local_upper_bound1,
|
|
|
|
true
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2014-03-06 12:09:54 -05:00
|
|
|
if( 0 < reverse_heap1.Size() ){
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RoutingStep(
|
|
|
|
reverse_heap1,
|
|
|
|
forward_heap1,
|
|
|
|
&middle1,
|
|
|
|
&local_upper_bound1,
|
|
|
|
false
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
}
|
2013-12-12 18:35:23 -05:00
|
|
|
|
2013-09-21 16:10:41 -04:00
|
|
|
if( !reverse_heap2.Empty() ) {
|
2013-02-06 09:23:57 -05:00
|
|
|
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){
|
2014-03-06 12:09:54 -05:00
|
|
|
if( 0 < forward_heap2.Size() ){
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RoutingStep(
|
|
|
|
forward_heap2,
|
|
|
|
reverse_heap2,
|
|
|
|
&middle2,
|
|
|
|
&local_upper_bound2,
|
|
|
|
true
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2014-03-06 12:09:54 -05:00
|
|
|
if( 0 < reverse_heap2.Size() ){
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RoutingStep(
|
|
|
|
reverse_heap2,
|
|
|
|
forward_heap2,
|
|
|
|
&middle2,
|
|
|
|
&local_upper_bound2,
|
|
|
|
false
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//No path found for both target nodes?
|
2013-09-21 16:10:41 -04:00
|
|
|
if(
|
2014-03-05 13:17:19 -05:00
|
|
|
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
|
|
|
|
(INVALID_EDGE_WEIGHT == local_upper_bound2)
|
2013-09-21 16:10:41 -04:00
|
|
|
) {
|
2014-03-05 13:17:19 -05:00
|
|
|
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
|
|
|
|
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
|
2012-06-19 11:26:34 -04:00
|
|
|
return;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2014-03-05 13:17:19 -05:00
|
|
|
if( SPECIAL_NODEID == middle1 ) {
|
2013-09-21 16:10:41 -04:00
|
|
|
search_from_1st_node = false;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2014-03-05 13:17:19 -05:00
|
|
|
if( SPECIAL_NODEID == middle2 ) {
|
2013-09-21 16:10:41 -04:00
|
|
|
search_from_2nd_node = false;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//Was at most one of the two paths not found?
|
2013-09-21 16:18:27 -04:00
|
|
|
BOOST_ASSERT_MSG(
|
|
|
|
(INT_MAX != distance1 || INT_MAX != distance2),
|
|
|
|
"no path found"
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
|
|
|
|
//Unpack paths if they exist
|
2013-12-12 18:35:23 -05:00
|
|
|
std::vector<NodeID> temporary_packed_leg1;
|
|
|
|
std::vector<NodeID> temporary_packed_leg2;
|
|
|
|
|
2013-12-18 07:19:23 -05:00
|
|
|
BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() );
|
|
|
|
BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() );
|
2013-12-12 18:35:23 -05:00
|
|
|
|
2014-03-05 13:17:19 -05:00
|
|
|
if( INVALID_EDGE_WEIGHT != local_upper_bound1 ) {
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RetrievePackedPathFromHeap(
|
|
|
|
forward_heap1,
|
|
|
|
reverse_heap1,
|
|
|
|
middle1,
|
2013-12-12 18:35:23 -05:00
|
|
|
temporary_packed_leg1
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
2014-03-05 13:17:19 -05:00
|
|
|
if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) {
|
2013-09-21 16:10:41 -04:00
|
|
|
super::RetrievePackedPathFromHeap(
|
|
|
|
forward_heap2,
|
|
|
|
reverse_heap2,
|
|
|
|
middle2,
|
2013-12-12 18:35:23 -05:00
|
|
|
temporary_packed_leg2
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//if one of the paths was not found, replace it with the other one.
|
2013-12-12 18:35:23 -05:00
|
|
|
if( temporary_packed_leg1.empty() ) {
|
|
|
|
temporary_packed_leg1.insert(
|
|
|
|
temporary_packed_leg1.end(),
|
|
|
|
temporary_packed_leg2.begin(),
|
|
|
|
temporary_packed_leg2.end()
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
|
|
|
local_upper_bound1 = local_upper_bound2;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2013-12-12 18:35:23 -05:00
|
|
|
if( temporary_packed_leg2.empty() ) {
|
|
|
|
temporary_packed_leg2.insert(
|
|
|
|
temporary_packed_leg2.end(),
|
|
|
|
temporary_packed_leg1.begin(),
|
|
|
|
temporary_packed_leg1.end()
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
|
|
|
local_upper_bound2 = local_upper_bound1;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
2013-09-21 16:18:27 -04:00
|
|
|
BOOST_ASSERT_MSG(
|
2013-12-12 18:35:23 -05:00
|
|
|
!temporary_packed_leg1.empty() ||
|
|
|
|
!temporary_packed_leg2.empty(),
|
2013-09-24 10:45:34 -04:00
|
|
|
"tempory packed paths empty"
|
2013-09-21 16:18:27 -04:00
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-12-12 18:35:23 -05:00
|
|
|
BOOST_ASSERT(
|
|
|
|
(0 == current_leg) || !packed_legs1[current_leg-1].empty()
|
|
|
|
);
|
|
|
|
BOOST_ASSERT(
|
|
|
|
(0 == current_leg) || !packed_legs2[current_leg-1].empty()
|
|
|
|
);
|
|
|
|
|
|
|
|
if( 0 < current_leg ) {
|
|
|
|
const NodeID end_id_of_segment1 = packed_legs1[current_leg-1].back();
|
|
|
|
const NodeID end_id_of_segment2 = packed_legs2[current_leg-1].back();
|
|
|
|
BOOST_ASSERT( !temporary_packed_leg1.empty() );
|
|
|
|
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
|
|
|
|
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
|
|
|
|
if( ( end_id_of_segment1 != start_id_of_leg1 ) &&
|
|
|
|
( end_id_of_segment2 != start_id_of_leg2 )
|
2013-09-22 16:29:03 -04:00
|
|
|
) {
|
2013-12-12 18:35:23 -05:00
|
|
|
std::swap(temporary_packed_leg1, temporary_packed_leg2);
|
|
|
|
std::swap(local_upper_bound1, local_upper_bound2);
|
|
|
|
}
|
|
|
|
}
|
2013-09-21 16:21:33 -04:00
|
|
|
|
2013-12-12 18:35:23 -05:00
|
|
|
// remove one path if both legs end at the same segment
|
|
|
|
if( 0 < current_leg ) {
|
|
|
|
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
|
|
|
|
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
|
|
|
|
if(
|
|
|
|
start_id_of_leg1 == start_id_of_leg2
|
|
|
|
) {
|
|
|
|
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg-1].back();
|
|
|
|
const NodeID last_id_of_packed_legs2 = packed_legs2[current_leg-1].back();
|
|
|
|
if( start_id_of_leg1 != last_id_of_packed_legs1 ) {
|
|
|
|
packed_legs1 = packed_legs2;
|
|
|
|
BOOST_ASSERT(
|
|
|
|
start_id_of_leg1 == temporary_packed_leg1.front()
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
2013-12-12 18:35:23 -05:00
|
|
|
} else
|
|
|
|
if( start_id_of_leg2 != last_id_of_packed_legs2 ) {
|
|
|
|
packed_legs2 = packed_legs1;
|
|
|
|
BOOST_ASSERT(
|
|
|
|
start_id_of_leg2 == temporary_packed_leg2.front()
|
2013-09-21 16:21:33 -04:00
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-12 18:35:23 -05:00
|
|
|
BOOST_ASSERT(
|
|
|
|
packed_legs1.size() == packed_legs2.size()
|
|
|
|
);
|
|
|
|
|
|
|
|
packed_legs1[current_leg].insert(
|
|
|
|
packed_legs1[current_leg].end(),
|
|
|
|
temporary_packed_leg1.begin(),
|
|
|
|
temporary_packed_leg1.end()
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
2013-12-12 18:35:23 -05:00
|
|
|
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size() );
|
|
|
|
packed_legs2[current_leg].insert(
|
|
|
|
packed_legs2[current_leg].end(),
|
|
|
|
temporary_packed_leg2.begin(),
|
|
|
|
temporary_packed_leg2.end()
|
2013-09-21 16:10:41 -04:00
|
|
|
);
|
2013-12-12 18:35:23 -05:00
|
|
|
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size() );
|
2012-06-15 12:47:27 -04:00
|
|
|
|
2013-09-21 16:10:41 -04:00
|
|
|
if(
|
2013-12-12 18:35:23 -05:00
|
|
|
(packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
|
2014-03-25 13:06:05 -04:00
|
|
|
phantom_node_pair.target_phantom.isBidirected()
|
2013-09-21 16:10:41 -04:00
|
|
|
) {
|
2013-12-12 18:35:23 -05:00
|
|
|
const NodeID last_node_id = packed_legs2[current_leg].back();
|
2014-03-25 13:06:05 -04:00
|
|
|
search_from_1st_node &= !(last_node_id == phantom_node_pair.target_phantom.reverse_node_id);
|
|
|
|
search_from_2nd_node &= !(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
|
2013-12-12 18:35:23 -05:00
|
|
|
BOOST_ASSERT( search_from_1st_node != search_from_2nd_node );
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
2013-09-21 16:21:33 -04:00
|
|
|
distance1 = local_upper_bound1;
|
|
|
|
distance2 = local_upper_bound2;
|
2013-12-12 18:35:23 -05:00
|
|
|
++current_leg;
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
|
2014-03-28 12:13:00 -04:00
|
|
|
if (distance1 > distance2)
|
|
|
|
{
|
2013-12-12 18:35:23 -05:00
|
|
|
std::swap( packed_legs1, packed_legs2 );
|
|
|
|
}
|
|
|
|
raw_route_data.unpacked_path_segments.resize( packed_legs1.size() );
|
2014-03-25 13:06:05 -04:00
|
|
|
// const int start_offset = ( packed_legs1[0].front() == phantom_nodes_vector.front().source_phantom.forward_node_id ? 1 : -1 )*phantom_nodes_vector.front().source_phantom.fwd_segment_position;
|
2014-02-26 09:55:04 -05:00
|
|
|
|
2014-03-28 12:13:00 -04:00
|
|
|
raw_route_data.source_traversed_in_reverse = (packed_legs1.front().front() != phantom_nodes_vector.front().source_phantom.forward_node_id);
|
|
|
|
raw_route_data.target_traversed_in_reverse = (packed_legs1.back().back() != phantom_nodes_vector.back().target_phantom.forward_node_id);
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < packed_legs1.size(); ++i)
|
|
|
|
{
|
|
|
|
BOOST_ASSERT(!phantom_nodes_vector.empty());
|
2014-03-19 11:42:37 -04:00
|
|
|
// const bool at_beginning = (packed_legs1[i] == packed_legs1.front());
|
|
|
|
// const bool at_end = (packed_legs1[i] == packed_legs1.back());
|
2014-03-28 12:13:00 -04:00
|
|
|
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
|
2014-03-05 13:17:19 -05:00
|
|
|
|
2014-03-10 10:36:58 -04:00
|
|
|
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i];
|
2014-03-12 12:23:21 -04:00
|
|
|
// if (!at_beginning)
|
|
|
|
// {
|
2014-03-25 13:06:05 -04:00
|
|
|
// unpack_phantom_node_pair.source_phantom.packed_geometry_id = SPECIAL_EDGEID;
|
|
|
|
// unpack_phantom_node_pair.source_phantom.fwd_segment_position = 0;
|
2014-03-12 12:23:21 -04:00
|
|
|
// }
|
|
|
|
|
|
|
|
// if (!at_end)
|
|
|
|
// {
|
2014-03-25 13:06:05 -04:00
|
|
|
// unpack_phantom_node_pair.target_phantom.packed_geometry_id = SPECIAL_EDGEID;
|
|
|
|
// unpack_phantom_node_pair.target_phantom.fwd_segment_position = 0;
|
2014-03-12 12:23:21 -04:00
|
|
|
// }
|
2014-03-05 13:17:19 -05:00
|
|
|
|
2013-12-12 18:35:23 -05:00
|
|
|
super::UnpackPath(
|
2014-03-05 13:17:19 -05:00
|
|
|
// -- packed input
|
2013-12-12 18:35:23 -05:00
|
|
|
packed_legs1[i],
|
2014-03-10 10:36:58 -04:00
|
|
|
// -- start and end of (sub-)route
|
|
|
|
unpack_phantom_node_pair,
|
2014-03-05 13:17:19 -05:00
|
|
|
// -- unpacked output
|
2013-12-12 18:35:23 -05:00
|
|
|
raw_route_data.unpacked_path_segments[i]
|
|
|
|
);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
2013-09-21 16:10:41 -04:00
|
|
|
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2);
|
2012-06-15 12:47:27 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* SHORTESTPATHROUTING_H_ */
|