Files
secondo/Algebras/TransportationMode/RoadNetwork.cpp
2026-01-23 17:03:45 +08:00

2397 lines
76 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] Source File of the Transportation Mode Algebra
July, 2011 Jianqiu Xu
[TOC]
1 Overview
This source file essentially contains the necessary implementations for
computing shortest path in road network
*/
#include "BusNetwork.h"
#include "RoadNetwork.h"
#include "PaveGraph.h"
#include "ListUtils.h"
using namespace std;
using namespace network;
/////////////////////////////////////////////////////////////////////////////
//////////////// road network graph ///////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
string RoadGraph::RGNodeTypeInfo = "(rel (tuple ((Jun_id int) (Jun_gp gpoint)\
(Jun_p point) (Rid int))))";
string RoadGraph::RGBTreeNodeTypeInfo = "(btree (tuple ((jun_id int)\
(jun_gp gpoint)(jun_p point) (rid int))) int)";
string RoadGraph::RGEdgeTypeInfo1 = "(rel (tuple ((Jun_id1 int)\
(Jun_id2 int))))";
string RoadGraph::RGEdgeTypeInfo2 = "(rel (tuple ((Jun_id1 int) (Jun_id2 int)\
(Path1 gline) (Path2 sline))))";
ListExpr RoadGraph::RoadGraphProp()
{
ListExpr examplelist = nl->TextAtom();
nl->AppendText(examplelist,
"createroadgraph(<id>,<node-relation>,<edge-relation>)");
return nl->TwoElemList(
nl->TwoElemList(nl->StringAtom("Creation"),
nl->StringAtom("Example Creation")),
nl->TwoElemList(examplelist,
nl->StringAtom("let rg=createroadgraph(id,n-rel,e-rel)")));
}
bool RoadGraph::CheckRoadGraph(ListExpr type, ListExpr& errorInfo)
{
// cout<<"CheckRoadGraph()"<<endl;
return nl->IsEqual(type, "roadgraph");
}
int RoadGraph::SizeOfRoadGraph()
{
// cout<<"SizeOfRoadGraph()"<<endl;
return 0;
}
void* RoadGraph::CastRoadGraph(void* addr)
{
// cout<<"CastRoadGraph()"<<endl;
return 0;
}
Word RoadGraph::CloneRoadGraph(const ListExpr typeInfo, const Word& w)
{
// cout<<"CloneMetroGraph()"<<endl;
return SetWord(Address(0));
}
void RoadGraph::CloseRoadGraph(const ListExpr typeInfo, Word& w)
{
// cout<<"CloseRoadGraph()"<<endl;
delete static_cast<RoadGraph*> (w.addr);
w.addr = NULL;
}
Word RoadGraph::CreateRoadGraph(const ListExpr typeInfo)
{
// cout<<"CreateRoadGraph()"<<endl;
return SetWord(new RoadGraph());
}
void RoadGraph::DeleteRoadGraph(const ListExpr typeInfo, Word& w)
{
// cout<<"DeleteRoadGraph()"<<endl;
RoadGraph* rg = (RoadGraph*)w.addr;
delete rg;
w.addr = NULL;
}
bool RoadGraph::SaveRoadGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value)
{
// cout<<"SaveRoadGraph()"<<endl;
RoadGraph* rg = (RoadGraph*)value.addr;
bool result = rg->Save(valueRecord, offset, typeInfo);
return result;
}
bool RoadGraph::OpenRoadGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value)
{
// cout<<"OpenRoadGraph()"<<endl;
value.addr = RoadGraph::Open(valueRecord, offset, typeInfo);
bool result = (value.addr != NULL);
return result;
}
/*
input road network graph
*/
Word RoadGraph::InRoadGraph(ListExpr in_xTypeInfo,
ListExpr in_xValue,
int in_iErrorPos, ListExpr& inout_xErrorInfo,
bool& inout_bCorrect)
{
// cout<<"InRoadGraph()"<<endl;
RoadGraph* rg = new RoadGraph(in_xValue, in_iErrorPos, inout_xErrorInfo,
inout_bCorrect);
if(inout_bCorrect) return SetWord(rg);
else{
delete rg;
return SetWord(Address(0));
}
}
ListExpr RoadGraph::OutRoadGraph(ListExpr typeInfo, Word value)
{
// cout<<"OutRoadGraph()"<<endl;
RoadGraph* rg = (RoadGraph*)value.addr;
return rg->Out(typeInfo);
}
ListExpr RoadGraph::Out(ListExpr typeInfo)
{
// cout<<"Out()"<<endl;
ListExpr xNode = nl->TheEmptyList();
ListExpr xLast = nl->TheEmptyList();
ListExpr xNext = nl->TheEmptyList();
bool bFirst = true;
for(int i = 1;i <= node_rel->GetNoTuples();i++){
Tuple* node_tuple = node_rel->GetTuple(i, false);
int id = ((CcInt*)node_tuple->GetAttribute(RG_JUN_ID))->GetIntval();
GPoint* gp = (GPoint*)node_tuple->GetAttribute(RG_JUN_GP);
Point* loc = (Point*)node_tuple->GetAttribute(RG_JUN_P);
xNext = nl->ThreeElemList(
nl->IntAtom(id),
GPoint::OutGPoint( nl->TheEmptyList(), SetWord(gp)),
OutPoint( nl->TheEmptyList(), SetWord(loc)));
if(bFirst){
xNode = nl->OneElemList(xNext);
xLast = xNode;
bFirst = false;
}else
xLast = nl->Append(xLast,xNext);
node_tuple->DeleteIfAllowed();
}
return nl->TwoElemList(nl->IntAtom(rg_id),xNode);
// return nl->OneElemList(nl->IntAtom(rg_id));
}
RoadGraph* RoadGraph::Open(SmiRecord& valueRecord,size_t& offset,
const ListExpr typeInfo)
{
return new RoadGraph(valueRecord,offset,typeInfo);
}
RoadGraph::RoadGraph():rg_id(0), node_rel(NULL), btree_node(NULL),
edge_rel1(NULL), adj_list1(0), entry_adj_list1(0),
edge_rel2(NULL), adj_list2(0), entry_adj_list2(0)
{
// cout<<"RoadGraph::RoadGraph()"<<endl;
}
RoadGraph::RoadGraph(ListExpr in_xValue,int in_iErrorPos,
ListExpr& inout_xErrorInfo,
bool& inout_bCorrect):rg_id(0), node_rel(NULL),
btree_node(NULL),
edge_rel1(NULL), adj_list1(0), entry_adj_list1(0),
edge_rel2(NULL), adj_list2(0), entry_adj_list2(0)
{
// cout<<"RoadGraph::RoadGraph(ListExpr)"<<endl;
}
RoadGraph::RoadGraph(SmiRecord& in_xValueRecord, size_t& inout_iOffset,
const ListExpr in_xTypeInfo):rg_id(0), node_rel(NULL), btree_node(NULL),
edge_rel1(NULL), adj_list1(0), entry_adj_list1(0),
edge_rel2(NULL), adj_list2(0), entry_adj_list2(0)
{
in_xValueRecord.Read(&rg_id,sizeof(int),inout_iOffset);
inout_iOffset += sizeof(int);
ListExpr xType;
ListExpr xNumericType;
///////////////////Open relation for node////////////////////////////
nl->ReadFromString(RGNodeTypeInfo,xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
node_rel = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType);
if(!node_rel) {
return;
}
///////////////////open btree built on nodes//////////////////////////
nl->ReadFromString(RGBTreeNodeTypeInfo, xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
btree_node = BTree::Open(in_xValueRecord, inout_iOffset, xNumericType);
if(!btree_node) {
node_rel->Delete();
return;
}
///////////////////////Open relation for edge1///////////////////////////
nl->ReadFromString(RGEdgeTypeInfo1, xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
edge_rel1 = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType);
if(!edge_rel1) {
node_rel->Delete();
delete btree_node;
return;
}
/////////////////open adjacency list1////////////////////////////////
size_t bufsize = DbArray<int>::headerSize();
SmiSize offset = 0;
char* buf = (char*) malloc(bufsize);
in_xValueRecord.Read(buf, bufsize, inout_iOffset);
inout_iOffset += bufsize;
assert(buf != NULL);
adj_list1.restoreHeader(buf,offset);
free(buf);
offset = 0;
buf = (char*) malloc(bufsize);
in_xValueRecord.Read(buf, bufsize, inout_iOffset);
assert(buf != NULL);
entry_adj_list1.restoreHeader(buf,offset);
inout_iOffset += bufsize;
free(buf);
///////////////////////Open relation for edge2//////////////////////////
nl->ReadFromString(RGEdgeTypeInfo2, xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
edge_rel2 = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType);
if(!edge_rel2) {
node_rel->Delete();
delete btree_node;
edge_rel1->Delete();
adj_list1.clean();
entry_adj_list1.clean();
return;
}
/////////////////open adjacency list2////////////////////////////////
bufsize = DbArray<int>::headerSize();
offset = 0;
buf = (char*) malloc(bufsize);
in_xValueRecord.Read(buf, bufsize, inout_iOffset);
inout_iOffset += bufsize;
assert(buf != NULL);
adj_list2.restoreHeader(buf,offset);
free(buf);
offset = 0;
buf = (char*) malloc(bufsize);
in_xValueRecord.Read(buf, bufsize, inout_iOffset);
assert(buf != NULL);
entry_adj_list2.restoreHeader(buf,offset);
inout_iOffset += bufsize;
free(buf);
}
RoadGraph::~RoadGraph()
{
if(node_rel != NULL) node_rel->Close();
if(edge_rel1 != NULL) edge_rel1->Close();
if(edge_rel2 != NULL) edge_rel2->Close();
if(btree_node != NULL) delete btree_node;
}
/*
save functions for the graph
*/
bool RoadGraph::Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset,
const ListExpr in_xTypeInfo)
{
// cout<<"save "<<endl;
in_xValueRecord.Write(&rg_id,sizeof(int),inout_iOffset);
inout_iOffset += sizeof(int);
ListExpr xType;
ListExpr xNumericType;
///////////////////////////save node/////////////////////////////
nl->ReadFromString(RGNodeTypeInfo,xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
if(!node_rel->Save(in_xValueRecord, inout_iOffset, xNumericType))
return false;
////////////////save btree on nodes///////////////////////////
nl->ReadFromString(RGBTreeNodeTypeInfo, xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
if(!btree_node->Save(in_xValueRecord, inout_iOffset, xNumericType))
return false;
/////////////////////save edge1/////////////////////////////
nl->ReadFromString(RGEdgeTypeInfo1, xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
if(!edge_rel1->Save(in_xValueRecord,inout_iOffset,xNumericType))
return false;
/////////////////adjacency list 1//////////////////////////////
SecondoCatalog *ctlg = SecondoSystem::GetCatalog();
SmiRecordFile *rf = ctlg->GetFlobFile();
adj_list1.saveToFile(rf, adj_list1);
SmiSize offset = 0;
size_t bufsize = adj_list1.headerSize();
char* buf = (char*) malloc(bufsize);
adj_list1.serializeHeader(buf,offset);
assert(offset==bufsize);
in_xValueRecord.Write(buf, bufsize, inout_iOffset);
inout_iOffset += bufsize;
free(buf);
entry_adj_list1.saveToFile(rf, entry_adj_list1);
offset = 0;
buf = (char*) malloc(bufsize);
entry_adj_list1.serializeHeader(buf,offset);
assert(offset==bufsize);
in_xValueRecord.Write(buf,bufsize, inout_iOffset);
free(buf);
inout_iOffset += bufsize;
///////////////////////save edge2/////////////////////////////////////
nl->ReadFromString(RGEdgeTypeInfo2,xType);
xNumericType = SecondoSystem::GetCatalog()->NumericType(xType);
if(!edge_rel2->Save(in_xValueRecord,inout_iOffset,xNumericType))
return false;
/////////////////adjacency list 2//////////////////////////////////
adj_list2.saveToFile(rf, adj_list2);
offset = 0;
bufsize = adj_list2.headerSize();
buf = (char*) malloc(bufsize);
adj_list2.serializeHeader(buf,offset);
assert(offset==bufsize);
in_xValueRecord.Write(buf, bufsize, inout_iOffset);
inout_iOffset += bufsize;
free(buf);
entry_adj_list2.saveToFile(rf, entry_adj_list2);
offset = 0;
buf = (char*) malloc(bufsize);
entry_adj_list2.serializeHeader(buf,offset);
assert(offset==bufsize);
in_xValueRecord.Write(buf,bufsize, inout_iOffset);
free(buf);
inout_iOffset += bufsize;
return true;
}
/*
load road graph from input relations
*/
void RoadGraph::Load(int id, Relation* r1, Relation* edge_rel1,
Relation* edge_rel2)
{
if(id < 0){
cout<<"invalid id "<<id<<endl;
return;
}
rg_id = id;
//////////////////node relation////////////////////
ListExpr ptrList1 = listutils::getPtrList(r1);
string strQuery = "(consume(feed(" + RGNodeTypeInfo +
"(ptr " + nl->ToString(ptrList1) + "))))";
Word xResult;
int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult);
assert(QueryExecuted);
node_rel = (Relation*)xResult.addr;
///////////////////rtree on junction points//////////////////////
ListExpr ptrList2 = listutils::getPtrList(r1);
strQuery = "(createbtree (" + RGNodeTypeInfo +
"(ptr " + nl->ToString(ptrList2) + "))" + "Rid)";//capital
QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult);
assert(QueryExecuted);
btree_node = (BTree*)xResult.addr;
// cout<<node_rel->GetNoTuples()<<endl;
LoadEdge1(edge_rel1);
LoadEdge2(edge_rel2);
}
/*
load road graph edges
*/
void RoadGraph::LoadEdge1(Relation* edge1)
{
ListExpr ptrList1 = listutils::getPtrList(edge1);
string strQuery = "(consume(feed(" + RGEdgeTypeInfo1 +
"(ptr " + nl->ToString(ptrList1) + "))))";
Word xResult;
int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult);
assert(QueryExecuted);
edge_rel1 = (Relation*)xResult.addr;
//////////////////create adjacency list////////////////////////////////////
ListExpr ptrList2 = listutils::getPtrList(edge1);
strQuery = "(createbtree (" + RGEdgeTypeInfo1 +
"(ptr " + nl->ToString(ptrList2) + "))" + "Jun_id1)";
QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult);
assert(QueryExecuted);
BTree* btree = (BTree*)xResult.addr;
/////////////////////////////////////////////////////////////////////////
/////////the adjacent list here is different from dual graph and
///////// visibility graph. it is the same as indoor graph ////////////
//////////in dual graph and visibility graph, we store the node id/////
/////////now we store the edge id because the weight, path is stored
////////in the edge relation ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
for(int i = 1;i <= node_rel->GetNoTuples();i++){
Tuple* ms_tuple = node_rel->GetTuple(i, false);
int jun_id = ((CcInt*)ms_tuple->GetAttribute(RG_JUN_ID))->GetIntval();
CcInt* nodeid = new CcInt(true, jun_id);
BTreeIterator* btree_iter = btree->ExactMatch(nodeid);
int start = adj_list1.Size();
while(btree_iter->Next()){
Tuple* edge_tuple = edge_rel1->GetTuple(btree_iter->GetId(), false);
adj_list1.Append(edge_tuple->GetTupleId());//get the edge tuple id
edge_tuple->DeleteIfAllowed();
}
delete btree_iter;
int end = adj_list1.Size();
entry_adj_list1.Append(ListEntry(start, end));
// cout<<jun_id<<" start "<<start<<" end "<<end<<endl;
delete nodeid;
ms_tuple->DeleteIfAllowed();
}
delete btree;
}
void RoadGraph::LoadEdge2(Relation* edge2)
{
ListExpr ptrList1 = listutils::getPtrList(edge2);
string strQuery = "(consume(feed(" + RGEdgeTypeInfo2 +
"(ptr " + nl->ToString(ptrList1) + "))))";
Word xResult;
int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult);
assert(QueryExecuted);
edge_rel2 = (Relation*)xResult.addr;
//////////////////create adjacency list////////////////////////////////////
ListExpr ptrList2 = listutils::getPtrList(edge2);
strQuery = "(createbtree (" + RGEdgeTypeInfo2 +
"(ptr " + nl->ToString(ptrList2) + "))" + "Jun_id1)";
QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult);
assert(QueryExecuted);
BTree* btree = (BTree*)xResult.addr;
/////////////////////////////////////////////////////////////////////////
/////////the adjacent list here is different from dual graph and
///////// visibility graph. it is the same as indoor graph ////////////
//////////in dual graph and visibility graph, we store the node id/////
/////////now we store the edge id because the weight, path is stored
////////in the edge relation ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
for(int i = 1;i <= node_rel->GetNoTuples();i++){
Tuple* ms_tuple = node_rel->GetTuple(i, false);
int jun_id = ((CcInt*)ms_tuple->GetAttribute(RG_JUN_ID))->GetIntval();
CcInt* nodeid = new CcInt(true, jun_id);
BTreeIterator* btree_iter = btree->ExactMatch(nodeid);
int start = adj_list2.Size();
while(btree_iter->Next()){
Tuple* edge_tuple = edge_rel2->GetTuple(btree_iter->GetId(), false);
adj_list2.Append(edge_tuple->GetTupleId());//get the edge tuple id
edge_tuple->DeleteIfAllowed();
}
delete btree_iter;
int end = adj_list2.Size();
entry_adj_list2.Append(ListEntry(start, end));
// cout<<jun_id<<" start "<<start<<" end "<<end<<endl;
delete nodeid;
ms_tuple->DeleteIfAllowed();
}
delete btree;
}
/*
get all junctions nodes of a route
*/
void RoadGraph::GetJunctionsNode(int rid, vector<GP_Point>& res_list)
{
CcInt* search_id = new CcInt(true, rid);
BTreeIterator* btree_iter = btree_node->ExactMatch(search_id);
while(btree_iter->Next()){
Tuple* tuple = node_rel->GetTuple(btree_iter->GetId(), false);
int node_id = ((CcInt*)tuple->GetAttribute(RG_JUN_ID))->GetIntval();
GPoint* gp = (GPoint*)tuple->GetAttribute(RG_JUN_GP);
Point* loc = (Point*)tuple->GetAttribute(RG_JUN_P);
GP_Point gp_p(gp->GetRouteId(), gp->GetPosition(), 0.0, *loc, *loc);
gp_p.oid = node_id;
res_list.push_back(gp_p);
tuple->DeleteIfAllowed();
}
delete btree_iter;
delete search_id;
}
/*
metro stops have the same spatial location in space
*/
void RoadGraph::FindAdj1(int node_id, vector<int>& list)
{
ListEntry list_entry;
entry_adj_list1.Get(node_id - 1, list_entry);
int low = list_entry.low;
int high = list_entry.high;
int j = low;
while(j < high){
int oid;
adj_list1.Get(j, oid);
j++;
list.push_back(oid);
}
}
/*
metro stops are connected by moving metros
*/
void RoadGraph::FindAdj2(int node_id, vector<int>& list)
{
ListEntry list_entry;
entry_adj_list2.Get(node_id - 1, list_entry);
int low = list_entry.low;
int high = list_entry.high;
int j = low;
while(j < high){
int oid;
adj_list2.Get(j, oid);
j++;
list.push_back(oid);
}
}
/////////////////////////////////////////////////////////////////////////
/////////////// query processing on the road graph//////////////////////
///////////////////////////////////////////////////////////////////////
void RoadNav::GenerateRoadLoc(Network* rn, int no,
vector<GPoint>& gp_list,
vector<Point>& gp_loc_list)
{
Relation* routes_rel = rn->GetRoutes();
for (int i = 1; i <= no;i++){
int m = GetRandom() % routes_rel->GetNoTuples() + 1;
Tuple* road_tuple = routes_rel->GetTuple(m, false);
int rid = ((CcInt*)road_tuple->GetAttribute(ROUTE_ID))->GetIntval();
SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(ROUTE_CURVE);
double len = sl->Length();
int pos = GetRandom() % (int)len;
GPoint gp(true, rn->GetId(), rid, pos, None);
Point* gp_loc = new Point();
assert(sl->GetStartSmaller());
assert(sl->AtPosition(pos, true, *gp_loc));//look at the value (dual) for r
gp_list.push_back(gp);
gp_loc_list.push_back(*gp_loc);
delete gp_loc;
road_tuple->DeleteIfAllowed();
}
}
/*
use road graph to calculate shortest path
1000 pair of shortest path:
old method: 99.64 seconds
road graph: 22.40 seconds
old method has some bugs:
NetworkId: 1 RouteId: 1011 Position: 613 Side: 2
NetworkId: 1 RouteId: 2655 Position: 622 Side: 2
road graph:11848.8 old:11975.2
*/
void RoadNav::ShortestPath(GPoint* gp1, GPoint* gp2,
RoadGraph* rg, Network* rn, GLine* res)
{
///////////////////////////////////////////////////////////////////////////
/////// testing the performance of different shortest path computation/////
//////////////////////////////////////////////////////////////////////////
// int no = 1000;
/* int no = 100;
vector<GPoint> gp_loc_list1;
vector<Point> p_loc_list1;
GenerateRoadLoc(rn, no, gp_loc_list1, p_loc_list1);
vector<GPoint> gp_loc_list2;
vector<Point> p_loc_list2;
GenerateRoadLoc(rn, no, gp_loc_list2, p_loc_list2);
const double delta_d = 0.001;
for(unsigned int i = 0;i < gp_loc_list1.size();i++){
GPoint* loc1 = &gp_loc_list1[i];
GPoint* loc2 = &gp_loc_list2[i];
GLine* gl1 = new GLine(0);
GLine* gl2 = new GLine(0);
ShortestPathSub(loc1, loc2, rg, rn, gl1);
// loc1->ShortestPath(loc2, gl2, rn);
// if(fabs(gl1->GetLength() - gl2->GetLength()) > delta_d){
// cout<<"error:different shortest path "<<endl;
// cout<<*loc1<<" "<<*loc2<<" "
// <<gl1->GetLength()<<" "<<gl2->GetLength()<<endl;
// }
cout<<i<<" "<<gl1->GetLength()<<endl;
delete gl1;
delete gl2;
} */
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
ShortestPathSub(gp1, gp2, rg, rn, res);
}
/*
calculate shortest path
*/
void RoadNav::ShortestPathSub(GPoint* gp1, GPoint* gp2, RoadGraph* rg,
Network* rn, GLine* res_path)
{
if(gp1->IsDefined() == false || gp2->IsDefined() == false){
return;
}
if(gp1->GetRouteId() == gp2->GetRouteId()){//the same route
res_path->SetNetworkId(gp1->GetNetworkId());
res_path->AddRouteInterval(gp1->GetRouteId(),
gp1->GetPosition(), gp2->GetPosition());
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
return;
}
//////////////////////////////////////////////////////////////////////
/////////find the junction node for gp1 and gp2//////////////////////
/////////////////////////////////////////////////////////////////////
const double delta_d = 0.001;
////////// collect all junction points of gp1.rid, gp2.rid//////////
//////// find the node id of these junction points in road graph////
///////////////////////////////////////////////////////////////////
vector<GP_Point> gp_p_list1;
rg->GetJunctionsNode(gp1->GetRouteId(), gp_p_list1);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list1);
vector<GP_Point> gp_p_list2;
rg->GetJunctionsNode(gp2->GetRouteId(), gp_p_list2);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list2);
Tuple* road_tuple1 = rn->GetRoute(gp1->GetRouteId());
SimpleLine* sl1 = (SimpleLine*)road_tuple1->GetAttribute(ROUTE_CURVE);
Point loc_start;
assert(sl1->GetStartSmaller());
assert(sl1->AtPosition(gp1->GetPosition(), true, loc_start));
road_tuple1->DeleteIfAllowed();
Tuple* road_tuple2 = rn->GetRoute(gp2->GetRouteId());
SimpleLine* sl2 = (SimpleLine*)road_tuple2->GetAttribute(ROUTE_CURVE);
Point loc_end;
assert(sl2->GetStartSmaller());
assert(sl2->AtPosition(gp2->GetPosition(), true, loc_end));
road_tuple2->DeleteIfAllowed();
if(loc_start.Distance(loc_end) < delta_d){
res_path->SetDefined(false);
return;
}
////////////check whether the start location equals to junction node///////
bool exist_jun1 = false;
int start_index = -1;
for(unsigned int i = 0;i < gp_p_list1.size();i++){
if(gp1->GetRouteId() == gp_p_list1[i].rid &&
fabs(gp1->GetPosition() - gp_p_list1[i].pos1) < delta_d &&
fabs(loc_start.Distance(gp_p_list1[i].loc1) < delta_d)){
start_index = i;
exist_jun1 = true;
break;
}
}
////////////check whether the end location is equal to junction node///////
bool exist_jun2 = false;
//int end_index = -1;
for(unsigned int i = 0;i < gp_p_list2.size();i++){
if(gp2->GetRouteId() == gp_p_list2[i].rid &&
fabs(gp2->GetPosition() - gp_p_list2[i].pos1) < delta_d &&
fabs(loc_end.Distance(gp_p_list2[i].loc1) < delta_d)){
//end_index = i;
exist_jun2 = true;
break;
}
}
// cout<<"exist_jun1 "<<exist_jun1<<" exist_jun2 "<<exist_jun2<<endl;
// cout<<gp_p_list1.size()<<" "<<gp_p_list2.size()<<endl;
priority_queue<RNPath_elem> path_queue;
vector<RNPath_elem> expand_queue;
//////////////////////////////////////////////////////////////////////////
//////////////////initialize the start node /////////////////////////////
/////////////////////////////////////////////////////////////////////////
if(exist_jun1 == false){///start location is not equal to junction point
if(gp_p_list1.size() == 1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[0].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[0].pos1);
double hw = gp_p_list1[0].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[0].oid, w + hw, w,
ri, true, gp_p_list1[0].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
// ri.Print(cout);
}else if(gp_p_list1.size() == 2){/////////two junction points
for(unsigned int i = 0;i < gp_p_list1.size();i++){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
}
}else{
for(unsigned int i = 0;i < gp_p_list1.size();i++){
// cout<<"i "<<i<<" "<<gp_p_list1[i].pos1<<endl;
// if(i == 0 && gp1->GetPosition() < gp_p_list1[i].pos1){//first jun
if(i == 0){
if(gp1->GetPosition() < gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
// }else if(i == gp_p_list1.size() - 1 &&
// gp1->GetPosition() > gp_p_list1[i].pos1){
}else if(i == gp_p_list1.size() - 1){
if(gp1->GetPosition() > gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
}else if(gp1->GetPosition() > gp_p_list1[i - 1].pos1&&
gp1->GetPosition() < gp_p_list1[i].pos1){ //two junctions
///////////////first element//////////////////////
RouteInterval ri1(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i - 1].pos1);
double w1 = fabs(gp1->GetPosition() - gp_p_list1[i - 1].pos1);
double hw1 = gp_p_list1[i - 1].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem1(-1, cur_size, gp_p_list1[i - 1].oid, w1 + hw1,
w1, ri1, true, gp_p_list1[i - 1].loc1);
path_queue.push(rn_elem1);
expand_queue.push_back(rn_elem1);
///////////////second element//////////////////////////////
RouteInterval ri2(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w2 = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw2 = gp_p_list1[i].loc1.Distance(loc_end);
cur_size = expand_queue.size();
RNPath_elem rn_elem2(-1, cur_size, gp_p_list1[i].oid, w2 + hw2, w2,
ri2, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem2);
expand_queue.push_back(rn_elem2);
break;
}
}
}
}else{////////start location is equal to jun point
assert(0 <= start_index && start_index < (int)gp_p_list1.size());
RouteInterval ri(0, 0, 0);
double w = 0;
double hw = loc_start.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[start_index].oid, w + hw, w,
ri, false, loc_start);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
/////////////////////////////////////////////////////////////////
/////put the neighbor node (same location) into queue////////////
/////////////////////////////////////////////////////////////////
vector<int> adj_list;
rg->FindAdj1(gp_p_list1[start_index].oid, adj_list);
for(unsigned int i = 0;i < adj_list.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
edge_tuple->DeleteIfAllowed();
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
assert(jun_p->Distance(loc_start) < delta_d);
double w = 0.0;
double hw = jun_p->Distance(loc_end);
RouteInterval ri(0, 0, 0);
int cur_size = expand_queue.size();
RNPath_elem elem(0, cur_size, neighbor_id, w + hw, w,
ri, false, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}////////end for
}
vector<GP_Point> end_jun_list;
if(exist_jun2 == false){//find the junction point to end location
if(gp_p_list2.size() == 1){
end_jun_list.push_back(gp_p_list2[0]);
}else if(gp_p_list2.size() == 2){
end_jun_list.push_back(gp_p_list2[0]);
end_jun_list.push_back(gp_p_list2[1]);
}else{
for(unsigned int i = 0;i < gp_p_list2.size();i++){
// if(i == 0 && gp2->GetPosition() < gp_p_list2[i].pos1){//first jun
if(i == 0){//first jun
if(gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
/* }else if(i == gp_p_list2.size() - 1 &&
gp2->GetPosition() > gp_p_list2[i].pos1){*/
}else if(i == gp_p_list2.size() - 1){
if(gp2->GetPosition() > gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}else if(gp2->GetPosition() > gp_p_list2[i - 1].pos1 &&
gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i - 1]);
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}
}
}
//////////////////////////////start searching//////////////////////////
vector<bool> visit_flag; //junction node visit
for(int i = 1;i <= rg->GetNode_Rel()->GetNoTuples();i++){
visit_flag.push_back(false);
}
bool found = false;
RNPath_elem dest;
while(path_queue.empty() == false){
RNPath_elem top = path_queue.top();
path_queue.pop();
// top.Print();
if(top.tri_index == 0 || top.to_loc.Distance(loc_end) < delta_d){
dest = top;
found = true;
break;
}
if(visit_flag[top.tri_index - 1]) continue;
//////////////////////////////////////////////////////////////////////
if(exist_jun2 == false){//end location is not equal to junction point
for(unsigned int i = 0;i < end_jun_list.size();i++){
if(end_jun_list[i].oid == top.tri_index){
int pos_expand_path = top.cur_index;;
int cur_size = expand_queue.size();
assert(end_jun_list[i].rid == gp2->GetRouteId());
double w = top.real_w +
fabs(end_jun_list[i].pos1 - gp2->GetPosition());
double hw = 0.0;
RouteInterval ri(gp2->GetRouteId(), end_jun_list[i].pos1,
gp2->GetPosition());
RNPath_elem elem(pos_expand_path, cur_size, 0, w + hw, w,
ri, true, loc_end);//end point not oid
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
}
int pos_expand_path;
int cur_size;
if(top.len){
///////////////////////neighbor list 1////////////////////////////////
vector<int> adj_list1;
rg->FindAdj1(top.tri_index, adj_list1);
for(unsigned int i = 0;i < adj_list1.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list1[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
edge_tuple->DeleteIfAllowed();
double w = top.real_w;
double hw = top.to_loc.Distance(loc_end);
RouteInterval ri(0, 0, 0);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, false, top.to_loc);
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
///////////////////////neighbor list 2////////////////////////////////
vector<int> adj_list2;
rg->FindAdj2(top.tri_index, adj_list2);
// cout<<"adj2 size "<<adj_list2.size()<<endl;
for(unsigned int i = 0;i < adj_list2.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel2()->GetTuple(adj_list2[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN_2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
GLine* gl = (GLine*)edge_tuple->GetAttribute(RoadGraph::RG_PATHA1);
assert(gl->NoOfComponents() == 1);
RouteInterval ri;
gl->Get(0, ri);
edge_tuple->DeleteIfAllowed();
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
double w = top.real_w + fabs(ri.GetStartPos() - ri.GetEndPos());
double hw = jun_p->Distance(loc_end);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, true, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}
visit_flag[top.tri_index - 1] = true;
}
if(found){
res_path->SetNetworkId(gp1->GetNetworkId());
vector<RouteInterval> ri_list;
while(dest.prev_index != -1){
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
dest = expand_queue[dest.prev_index];
}
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
// for(int i = ri_list.size() - 1;i >= 0; i--){
// res_path->AddRouteInterval(ri_list[i]);
// }
////////////////merge intervals on the same route///////////////////
vector<RouteInterval> new_ri_list;
for(int i = ri_list.size() - 1; i >= 0;i--){
RouteInterval ri = ri_list[i];
int j = i - 1;
while(j >= 0 && ri_list[j].GetRouteId() == ri.GetRouteId()){
if(fabs(ri.GetEndPos() - ri_list[j].GetStartPos()) < delta_d){
ri.SetEndPos(ri_list[j].GetEndPos());
j--;
}else
assert(false);
}
new_ri_list.push_back(ri);
i = j + 1;
}
for(unsigned int i = 0;i < new_ri_list.size(); i++){
res_path->AddRouteInterval(new_ri_list[i]);
}
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
}else{
res_path->SetDefined(false);
}
}
/*
find all routes that intersect the route
*/
void RoadNav::DFTraverse(Network* rn, R_Tree<2,TupleId>* rtree,
SmiRecordId adr,
SimpleLine* line, vector<GPoint_Dist>& res_list)
{
Relation* routes = rn->GetRoutes();
R_TreeNode<2,TupleId>* node = rtree->GetMyNode(adr,false,
rtree->MinEntries(0), rtree->MaxEntries(0));
for(int j = 0;j < node->EntryCount();j++){
if(node->IsLeaf()){
R_TreeLeafEntry<2,TupleId> e =
(R_TreeLeafEntry<2,TupleId>&)(*node)[j];
Tuple* route_tuple = routes->GetTuple(e.info, false);
SimpleLine* road =
(SimpleLine*)route_tuple->GetAttribute(ROUTE_CURVE);
int rid =
((CcInt*)route_tuple->GetAttribute(ROUTE_ID))->GetIntval();
Points* ps = new Points(0);
line->Crossings(*road, *ps);
if(ps->Size() > 0){
// cout<<"ps size "<<ps->Size()<<endl;
for(int i = 0;i < ps->Size();i++){
Point p;
ps->Get(i, p);
double pos;
if(road->AtPoint(p, true, pos)){
GPoint gp(true, rn->GetId(), rid, pos, None);
GPoint_Dist gpd(gp, p, 0.0);
res_list.push_back(gpd);
}
}
}
ps->DeleteIfAllowed();
route_tuple->DeleteIfAllowed();
}else{
R_TreeInternalEntry<2> e =
(R_TreeInternalEntry<2>&)(*node)[j];
if(e.box.Intersects(line->BoundingBox())){
DFTraverse(rn, rtree, e.pointer, line, res_list);
}
}
}
delete node;
}
/*
find a path from a gpoint to another. avoid the road network center area
*/
void RoadNav::ShortestPath2(GPoint* gp1, GPoint* gp2, RoadGraph* rg,
Network* rn, GLine* res_path)
{
// ShortestPathSub2(gp1, gp2, rg, rn, res_path);
ShortestPathSub3(gp1, gp2, rg, rn, res_path);
}
void RoadNav::ShortestPathSub2(GPoint* gp1, GPoint* gp2, RoadGraph* rg,
Network* rn, GLine* res_path)
{
if(gp1->IsDefined() == false || gp2->IsDefined() == false){
return;
}
if(gp1->GetRouteId() == gp2->GetRouteId()){//the same route
res_path->SetNetworkId(gp1->GetNetworkId());
res_path->AddRouteInterval(gp1->GetRouteId(),
gp1->GetPosition(), gp2->GetPosition());
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
return;
}
Rectangle<2> bbox = rn->GetRTree()->BoundingBox();
double mid_x = (bbox.MinD(0) + bbox.MaxD(0))/2;
double mid_y = (bbox.MinD(1) + bbox.MaxD(1))/2;
// cout<<"mindx "<<mid_x<<" mindy "<<mid_y<<endl;
const double dist1 = 5000.0;
const double dist2 = 4000.0;
double min[2], max[2];
min[0] = mid_x - dist1;
min[1] = mid_y - dist2;
max[0] = mid_x + dist1;
max[1] = mid_y + dist2;
Rectangle<2> center_area(true, min, max);//shortest path avoid center area
//////////////////////////////////////////////////////////////////////
/////////find the junction node for gp1 and gp2//////////////////////
/////////////////////////////////////////////////////////////////////
const double delta_d = 0.001;
////////// collect all junction points of gp1.rid, gp2.rid//////////
//////// find the node id of these junction points in road graph////
///////////////////////////////////////////////////////////////////
vector<GP_Point> gp_p_list1;
rg->GetJunctionsNode(gp1->GetRouteId(), gp_p_list1);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list1);
vector<GP_Point> gp_p_list2;
rg->GetJunctionsNode(gp2->GetRouteId(), gp_p_list2);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list2);
Tuple* road_tuple1 = rn->GetRoute(gp1->GetRouteId());
SimpleLine* sl1 = (SimpleLine*)road_tuple1->GetAttribute(ROUTE_CURVE);
Point loc_start;
assert(sl1->GetStartSmaller());
assert(sl1->AtPosition(gp1->GetPosition(), true, loc_start));
road_tuple1->DeleteIfAllowed();
Tuple* road_tuple2 = rn->GetRoute(gp2->GetRouteId());
SimpleLine* sl2 = (SimpleLine*)road_tuple2->GetAttribute(ROUTE_CURVE);
Point loc_end;
assert(sl2->GetStartSmaller());
assert(sl2->AtPosition(gp2->GetPosition(), true, loc_end));
road_tuple2->DeleteIfAllowed();
if(loc_start.Distance(loc_end) < delta_d){
res_path->SetDefined(false);
return;
}
////////////check whether the start location equals to junction node///////
bool exist_jun1 = false;
int start_index = -1;
for(unsigned int i = 0;i < gp_p_list1.size();i++){
if(gp1->GetRouteId() == gp_p_list1[i].rid &&
fabs(gp1->GetPosition() - gp_p_list1[i].pos1) < delta_d &&
fabs(loc_start.Distance(gp_p_list1[i].loc1) < delta_d)){
start_index = i;
exist_jun1 = true;
break;
}
}
////////////check whether the end location is equal to junction node///////
bool exist_jun2 = false;
// int end_index = -1;
for(unsigned int i = 0;i < gp_p_list2.size();i++){
if(gp2->GetRouteId() == gp_p_list2[i].rid &&
fabs(gp2->GetPosition() - gp_p_list2[i].pos1) < delta_d &&
fabs(loc_end.Distance(gp_p_list2[i].loc1) < delta_d)){
//end_index = i;
exist_jun2 = true;
break;
}
}
priority_queue<RNPath_elem> path_queue;
vector<RNPath_elem> expand_queue;
//////////////////////////////////////////////////////////////////////////
//////////////////initialize the start node /////////////////////////////
/////////////////////////////////////////////////////////////////////////
if(exist_jun1 == false){///start location is not equal to junction point
if(gp_p_list1.size() == 1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[0].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[0].pos1);
double hw = gp_p_list1[0].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[0].oid, w + hw, w,
ri, true, gp_p_list1[0].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
// ri.Print(cout);
}else if(gp_p_list1.size() == 2){/////////two junction points
for(unsigned int i = 0;i < gp_p_list1.size();i++){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
}
}else{
for(unsigned int i = 0;i < gp_p_list1.size();i++){
// if(i == 0 && gp1->GetPosition() < gp_p_list1[i].pos1){//first jun
if(i == 0){//first jun)
if(gp1->GetPosition() < gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
// }else if(i == gp_p_list1.size() - 1 &&
// gp1->GetPosition() > gp_p_list1[i].pos1){
}else if(i == gp_p_list1.size() - 1){
if(gp1->GetPosition() > gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
}else if(gp1->GetPosition() > gp_p_list1[i - 1].pos1&&
gp1->GetPosition() < gp_p_list1[i].pos1){///two juns
///////////////first element//////////////////////
RouteInterval ri1(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i - 1].pos1);
double w1 = fabs(gp1->GetPosition() - gp_p_list1[i - 1].pos1);
double hw1 = gp_p_list1[i - 1].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem1(-1, cur_size, gp_p_list1[i - 1].oid, w1 + hw1,
w1, ri1, true, gp_p_list1[i - 1].loc1);
path_queue.push(rn_elem1);
expand_queue.push_back(rn_elem1);
///////////////second element//////////////////////////////
RouteInterval ri2(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w2 = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw2 = gp_p_list1[i].loc1.Distance(loc_end);
cur_size = expand_queue.size();
RNPath_elem rn_elem2(-1, cur_size, gp_p_list1[i].oid, w2 + hw2, w2,
ri2, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem2);
expand_queue.push_back(rn_elem2);
break;
}
}
}
}else{////////start location is equal to jun point
assert(0 <= start_index && start_index < (int)gp_p_list1.size());
RouteInterval ri(0, 0, 0);
double w = 0;
double hw = loc_start.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[start_index].oid, w + hw, w,
ri, false, loc_start);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
/////////////////////////////////////////////////////////////////
/////put the neighbor node (same location) into queue////////////
/////////////////////////////////////////////////////////////////
vector<int> adj_list;
rg->FindAdj1(gp_p_list1[start_index].oid, adj_list);
for(unsigned int i = 0;i < adj_list.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
edge_tuple->DeleteIfAllowed();
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
assert(jun_p->Distance(loc_start) < delta_d);
double w = 0.0;
double hw = jun_p->Distance(loc_end);
RouteInterval ri(0, 0, 0);
int cur_size = expand_queue.size();
RNPath_elem elem(0, cur_size, neighbor_id, w + hw, w,
ri, false, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}////////end for
}
vector<GP_Point> end_jun_list;
if(exist_jun2 == false){//find the junction point to end location
if(gp_p_list2.size() == 1){
end_jun_list.push_back(gp_p_list2[0]);
}else if(gp_p_list2.size() == 2){
end_jun_list.push_back(gp_p_list2[0]);
end_jun_list.push_back(gp_p_list2[1]);
}else{
for(unsigned int i = 0;i < gp_p_list2.size();i++){
// if(i == 0 && gp2->GetPosition() < gp_p_list2[i].pos1){//first jun
if(i == 0){//first jun
if(gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
/* }else if(i == gp_p_list2.size() - 1 &&
gp2->GetPosition() > gp_p_list2[i].pos1){*/
}else if(i == gp_p_list2.size() - 1){
if(gp2->GetPosition() > gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}else if(gp2->GetPosition() > gp_p_list2[i - 1].pos1 &&
gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i - 1]);
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}
}
}
//////////////////////////////start searching//////////////////////////
vector<bool> visit_flag; //junction node visit
for(int i = 1;i <= rg->GetNode_Rel()->GetNoTuples();i++){
visit_flag.push_back(false);
}
bool found = false;
RNPath_elem dest;
while(path_queue.empty() == false){
RNPath_elem top = path_queue.top();
path_queue.pop();
// top.Print();
if(top.tri_index == 0 || top.to_loc.Distance(loc_end) < delta_d){
dest = top;
found = true;
break;
}
if(visit_flag[top.tri_index - 1]) continue;
//////////////////////////////////////////////////////////////////////
if(exist_jun2 == false){//end location is not equal to junction point
for(unsigned int i = 0;i < end_jun_list.size();i++){
if(end_jun_list[i].oid == top.tri_index){
int pos_expand_path = top.cur_index;;
int cur_size = expand_queue.size();
assert(end_jun_list[i].rid == gp2->GetRouteId());
double w = top.real_w +
fabs(end_jun_list[i].pos1 - gp2->GetPosition());
double hw = 0.0;
RouteInterval ri(gp2->GetRouteId(), end_jun_list[i].pos1,
gp2->GetPosition());
RNPath_elem elem(pos_expand_path, cur_size, 0, w + hw, w,
ri, true, loc_end);//end point not oid
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
}
int pos_expand_path;
int cur_size;
if(top.len){
///////////////////////neighbor list 1////////////////////////////////
vector<int> adj_list1;
rg->FindAdj1(top.tri_index, adj_list1);
for(unsigned int i = 0;i < adj_list1.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list1[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
edge_tuple->DeleteIfAllowed();
double w = top.real_w;
double hw = top.to_loc.Distance(loc_end);
RouteInterval ri(0, 0, 0);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, false, top.to_loc);
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
///////////////////////neighbor list 2////////////////////////////////
vector<int> adj_list2;
rg->FindAdj2(top.tri_index, adj_list2);
// cout<<"adj2 size "<<adj_list2.size()<<endl;
for(unsigned int i = 0;i < adj_list2.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel2()->GetTuple(adj_list2[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN_2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
GLine* gl = (GLine*)edge_tuple->GetAttribute(RoadGraph::RG_PATHA1);
assert(gl->NoOfComponents() == 1);
RouteInterval ri;
gl->Get(0, ri);
edge_tuple->DeleteIfAllowed();
// cout<<ri.GetRouteId()<<" "<<ri.GetStartPos()<<" "<<ri.GetEndPos()<<endl;
///////////////////////////////////////////////////////////////////
Tuple* road_tuple = rn->GetRoute(ri.GetRouteId());
SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(ROUTE_CURVE);
assert(sl->StartsSmaller());
SimpleLine* sub_sl = new SimpleLine(0);
if(ri.GetStartPos() < ri.GetEndPos())
sl->SubLine(ri.GetStartPos(), ri.GetEndPos(), true, *sub_sl);
else
sl->SubLine(ri.GetEndPos(), ri.GetStartPos(), true, *sub_sl);
// cout<<sub_sl->Length()<<endl;
if(center_area.Contains(sub_sl->BoundingBox())){
sub_sl->DeleteIfAllowed();
road_tuple->DeleteIfAllowed();
continue;
}
sub_sl->DeleteIfAllowed();
road_tuple->DeleteIfAllowed();
//////////////////////////////////////////////////////////////////
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
double w = top.real_w + fabs(ri.GetStartPos() - ri.GetEndPos());
double hw = jun_p->Distance(loc_end);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, true, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}
visit_flag[top.tri_index - 1] = true;
}
if(found){
res_path->SetNetworkId(gp1->GetNetworkId());
vector<RouteInterval> ri_list;
while(dest.prev_index != -1){
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
dest = expand_queue[dest.prev_index];
}
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
// for(int i = ri_list.size() - 1;i >= 0; i--){
// res_path->AddRouteInterval(ri_list[i]);
// }
////////////////merge intervals on the same route///////////////////
vector<RouteInterval> new_ri_list;
for(int i = ri_list.size() - 1; i >= 0;i--){
RouteInterval ri = ri_list[i];
int j = i - 1;
while(j >= 0 && ri_list[j].GetRouteId() == ri.GetRouteId()){
if(fabs(ri.GetEndPos() - ri_list[j].GetStartPos()) < delta_d){
ri.SetEndPos(ri_list[j].GetEndPos());
j--;
}else
assert(false);
}
new_ri_list.push_back(ri);
i = j + 1;
}
for(unsigned int i = 0;i < new_ri_list.size(); i++){
res_path->AddRouteInterval(new_ri_list[i]);
}
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
}else{
res_path->SetDefined(false);
}
}
/*
not use the distance as weight in the priority queue
*/
void RoadNav::ShortestPathSub3(GPoint* gp1, GPoint* gp2, RoadGraph* rg,
Network* rn, GLine* res_path)
{
if(gp1->IsDefined() == false || gp2->IsDefined() == false){
return;
}
if(gp1->GetRouteId() == gp2->GetRouteId()){//the same route
res_path->SetNetworkId(gp1->GetNetworkId());
res_path->AddRouteInterval(gp1->GetRouteId(),
gp1->GetPosition(), gp2->GetPosition());
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
return;
}
//////////////////////////////////////////////////////////////////////
/////////find the junction node for gp1 and gp2//////////////////////
/////////////////////////////////////////////////////////////////////
const double delta_d = 0.001;
////////// collect all junction points of gp1.rid, gp2.rid//////////
//////// find the node id of these junction points in road graph////
///////////////////////////////////////////////////////////////////
vector<GP_Point> gp_p_list1;
rg->GetJunctionsNode(gp1->GetRouteId(), gp_p_list1);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list1);
vector<GP_Point> gp_p_list2;
rg->GetJunctionsNode(gp2->GetRouteId(), gp_p_list2);
assert(gp_p_list1.size() > 0);
// LOOP_PRINT2(gp_p_list2);
Tuple* road_tuple1 = rn->GetRoute(gp1->GetRouteId());
SimpleLine* sl1 = (SimpleLine*)road_tuple1->GetAttribute(ROUTE_CURVE);
Point loc_start;
assert(sl1->GetStartSmaller());
assert(sl1->AtPosition(gp1->GetPosition(), true, loc_start));
road_tuple1->DeleteIfAllowed();
Tuple* road_tuple2 = rn->GetRoute(gp2->GetRouteId());
SimpleLine* sl2 = (SimpleLine*)road_tuple2->GetAttribute(ROUTE_CURVE);
Point loc_end;
assert(sl2->GetStartSmaller());
assert(sl2->AtPosition(gp2->GetPosition(), true, loc_end));
road_tuple2->DeleteIfAllowed();
if(loc_start.Distance(loc_end) < delta_d){
res_path->SetDefined(false);
return;
}
////////////check whether the start location equals to junction node///////
bool exist_jun1 = false;
int start_index = -1;
for(unsigned int i = 0;i < gp_p_list1.size();i++){
if(gp1->GetRouteId() == gp_p_list1[i].rid &&
fabs(gp1->GetPosition() - gp_p_list1[i].pos1) < delta_d &&
fabs(loc_start.Distance(gp_p_list1[i].loc1) < delta_d)){
start_index = i;
exist_jun1 = true;
break;
}
}
////////////check whether the end location is equal to junction node///////
bool exist_jun2 = false;
//int end_index = -1;
for(unsigned int i = 0;i < gp_p_list2.size();i++){
if(gp2->GetRouteId() == gp_p_list2[i].rid &&
fabs(gp2->GetPosition() - gp_p_list2[i].pos1) < delta_d &&
fabs(loc_end.Distance(gp_p_list2[i].loc1) < delta_d)){
//end_index = i;
exist_jun2 = true;
break;
}
}
priority_queue<RNPath_elem> path_queue;
vector<RNPath_elem> expand_queue;
//////////////////////////////////////////////////////////////////////////
//////////////////initialize the start node /////////////////////////////
/////////////////////////////////////////////////////////////////////////
if(exist_jun1 == false){///start location is not equal to junction point
if(gp_p_list1.size() == 1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[0].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[0].pos1);
double hw = gp_p_list1[0].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[0].oid, w + hw, w,
ri, true, gp_p_list1[0].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
// ri.Print(cout);
}else if(gp_p_list1.size() == 2){/////two junction points
for(unsigned int i = 0;i < gp_p_list1.size();i++){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
}
}else{
for(unsigned int i = 0;i < gp_p_list1.size();i++){
// if(i == 0 && gp1->GetPosition() < gp_p_list1[i].pos1){//first jun
if(i == 0){//first jun
if(gp1->GetPosition() < gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
// }else if(i == gp_p_list1.size() - 1 &&
// gp1->GetPosition() > gp_p_list1[i].pos1){
}else if(i == gp_p_list1.size() - 1){
if(gp1->GetPosition() > gp_p_list1[i].pos1){
RouteInterval ri(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw = gp_p_list1[i].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[i].oid, w + hw, w,
ri, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
break;
}
}else if(gp1->GetPosition() > gp_p_list1[i - 1].pos1&&
gp1->GetPosition() < gp_p_list1[i].pos1){///two juns
///////////////first element//////////////////////
RouteInterval ri1(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i - 1].pos1);
double w1 = fabs(gp1->GetPosition() - gp_p_list1[i - 1].pos1);
double hw1 = gp_p_list1[i - 1].loc1.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem1(-1, cur_size, gp_p_list1[i - 1].oid, w1 + hw1,
w1, ri1, true, gp_p_list1[i - 1].loc1);
path_queue.push(rn_elem1);
expand_queue.push_back(rn_elem1);
///////////////second element//////////////////////////////
RouteInterval ri2(gp1->GetRouteId(), gp1->GetPosition(),
gp_p_list1[i].pos1);
double w2 = fabs(gp1->GetPosition() - gp_p_list1[i].pos1);
double hw2 = gp_p_list1[i].loc1.Distance(loc_end);
cur_size = expand_queue.size();
RNPath_elem rn_elem2(-1, cur_size, gp_p_list1[i].oid, w2 + hw2, w2,
ri2, true, gp_p_list1[i].loc1);
path_queue.push(rn_elem2);
expand_queue.push_back(rn_elem2);
break;
}
}
}
}else{////////start location is equal to jun point
assert(0 <= start_index && start_index < (int)gp_p_list1.size());
RouteInterval ri(0, 0, 0);
double w = 0;
double hw = loc_start.Distance(loc_end);
int cur_size = expand_queue.size();
RNPath_elem rn_elem(-1, cur_size, gp_p_list1[start_index].oid, w + hw, w,
ri, false, loc_start);
path_queue.push(rn_elem);
expand_queue.push_back(rn_elem);
/////////////////////////////////////////////////////////////////
/////put the neighbor node (same location) into queue////////////
/////////////////////////////////////////////////////////////////
vector<int> adj_list;
rg->FindAdj1(gp_p_list1[start_index].oid, adj_list);
for(unsigned int i = 0;i < adj_list.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
edge_tuple->DeleteIfAllowed();
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
assert(jun_p->Distance(loc_start) < delta_d);
double w = 0.0;
double hw = jun_p->Distance(loc_end);
RouteInterval ri(0, 0, 0);
int cur_size = expand_queue.size();
RNPath_elem elem(0, cur_size, neighbor_id, w + hw, w,
ri, false, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}////////end for
}
vector<GP_Point> end_jun_list;
if(exist_jun2 == false){//find the junction point to end location
if(gp_p_list2.size() == 1){
end_jun_list.push_back(gp_p_list2[0]);
}else if(gp_p_list2.size() == 2){
end_jun_list.push_back(gp_p_list2[0]);
end_jun_list.push_back(gp_p_list2[1]);
}else{
for(unsigned int i = 0;i < gp_p_list2.size();i++){
// if(i == 0 && gp2->GetPosition() < gp_p_list2[i].pos1){//first jun
if(i == 0){//first jun
if(gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
/* }else if(i == gp_p_list2.size() - 1 &&
gp2->GetPosition() > gp_p_list2[i].pos1){*/
}else if(i == gp_p_list2.size() - 1){
if(gp2->GetPosition() > gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}else if(gp2->GetPosition() > gp_p_list2[i - 1].pos1 &&
gp2->GetPosition() < gp_p_list2[i].pos1){
end_jun_list.push_back(gp_p_list2[i - 1]);
end_jun_list.push_back(gp_p_list2[i]);
break;
}
}
}
}
//////////////////////////////start searching//////////////////////////
vector<bool> visit_flag; //junction node visit
for(int i = 1;i <= rg->GetNode_Rel()->GetNoTuples();i++){
visit_flag.push_back(false);
}
bool found = false;
RNPath_elem dest;
while(path_queue.empty() == false){
RNPath_elem top = path_queue.top();
path_queue.pop();
// top.Print();
if(top.tri_index == 0 || top.to_loc.Distance(loc_end) < delta_d){
dest = top;
found = true;
break;
}
if(visit_flag[top.tri_index - 1]) continue;
//////////////////////////////////////////////////////////////////////
if(exist_jun2 == false){//end location is not equal to junction point
for(unsigned int i = 0;i < end_jun_list.size();i++){
if(end_jun_list[i].oid == top.tri_index){
int pos_expand_path = top.cur_index;;
int cur_size = expand_queue.size();
assert(end_jun_list[i].rid == gp2->GetRouteId());
/* double w = top.real_w +
fabs(end_jun_list[i].pos1 - gp2->GetPosition());*/
double l = fabs(end_jun_list[i].pos1 - gp2->GetPosition());
double w = top.real_w + l;
double hw = 0.0;
RouteInterval ri(gp2->GetRouteId(), end_jun_list[i].pos1,
gp2->GetPosition());
RNPath_elem elem(pos_expand_path, cur_size, 0, w + hw, w,
ri, true, loc_end);//end point not oid
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
}
int pos_expand_path;
int cur_size;
if(top.len){
///////////////////////neighbor list 1////////////////////////////////
vector<int> adj_list1;
rg->FindAdj1(top.tri_index, adj_list1);
for(unsigned int i = 0;i < adj_list1.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(adj_list1[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
edge_tuple->DeleteIfAllowed();
double w = top.real_w;
double hw = top.to_loc.Distance(loc_end);
RouteInterval ri(0, 0, 0);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, false, top.to_loc);
path_queue.push(elem);
expand_queue.push_back(elem);
}
}
///////////////////////neighbor list 2////////////////////////////////
vector<int> adj_list2;
rg->FindAdj2(top.tri_index, adj_list2);
// cout<<"adj2 size "<<adj_list2.size()<<endl;
for(unsigned int i = 0;i < adj_list2.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel2()->GetTuple(adj_list2[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN_2))->GetIntval();
if(visit_flag[neighbor_id - 1]){
edge_tuple->DeleteIfAllowed();
continue;
}
GLine* gl = (GLine*)edge_tuple->GetAttribute(RoadGraph::RG_PATHA1);
assert(gl->NoOfComponents() == 1);
RouteInterval ri;
gl->Get(0, ri);
edge_tuple->DeleteIfAllowed();
// cout<<ri.GetRouteId()<<" "<<ri.GetStartPos()<<" "<<ri.GetEndPos()<<endl;
///////////////////////////////////////////////////////////////////
Tuple* road_tuple = rn->GetRoute(ri.GetRouteId());
SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(ROUTE_CURVE);
assert(sl->StartsSmaller());
SimpleLine* sub_sl = new SimpleLine(0);
if(ri.GetStartPos() < ri.GetEndPos())
sl->SubLine(ri.GetStartPos(), ri.GetEndPos(), true, *sub_sl);
else
sl->SubLine(ri.GetEndPos(), ri.GetStartPos(), true, *sub_sl);
// cout<<sub_sl->Length()<<endl;
sub_sl->DeleteIfAllowed();
road_tuple->DeleteIfAllowed();
//////////////////////////////////////////////////////////////////
Tuple* node_tuple = rg->GetNode_Rel()->GetTuple(neighbor_id, false);
int oid =
((CcInt*)node_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval();
assert(neighbor_id == oid);
Point* jun_p =
(Point*)node_tuple->GetAttribute(RoadGraph::RG_JUN_P);
// double w = top.real_w + fabs(ri.GetStartPos() - ri.GetEndPos());
double l = fabs(ri.GetStartPos() - ri.GetEndPos());
double w;
if(l > 50.0) ////////10 ?
w = top.real_w + GetRandom() % (int)l;
else
w = top.real_w + l;
double hw = jun_p->Distance(loc_end);
pos_expand_path = top.cur_index;
cur_size = expand_queue.size();
RNPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w,
ri, true, *jun_p);
path_queue.push(elem);
expand_queue.push_back(elem);
node_tuple->DeleteIfAllowed();
}
visit_flag[top.tri_index - 1] = true;
}
if(found){
res_path->SetNetworkId(gp1->GetNetworkId());
vector<RouteInterval> ri_list;
while(dest.prev_index != -1){
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
dest = expand_queue[dest.prev_index];
}
if(dest.len){
// res_path->AddRouteInterval(dest.ri);
ri_list.push_back(dest.ri);
}
// for(int i = ri_list.size() - 1;i >= 0; i--){
// res_path->AddRouteInterval(ri_list[i]);
// }
////////////////merge intervals on the same route///////////////////
vector<RouteInterval> new_ri_list;
for(int i = ri_list.size() - 1; i >= 0;i--){
RouteInterval ri = ri_list[i];
int j = i - 1;
while(j >= 0 && ri_list[j].GetRouteId() == ri.GetRouteId()){
if(fabs(ri.GetEndPos() - ri_list[j].GetStartPos()) < delta_d){
ri.SetEndPos(ri_list[j].GetEndPos());
j--;
}else
assert(false);
}
new_ri_list.push_back(ri);
i = j + 1;
}
for(unsigned int i = 0;i < new_ri_list.size(); i++){
res_path->AddRouteInterval(new_ri_list[i]);
}
res_path->SetDefined(true);
res_path->SetSorted(false);
res_path->TrimToSize();
}else{
res_path->SetDefined(false);
}
}
/*
get all neighbor junction nodes for a given junction
*/
void RoadNav::GetAdjNodeRG(RoadGraph* rg, int nodeid)
{
if(rg->GetNode_Rel() == NULL){
cout<<"no road graph node rel"<<endl;
return;
}
if(nodeid < 1 || nodeid > rg->GetNode_Rel()->GetNoTuples()){
cout<<"invalid node id "<<endl;
return;
}
cout<<"total "<<rg->GetNode_Rel()->GetNoTuples()<<" nodes "<<endl;
cout<<"total "<<rg->GetEdge_Rel1()->GetNoTuples() +
rg->GetEdge_Rel2()->GetNoTuples()<<" edges "<<endl;
Relation* node_rel = rg->GetNode_Rel();
Tuple* jun_tuple = node_rel->GetTuple(nodeid, false);
GPoint* jun1 = (GPoint*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_GP);
// cout<<*jun1<<endl;
///////////////////////////////////////////////////////////////////////////
//////the first kind of connection (no path; the same spatial location)////
////////////////////////////////////////////////////////////////////////////
vector<int> tid_list1;
rg->FindAdj1(nodeid, tid_list1);
for(unsigned int i = 0;i < tid_list1.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel1()->GetTuple(tid_list1[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN2))->GetIntval();
edge_tuple->DeleteIfAllowed();
Tuple* jun_neighbor1 = node_rel->GetTuple(neighbor_id, false);
GPoint* gp2 = (GPoint*)jun_neighbor1->GetAttribute(RoadGraph::RG_JUN_GP);
GLine* path = new GLine(0);
jun_list1.push_back(*jun1);
jun_list2.push_back(*gp2);
gline_list.push_back(*path);
path->DeleteIfAllowed();
jun_neighbor1->DeleteIfAllowed();
type_list.push_back(1);
}
////////////////////////////////////////////////////////////////////
//////the second kind of connection (connected by moving metros)////
////////////////////////////////////////////////////////////////////
vector<int> tid_list2;
rg->FindAdj2(nodeid, tid_list2);
for(unsigned int i = 0;i < tid_list2.size();i++){
Tuple* edge_tuple = rg->GetEdge_Rel2()->GetTuple(tid_list2[i], false);
int neighbor_id =
((CcInt*)edge_tuple->GetAttribute(RoadGraph::RG_JUN_2))->GetIntval();
Tuple* jun_neighbor2 = node_rel->GetTuple(neighbor_id, false);
GPoint* gp3 =
(GPoint*)jun_neighbor2->GetAttribute(RoadGraph::RG_JUN_GP);
GLine* path =
(GLine*)edge_tuple->GetAttribute(RoadGraph::RG_PATHA1);
jun_list1.push_back(*jun1);
jun_list2.push_back(*gp3);
gline_list.push_back(*path);
edge_tuple->DeleteIfAllowed();
jun_neighbor2->DeleteIfAllowed();
type_list.push_back(2);
}
jun_tuple->DeleteIfAllowed();
}