/* ---- 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 Oct, 2010 Jianqiu Xu [TOC] 1 Overview This source file essentially contains the necessary implementations for creating bus network */ #include "BusNetwork.h" #include "PaveGraph.h" using namespace std; using namespace network; using namespace temporalalgebra; using namespace datetime; string BusRoute::StreetSectionCellTypeInfo = "(rel (tuple ((Secid int)(Cellid int) (Cnt int) (Cover_area region))))"; string BusRoute::BusRoutesTmpTypeInfo = "(rel (tuple ((Br_id int) (Bus_route1 gline) (Bus_route2 line)\ (Start_loc point)(End_loc point) (Route_type int))))"; string BusRoute::NewBusRoutesTmpTypeInfo = "(rel (tuple ((Br_id int) (Bus_route1 line) (Bus_route2 line) (Route_type int)\ (Br_uid int))))"; string BusRoute::FinalBusRoutesTypeInfo = "(rel (tuple ((Br_id int) (Bus_route line) (Route_type int) (Br_uid int)\ (Bus_direction bool) (StartSmaller bool))))"; string BusRoute::BusStopTemp1TypeInfo = "(rel (tuple ((Br_id int) (Bus_stop_id int) (Bus_stop1 gpoint)\ (Bus_stop2 point))))"; string BusRoute::BusNetworkParaInfo = "(rel (tuple ((para real))))"; /* create route bus route a pair of cells, start cell-end cell. the start cell can be considered as the start location of a bus route and the end cell is the end location of a bus route. Then it randomly selectes two locations in these two cells it creates three kinds of routes determined by cells high density - low density; middle denstiy - low density ; low density - lowdenstiy; Berlin and Houston have different roads distribution. */ void BusRoute::CreateRoute1(int attr1,int attr2,int attr3, Relation* bus_para) { // cout<<"attr1 "<GetNoTuples();i++){ Tuple* tuple_cell = rel1->GetTuple(i,false); CcInt* cell_id = (CcInt*)tuple_cell->GetAttribute(attr1); CcInt* cnt = (CcInt*)tuple_cell->GetAttribute(attr2); // cout<GetIntval()<<" " // <GetIntval()<<" "<GetIntval()<GetIntval() > max_cell_id) max_cell_id = cell_id->GetIntval(); if(cnt->GetIntval() > max_cnt) max_cnt = cnt->GetIntval(); tuple_cell->DeleteIfAllowed(); } // cout<<"max_cell_id "< cell_list; //////////////////////array // cell_list.resize(max_cell_id); // for(int i = 0;i < max_cell_id;i++) // cell_list[i].def = false; //crashes if all BuildRoute is called 3 times for(int i = 0;i < max_cell_id;i++){ double min[2], max[2]; min[0] = 0; min[1] = 0; max[0] = 1; max[1] = 1; BBox<2>* reg = new BBox<2>(true,min,max); Section_Cell* sc_ptr = new Section_Cell(0,0,0,false,*reg); cell_list.push_back(*sc_ptr); reg->DeleteIfAllowed(); delete sc_ptr; } /////////////////////////////////////////////////////////////////// // float div_number1 = 0.5; float div_number1 = 0.4; // float div_number2 = 0.2; float div_number2 = 0.25; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_cell = rel1->GetTuple(i,false); CcInt* cell_id = (CcInt*)tuple_cell->GetAttribute(attr1); CcInt* cnt = (CcInt*)tuple_cell->GetAttribute(attr2); Region* reg = (Region*)tuple_cell->GetAttribute(attr3); int cellid = cell_id->GetIntval(); cell_list[cellid - 1].cell_id = cellid; cell_list[cellid - 1].sec_intersect_count = cnt->GetIntval(); cell_list[cellid - 1].reg = reg->BoundingBox(); if(cnt->GetIntval() > (int)(max_cnt*div_number1)){ cell_list[cellid - 1].count_1 = 3; } else if(cnt->GetIntval() > (int)(max_cnt*div_number2) ){ cell_list[cellid - 1].count_1 = 2; } else{ cell_list[cellid - 1].count_1 = 1; } cell_list[cellid - 1].def = true; tuple_cell->DeleteIfAllowed(); } // cout<<"cell list size "< cell_queue; //////////priority_queue ////////////cells are ordered by intersecting number from large to small//// for(unsigned int i = 0;i < cell_list.size();i++) if(cell_list[i].def){ // cell_list[i].Print(); count++; cell_queue.push(cell_list[i]); } // cout<<"count "< cell_list3; //////////////////////array vector cell_list2; //////////////////////array vector cell_list1; //////////////////////array while(cell_queue.empty() == false){ Section_Cell top = cell_queue.top(); cell_queue.pop(); // top.Print(); if(top.count_1 == 3) cell_list3.push_back(top); if(top.count_1 == 2) cell_list2.push_back(top); if(top.count_1 == 1) cell_list1.push_back(top); } //3---13 2---49 1---204 //berlin roads---div1 0.5 //3---21 2---41 1---204 //berlin roads---div1 0.4 //3---27 2---21 1---218 //berlin roads---div1 0.4; div 0.25 //3---10 2---8 1---619 //houston roads cout<GetNoTuples() != 3){ cout<<"wrong bus parameter relation"<GetTuple(1, false); unsigned int limit_no = (unsigned int)((CcReal*)tuple1->GetAttribute(0))->GetRealval(); tuple1->DeleteIfAllowed(); Tuple* tuple2 = bus_para->GetTuple(2, false); float dist_para1 = ((CcReal*)tuple2->GetAttribute(0))->GetRealval(); tuple2->DeleteIfAllowed(); Tuple* tuple3 = bus_para->GetTuple(3, false); float dist_para2 = ((CcReal*)tuple3->GetAttribute(0))->GetRealval(); tuple3->DeleteIfAllowed(); // cout<& from_cell_list, vector to_cell_list, int type, bool start, float dist_val) { for(unsigned int i = 0;i < from_cell_list.size();i++){ Section_Cell elem = from_cell_list[i]; int end_cellid = FindEndCell1(from_cell_list[i],to_cell_list,dist_val, start); if(end_cellid >= 0){ // cout<<"start cell "<& from_cell_list, vector to_cell_list, unsigned int limit_no, float dist_val) { unsigned int count = 0; for(unsigned int i = 0;i < from_cell_list.size();i++){ Section_Cell elem = from_cell_list[i]; if(from_cell_list[i].def == false) continue; int end_cellid = FindEndCell2(from_cell_list[i],to_cell_list,dist_val); if(end_cellid >= 0){ // cout<<"start cell "< limit_no/2) break; } count = 0; for(int i = from_cell_list.size() - 1;i >= 0;i--){ Section_Cell elem = from_cell_list[i]; if(from_cell_list[i].def == false) continue; int end_cellid = FindEndCell2(from_cell_list[i],to_cell_list,dist_val); if(end_cellid >= 0){ start_cells.push_back(from_cell_list[i].reg); end_cells.push_back(to_cell_list[end_cellid].reg); start_cell_id.push_back(from_cell_list[i].cell_id); end_cell_id.push_back(to_cell_list[end_cellid].cell_id); bus_route_type.push_back(3);//the lowest route to_cell_list[i].def = false; from_cell_list[end_cellid].def = false; count++; } if(count > limit_no/2) break; } } /* use the first paramter as the start cell and find a cell from the second parameter that the distance between them is larger than a value if flag is true, from small index to large. otherwise from large to small */ int BusRoute::FindEndCell1(Section_Cell& start_cell, vector& cell_list, float dist_val, bool flag) { if(flag){ for(unsigned int i = 0;i < cell_list.size();i++){ if(cell_list[i].def){ if(start_cell.reg.Distance(cell_list[i].reg) > dist_val){ cell_list[i].def = false; return i; } } } }else{ for(int i = cell_list.size() - 1;i >= 0;i--){ if(cell_list[i].def){ if(start_cell.reg.Distance(cell_list[i].reg) > dist_val){ cell_list[i].def = false; return i; } } } } return -1; } /* use the first paramter as the start cell and find a cell from the second parameter that the distance between them is larger than a value */ int BusRoute::FindEndCell2(Section_Cell& start_cell, vector& cell_list, float dist_val) { for(unsigned int i = 0;i < cell_list.size();i++){ if(cell_list[i].def){ if(start_cell.reg.Distance(cell_list[i].reg) > dist_val){ cell_list[i].def = false; return i; } } } // cout<<"do not find an end cell for cell "<LoadRoadNetwork(IF_LINE); if(rn == NULL){ cout<<"load road network error"<LoadRoadGraph(); for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple_cell_pair = rel2->GetTuple(i, false); int from_cell_id = ((CcInt*)tuple_cell_pair->GetAttribute(attr1))->GetIntval(); int end_cell_id = ((CcInt*)tuple_cell_pair->GetAttribute(attr2))->GetIntval(); int route_type = ((CcInt*)tuple_cell_pair->GetAttribute(attr3))->GetIntval(); // cout<<"from_cell "<DeleteIfAllowed(); } sp->CloseRoadGraph(rg); sp->CloseRoadNetwork(rn); ///////////////////add several special routes////////////////////////// /////////maybe not the shortest path, cycle route////////////////////// //////////////////////////////////////////////////////////////////////// } /* randomly choose two positions in two cells and find the shortest path connecting them. use the shortest path as the bus route */ void BusRoute::ConnectCell(RoadGraph* rg, int attr,int from_cell_id, int end_cell_id, int route_type, int seed) { Relation* routes = n->GetRoutes(); RoadNav* road_nav = new RoadNav(); ////use btree to get the sections that this cell interesects//////// CcInt* search_cell_id_from = new CcInt(true, from_cell_id); BTreeIterator* btree_iter1 = btree->ExactMatch(search_cell_id_from); vector sec_id_list_from; while(btree_iter1->Next()){ Tuple* tuple_cell = rel1->GetTuple(btree_iter1->GetId(), false); CcInt* sec_id = (CcInt*)tuple_cell->GetAttribute(attr); sec_id_list_from.push_back(sec_id->GetIntval()); tuple_cell->DeleteIfAllowed(); } delete btree_iter1; search_cell_id_from->DeleteIfAllowed(); ////////////////////create first gpoint//////////////////////// int index1 = 0; index1 = (index1 + seed) % sec_id_list_from.size(); int sec_id_1 = sec_id_list_from[index1]; ///////// create two gpoints from selected two sections/////////////// /////////choose the first road section for each cell///////////////// Tuple* tuple_sec_1 = n->GetSection(sec_id_1); int rid1 = ((CcInt*)tuple_sec_1->GetAttribute(SECTION_RID))->GetIntval(); double loc1 = ((CcReal*)tuple_sec_1->GetAttribute(SECTION_MEAS1))->GetRealval(); GPoint* gp1 = new GPoint(true,n->GetId(),rid1,loc1,None); Point* location1 = new Point(); Tuple* road_tuple1 = routes->GetTuple(gp1->GetRouteId(), false); SimpleLine* sl1 = (SimpleLine*)road_tuple1->GetAttribute(ROUTE_CURVE); assert(sl1->GetStartSmaller()); assert(sl1->AtPosition(gp1->GetPosition(), true, *location1)); road_tuple1->DeleteIfAllowed(); start_gp.push_back(*location1); //////////////////////////////////////////////////////////////////////// CcInt* search_cell_id_end = new CcInt(true, end_cell_id); BTreeIterator* btree_iter2 = btree->ExactMatch(search_cell_id_end); vector sec_id_list_end; while(btree_iter2->Next()){ Tuple* tuple_cell = rel1->GetTuple(btree_iter2->GetId(), false); CcInt* sec_id = (CcInt*)tuple_cell->GetAttribute(attr); sec_id_list_end.push_back(sec_id->GetIntval()); tuple_cell->DeleteIfAllowed(); } delete btree_iter2; search_cell_id_end->DeleteIfAllowed(); ///////////////////create second gpoint///////////////////////////// int index2 = 0; index2 = (index2 + seed) % sec_id_list_end.size(); int sec_id_2 = sec_id_list_end[index2]; Tuple* tuple_sec_2 = n->GetSection(sec_id_2); int rid2 = ((CcInt*)tuple_sec_2->GetAttribute(SECTION_RID))->GetIntval(); double loc2 = ((CcReal*)tuple_sec_2->GetAttribute(SECTION_MEAS1))->GetRealval(); GPoint* gp2 = new GPoint(true,n->GetId(),rid2,loc2,None); Point* location2 = new Point(); Tuple* road_tuple2 = routes->GetTuple(gp2->GetRouteId(), false); SimpleLine* sl2 = (SimpleLine*)road_tuple2->GetAttribute(ROUTE_CURVE); assert(sl2->GetStartSmaller()); assert(sl2->AtPosition(gp2->GetPosition(), true, *location2)); road_tuple2->DeleteIfAllowed(); end_gp.push_back(*location2); GLine* gl = new GLine(0); // cout<<"gp1 "<<*gp1<<" gp2 "<<*gp2<ShortestPathSub(gp1, gp2, rg, n, gl); if(route_type == 1){ if(GetRandom() % 2 == 0) road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); else{ road_nav->ShortestPathSub3(gp1, gp2, rg, n, gl); if(gl->IsDefined() == false) road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); } }else if(route_type == 2){ if(GetRandom() % 2 == 0){ road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); }else{ road_nav->ShortestPathSub3(gp1, gp2, rg, n, gl); if(gl->IsDefined() == false) road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); } }else{ //////paths avoid city center area if(GetRandom() % 2 == 0){ road_nav->ShortestPathSub2(gp1, gp2, rg, n, gl); if(gl->IsDefined() == false){//in case cannot find such a path road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); } }else{ road_nav->ShortestPathSub3(gp1, gp2, rg, n, gl); if(gl->IsDefined() == false){//in case cannot find such a path road_nav->ShortestPathSub(gp1, gp2, rg, n, gl); } } } location1->DeleteIfAllowed(); gp1->DeleteIfAllowed(); location2->DeleteIfAllowed(); gp2->DeleteIfAllowed(); tuple_sec_1->DeleteIfAllowed(); tuple_sec_2->DeleteIfAllowed(); ////////////////////////////////////////////////////////////////////////// bus_lines1.push_back(*gl); ////////////////////////////////////////////////////////////////////////// Line* l = new Line(0); gl->Gline2line(l); bus_lines2.push_back(*l); l->DeleteIfAllowed(); gl->DeleteIfAllowed(); bus_route_type.push_back(route_type); delete road_nav; } /* Refine bus routes: filter some routes which are very similar to each other map each bus route to the road line, gline (rid,pos1)-(rid,pos2) (rel (tuple ((br id int) (bus route1 gline) (bus route2 line) (start loc point) (end loc point) (route type int)))) */ void BusRoute::RefineBusRoute(int attr1, int attr2, int attr3, int attr4, int attr5, int attr6) { // cout<<"attr1 "< routes_def; for(int i = 0;i < rel1->GetNoTuples();i++) routes_def.push_back(true); for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_route1 = rel1->GetTuple(i, false); int br_id1 = ((CcInt*)tuple_bus_route1->GetAttribute(attr1))->GetIntval(); if(routes_def[br_id1 - 1] == false){ tuple_bus_route1->DeleteIfAllowed(); continue; } GLine* gl1 = (GLine*)tuple_bus_route1->GetAttribute(attr2); for(int j = i + 1; j <= rel1->GetNoTuples();j++){ Tuple* tuple_bus_route2 = rel1->GetTuple(j, false); int br_id2 = ((CcInt*)tuple_bus_route2->GetAttribute(attr1))->GetIntval(); if(routes_def[br_id2 - 1] == false){ tuple_bus_route2->DeleteIfAllowed(); continue; } GLine* gl2 = (GLine*)tuple_bus_route2->GetAttribute(attr2); // cout<<"br_id1 "<GetLength()<<" "<GetLength()< 0){ // cout<<" br_1 "<DeleteIfAllowed(); break; } } tuple_bus_route2->DeleteIfAllowed(); } tuple_bus_route1->DeleteIfAllowed(); } /////////////////////collect the non-filtered bus routes///////////////// /* unsigned int final_no = 0; for(unsigned int i = 0;i < routes_def.size();i++){ if(routes_def[i])final_no++; } cout<<"final bus routes no "<GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); if(routes_def[br_id - 1] == false){ tuple_bus_route->DeleteIfAllowed(); continue; } GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr2); Line* l = (Line*)tuple_bus_route->GetAttribute(attr3); Point* start_p = (Point*)tuple_bus_route->GetAttribute(attr4); Point* end_p = (Point*)tuple_bus_route->GetAttribute(attr5); int route_type = ((CcInt*)tuple_bus_route->GetAttribute(attr6))->GetIntval(); br_id_list.push_back(new_br_id); bus_lines1.push_back(*gl); bus_lines2.push_back(*l); start_gp.push_back(*start_p); end_gp.push_back(*end_p); bus_route_type.push_back(route_type); new_br_id++; tuple_bus_route->DeleteIfAllowed(); } } /* compare two bus routes represented by gline it checkes whether one of them needs to be filtered */ bool CompareRouteInterval(const RouteInterval& ri1, const RouteInterval& ri2) { if(ri1.GetRouteId() < ri2.GetRouteId()) return true; else if(ri1.GetRouteId() > ri2.GetRouteId()) return false; else{ double start1 = ri1.GetStartPos(); double end1 = ri1.GetEndPos(); if(start1 > end1){ double temp = start1; start1 = end1; end1 = temp; } double start2 = ri2.GetStartPos(); double end2 = ri2.GetEndPos(); if(start2 > end2){ double temp = start2; start2 = end2; end2 = temp; } if(AlmostEqual(start1, start2)){ if(AlmostEqual(end1, end2))return true; else if(end1 < end2) return true; else return false; } else if(start1 < start2 )return true; else return false; } } int BusRoute::FilterBusRoute(GLine* gl1, GLine* gl2, int br_id1, int br_id2) { //////////////////////convert GLine to RouteInterval//////////////////////// vector ri_list1; for(int i = 0; i < gl1->Size();i++){ RouteInterval* ri = new RouteInterval(); gl1->Get(i, *ri); ri_list1.push_back(*ri); } sort(ri_list1.begin(), ri_list1.end(), CompareRouteInterval); double length1 = 0.0; // cout<<"GLine1"< ri_list2; for(int i = 0; i < gl2->Size();i++){ RouteInterval* ri = new RouteInterval(); gl2->Get(i, *ri); ri_list2.push_back(*ri); } sort(ri_list2.begin(), ri_list2.end(), CompareRouteInterval); double length2 = 0.0; // cout<<"GLine2"< e1){ double temp = s1; s1 = e1; e1 = temp; } double s2 = ri_list2[index2].GetStartPos(); double e2 = ri_list2[index2].GetEndPos(); if(s2 > e2){ double temp = s2; s2 = e2; e2 = temp; } // cout<<"s1 "< e2){ find_comm += fabs(e2-s2); }else{//e1 < e2 find_comm += fabs(e1-s1); } }else if(s1 < s2){//check the position between e1, s2 // cout<<"s1 < s2"< s2 && e1 < e2){ // exists common part find_comm += fabs(e1-s2); } }else{//s1 > s2 // cout<<"s1 > s2 "< s1 && e2 < e1){ // exists common part find_comm += fabs(e2-s1); } } if(find_comm > comm_length){ // if(length1 < length2) return br_id1;//filter shorter one // else return br_id2; break; } i++; if(index2 + 1 < ri_list2.size()) index2++; } else if(rid1 > rid2){ while((index2 + 1) < ri_list2.size() && rid1 > rid2){ index2++; rid2 = ri_list2[index2].GetRouteId(); } if(index2 + 1 == ri_list2.size())break; } else assert(false); // cout<<"find comm "< comm_length){ // cout<<"br_id1 "<GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); Line* l = (Line*)tuple_bus_route->GetAttribute(attr2); int route_type = ((CcInt*)tuple_bus_route->GetAttribute(attr3))->GetIntval(); // if(br_id != 38){ // tuple_bus_route->DeleteIfAllowed(); // continue; // } ////////////////////////translate///////////////////////////////// SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); SpacePartition* sp = new SpacePartition(); vector seq_halfseg; //reorder it from start to end sp->ReorderLine(sl, seq_halfseg); // cout<<"l1 "<Length()<<" l2 "<Length()< outer_l; vector outer_r; sp->ExtendSeg3(seq_halfseg, w, true, outer_l); sp->ExtendSeg3(seq_halfseg, w, false, outer_r); ///////////////////////////////////////////////////////////// Line* l1 = new Line(0); l1->StartBulkLoad(); ComputeLine(outer_l, l1); l1->EndBulkLoad(); bus_sections1.push_back(*l1); br_id_list.push_back(br_id); bus_lines2.push_back(*l); bus_route_type.push_back(route_type); br_uid_list.push_back(bus_route_uid); bus_route_uid++; Line* l2 = new Line(0); l2->StartBulkLoad(); ComputeLine(outer_r, l2); l2->EndBulkLoad(); bus_sections1.push_back(*l2); br_id_list.push_back(br_id); bus_lines2.push_back(*l); bus_route_type.push_back(route_type); br_uid_list.push_back(bus_route_uid); bus_route_uid++; //////////////////////////////////////////////////////////// l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); delete sp; sl->DeleteIfAllowed(); tuple_bus_route->DeleteIfAllowed(); } } /* it inputs a list of points and computes a line value */ void BusRoute::ComputeLine(vector& point_list, Line* l) { assert(point_list.size() > 0); int edgeno = 0; // for(unsigned int i = 0;i < point_list.size() - 1;i++){ // Point lp = point_list[i]; // Point rp = point_list[i + 1]; // // HalfSegment* hs = new HalfSegment(true, lp, rp); // hs->attr.edgeno = edgeno++; // *l += *hs; // // hs->SetLeftDomPoint(!hs->IsLeftDomPoint()); // *l += *hs; // // delete hs; // // } for(unsigned int i = 0;i < point_list.size() - 1;i++){ Point lp = point_list[i]; Point rp = point_list[i + 1]; HalfSegment hs1(true, lp, rp); unsigned int j = i + 2; for(; j < point_list.size() - 1;j++){ Point p1 = point_list[j]; Point p2 = point_list[j + 1]; HalfSegment hs2(true, p1, p2); Point res; if(hs1.Intersection(hs2, res)){ // cout<<"crossing"<= point_list.size() - 1){ HalfSegment* hs = new HalfSegment(true, lp, rp); hs->attr.edgeno = edgeno++; *l += *hs; hs->SetLeftDomPoint(!hs->IsLeftDomPoint()); *l += *hs; delete hs; }else{ rp = point_list[j]; HalfSegment* hs = new HalfSegment(true, lp, rp); hs->attr.edgeno = edgeno++; *l += *hs; hs->SetLeftDomPoint(!hs->IsLeftDomPoint()); *l += *hs; delete hs; i = j; } } } /* for each bus route, it creates a sequence of points on it as bus stops */ void BusRoute::CreateBusStop1(int attr1, int attr2, int attr3, int attr4, Relation* pave_rel, BTree* btree_pave, Relation* stop_para) { ////////////initialize distance for stops/////////////////////// vector dist_stops;// distance between two bus stops InitializeDistStop(dist_stops, stop_para); /////////////////////////////////////////////////////// for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr2); Line* l = (Line*)tuple_bus_route->GetAttribute(attr3); int route_type = ((CcInt*)tuple_bus_route->GetAttribute(attr4))->GetIntval(); // if(br_id != 5){ // tuple_bus_route->DeleteIfAllowed(); // continue; // } // cout<<"br_id "<DeleteIfAllowed(); ///modify the bus stops if they are located on the zebracrossing///// CheckBusStopZC(cur_size, pave_rel, btree_pave); } } /* set the distance value for two adjacent bus stops */ void BusRoute::InitializeDistStop(vector& dist_for_stops, Relation* stop_para) { // cout<GetNoTuples()<GetTuple(index, false); int no_1 = (int)((CcReal*)tuple_tmp->GetAttribute(0))->GetRealval(); // cout<GetTuple(i, false); float dist = ((CcReal*)tuple->GetAttribute(0))->GetRealval(); // cout<DeleteIfAllowed(); dist_for_stops.push_back(dist); } tuple_tmp->DeleteIfAllowed(); /* if(type == "Berlin"){ dist_for_stops1.push_back(1000.0); dist_for_stops1.push_back(900.0); dist_for_stops1.push_back(1100.0); dist_for_stops1.push_back(1050.0); dist_for_stops1.push_back(1500.0); dist_for_stops1.push_back(1300.0); dist_for_stops1.push_back(950.0); dist_for_stops1.push_back(1200.0); dist_for_stops1.push_back(1400.0); dist_for_stops1.push_back(1300.0); dist_for_stops1.push_back(800.0);////////add smaller distance dist_for_stops1.push_back(500.0);////////add smaller distance }else if(type == "Houston"){ dist_for_stops1.push_back(2600.0); dist_for_stops1.push_back(2350.0); dist_for_stops1.push_back(2000.0); dist_for_stops1.push_back(2100.0); dist_for_stops1.push_back(2300.0); dist_for_stops1.push_back(2400.0); dist_for_stops1.push_back(2200.0); dist_for_stops1.push_back(2500.0); dist_for_stops1.push_back(2700.0); } if(type == "Berlin"){ dist_for_stops2.push_back(900.0); dist_for_stops2.push_back(1100.0); dist_for_stops2.push_back(1150.0); dist_for_stops2.push_back(1250.0); dist_for_stops2.push_back(1050.0); dist_for_stops2.push_back(1000.0); dist_for_stops2.push_back(1200.0); dist_for_stops2.push_back(800.0);////////add smaller distance dist_for_stops2.push_back(500.0);////////add smaller distance }else if(type == "Houston"){ dist_for_stops2.push_back(2000.0); dist_for_stops2.push_back(2200.0); dist_for_stops2.push_back(2100.0); dist_for_stops1.push_back(2600.0); dist_for_stops2.push_back(2700.0); dist_for_stops2.push_back(2300.0); dist_for_stops2.push_back(2400.0); dist_for_stops2.push_back(2500.0); } if(type == "Berlin"){ dist_for_stops3.push_back(900.0); dist_for_stops3.push_back(1100.0); dist_for_stops3.push_back(950.0); dist_for_stops3.push_back(1300.0); dist_for_stops3.push_back(1000.0); dist_for_stops3.push_back(1200.0); dist_for_stops3.push_back(1150.0); dist_for_stops3.push_back(800.0); ////////add smaller distance dist_for_stops3.push_back(500.0); }else if(type == "Houston"){ dist_for_stops3.push_back(2000.0); dist_for_stops3.push_back(2200.0); dist_for_stops3.push_back(2600.0); dist_for_stops3.push_back(2100.0); dist_for_stops3.push_back(2300.0); dist_for_stops3.push_back(2400.0); dist_for_stops3.push_back(2500.0); dist_for_stops3.push_back(2700.0); } */ } /* for such a gline, create a set of points on it */ void BusRoute::CreateStops(int br_id, GLine* gl, Line* l, int route_type,vector dist_for_stops) { ////we have to know it goes from start to end or the other direction///// vector start_from; //or end_from vector sec_list; GetSectionList(gl, sec_list, start_from); /* for(unsigned int i = 0;i < sec_list.size();i++){ SectTreeEntry nEntry = sec_list[i]; cout<<"i "<GetId(),entry.rid,last_sec_gp_pos,None); bus_stop_loc_1.push_back(*gp); // Point* p = new Point(); // gp->ToPoint(p); // bus_stop_loc_2.push_back(*p); Point res; MyToPoint(n, gp, res); assert(res.IsDefined()); bus_stop_loc_2.push_back(res); // delete p; gp->DeleteIfAllowed(); br_id_list.push_back(br_id); br_stop_id.push_back(stop_count + 1); stop_count++; break; } //////////////create more bus stops//////////////////////////////////////// while(true){ double next_stop_dist; if(route_type == 1 || route_type == 2 || route_type == 3) next_stop_dist = dist_for_stops[(stop_count - 1)% dist_for_stops.size()]; else assert(false); /* cout<<"stop_id "< sec_list, unsigned int& last_sec_index,double& last_sec_start, double& last_sec_end, double& last_sec_gp_pos, double next_stop_dist, double dist_to_jun, vector start_from) { if(start_from[last_sec_index]){ //from small to big // int rid; int rid = -1; //still in the same section, very long road section if(fabs(last_sec_gp_pos - last_sec_end) > (next_stop_dist + dist_to_jun)){ last_sec_gp_pos += next_stop_dist; rid = sec_list[last_sec_index].rid; }else{//move to the next road section next_stop_dist -= fabs(last_sec_gp_pos - last_sec_end); for(last_sec_index++;last_sec_index < sec_list.size();last_sec_index++){ double cur_start = sec_list[last_sec_index].start; double cur_end = sec_list[last_sec_index].end; ////////////////////////////////////////////////////// /* cout<<"rid "< 0.0){//if smaller than 0, keep the value, skip the part next_stop_dist = temp_dist; } continue; } if(next_stop_dist - fabs(cur_end - cur_start) < 0){ if(start_from[last_sec_index]){ //from small to big double temp_pos = cur_start + next_stop_dist; if(fabs(temp_pos - cur_start) < dist_to_jun) temp_pos = cur_start + dist_to_jun; if(fabs(cur_end - temp_pos) < dist_to_jun) temp_pos = cur_end - dist_to_jun; last_sec_gp_pos = temp_pos; }else{ //from big to small double temp_pos = cur_end - next_stop_dist; if(fabs(temp_pos - cur_end) < dist_to_jun) temp_pos = cur_end - dist_to_jun; if(fabs(temp_pos - cur_start) < dist_to_jun) temp_pos = cur_start + dist_to_jun; last_sec_gp_pos = temp_pos; } last_sec_start = cur_start; last_sec_end = cur_end; rid = sec_list[last_sec_index].rid; break; }else next_stop_dist -= fabs(cur_end - cur_start); } if(last_sec_index == sec_list.size()) return false; } // cout<<"last_sec_index "<GetId(),rid,last_sec_gp_pos,None); bus_stop_loc_1.push_back(*gp); // Point* p = new Point(); // gp->ToPoint(p); // bus_stop_loc_2.push_back(*p); // delete p; Point res; MyToPoint(n, gp, res); assert(res.IsDefined()); bus_stop_loc_2.push_back(res); gp->DeleteIfAllowed(); return true; }else{///from big to small // cout<<"from big to small"< (next_stop_dist + dist_to_jun)){ last_sec_gp_pos -= next_stop_dist; rid = sec_list[last_sec_index].rid; }else{ next_stop_dist -= fabs(last_sec_gp_pos - last_sec_start); for(last_sec_index++;last_sec_index < sec_list.size();last_sec_index++){ double cur_start = sec_list[last_sec_index].start; double cur_end = sec_list[last_sec_index].end; //////////////////////////////////////////////////////////////// // cout<<"cur_start "< 0.0){//if smaller than 0, keep the value, skip the part next_stop_dist = temp_dist; } continue; } if(next_stop_dist - fabs(cur_end - cur_start) < 0){ if(start_from[last_sec_index]){ //from small to big double temp_pos = cur_start + next_stop_dist; if(fabs(temp_pos - cur_start) < dist_to_jun) temp_pos = cur_start + dist_to_jun; if(fabs(cur_end - temp_pos) < dist_to_jun) temp_pos = cur_end - dist_to_jun; last_sec_gp_pos = temp_pos; }else{ //from big to small // cout<<"next_stop_dist "<GetId(),rid,last_sec_gp_pos,None); bus_stop_loc_1.push_back(*gp); /* Point* p = new Point(); gp->ToPoint(p); bus_stop_loc_2.push_back(*p); delete p;*/ Point res; MyToPoint(n, gp, res); assert(res.IsDefined()); bus_stop_loc_2.push_back(res); gp->DeleteIfAllowed(); return true; } } /* if the bus stops are located on the zebra crossing, we modify the position by a small distance */ void BusRoute::CheckBusStopZC(unsigned int cur_size, Relation* pave_rel, BTree* btree_pave) { for(;cur_size < bus_stop_loc_1.size(); cur_size++){ GPoint gp = bus_stop_loc_1[cur_size]; Point p = bus_stop_loc_2[cur_size]; int rid = gp.GetRouteId(); CcInt* search_id = new CcInt(true, rid); BTreeIterator* btree_iter = btree_pave->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* pave_tuple = pave_rel->GetTuple(btree_iter->GetId(), false); Region* reg = (Region*)pave_tuple->GetAttribute(DualGraph::PAVEMENT); /////////////////bus stops are on the zebra crossing///////////////// if(p.Inside(*reg)){ // cout<<"br id "<GetSectionOnRoute(&gp); double meas1 = ((CcReal*)sec->GetAttribute(SECTION_MEAS1))->GetRealval(); double meas2 = ((CcReal*)sec->GetAttribute(SECTION_MEAS2))->GetRealval(); // cout<DeleteIfAllowed(); double m1 = MIN(meas1, meas2); double m2 = MAX(meas1, meas2); double pos = gp.GetPosition(); assert(pos > m1 && pos < m2); double delta; if((pos - m1) > (m2 - pos)) delta = -2.0; else delta = 2.0; GPoint* new_gp = new GPoint(gp); while(true){ new_gp->SetPosition(new_gp->GetPosition() + delta); Point* new_p = new Point(); // new_gp->ToPoint(new_p); MyToPoint(n, new_gp, *new_p); assert(new_p->IsDefined()); if(new_p->Inside(*reg) == false){ bus_stop_loc_1[cur_size] = *new_gp; bus_stop_loc_2[cur_size] = *new_p; new_p->DeleteIfAllowed(); break; } new_p->DeleteIfAllowed(); assert(new_gp->GetPosition() > m1 && new_gp->GetPosition() < m2); } new_gp->DeleteIfAllowed(); } pave_tuple->DeleteIfAllowed(); } delete btree_iter; search_id->DeleteIfAllowed(); } } /* merge bus stops for several bus stops on the same road section, it might be merge them into one the minimum length of road section is 0.055 the maximum length of road section is 5046.577 we merge bus stops that locate on the same road section */ void BusRoute::CreateBusStop2(int attr1,int attr2,int attr3) { // cout<<"attr1 "< bus_stop_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_stop = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr1))->GetIntval(); /* if(br_id != 108){ tuple_bus_stop->DeleteIfAllowed(); continue; }*/ int stop_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr2))->GetIntval(); GPoint* gp = (GPoint*)tuple_bus_stop->GetAttribute(attr3); // cout<<"br_id "<GetSectionOnRoute(gp); assert(temp != NULL); int sid = n->GetSectionOnRoute(gp)->GetTupleId(); // cout<<*tuple_bus_stop<GetSectionOnRoute(gp)<GetRouteId(), gp->GetPosition(), sid, true); bus_stop_list.push_back(*bs); delete bs; tuple_bus_stop->DeleteIfAllowed(); } sort(bus_stop_list.begin(),bus_stop_list.end()); /* for(int i = 0;i < bus_stop_list.size();i++){ bus_stop_list[i].Print(); }*/ ////////////////take all stops in one route//////////////////////// int count = 0; for(unsigned int i = 0;i < bus_stop_list.size();i++){ unsigned int sid = bus_stop_list[i].sid; vector temp_list; temp_list.push_back(bus_stop_list[i]); while((i + 1)< bus_stop_list.size() && bus_stop_list[i + 1].sid == sid){ i++; temp_list.push_back(bus_stop_list[i]); } MergeBusStop1(temp_list); count += temp_list.size(); } // cout<& stop_list) { // cout<<"stop_list size "<GetId(),stop_list[0].rid,stop_list[0].pos); bus_stop_loc_1.push_back(*gp); /* Point* p = new Point(); gp->ToPoint(p); bus_stop_loc_2.push_back(*p); delete p; */ Point res; MyToPoint(n, gp, res); assert(res.IsDefined()); bus_stop_loc_2.push_back(res); gp->DeleteIfAllowed(); // point_id_list.push_back(point_id); sec_id_list.push_back(stop_list[0].sid); }else{//there are several bus stops on the same road section //to avoid that two bus stops coming from the same bus route are mereged //into one position // const double dist_val = 800.0; //the minimum distance between stops const double dist_val = 300.0; //the minimum distance between stops const double dist_to_jun = 15.0;//minimum distance between bus stop and jun int sec_id = stop_list[0].sid; Tuple* tuple_sec = n->GetSection(sec_id); SimpleLine* curve = (SimpleLine*)tuple_sec->GetAttribute(SECTION_CURVE); if(curve->Length() < dist_val){//merge all stops in one position double final_pos = 0.0; for(unsigned int i = 0;i < stop_list.size();i++){ // cout<<"stop_list pos "<GetId(),stop_list[i].rid,final_pos); bus_stop_loc_1.push_back(*gp); // cout<<"gp "<<*gp<ToPoint(p); MyToPoint(n, gp, *p); assert(p->IsDefined()); bus_stop_loc_2.push_back(*p); p->DeleteIfAllowed(); gp->DeleteIfAllowed(); count1++; sec_id_list.push_back(stop_list[i].sid); } // cout<<"count1 "<GetAttribute(SECTION_MEAS1))->GetRealval(); double sec_pos2 = ((CcReal*)tuple_sec->GetAttribute(SECTION_MEAS2))->GetRealval(); if(sec_pos1 > sec_pos2){ double temp = sec_pos1; sec_pos1 = sec_pos2; sec_pos2 = temp; } // int interval = curve->Length() / dist_val; int interval = (int) (curve->Length() / dist_val); /* cout<<"interval "<Length()<= 0 && interval_pos <= interval); double new_pos = dist_val / 4 + interval_pos*dist_val; if(new_pos > curve->Length()){ // new_pos = interval_pos*dist_val; new_pos = curve->Length() - dist_to_jun; } ///////////////////////////////// new_pos += sec_pos1; ///////////////////////////////// br_id_list.push_back(stop_list[i].br_id); br_stop_id.push_back(stop_list[i].br_stop_id); GPoint* gp = new GPoint(true,n->GetId(),stop_list[i].rid,new_pos); bus_stop_loc_1.push_back(*gp); Point* p = new Point(); // gp->ToPoint(p); MyToPoint(n, gp, *p); assert(p->IsDefined()); bus_stop_loc_2.push_back(*p); p->DeleteIfAllowed(); gp->DeleteIfAllowed(); sec_id_list.push_back(stop_list[i].sid); } } tuple_sec->DeleteIfAllowed(); } } /* Merge bus stops locating on different road sections (adjacent) use a distance threshold value to expand the bus stop (gpoint) to a gline value after changing the position of some bus stops, they should still locate on their original bus route Note: each bus route covers a complete road section or none of it. it can't only cover part of a road section It also calculates the startSmaller value for each bus route. very important value startSmaller. It records whether the simpleline starts from the small or big. The simpleline comes from coverting gline. gline records the shortest path. We have to know after converting where the start point is. */ void BusRoute::CreateBusStop3(int attr,int attr1,int attr2,int attr3) { // cout<<"attr "< bus_stop_list; for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple_bus_stop = rel2->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr1))->GetIntval(); int stop_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr2))->GetIntval(); GPoint* gp = (GPoint*)tuple_bus_stop->GetAttribute(attr3); int sid = n->GetSectionOnRoute(gp)->GetTupleId(); BusStop* bs = new BusStop(br_id,stop_id,gp->GetRouteId(),gp->GetPosition(),sid,true); bus_stop_list.push_back(*bs); delete bs; tuple_bus_stop->DeleteIfAllowed(); } // cout<<"bus_stop_list size "< sec_list; vector start_from; for(unsigned int i = 0;i < bus_stop_list.size();i++){ // if(bus_stop_list[i].br_id > 10) continue; if(bus_stop_list[i].def == false) continue; /////////////////////////////////////////////////////////////////////////// //collect road sections that are with the distance distval to the bus stop/ /////////////////////////////////////////////////////////////////////////// //if it is false, it means the section starts from the big value //instead of the small value if(bus_stop_list[i].br_id != last_br_id){ sec_list.clear(); start_from.clear(); Tuple* tuple_bus_route = rel1->GetTuple(bus_stop_list[i].br_id,false); GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr); GetSectionList(gl, sec_list, start_from); tuple_bus_route->DeleteIfAllowed(); last_br_id = bus_stop_list[i].br_id; /////////////////////////////////////////////////////// assert(sec_list.size() == start_from.size()); /* for(unsigned int j = 0;j < sec_list.size();j++){ cout<<" rid "< sec_down; vector sec_up; //we only consider adjacent section. //the same section has been processed before if(start_from[sec_index]) { if(fabs(bus_stop_list[i].pos - sec_list[sec_index].start) < dist_val){ FindDownSection(bus_stop_list[i].pos,sec_list,sec_index, dist_val,sec_down,start_from); } /////////////// find the down adjacent sections /////////////////////// if(fabs(bus_stop_list[i].pos - sec_list[sec_index].end) < dist_val){ FindUpSection(bus_stop_list[i].pos,sec_list,sec_index, dist_val,sec_up,start_from); } }else{ if(fabs(bus_stop_list[i].pos - sec_list[sec_index].end) < dist_val){ FindDownSection(bus_stop_list[i].pos,sec_list,sec_index, dist_val,sec_down,start_from); } /////////////// find the down adjacent sections /////////////////////// if(fabs(bus_stop_list[i].pos - sec_list[sec_index].start) < dist_val){ FindUpSection(bus_stop_list[i].pos,sec_list,sec_index, dist_val,sec_up,start_from); } } ////////////////////////////////////////////////////////////////////// /* cout<<"bus route down direction"< temp_bus_stop_list; int last_br = 0; const double delta_dist = 50.0; for(unsigned int i = 0;i < bus_stop_list.size();i++){ if(temp_bus_stop_list.size() == 0){ temp_bus_stop_list.push_back(bus_stop_list[i]); last_br = bus_stop_list[i].br_id; }else{ if(bus_stop_list[i].br_id != last_br){ temp_bus_stop_list.push_back(bus_stop_list[i]); last_br = bus_stop_list[i].br_id; }else{ BusStop tmp_bs = temp_bus_stop_list[temp_bus_stop_list.size() - 1]; if(fabs(tmp_bs.pos - bus_stop_list[i].pos) > delta_dist){ int sid1 = tmp_bs.br_stop_id; int sid2 = bus_stop_list[i].br_stop_id; if(fabs(sid1 - sid2) > 1){ if(sid1 < sid2) bus_stop_list[i].br_stop_id = sid1 + 1; else if(sid1 > sid2) bus_stop_list[i].br_stop_id = sid1 - 1; else assert(false); } temp_bus_stop_list.push_back(bus_stop_list[i]); last_br = bus_stop_list[i].br_id; } } } } bus_stop_list.clear(); for(unsigned int i = 0;i < temp_bus_stop_list.size();i++) bus_stop_list.push_back(temp_bus_stop_list[i]); ///////////////////////////////////////////////////////////////////// ///////////////////////get the result/////////////////////////////// for(unsigned int i = 0;i < bus_stop_list.size();i++){ br_id_list.push_back(bus_stop_list[i].br_id); br_stop_id.push_back(bus_stop_list[i].br_stop_id); sec_id_list.push_back(bus_stop_list[i].sid); int rid = bus_stop_list[i].rid; double pos = bus_stop_list[i].pos; GPoint* gp = new GPoint(true,n->GetId(),rid,pos,None); bus_stop_loc_1.push_back(*gp); Point* p = new Point(); // gp->ToPoint(p); MyToPoint(n, gp, *p); assert(p->IsDefined()); bus_stop_loc_2.push_back(*p); p->DeleteIfAllowed(); gp->DeleteIfAllowed(); } ///////////////////////calculate the startsmaller value///////////// unsigned int index = 0; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr); vector start_from; //or end_from vector sec_list; GetSectionList(gl, sec_list, start_from); /////collect bus stops from the same bus route ///// int start = index; while(bus_stop_list[index].br_id == i && index < bus_stop_list.size()){ index++; } int end = index; // cout<<"br_id "< dist_list; ////////////get the startsmaller value ////////////////////////////// Line* l = new Line(0); gl->Gline2line(l); SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); CalculateStartSmaller(bus_stop_list,start,end,sec_list, start_from, dist_list, sl); sl->DeleteIfAllowed(); l->DeleteIfAllowed(); ///////////////////////////////////////////////////////////////////// tuple_bus_route->DeleteIfAllowed(); } assert(bus_stop_list.size() == startSmaller.size()); } /* Merge bus stops that locate on adjacent road sections */ void BusRoute::MergeBusStop2(vector sec_down, vector sec_up, vector& bus_stop_list, int cur_index, int attr) { vector sec_all; for(unsigned int i = 0;i < sec_down.size();i++) sec_all.push_back(sec_down[i]); for(unsigned int i = 0;i < sec_up.size();i++){ if(sec_down.size() > 0 && sec_up[i].secttid == sec_down[0].secttid)continue; //the same section sec_all.push_back(sec_up[i]); } if(sec_all.size() > 0){ vector bus_stop_id_list; for(unsigned int i = 0;i < sec_all.size();i++){ int sec_id = sec_all[i].secttid; double start = sec_all[i].start; double end = sec_all[i].end; /////////collect all bus stops on these sections///////////// CcInt* search_cell_id = new CcInt(true, sec_id); BTreeIterator* btree_iter = btree->ExactMatch(search_cell_id); while(btree_iter->Next()){ int tuple_id = btree_iter->GetId(); if(tuple_id - 1 != cur_index){//do not include itself if(start <= bus_stop_list[tuple_id - 1].pos && bus_stop_list[tuple_id - 1].pos <= end){//bus stop locate on it bus_stop_id_list.push_back(tuple_id - 1); } } } delete btree_iter; search_cell_id->DeleteIfAllowed(); } //check whether the route of the bus stop changed position ///////////// /////////////////has the section id ////////// //do not merge bus stops come from the same route ///////////// vector bus_stop_id_list_new; vector br_id_array; br_id_array.push_back(bus_stop_list[cur_index].br_id); for(unsigned int i = 0;i < bus_stop_id_list.size();i++){ unsigned int j = 0; for(;j < br_id_array.size();j++){ int index = bus_stop_id_list[i]; BusStop bs = bus_stop_list[index]; if(bs.br_id == br_id_array[j]) break; } if(j == br_id_array.size()){ bus_stop_id_list_new.push_back(bus_stop_id_list[i]); BusStop bs = bus_stop_list[bus_stop_id_list[i]]; br_id_array.push_back(bs.br_id); } } // for(unsigned int i = 0;i < bus_stop_id_list.size();i++){ for(unsigned int i = 0;i < bus_stop_id_list_new.size();i++){ // int index = bus_stop_id_list[i]; int index = bus_stop_id_list_new[i]; BusStop bs = bus_stop_list[index]; int br_id = bs.br_id; Tuple* tuple_bus_route = rel1->GetTuple(br_id,false); GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr); vector sec_list; vector start_from; GetSectionList(gl, sec_list, start_from); for(unsigned int j = 0;j < sec_list.size();j++){ if(sec_list[j].secttid == bus_stop_list[cur_index].sid){ //do not move bus stops that come from the same bus route bus_stop_list[index].rid = bus_stop_list[cur_index].rid; bus_stop_list[index].pos = bus_stop_list[cur_index].pos; bus_stop_list[index].sid = bus_stop_list[cur_index].sid; bus_stop_list[cur_index].def = false; bus_stop_list[index].def = false; break; } } tuple_bus_route->DeleteIfAllowed(); } } } /* find the section to down direction. bus route goes down */ void BusRoute::FindDownSection(double cur_bus_stop_pos, vector sec_list,int sec_index, const double dist_val, vector& sec_down,vector start_from) { double temp_dist; if(start_from[sec_index]){ int secttid = sec_list[sec_index].secttid; int rid = sec_list[sec_index].rid; double start = sec_list[sec_index].start; double end = cur_bus_stop_pos; SectTreeEntry* tmp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_down.push_back(*tmp_entry); delete tmp_entry; temp_dist = dist_val - fabs(end - start); }else{ int secttid = sec_list[sec_index].secttid; int rid = sec_list[sec_index].rid; double start = cur_bus_stop_pos; double end = sec_list[sec_index].end; SectTreeEntry* tmp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_down.push_back(*tmp_entry); delete tmp_entry; temp_dist = dist_val - fabs(end - start); } int temp_index = sec_index; while(temp_dist > 0.0){ temp_index--; if(temp_index >= 0){ SectTreeEntry entry = sec_list[temp_index]; if(temp_dist - fabs(entry.start - entry.end) > 0){ sec_down.push_back(entry); temp_dist -= fabs(entry.start - entry.end); }else{ if(start_from[temp_index] == false){ int secttid = entry.secttid; int rid = entry.rid; double start = entry.start; double end = start + temp_dist; SectTreeEntry* temp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_down.push_back(*temp_entry); delete temp_entry; temp_dist -= fabs(entry.start - entry.end); }else{ int secttid = entry.secttid; int rid = entry.rid; double start = entry.end - temp_dist; double end = entry.end; SectTreeEntry* temp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_down.push_back(*temp_entry); delete temp_entry; temp_dist -= fabs(entry.start - entry.end); } } }else break; } } /* find the section to up direction. bus route goes up */ void BusRoute::FindUpSection(double cur_bus_stop_pos, vector sec_list,int sec_index, const double dist_val, vector& sec_up,vector start_from) { double temp_dist; if(start_from[sec_index]){ int secttid = sec_list[sec_index].secttid; int rid = sec_list[sec_index].rid; double start = cur_bus_stop_pos; double end = sec_list[sec_index].end; SectTreeEntry* tmp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_up.push_back(*tmp_entry); delete tmp_entry; temp_dist = dist_val - fabs(end - start); }else{ int secttid = sec_list[sec_index].secttid; int rid = sec_list[sec_index].rid; double start = sec_list[sec_index].start; double end = cur_bus_stop_pos; SectTreeEntry* tmp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_up.push_back(*tmp_entry); delete tmp_entry; temp_dist = dist_val - fabs(end - start); } unsigned int temp_index = sec_index; while(temp_dist > 0.0){ temp_index++; if(temp_index < sec_list.size()){ SectTreeEntry entry = sec_list[temp_index]; if(temp_dist - fabs(entry.start - entry.end) > 0){ sec_up.push_back(entry); temp_dist -= fabs(entry.start - entry.end); }else{ if(start_from[temp_index]){ int secttid = entry.secttid; int rid = entry.rid; double start = entry.start; double end = start + temp_dist; SectTreeEntry* temp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_up.push_back(*temp_entry); delete temp_entry; temp_dist -= fabs(entry.start - entry.end); }else{ int secttid = entry.secttid; int rid = entry.rid; double start = entry.end - temp_dist; double end = entry.end; SectTreeEntry* temp_entry = new SectTreeEntry(secttid,rid,start,end,true,true); sec_up.push_back(*temp_entry); delete temp_entry; temp_dist -= fabs(entry.start - entry.end); } } }else break; } } /* convert a gline object to a list of section representations */ void BusRoute::GetSectionList(GLine* gl,vector& sec_list, vector& start_from) { ////////////////////////////////////////////////////////////////////////// for(int i = 0; i < gl->Size();i++){ RouteInterval* ri = new RouteInterval(); gl->Get(i, *ri); // cout<<"rid "<GetRouteId() // <<"start "<GetStartPos() // <<"end "<GetEndPos()<GetStartPos(), ri->GetEndPos())){ vector actSections; n->GetSectionsOfRouteInterval(ri,actSections); SectTreeEntry nEntry; vector sec_list_temp; for(unsigned int j = 0;j < actSections.size();j++){ nEntry = actSections[j]; //////////////////////////////////////////////////// // cout<<"entry "<GetStartPos() < ri->GetEndPos()) start_from.push_back(true); else start_from.push_back(false); } if(ri->GetStartPos() < ri->GetEndPos()){ for(unsigned int k = 0;k < sec_list_temp.size();k++) sec_list.push_back(sec_list_temp[k]); }else{ for(int k = sec_list_temp.size() - 1;k >= 0;k--) sec_list.push_back(sec_list_temp[k]); } } delete ri; } } /* change the representation for bus stop, get the pos value. i.e., the relative position on its bus route */ void BusRoute::CalculateStartSmaller(vector& bus_stop_list, int start, int end, vector& sec_list, vector& start_from, vector& dist_list, SimpleLine* sl) { // cout<<"start "<GetId(), rid, pos, None); Point* p = new Point(); // gp->ToPoint(p); MyToPoint(n, gp, *p); assert(p->IsDefined()); ////////////////////////////////////////////////////////////// if(initialize == false){ Point temp_p; assert(sl->AtPosition(dist, true, temp_p)); const double dist_delta = 1.0; if(temp_p.Distance(*p) < dist_delta) startsmaller = true; else startsmaller = false; initialize = true; /* cout<<"loc1 "<<*p<<" loc2 "<DeleteIfAllowed(); gp->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// bus_stop_index++; dist -= temp_dist; } if(bus_stop_list[bus_stop_index].sid != sec_id) dist += fabs(start - end); } assert((int)dist_list.size() == (end - start)); } /* change the position of bus stops after translate the bus route: down and up and for each route, it gets pos value. bus stops on up direction are from small to big bus tops on down direction are from big to small, but the pos value is set according to the smaller start point */ void BusRoute::CreateBusStop4(int attr_a,int attr_b,int attr1,int attr2, int attr3, int attr4) { // cout<<"attr_a "< bus_stop_list; for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple_bus_stop = rel2->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr1))->GetIntval(); int stop_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr2))->GetIntval(); Point* loc = (Point*)tuple_bus_stop->GetAttribute(attr3); bool start_small = ((CcBool*)tuple_bus_stop->GetAttribute(attr4))->GetBoolval(); BusStop_Ext* bse = new BusStop_Ext(br_id,stop_id,0,*loc,start_small); bus_stop_list.push_back(*bse); delete bse; tuple_bus_stop->DeleteIfAllowed(); } sort(bus_stop_list.begin(), bus_stop_list.end()); /* for(unsigned int i = 0;i < bus_stop_list.size();i++) bus_stop_list[i].Print(); */ vector line_list1; vector line_list2; vector sline_list; vector bus_route_direction; for(int i = 1;i <= rel1->GetNoTuples();i+= 2){ Tuple* tuple_bus_route1 = rel1->GetTuple(i, false); Tuple* tuple_bus_route2 = rel1->GetTuple(i + 1, false); Line* l = (Line*)tuple_bus_route1->GetAttribute(attr_a); Line* l1 = (Line*)tuple_bus_route1->GetAttribute(attr_b); Line* l2 = (Line*)tuple_bus_route2->GetAttribute(attr_b); SimpleLine* sl1 = new SimpleLine(0); SimpleLine* sl2 = new SimpleLine(0); sl1->fromLine(*l1); sl2->fromLine(*l2); line_list1.push_back(*l); line_list2.push_back(*l1); line_list2.push_back(*l2); sline_list.push_back(*sl1); sline_list.push_back(*sl2); if(sl1->Length() < 1.0 || sl2->Length() < 1.0){ cout<DeleteIfAllowed(); sl2->DeleteIfAllowed(); tuple_bus_route1->DeleteIfAllowed(); tuple_bus_route2->DeleteIfAllowed(); } // cout<<"line list size "< bus_stop_list_new; bus_stop_list_new.push_back(bus_stop_list[i]); ////////collect all bus stops mapping to the same 2D point in space///// unsigned int j = i + 1; BusStop_Ext bse = bus_stop_list_new[0]; while(j < bus_stop_list.size() && bus_stop_list[j].loc.Distance(bse.loc) < dist_delta ){ bus_stop_list_new.push_back(bus_stop_list[j]); j++; } i = j - 1; ////////////get the intersection point////////////////////////////// BusStop_Ext bse_0 = bus_stop_list_new[0]; // bse_0.Print(); Line* l = &line_list1[bse_0.br_id - 1]; HalfSegment hs; int index = -1; double hs_p_dist = numeric_limits::max(); int temp_index = -1; for(index = 0;index < l->Size();index++){ l->Get(index, hs); if(hs.IsLeftDomPoint() == false)continue; if(hs.Contains(bse_0.loc))break; if(hs.Distance(bse_0.loc) < hs_p_dist){ //solve numeric problem hs_p_dist = hs.Distance(bse_0.loc); temp_index = index; } } if(index == -1 || index == l->Size()){ if(temp_index != -1){ l->Get(temp_index, hs); }else{ cout<<"can't find the point (might be numeric problem)"< intersect_ps; GetInterestingPoints(hs, bse_0.loc, intersect_ps, l1, l2); assert(intersect_ps.size() == 2); // cout<<"0 "<AtPoint(intersect_ps[0].loc,sm,pos1)); // assert(sl2->AtPoint(intersect_ps[1].loc,sm,pos2)); //to solve numeric problem if(sl1->AtPoint(intersect_ps[0].loc,sm,pos1) == false) assert(MyAtPoint(sl1,intersect_ps[0].loc,sm,pos1,dist_delta)); //to solve numeric problem if(sl2->AtPoint(intersect_ps[1].loc,sm,pos2) == false) assert(MyAtPoint(sl2,intersect_ps[1].loc,sm,pos2,dist_delta)); // cout<<"pos1 "<& list, Line* reg1, Line* reg2) { Point p1 = hs.GetLeftPoint(); Point p2 = hs.GetRightPoint(); const double delta_dist = 10.0; Line* line1 = new Line(0); if(MyAlmostEqual(p1.GetX(), p2.GetX())){ double y = ip.GetY(); double x1 = ip.GetX() - delta_dist; double x2 = ip.GetX() + delta_dist; line1->StartBulkLoad(); HalfSegment hs; Point lp,rp; lp.Set(x1, y); rp.Set(x2, y); hs.Set(true,lp,rp); int edgeno = 0; hs.attr.edgeno = edgeno++; *line1 += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *line1 += hs; line1->EndBulkLoad(); }else if(MyAlmostEqual(p1.GetY(), p2.GetY())){ double y1 = ip.GetY() - delta_dist; double y2 = ip.GetY() + delta_dist; double x = ip.GetX(); line1->StartBulkLoad(); HalfSegment hs; Point lp,rp; lp.Set(x, y1); rp.Set(x, y2); hs.Set(true,lp,rp); int edgeno = 0; hs.attr.edgeno = edgeno++; *line1 += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *line1 += hs; line1->EndBulkLoad(); }else{//not vertical double k1 = (p2.GetY() - p1.GetY())/(p2.GetX() - p1.GetX()); double k2 = -1/k1; double c2 = ip.GetY() - ip.GetX()*k2; double x1 = ip.GetX() - delta_dist; double x2 = ip.GetX() + delta_dist; line1->StartBulkLoad(); HalfSegment hs; Point lp,rp; lp.Set(x1, x1*k2 + c2); rp.Set(x2, x2*k2 + c2); hs.Set(true,lp,rp); int edgeno = 0; hs.attr.edgeno = edgeno++; *line1 += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *line1 += hs; line1->EndBulkLoad(); } // cout<<"ip "<Crossings(*reg1, *ps1); line1->Crossings(*reg2, *ps2); // cout<Size()<<" "<Size()<Size()<<" "<Size()<Size() ==0 || ps2->Size() == 0){ SpacePartition* sp = new SpacePartition(); vector temp1; for(int i = 0;i < reg1->Size();i++){ HalfSegment hs; reg1->Get(i, hs); if(!hs.IsLeftDomPoint()) continue; Point cp; sp->GetClosestPoint(hs, ip , cp); MyPoint mp(cp, ip.Distance(cp)); temp1.push_back(mp); } sort(temp1.begin(),temp1.end()); list.push_back(temp1[0]); vector temp2; for(int i = 0;i < reg2->Size();i++){ HalfSegment hs; reg2->Get(i, hs); if(!hs.IsLeftDomPoint()) continue; Point cp; sp->GetClosestPoint(hs, ip , cp); MyPoint mp(cp, ip.Distance(cp)); temp2.push_back(mp); } sort(temp2.begin(),temp2.end()); list.push_back(temp2[0]); delete sp; ps1->DeleteIfAllowed(); ps2->DeleteIfAllowed(); line1->DeleteIfAllowed(); return; } assert(ps1->Size() >= 1 && ps2->Size() >= 1); // cout<<*ps1<<" "<<*ps2< temp1; for(int i = 0;i Size();i++){ Point p; ps1->Get(i,p); MyPoint mp(p, p.Distance(ip)); temp1.push_back(mp); } sort(temp1.begin(),temp1.end()); list.push_back(temp1[0]); vector temp2; for(int i = 0;i Size();i++){ Point p; ps2->Get(i,p); MyPoint mp(p, p.Distance(ip)); temp2.push_back(mp); } sort(temp2.begin(),temp2.end()); list.push_back(temp2[0]); ps1->DeleteIfAllowed(); ps2->DeleteIfAllowed(); line1->DeleteIfAllowed(); } /* If the original SimpleLine::AtPoint does not work. use this one. It uses the distance (a very small distance) between the point and halfsegment to determine whether the point locates on the simpleline */ bool BusRoute::MyAtPoint(SimpleLine* sl, Point& loc, bool sm, double& res, double dist_delta) { SpacePartition* sp = new SpacePartition(); vector seq_halfseg; //reorder it from start to end sp->ReorderLine(sl, seq_halfseg); bool find = false; double pos = 0.0; if(sm){ for(unsigned int i = 0;i < seq_halfseg.size();i++){ HalfSegment hs(true,seq_halfseg[i].from,seq_halfseg[i].to); if(hs.Distance(loc) < dist_delta){ pos += loc.Distance(seq_halfseg[i].from); res = pos; find = true; break; }else pos += hs.Length(); } }else{ for(int i = seq_halfseg.size() - 1;i >= 0;i--){ HalfSegment hs(true,seq_halfseg[i].from,seq_halfseg[i].to); if(hs.Distance(loc) < dist_delta){ pos += loc.Distance(seq_halfseg[i].to); res = pos; find = true; break; }else pos += hs.Length(); } } delete sp; return find; } /* for the two new generated bus routes, it sets the up and down value */ void BusRoute::CreateRoute4(int attr1, int attr2, int attr3, int attr4, int attr_a, int attr_b) { // cout<<"attr1 "< start_small_list; int last_br_id = 0; for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple_bus_stop = rel2->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr_a))->GetIntval(); bool sm = ((CcBool*)tuple_bus_stop->GetAttribute(attr_b))->GetBoolval(); if(start_small_list.size() == 0){ start_small_list.push_back(sm); last_br_id = br_id; } else{ if(br_id != last_br_id){ last_br_id = br_id; start_small_list.push_back(sm); } } tuple_bus_stop->DeleteIfAllowed(); } // cout<<"start_small_list size "<GetNoTuples() / 2); for(int i = 1;i <= rel1->GetNoTuples();i+=2){ Tuple* tuple_bus_route1 = rel1->GetTuple(i, false); Tuple* tuple_bus_route2 = rel1->GetTuple(i + 1, false); int br_id1 = ((CcInt*)tuple_bus_route1->GetAttribute(attr1))->GetIntval(); int br_id2 = ((CcInt*)tuple_bus_route2->GetAttribute(attr1))->GetIntval(); assert(br_id1 == br_id2); Line* l1 = (Line*)tuple_bus_route1->GetAttribute(attr2); Line* l2 = (Line*)tuple_bus_route2->GetAttribute(attr2); SimpleLine* sl1 = new SimpleLine(0); SimpleLine* sl2 = new SimpleLine(0); sl1->fromLine(*l1); sl2->fromLine(*l2); // cout<DeleteIfAllowed(); sl2->DeleteIfAllowed(); int route_type1 = ((CcInt*)tuple_bus_route1->GetAttribute(attr3))->GetIntval(); int route_type2 = ((CcInt*)tuple_bus_route2->GetAttribute(attr3))->GetIntval(); int br_uid_1 = ((CcInt*)tuple_bus_route1->GetAttribute(attr4))->GetIntval(); int br_uid_2 = ((CcInt*)tuple_bus_route2->GetAttribute(attr4))->GetIntval(); br_id_list.push_back(br_id1); br_id_list.push_back(br_id2); bus_sections1.push_back(*l1); bus_sections1.push_back(*l2); bus_route_type.push_back(route_type1); bus_route_type.push_back(route_type2); br_uid_list.push_back(br_uid_1); br_uid_list.push_back(br_uid_2); ///////////////////add the startsmaller value ///////////////////////// startSmaller.push_back(start_small_list[br_id1 - 1]); startSmaller.push_back(start_small_list[br_id1 - 1]); tuple_bus_route1->DeleteIfAllowed(); tuple_bus_route2->DeleteIfAllowed(); } assert(startSmaller.size() == br_id_list.size()); } /* define the up and down for each route. if it is up, the bus stop id increases if it is down, the bus stop id decreases use l1, and l2 to build a cycle. use the cycle (counter-clockwise or clockwise) to determine the direction for l1 and l2. we also have to the start smaller value because it needs to identify where the route starts We assume all buses moving on the right side of the road (Germany,China) */ void BusRoute::CalculateUpandDown( SimpleLine* sl1, SimpleLine* sl2, bool sm) { SpacePartition* sp = new SpacePartition(); vector seq_halfseg1; //reorder it from start to end sp->ReorderLine(sl1, seq_halfseg1); vector seq_halfseg2; //reorder it from start to end sp->ReorderLine(sl2, seq_halfseg2); assert(sl1->Size() >= 2); assert(sl2->Size() >= 2); vector point_list; //assume we start from sl1 (up direction) if(sm){ unsigned int index1 = 0; unsigned int index2 = 1; point_list.push_back(seq_halfseg1[index1].from); point_list.push_back(seq_halfseg1[index2].from); point_list.push_back(seq_halfseg1[index2].to); point_list.push_back(seq_halfseg2[index2].to); point_list.push_back(seq_halfseg2[index2].from); point_list.push_back(seq_halfseg2[index1].from); }else{ unsigned int index1 = seq_halfseg1.size() - 1; unsigned int index2 = seq_halfseg1.size() - 2; // cout<<"index1 "< regs; sp->ComputeRegion(point_list,regs); assert(regs.size() == 1); delete sp; CompTriangle* ct = new CompTriangle(); bool clock_wise = ct->GetClockwise(point_list); if(clock_wise){ // cout<<"l1 "< br_direction; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); bool direction = ((CcBool*)tuple_bus_route->GetAttribute(attr))->GetBoolval(); br_direction.push_back(direction); tuple_bus_route->DeleteIfAllowed(); } // cout<<"direction size "<GetNoTuples();i++){ Tuple* tuple_bus_stop = rel2->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr1))->GetIntval(); int br_uid = ((CcInt*)tuple_bus_stop->GetAttribute(attr2))->GetIntval(); int stop_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr3))->GetIntval(); Point* loc = (Point*)tuple_bus_stop->GetAttribute(attr4); double pos = ((CcReal*)tuple_bus_stop->GetAttribute(attr5))->GetRealval(); assert(br_uid == br_id *2 - 1 || br_uid == br_id * 2); bool direction = br_direction[br_uid - 1]; br_id_list.push_back(br_id); br_uid_list.push_back(br_uid); br_stop_id.push_back(stop_id); start_gp.push_back(*loc); bus_stop_loc_3.push_back(pos); bus_stop_flag.push_back(direction); tuple_bus_stop->DeleteIfAllowed(); } } /* create bus stops relations with the data type busstop */ void BusRoute::GetBusStops() { for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* br_tuple = rel2->GetTuple(i, false); int br_id = ((CcInt*)br_tuple->GetAttribute(RoadDenstiy::BR_ID6))->GetIntval(); bool direction = ((CcBool*)br_tuple->GetAttribute(RoadDenstiy::BR_DIRECTION))->GetBoolval(); int br_uid = ((CcInt*)br_tuple->GetAttribute(RoadDenstiy::BR_RUID))->GetIntval(); CcInt* search_id = new CcInt(true, br_id); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int count = 0; while(btree_iter->Next()){ Tuple* bs_tuple = rel1->GetTuple(btree_iter->GetId(), false); bool d = ((CcBool*)bs_tuple->GetAttribute(RoadDenstiy::STOP_DIRECTION))->GetBoolval(); if(direction == d){ int br_id_s = ((CcInt*)bs_tuple->GetAttribute(RoadDenstiy::BR_ID4))->GetIntval(); int br_uid_s = ((CcInt*)bs_tuple->GetAttribute(RoadDenstiy::BR_UID))->GetIntval(); assert(br_id_s == br_id); assert(br_uid == br_uid_s); int s_id = ((CcInt*)bs_tuple->GetAttribute(RoadDenstiy::BUS_STOP_ID))->GetIntval(); Point* loc = (Point*)bs_tuple->GetAttribute(RoadDenstiy::BUS_LOC); // cout<<"busstop_rid "<DeleteIfAllowed(); } delete btree_iter; search_id->DeleteIfAllowed(); br_tuple->DeleteIfAllowed(); } } /* create bus routes represented by the data type busroute */ void BusRoute::GetBusRoutes() { for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* br_tuple = rel2->GetTuple(i, false); int br_id = ((CcInt*)br_tuple->GetAttribute(RoadDenstiy::BR_ID6))->GetIntval(); // cout<<"br_id "<GetAttribute(RoadDenstiy::BR_DIRECTION))->GetBoolval(); bool small = ((CcBool*)br_tuple->GetAttribute(RoadDenstiy::BR_STARTSMALLER))->GetBoolval(); Line* l = (Line*)br_tuple->GetAttribute(RoadDenstiy::BR_GEODATA); CcInt* search_id = new CcInt(true, br_id); BTreeIterator* btree_iter = btree->ExactMatch(search_id); vector tid_list; while(btree_iter->Next()){ Tuple* bs_tuple = rel1->GetTuple(btree_iter->GetId(), false); bool d = ((CcBool*)bs_tuple->GetAttribute(RoadDenstiy::STOP_DIRECTION))->GetBoolval(); if(direction == d){ tid_list.push_back(bs_tuple->GetTupleId()); } bs_tuple->DeleteIfAllowed(); } SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); CreateRoutes(tid_list, br_id, sl, small, direction); sl->DeleteIfAllowed(); delete btree_iter; search_id->DeleteIfAllowed(); br_tuple->DeleteIfAllowed(); } } /* sort bus stops of one route by stop id */ bool CompareBusStopExt(const BusStop_Ext& bs1, const BusStop_Ext& bs2) { if(bs1.br_stop_id < bs2.br_stop_id) return true; else return false; } /* create a bus route consisting of a set of bus segments. there is a restriction of bus routes. before the first stop and after the last stop, there are also some bus segments */ void BusRoute::CreateRoutes(vector& tid_list, int br_id, SimpleLine* sl, bool small, bool direction) { vector bslist; for(unsigned int i = 0;i < tid_list.size();i++){ Tuple* bs_tuple = rel1->GetTuple(tid_list[i], false); int bs_id = ((CcInt*)bs_tuple->GetAttribute(RoadDenstiy::BR_ID4))->GetIntval(); assert(bs_id == br_id); double pos = ((CcReal*)bs_tuple->GetAttribute(RoadDenstiy::BUS_POS))->GetRealval(); Point* loc = (Point*)bs_tuple->GetAttribute(RoadDenstiy::BUS_LOC); int s_id = ((CcInt*)bs_tuple->GetAttribute(RoadDenstiy::BUS_STOP_ID))->GetIntval(); BusStop_Ext bs(bs_id, s_id, pos, *loc, small); bslist.push_back(bs); bs_tuple->DeleteIfAllowed(); } const double delta_dist = 0.001; sort(bslist.begin(), bslist.end(), CompareBusStopExt); Bus_Route* br = new Bus_Route(br_id, direction); br->StartBulkLoad(); int count = 0; SpacePartition* sp_pt = new SpacePartition(); vector mhs; sp_pt->ReorderLine(sl, mhs); delete sp_pt; for(unsigned int i = 0;i < bslist.size() - 1;i++){//ordered by stop id Point loc1 = bslist[i].loc; Point loc2 = bslist[i + 1].loc; // cout<<"br_id "< 0.0 && !AlmostEqual(pos1, sl->Length())); double l1; double l2; if(pos1 > pos2){ l1 = pos1; l2 = sl->Length(); }else{ l1 = 0.0; l2 = pos1; } SimpleLine sub_line(0); if(sl->GetStartSmaller()) sl->SubLine(l1, l2, sl->GetStartSmaller(), sub_line); else sl->SubLine(l2, l1, sl->GetStartSmaller(), sub_line); assert(AlmostEqual(sub_line.Length(), l2 - l1)); Point p1, p2; sub_line.AtPosition(0.0, sub_line.GetStartSmaller() ,p1); sub_line.AtPosition(sub_line.Length(), sub_line.GetStartSmaller(), p2); //bool startSmaller; if(loc1.Distance(p1) < delta_dist){ // startSmaller = !sub_line.GetStartSmaller(); ; }else if(loc1.Distance(p2) < delta_dist){ //startSmaller = sub_line.GetStartSmaller(); ; }else assert(false); br->Add(&sub_line, count); count++; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// double len1, len2; if(pos1 > pos2){ len1 = pos2; len2 = pos1; }else{ len1 = pos1; len2 = pos2; } SimpleLine sub_l(0); if(sl->GetStartSmaller()){ sl->SubLine(len1, len2, sl->GetStartSmaller(), sub_l); }else{ sl->SubLine(len2, len1, sl->GetStartSmaller(), sub_l); } assert(AlmostEqual(sub_l.Length(), fabs(pos2 - pos1))); Point sp, ep; sub_l.AtPosition(0.0, sub_l.GetStartSmaller() ,sp); sub_l.AtPosition(sub_l.Length(), sub_l.GetStartSmaller(), ep); // cout<<"sp "<Add(&sub_l, count); count++; //////////////////////////////////////////////////////////////////////// ////////////////////the segment after the last stop////////////////////// ///////////////////////////////////////////////////////////////////////// if(i == bslist.size() - 2){ assert(pos2 > 0.0 && !AlmostEqual(pos2, sl->Length())); double l1; double l2; if(pos1 > pos2){ l1 = 0.0; l2 = pos2; }else{ l1 = pos2; l2 = sl->Length(); } SimpleLine sub_line(0); if(sl->GetStartSmaller()) sl->SubLine(l1, l2, sl->GetStartSmaller(), sub_line); else sl->SubLine(l2, l1, sl->GetStartSmaller(), sub_line); assert(AlmostEqual(sub_line.Length(), l2 - l1)); Point p1, p2; sub_line.AtPosition(0.0, sub_line.GetStartSmaller() ,p1); sub_line.AtPosition(sub_line.Length(), sub_line.GetStartSmaller(), p2); //bool startSmaller; //for the last bus segment, the point corresponds to the start point if(loc2.Distance(p1) < delta_dist){//the last segment is different //startSmaller = sub_line.GetStartSmaller(); ; }else if(loc2.Distance(p2) < delta_dist){ //startSmaller = !sub_line.GetStartSmaller(); ; }else assert(false); br->Add(&sub_line, count); count++; } } ///////////////////////////////////////////////////////////////////////// br->EndBulkLoad(); br_id_list.push_back(br_id); bus_route_list.push_back(*br); br->DeleteIfAllowed(); } /* due to numeric problem, use the following method to find pos for a point on a sline */ void BusRoute::GetPosOnSL(SimpleLine* sl, Point loc, double& pos, vector& mhs) { ////////get the start point of sline ///////////// Point start_loc; assert(sl->AtPosition(0.0, sl->StartsSmaller(), start_loc)); /////////convert to myhalfsegment///////////////// SpacePartition* sp = new SpacePartition(); ////////use getclosespoint////////////////////// const double delta_d = 0.001; if(mhs[0].from.Distance(start_loc) < delta_d){ double len = 0; unsigned int i = 0; for(;i < mhs.size();i++){ HalfSegment hs(true, mhs[i].from, mhs[i].to); Point res; sp->GetClosestPoint_New(hs, loc, res); if(res.Distance(loc) < delta_d){ len += res.Distance(mhs[i].from); pos = len; break; }else{ len += hs.Length(); } } if(i == mhs.size())assert(false); }else if(mhs[mhs.size() - 1].to.Distance(start_loc) < delta_d){ double len = 0; int i = mhs.size() - 1; for(;i >= 0;i--){ HalfSegment hs(true, mhs[i].from, mhs[i].to); Point res; sp->GetClosestPoint_New(hs, loc, res); if(res.Distance(loc) < delta_d){ len += res.Distance(mhs[i].to); pos = len; break; }else{ len += hs.Length(); } } if(i < 0)assert(false); }else{ cout<<"should not be here"<AtPosition(pos,sl->StartsSmaller(), test)); assert(test.Distance(loc) < delta_d); } /*void BusRoute::GetPosOnSL(SimpleLine* sl, Point loc, double& pos) { ////////get the start point of sline ///////////// Point start_loc; assert(sl->AtPosition(0.0, sl->StartsSmaller(), start_loc)); /////////convert to myhalfsegment///////////////// SpacePartition* sp = new SpacePartition(); vector mhs; sp->ReorderLine(sl, mhs); ////////use getclosespoint////////////////////// const double delta_d = 0.001; if(mhs[0].from.Distance(start_loc) < delta_d){ double len = 0; unsigned int i = 0; for(;i < mhs.size();i++){ HalfSegment hs(true, mhs[i].from, mhs[i].to); Point res; sp->GetClosestPoint_New(hs, loc, res); if(res.Distance(loc) < delta_d){ len += res.Distance(mhs[i].from); pos = len; break; }else{ len += hs.Length(); } } if(i == mhs.size())assert(false); }else if(mhs[mhs.size() - 1].to.Distance(start_loc) < delta_d){ double len = 0; int i = mhs.size() - 1; for(;i >= 0;i--){ HalfSegment hs(true, mhs[i].from, mhs[i].to); Point res; sp->GetClosestPoint_New(hs, loc, res); if(res.Distance(loc) < delta_d){ len += res.Distance(mhs[i].to); pos = len; break; }else{ len += hs.Length(); } } if(i < 0)assert(false); }else{ cout<<"should not be here"<AtPosition(pos,sl->StartsSmaller(), test)); assert(test.Distance(loc) < delta_d); }*/ ////////////////////////////////////////////////////////////////////////////// // use the road density data to set time schedule for each bus route /// ///////////////////////////////////////////////////////////////////////////// string RoadDenstiy::bus_route_speed_typeinfo = "(rel (tuple ((br_id int) (br_pos real) (speed_limit real)\ (route_segment line))))"; string RoadDenstiy::bus_stop_typeinfo = "(rel (tuple ((Br_id int) (Br_uid int) (Bus_stop_id int) (Bus_stop point)\ (Bus_pos real) (Stop_direction bool))))"; string RoadDenstiy::night_sched_typeinfo = "(rel (tuple ((br_id int) (duration1 periods) (duration2 periods) (br_interval\ real))))"; string RoadDenstiy::day_sched_typeinfo = "(rel (tuple ((br_id int) (duration1 periods) (duration2 periods) (br_interval1\ real) (br_interval2 real))))"; string RoadDenstiy::mo_bus_typeinfo = "(rel (tuple ((br_id int) (bus_direction bool) (bus_trip mpoint) (bus_type \ string) (bus_day string) (schedule_id int))))"; string RoadDenstiy::bus_route_typeinfo = "(rel (tuple ((Br_id int) (Bus_route line) (Route_type int) (Br_uid int)\ (Bus_direction bool) (StartSmaller bool))))"; string RoadDenstiy::bus_route_old_typeinfo = "(rel (tuple ((br_id int) (bus_route1 gline) (bus_route2 line)\ (start_loc point) (end_loc point) (route_type int))))"; /* get night buses. use the network flow value. for night bus, we don't dinstinguish Sunday and Workday */ void RoadDenstiy::GetNightRoutes(int attr1, int attr2, int attr_a, int attr_b,Periods* peri1, Periods* peri2) { // cout<<"attr1 "< periods1; Interval periods2; peri1->Get(0, periods1); peri2->Get(0, periods2); // cout<GetNoTuples();i++){ Tuple* tuple_bus_stop = rel2->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(attr_a))->GetIntval(); GLine* gl = (GLine*)tuple_bus_stop->GetAttribute(attr_b); // cout<<*gl< start_from; vector sec_list; br->GetSectionList(gl, sec_list, start_from); int traffic_num = 0; Interval time_span1 = periods1; Interval time_span2 = periods2; for(unsigned int j = 0;j < sec_list.size();j++){ int secid = sec_list[j].secttid; /////////////use btree to find the section///////////////// CcInt* search_sec_id = new CcInt(true, secid); BTreeIterator* btree_iter = btree->ExactMatch(search_sec_id); while(btree_iter->Next()){ Tuple* tuple_traffic = rel1->GetTuple(btree_iter->GetId(), false); MInt* flow = (MInt*)tuple_traffic->GetAttribute(attr2); // cout<<*flow<GetNoComponents();k++){ UInt cur_uint; flow->Get(k,cur_uint); if(periods1.Intersects(cur_uint.timeInterval)){ // cout<<"1"< time_span1.start && cur_uint.timeInterval.start < time_span1.end){ time_span1.start = cur_uint.timeInterval.start; } if(cur_uint.timeInterval.end < time_span1.end && cur_uint.timeInterval.end > time_span1.start) time_span1.end = cur_uint.timeInterval.end; } if(periods2.Intersects(cur_uint.timeInterval)){ // cout<<"2"< time_span2.start && cur_uint.timeInterval.start < time_span2.end) time_span2.start = cur_uint.timeInterval.start; if(cur_uint.timeInterval.end < time_span2.end && cur_uint.timeInterval.end > time_span2.start) time_span2.end = cur_uint.timeInterval.end; } } tuple_traffic->DeleteIfAllowed(); } delete btree_iter; search_sec_id->DeleteIfAllowed(); ////////////////////////////////////////////////////////// } delete br; tuple_bus_stop->DeleteIfAllowed(); br_id_list.push_back(br_id); traffic_no.push_back(traffic_num); Periods* p1 = new Periods(0); p1->StartBulkLoad(); p1->MergeAdd(time_span1); p1->EndBulkLoad(); duration1.push_back(*p1); p1->DeleteIfAllowed(); Periods* p2 = new Periods(0); p2->StartBulkLoad(); p2->MergeAdd(time_span2); p2->EndBulkLoad(); duration2.push_back(*p2); p2->DeleteIfAllowed(); } } /* create time interval for each night bus it returns brid, time interval for each schedule and two intervals each interval records the first and last schedule time instant of this route */ void RoadDenstiy::SetTSNightBus(int attr1,int attr2, int attr3, Periods* peri1, Periods* peri2) { // cout<<"attr1 "<GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); Periods* time1 = (Periods*)tuple_bus_route->GetAttribute(attr2); Periods* time2 = (Periods*)tuple_bus_route->GetAttribute(attr3); Interval time_span1; Interval time_span2; Interval interval1; Interval interval2; time1->Get(0, interval1); time2->Get(0, interval2); int h1 = interval1.start.GetHour(); int h2 = interval2.start.GetHour(); if(h1 > h2){ double m = CalculateTimeSpan1(time1, peri1,time_span1,i); CalculateTimeSpan2(peri2,time_span2,m); }else{ double m = CalculateTimeSpan1(time2, peri2,time_span2,i); CalculateTimeSpan2(peri1,time_span1,m); } br_id_list.push_back(br_id); // duration1.push_back(*time1); // duration2.push_back(*time2); // cout<StartBulkLoad(); p1->MergeAdd(time_span1); p1->EndBulkLoad(); duration1.push_back(*p1); p1->DeleteIfAllowed(); Periods* p2 = new Periods(0); p2->StartBulkLoad(); p2->MergeAdd(time_span2); p2->EndBulkLoad(); duration2.push_back(*p2); p2->DeleteIfAllowed(); time_interval.push_back(1.0/24.0); //1 means 1 day , 1.0/24.0 = 1 hour tuple_bus_route->DeleteIfAllowed(); } } /* create time interval for each daytime bus it returns brid, time interval for each schedule and two intervals each interval records the first and last schedule time instant of this route the time interval for Monday and Sunday is different the start time for Monday and Sunday is also different streets have high density are closeer to city and longer than those low density streets */ void RoadDenstiy::SetTSDayTimeBus(int attr1,int attr2, int attr3, Periods* peri1, Periods* peri2) { // cout<<"attr1 "<GetNoTuples() * factor); ////////////////////////////////////////////////////// for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); // cout<<"br_id "<GetAttribute(attr2);//Monday Periods* time2 = (Periods*)tuple_bus_route->GetAttribute(attr3);//Sunday double interval = 15.0/(24.0*60.0);//15 minutes if(i > num_high_freq) interval = 30.0/(24.0*60.0); //30 minutes Interval time_span1;//For Monday // cout<<"Monday"< time_span2;//For Sunday // cout<<"Sunday"<StartBulkLoad(); p1->MergeAdd(time_span1); p1->EndBulkLoad(); duration1.push_back(*p1); p1->DeleteIfAllowed(); // cout<StartBulkLoad(); p2->MergeAdd(time_span2); p2->EndBulkLoad(); duration2.push_back(*p2); p2->DeleteIfAllowed(); time_interval.push_back(interval); time_interval2.push_back(2.0*interval); ///////////////////////////////////////////////////////////////////////// tuple_bus_route->DeleteIfAllowed(); } } /* calculate the first and end time schedule of bus route if the start minute is larger than 30. we reduce the start hour by one e.g., 21:57 ---> 20:57 else keep it e.g., 21:14 --> 21:14 */ double RoadDenstiy::CalculateTimeSpan1(Periods* t, Periods* p, Interval& span, int index) { const int bti = 60; Interval p1; Interval t1; p->Get(0, p1); t->Get(0, t1); int m1 = t1.start.GetMinute(); // cout<<"start minute "< bti/2){ // larger than half an hour start = p1.start; // 1 means 1 day. 1.0/24.0 1 hour 1.0/(24*60) 1 minute double d = start.ToDouble() - 1.0/24.0 + m1*1.0/(24.0*60); start.ReadFrom(d); }else{ start = p1.start; double d = start.ToDouble() + m1*1.0/(24.0*60); start.ReadFrom(d); } // cout<<"start "<& span, double m) { Interval p1; p->Get(0, p1); /////////////set the time for the first schedule ////////////////////////// Instant start = p1.start; double d = start.ToDouble() + m; start.ReadFrom(d); // cout<<"start "< 20:57 else keep it e.g., 21:14 --> 21:14 For Monday */ void RoadDenstiy::CalculateTimeSpan3(Periods* t, Periods* p, Interval& span, int index, double interval) { const int bti = 60; Interval p1; Interval t1; p->Get(0, p1); t->Get(0, t1); int m1 = t1.start.GetMinute(); if(m1 == 0){ m1 = index % bti; } /////////////set the time for the first schedule ////////////////////////// Instant start = t1.start; // cout<<"old "< bti/2){ // larger than half an hour start = p1.start; // 1 means 1 day. 1.0/24.0 1 hour 1.0/(24*60) 1 minute double d = start.ToDouble() - 1.0/24.0 + m1*1.0/(24.0*60); start.ReadFrom(d); }else{ start = p1.start; double d = start.ToDouble() + m1*1.0/(24.0*60); start.ReadFrom(d); } // cout<<"start "< sm_list; for(int i = 1;i <= rel3->GetNoTuples();i+= 2){ Tuple* tuple_route1 = rel3->GetTuple(i, false); bool sm1 = ((CcBool*)tuple_route1->GetAttribute(attr_sm))->GetBoolval(); sm_list.push_back(sm1); Tuple* tuple_route2 = rel3->GetTuple(i + 1, false); bool sm2 = ((CcBool*)tuple_route2->GetAttribute(attr_sm))->GetBoolval(); assert(sm1 == sm2); tuple_route1->DeleteIfAllowed(); tuple_route2->DeleteIfAllowed(); } // cout<<"attr1 "< route_speed; //// take the speed limit value from the relation/////////////// for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple_route = rel2->GetTuple(i, false); double speed_val = ((CcReal*)tuple_route->GetAttribute(attr))->GetRealval(); route_speed.push_back(speed_val); tuple_route->DeleteIfAllowed(); } // cout<<"size "<GetNoTuples();i++){ // if(i > 3 ) continue; Tuple* tuple_bus_route = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); GLine* gl = (GLine*)tuple_bus_route->GetAttribute(attr2); ///////////////collect all road sections///////////////////////// ///////////////get the route id and the corresponding speed value//////// BusRoute* br = new BusRoute(n,NULL,NULL); vector start_from; vector sec_list; br->GetSectionList(gl, sec_list, start_from); vector pos_speed1; double dist = 0.0; for(unsigned int j = 0;j < sec_list.size();j++){ dist += fabs(sec_list[j].end - sec_list[j].start); double s = route_speed[sec_list[j].rid - 1]; /////////////we define -1 --- 10km/h ////////////////////////// ////////the street that is not valid for cars////////////// if(s < 0.0) s = 10.0; /////////////////////////////////////////////////////////// Pos_Speed* ps = new Pos_Speed(dist, s); pos_speed1.push_back(*ps); delete ps; } // cout<<" size "< pos_speed2; pos_speed2.push_back(pos_speed1[0]); // cout<<"before "<Gline2line(l); SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); for(unsigned int j = 0;j < pos_speed2.size();j++){ // pos_speed2[j].Print(); br_id_list.push_back(br_id); br_pos.push_back(pos_speed2[j].pos); speed_limit.push_back(pos_speed2[j].speed_val); /////////////get the sub line of the speed////////////////////////// SimpleLine* sub_line = new SimpleLine(0); double pos1, pos2; if(j == 0){ pos1 = 0.0;; pos2 = pos_speed2[j].pos; }else{ pos1 = pos_speed2[j - 1].pos; pos2 = pos_speed2[j].pos; } sl->SubLine(pos1, pos2, sm_list[br_id - 1] , *sub_line); Line* sub_l = new Line(0); sub_line->toLine(*sub_l); br_subroute.push_back(*sub_l); sub_l->DeleteIfAllowed(); sub_line->DeleteIfAllowed(); ///////////////////////////////////////////////////////////////////// } sl->DeleteIfAllowed(); l->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// tuple_bus_route->DeleteIfAllowed(); } } bool CompareBusStop(const BusStop_Ext& bs1, const BusStop_Ext& bs2) { if(bs1.rid < bs2.rid) return true; else if(bs1.rid == bs2.rid){ if(bs1.pos < bs2.pos) return true; else if(AlmostEqual(bs1.pos,bs2.pos))return true; else return false; }else return false; } /* for each bus route segment, it sets the speed value */ void RoadDenstiy::CreateSegmentSpeed(int attr1, int attr2, int attr3, int attr4, int attr_a, int attr_b) { // cout<<"attr1 "<GetNoTuples();i++){ Tuple* tuple_bus_route = rel1->GetTuple(i, false); /////collect br id, line, up down, startSmaller value of each route///// int br_id = ((CcInt*)tuple_bus_route->GetAttribute(attr1))->GetIntval(); /* if(br_id != 48){ tuple_bus_route->DeleteIfAllowed(); continue; }*/ Line* l = (Line*)tuple_bus_route->GetAttribute(attr2); bool up_down = ((CcBool*)tuple_bus_route->GetAttribute(attr3))->GetBoolval(); bool startsmaller = ((CcBool*)tuple_bus_route->GetAttribute(attr4))->GetBoolval(); // cout<<"br_id "<ExactMatch(search_speed_id); vector br_speed_list; while(btree_iter2->Next()){ Tuple* tuple_bs = rel3->GetTuple(btree_iter2->GetId(), false); double bs_pos = ((CcReal*)tuple_bs->GetAttribute(BR_POS))->GetRealval(); double speed_val = ((CcReal*)tuple_bs->GetAttribute(BR_SPEED))->GetRealval(); Pos_Speed* pos_speed = new Pos_Speed(bs_pos, speed_val); br_speed_list.push_back(*pos_speed); delete pos_speed; tuple_bs->DeleteIfAllowed(); } delete btree_iter2; search_speed_id->DeleteIfAllowed(); /* cout<<"speed limit"<ExactMatch(search_bs_id); vector bus_stop_list; while(btree_iter1->Next()){ Tuple* tuple_bs = rel2->GetTuple(btree_iter1->GetId(), false); double bs_pos = ((CcReal*)tuple_bs->GetAttribute(attr_a))->GetRealval(); bool direction = ((CcBool*)tuple_bs->GetAttribute(attr_b))->GetBoolval(); //take bus stops on the same side of the route if(direction == up_down){ Point p(true,0.0,0.0); BusStop_Ext* bs_ext = new BusStop_Ext(br_id,0,bs_pos,p,direction); bus_stop_list.push_back(*bs_ext); delete bs_ext; } tuple_bs->DeleteIfAllowed(); } delete btree_iter1; search_bs_id->DeleteIfAllowed(); sort(bus_stop_list.begin(),bus_stop_list.end(),CompareBusStop); /* cout<<"bus stop list "<fromLine(*l); CalculateRouteSegment(sl, br_speed_list, bus_stop_list, startsmaller); sl->DeleteIfAllowed(); //////////////////////////////////////////////////////////////////////// tuple_bus_route->DeleteIfAllowed(); } } /* calculate the bus segment combined with speed limit value the returned lines are already ordered in the same way as bus stops from bus stop id small to big. It also writes down the start location (point) of each bus route for each direction return segment id (start from 1) bus stop id (starts from 1) */ void RoadDenstiy::CalculateRouteSegment(SimpleLine* sl, vector br_speed_list, vector bus_stop_list, bool sm) { BusStop_Ext last_stop = bus_stop_list[0]; // last_stop.Print(); unsigned int index_speed = 0; // cout<<"length "<Length()< sub_line_list; vector speed_val_list; vector bus_segment_id_list; for(unsigned int i = 1;i < bus_stop_list.size();i++){ BusStop_Ext cur_stop = bus_stop_list[i]; // cur_stop.Print(); ////////////advance the index /////////////////////////// while(br_speed_list[index_speed].pos < last_stop.pos || AlmostEqual(br_speed_list[index_speed].pos,last_stop.pos)) index_speed++; ////////////////////////////////////////////////////////// if(cur_stop.pos < br_speed_list[index_speed].pos || AlmostEqual(cur_stop.pos,br_speed_list[index_speed].pos)){ SimpleLine* sub_line1 = new SimpleLine(0); sl->SubLine(last_stop.pos,cur_stop.pos,sm,*sub_line1); // cout<<"sub length1 "<Length()<DeleteIfAllowed(); speed_val_list.push_back(br_speed_list[index_speed].speed_val); bus_segment_id_list.push_back(i); }else{ //between last stop and cur stop assert(last_stop.pos < br_speed_list[index_speed].pos && br_speed_list[index_speed].pos < cur_stop.pos); SimpleLine* sub_line2 = new SimpleLine(0); sl->SubLine(last_stop.pos,br_speed_list[index_speed].pos, sm,*sub_line2); // cout<<"sub length2 "<Length()<DeleteIfAllowed(); speed_val_list.push_back(br_speed_list[index_speed].speed_val); bus_segment_id_list.push_back(i); unsigned int index_speed_tmp = index_speed + 1; while(index_speed_tmp < br_speed_list.size() && br_speed_list[index_speed_tmp].pos < cur_stop.pos){ SimpleLine* sub_line3 = new SimpleLine(0); sl->SubLine(br_speed_list[index_speed].pos, br_speed_list[index_speed_tmp].pos, sm,*sub_line3); // cout<<"sub length3 "<Length()<DeleteIfAllowed(); speed_val_list.push_back(br_speed_list[index_speed_tmp].speed_val); bus_segment_id_list.push_back(i); index_speed = index_speed_tmp; index_speed_tmp = index_speed + 1; } SimpleLine* sub_line4 = new SimpleLine(0); sl->SubLine(br_speed_list[index_speed].pos,cur_stop.pos, sm,*sub_line4); // cout<<"sub length4 "<Length()<DeleteIfAllowed(); if(index_speed_tmp < br_speed_list.size()) speed_val_list.push_back(br_speed_list[index_speed_tmp].speed_val); else speed_val_list.push_back(br_speed_list[index_speed].speed_val); bus_segment_id_list.push_back(i); } last_stop = cur_stop; } BusStop_Ext temp_stop = bus_stop_list[0]; assert(speed_val_list.size() == sub_line_list.size()); assert(speed_val_list.size() == bus_segment_id_list.size()); ////////////get start location /////////////////// Point sp; if(temp_stop.start_small){ //up and down bus stop assert(sl->AtPosition(temp_stop.pos,sm,sp)); }else{ BusStop_Ext temp_stop_end = bus_stop_list[bus_stop_list.size() - 1]; assert(sl->AtPosition(temp_stop_end.pos,sm,sp)); } ////////////////////////////////////////////////// for(unsigned int i = 0;i < sub_line_list.size();i++){ br_id_list.push_back(temp_stop.br_id); br_direction.push_back(temp_stop.start_small);//!!actually up and down Line* temp_l = new Line(0); sub_line_list[i].toLine(*temp_l); br_subroute.push_back(*temp_l); temp_l->DeleteIfAllowed(); speed_limit.push_back(speed_val_list[i]); startSmaller.push_back(sm); //write down the location of first bus stop start_loc_list.push_back(sp); //segmend id starts from 1 segment_id_list.push_back(bus_segment_id_list[i]); } } /* create night moving bus. it has two time intervals 0-5 21-24 */ void RoadDenstiy::CreateNightBus() { for(int i = 1; i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_ts = rel1->GetTuple(i, false); int br_id= ((CcInt*)tuple_bus_ts->GetAttribute(BR_ID2))->GetIntval(); // if(br_id != 41){ // tuple_bus_ts->DeleteIfAllowed(); // continue; // } Periods* peri1 = (Periods*)tuple_bus_ts->GetAttribute(DURATION1); Periods* peri2 = (Periods*)tuple_bus_ts->GetAttribute(DURATION2); double time_interval = ((CcReal*)tuple_bus_ts->GetAttribute(BR_INTERVAL))->GetRealval(); // cout<<"br_id "<DeleteIfAllowed(); // break; } } /* create moving objects during the time interval.peri actually, it creates a set of moving objects. the start time deviation between each two consequent schedule is time interval 70 km h 1166.67 m minute 19.44 m second 50 km h 8333.3m minute 13.89 m second 30 km h 500 m minute 8.33 m second 10 km h 166.67 m minute 2.78 m second */ void RoadDenstiy::CreateMovingBus(int br_id,Periods* peri, double time_interval, bool daytime) { CreateUp(br_id, peri, time_interval, daytime); CreateDown(br_id, peri, time_interval, daytime); } /* create moving bus in up direction */ void RoadDenstiy::CreateUp(int br_id, Periods* peri, double time_interval, bool daytime) { // cout<<"create bus trip: route "< sub_sline_list; vector speed_list; vector seg_id_list; //////////////////////collect all bus segments of up direction////////////// CcInt* search_bs_id = new CcInt(true, br_id); BTreeIterator* btree_iter = btree->ExactMatch(search_bs_id); Point start_p; while(btree_iter->Next()){ Tuple* tuple_bs = rel2->GetTuple(btree_iter->GetId(), false); bool direction = ((CcBool*)tuple_bs->GetAttribute(BUS_DIRECTION))->GetBoolval(); if(direction){ //up direction Line* l = (Line*)tuple_bs->GetAttribute(SUB_ROUTE_LINE); double speed_val = ((CcReal*)tuple_bs->GetAttribute(SPEED_LIMIT))->GetRealval(); SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); sub_sline_list.push_back(*sl); sl->DeleteIfAllowed(); speed_list.push_back(speed_val); int segid = ((CcInt*)tuple_bs->GetAttribute(SEGMENT_ID))->GetIntval(); seg_id_list.push_back(segid); ////get the start point/// Point* p = (Point*)tuple_bs->GetAttribute(START_LOC); start_p = *p; } tuple_bs->DeleteIfAllowed(); } delete btree_iter; search_bs_id->DeleteIfAllowed(); /////////////////create one bus trip movement/////////////////////////////// const double dist_delta = 0.01; MPoint* bus_mo = new MPoint(0); bus_mo->StartBulkLoad(); Interval bus_periods; peri->Get(0, bus_periods); // cout<<"seg_id_list size "< seq_halfseg; //reorder it from start to end // cout< 0.0)){ delete sp; continue; } sp->ReorderLine(&sub_sline_list[i], seq_halfseg); assert(seq_halfseg.size() > 0); Point temp_sp1 = seq_halfseg[0].from; Point temp_sp2 = seq_halfseg[seq_halfseg.size() - 1].to; // cout<<"last start p "< up_interval; up_interval.start = bus_periods.start; up_interval.lc = true; Instant newend = bus_periods.start; ////////////////pause for 30 seconds ///////////////////////////// newend.ReadFrom(bus_periods.start.ToDouble() + 30.0/(24.0*60*60)); up_interval.end = newend; up_interval.rc = false; UPoint* up = new UPoint(up_interval,temp_sp1,temp_sp1); bus_mo->Add(*up); up->DeleteIfAllowed(); bus_periods.start = newend; } //start = true; start_p = temp_sp2; CreateBusTrip1(bus_mo, seq_halfseg, bus_periods.start, real_speed, last_upoint); }else if(start_p.Distance(temp_sp2) < dist_delta){ ////////moving bus moves to the bus stop and wait for a while////// if(last_seg_id != seg_id_list[i]){ // cout<<"trip 2" // <<"last_seg_id "< up_interval; up_interval.start = bus_periods.start; up_interval.lc = true; Instant newend = bus_periods.start; ////////////////pause for 30 seconds ////////////////////////// newend.ReadFrom(bus_periods.start.ToDouble() + 30.0/(24.0*60*60)); up_interval.end = newend; up_interval.rc = false; UPoint* up = new UPoint(up_interval,temp_sp2,temp_sp2); bus_mo->Add(*up); last_upoint = *up; up->DeleteIfAllowed(); bus_periods.start = newend; } //start = false; start_p = temp_sp1; CreateBusTrip2(bus_mo, seq_halfseg, bus_periods.start, real_speed, last_upoint); }else assert(false); delete sp; } ////////////////add 30 seconds wait for the last bus stop///////////////// Instant new_end = last_upoint.timeInterval.end; last_upoint.timeInterval.start = new_end; new_end.ReadFrom(new_end.ToDouble() + 30.0/(24.0*60*60)); last_upoint.timeInterval.end = new_end; last_upoint.p0 = last_upoint.p1; bus_mo->Add(last_upoint); ///////////////////////////////////////////////////////////////////// bus_mo->EndBulkLoad(); ///////////////////////////add to the result /////////////////////// br_id_list.push_back(br_id); br_direction.push_back(true); //UP direction bus_trip.push_back(*bus_mo); //////////////////////////////////////////////////////////////////// AddTypeandDay(bus_mo,daytime); ////////////////////////////////////////////////////////////////// int schedule_id = 1; schedule_id_list.push_back(schedule_id); schedule_id++; //////////////////copy the trip by time interval////////////////////////// CopyBusTrip(br_id, true, bus_mo, peri, time_interval,daytime,schedule_id); ////////////////////////////////////////////////////////////////////////// delete bus_mo; } /* create moving bus units and add them into the trip, it travers from index small to big in myhalfsegment list use the maxspeed as bus speed */ void RoadDenstiy::CreateBusTrip1(MPoint* mo, vector seq_halfseg, Instant& start_time, double speed_val, UPoint& last_up) { // cout<<"trip1 max speed "< up_interval; for(unsigned int i = 0;i < seq_halfseg.size();i++){ Point from_loc = seq_halfseg[i].from; Point to_loc = seq_halfseg[i].to; double dist = from_loc.Distance(to_loc); double time = dist/speed_val; // cout<<"dist "<Add(*up); last_up = *up; up->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// st = et; } start_time = et; } /* create moving bus units and add them into the trip, !!! it traverse from index big to small in myhalfsegment list use the maxspeed as bus speed */ void RoadDenstiy::CreateBusTrip2(MPoint* mo, vector seq_halfseg, Instant& start_time, double speed_val, UPoint& last_up) { const double dist_delta = 0.01; // cout<<"trip2 max speed "< up_interval; for(int i = seq_halfseg.size() - 1;i >= 0;i--){ Point from_loc = seq_halfseg[i].to; Point to_loc = seq_halfseg[i].from; double dist = from_loc.Distance(to_loc); double time = dist/speed_val; // cout<<"dist "<Add(*up); last_up = *up; up->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// st = et; } start_time = et; } /* create moving bus in down direction. the bus moves from large bus stop id to small bus stop id */ void RoadDenstiy::CreateDown(int br_id, Periods* peri, double time_interval, bool daytime) { // cout<<"create bus trip: route "< sub_sline_list; vector speed_list; vector seg_id_list; //////////////////////collect all bus segments of up direction////////////// CcInt* search_bs_id = new CcInt(true, br_id); BTreeIterator* btree_iter = btree->ExactMatch(search_bs_id); Point start_p; while(btree_iter->Next()){ Tuple* tuple_bs = rel2->GetTuple(btree_iter->GetId(), false); bool direction = ((CcBool*)tuple_bs->GetAttribute(BUS_DIRECTION))->GetBoolval(); if(direction == false){ //down direction Line* l = (Line*)tuple_bs->GetAttribute(SUB_ROUTE_LINE); double speed_val = ((CcReal*)tuple_bs->GetAttribute(SPEED_LIMIT))->GetRealval(); SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); sub_sline_list.push_back(*sl); sl->DeleteIfAllowed(); speed_list.push_back(speed_val); int segid = ((CcInt*)tuple_bs->GetAttribute(SEGMENT_ID))->GetIntval(); seg_id_list.push_back(segid); ////get the start point/// Point* p = (Point*)tuple_bs->GetAttribute(START_LOC); start_p = *p; } tuple_bs->DeleteIfAllowed(); } delete btree_iter; search_bs_id->DeleteIfAllowed(); /////////////////create one bus trip movement/////////////////////////////// const double dist_delta = 0.01; MPoint* bus_mo = new MPoint(0); bus_mo->StartBulkLoad(); Interval bus_periods; peri->Get(0, bus_periods); // cout<<"seg_id_list size "<= 0 ;i--){ SpacePartition* sp = new SpacePartition(); vector seq_halfseg; //reorder it from start to end // cout< 0.0)){ delete sp; continue; } sp->ReorderLine(&sub_sline_list[i], seq_halfseg); assert(seq_halfseg.size() > 0); Point temp_sp1 = seq_halfseg[0].from; Point temp_sp2 = seq_halfseg[seq_halfseg.size() - 1].to; double real_speed = speed_list[i] * 1000 / 60;// convert to meter minute if(start_p.Distance(temp_sp1) < dist_delta){ ////////moving bus moves to the bus stop and wait for a while////// if(last_seg_id != seg_id_list[i]){ // cout<<"trip 1" // <<"last_seg_id "< up_interval; up_interval.start = bus_periods.start; up_interval.lc = true; Instant newend = bus_periods.start; ////////////////pause for 30 seconds ///////////////////////////// newend.ReadFrom(bus_periods.start.ToDouble() + 30.0/(24.0*60*60)); up_interval.end = newend; up_interval.rc = false; UPoint* up = new UPoint(up_interval,temp_sp1,temp_sp1); bus_mo->Add(*up); delete up; bus_periods.start = newend; } start_p = temp_sp2; CreateBusTrip1(bus_mo, seq_halfseg, bus_periods.start, real_speed, last_upoint); }else if(start_p.Distance(temp_sp2) < dist_delta){ ////////moving bus moves to the bus stop and wait for a while////// if(last_seg_id != seg_id_list[i]){ // cout<<"trip 2" // <<"last_seg_id "< up_interval; up_interval.start = bus_periods.start; up_interval.lc = true; Instant newend = bus_periods.start; ////////////////pause for 30 seconds ////////////////////////// newend.ReadFrom(bus_periods.start.ToDouble() + 30.0/(24.0*60*60)); up_interval.end = newend; up_interval.rc = false; UPoint* up = new UPoint(up_interval,temp_sp2,temp_sp2); bus_mo->Add(*up); delete up; bus_periods.start = newend; } start_p = temp_sp1; CreateBusTrip2(bus_mo, seq_halfseg, bus_periods.start, real_speed, last_upoint); }else assert(false); delete sp; } ////////////////add 30 seconds wait for the last bus stop///////////////// Instant new_end = last_upoint.timeInterval.end; last_upoint.timeInterval.start = new_end; new_end.ReadFrom(new_end.ToDouble() + 30.0/(24.0*60*60)); last_upoint.timeInterval.end = new_end; last_upoint.p0 = last_upoint.p1; bus_mo->Add(last_upoint); ///////////////////////////////////////////////////////////////////////// bus_mo->EndBulkLoad(); ///////////////////////////add to the result /////////////////////// br_id_list.push_back(br_id); br_direction.push_back(false); //DOWN direction bus_trip.push_back(*bus_mo); //////////////////////////////////////////////////////////////////// AddTypeandDay(bus_mo, daytime); ///////////////////////add schedule counter///////////////////////////// int schedule_id = 1; schedule_id_list.push_back(schedule_id); schedule_id++; //////////////////copy the trip by time interval/////////////////////////// CopyBusTrip(br_id, false, bus_mo, peri, time_interval,daytime,schedule_id); /////////////////////////////////////////////////////////////////////////// delete bus_mo; } /* create a moving bus trip for every time interval */ void RoadDenstiy::CopyBusTrip(int br_id,bool direction, MPoint* mo, Periods* peri, double time_interval, bool daytime, int schedule_id) { // cout<<"periods "<<*peri< bus_periods; peri->Get(0, bus_periods); Instant st = bus_periods.start; st.ReadFrom(st.ToDouble() + time_interval); /////////////calculate the number of copies ///////////////////// unsigned int copy_no = 0; while(st <= bus_periods.end){ copy_no++; // cout<<"new st "<StartBulkLoad(); for(int j = 0;j < mo->GetNoComponents();j++){ UPoint up1; mo->Get(j, up1); Interval up_interval; Instant st = up1.timeInterval.start; st.ReadFrom(st.ToDouble() + (i+1)*time_interval); up_interval.start = st; up_interval.lc = up1.timeInterval.lc; Instant et = up1.timeInterval.end; et.ReadFrom(et.ToDouble() + (i+1)*time_interval); up_interval.end = et; up_interval.rc = up1.timeInterval.rc; UPoint* up2 = new UPoint(up_interval, up1.p0,up1.p1); mo1->Add(*up2); delete up2; } mo1->EndBulkLoad(); br_id_list.push_back(br_id); br_direction.push_back(direction); bus_trip.push_back(*mo1); ////////Sunday,Monday,Night,Daytime//////////////////// AddTypeandDay(mo1, daytime); /////////Schedule ID////////////////////////////////// schedule_id_list.push_back(schedule_id); schedule_id++; //////////////////////////////////////////////////////// mo1->DeleteIfAllowed(); } //////////////////////////copy the trip one day more////////////////////// if(daytime == false){ //only for night bus for(unsigned int i = 0;i < copy_no + 1;i++){ MPoint* mo1 = new MPoint(0); mo1->StartBulkLoad(); for(int j = 0;j < mo->GetNoComponents();j++){ UPoint up1; mo->Get(j, up1); Interval up_interval; Instant st = up1.timeInterval.start; st.ReadFrom(st.ToDouble() + i*time_interval + 1.0);//1 day more up_interval.start = st; up_interval.lc = up1.timeInterval.lc; Instant et = up1.timeInterval.end; et.ReadFrom(et.ToDouble() + i*time_interval + 1.0);//1 day more up_interval.end = et; up_interval.rc = up1.timeInterval.rc; UPoint* up2 = new UPoint(up_interval, up1.p0,up1.p1); mo1->Add(*up2); delete up2; } mo1->EndBulkLoad(); br_id_list.push_back(br_id); br_direction.push_back(direction); bus_trip.push_back(*mo1); //////////Sunday,Monday,Night,Daytime/////////////////////// AddTypeandDay(mo1, daytime); /////////Schedule ID//////////////////// schedule_id_list.push_back(schedule_id); schedule_id++; ////////////////////////////////////////////// mo1->DeleteIfAllowed(); } } } /* add type of the bus: night or daytime add whether it is Monday, Sunday or ... */ void RoadDenstiy::AddTypeandDay(MPoint* mo, bool daytime) { if(daytime) trip_type.push_back("daytime"); else trip_type.push_back("night"); assert(mo->GetNoComponents() > 0); UPoint up; mo->Get(0, up); Instant st = up.timeInterval.start; int d = st.GetWeekday();//0--Monday // cout<<"start time "<GetNoTuples();i++){ Tuple* tuple_bus_ts = rel1->GetTuple(i, false); int br_id= ((CcInt*)tuple_bus_ts->GetAttribute(BR_ID3))->GetIntval(); // cout<<"br_id "<DeleteIfAllowed(); // continue; // } Periods* peri1 = (Periods*)tuple_bus_ts->GetAttribute(DURATION1); Periods* peri2 = (Periods*)tuple_bus_ts->GetAttribute(DURATION2); double time_interval1 = ((CcReal*)tuple_bus_ts->GetAttribute(BR_INTERVAL1))->GetRealval(); double time_interval2 = ((CcReal*)tuple_bus_ts->GetAttribute(BR_INTERVAL2))->GetRealval(); // cout<<"br_id "<DeleteIfAllowed(); } } /* create time table at each spatial location. several bus stops from different bus routes can locate at the same spatial location Compact Storage: loc:point lineid:int stopid:int direction:bool deftime:periods locid:int scheduleinterval:double for one route, one direction, one stop, it has at most four tuples night1 night2 sunday monday or only two tuples: sunday mondy */ void RoadDenstiy::CreateTimeTable_Compact(Periods* peri1, Periods* peri2) { ////////////collect all bus stops ///////////////////////////////// vector bus_stop_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_bus_stop = rel1->GetTuple(i, false); int br_id = ((CcInt*)tuple_bus_stop->GetAttribute(BR_ID4))->GetIntval(); int stop_id = ((CcInt*)tuple_bus_stop->GetAttribute(BUS_STOP_ID))->GetIntval(); Point* loc = (Point*)tuple_bus_stop->GetAttribute(BUS_LOC); bool start_small = ((CcBool*)tuple_bus_stop->GetAttribute(STOP_DIRECTION))->GetBoolval(); BusStop_Ext* bse = new BusStop_Ext(br_id,stop_id,0,*loc,start_small); bus_stop_list.push_back(*bse); delete bse; tuple_bus_stop->DeleteIfAllowed(); } sort(bus_stop_list.begin(), bus_stop_list.end()); // cout<<"bus_stop_list size "< bus_stop_list_new; bus_stop_list_new.push_back(bus_stop_list[i]); ////////collect all bus stops mapping to the same 2D point in space///// unsigned int j = i + 1; BusStop_Ext bse = bus_stop_list_new[0]; // bse.Print(); while(j < bus_stop_list.size() && bus_stop_list[j].loc.Distance(bse.loc) < dist_delta ){ bus_stop_list_new.push_back(bus_stop_list[j]); j++; } i = j - 1; ///////////////////process bus stop list new /////////////////////////// // cout<<"sub size "< bus_stop_list_new, int count_id, Periods* peri1, Periods* peri2) { // cout<<"bus_stop_list_new size "<ExactMatch(search_trip_id); vector night_mo; vector day_mo1; //Monday vector day_mo2; //Sunday while(btree_iter->Next()){ Tuple* tuple_trip = rel2->GetTuple(btree_iter->GetId(), false); int br_trip_id = ((CcInt*)tuple_trip->GetAttribute(BR_ID5))->GetIntval(); bool trip_direction = ((CcBool*)tuple_trip->GetAttribute(MO_BUS_DIRECTION))->GetBoolval(); assert(br_id == br_trip_id); if(direction == trip_direction){ MPoint* mo = (MPoint*)tuple_trip->GetAttribute(BUS_TRIP); string busday = ((CcString*)tuple_trip->GetAttribute(BUS_DAY))->GetValue(); string bus_type = ((CcString*)tuple_trip->GetAttribute(BUS_TYPE))->GetValue(); UPoint up; mo->Get(0, up); //////////////////////////////////////////////////////////////////// //////// classify the buses into groups according to time /////// ////////////////////////////////////////////////////////////////// if(bus_type.compare("night") == 0){// only need one day for night bus if(SameDay(up,peri1)) night_mo.push_back(*mo); }else{ if(busday.compare("Monday") == 0){ day_mo1.push_back(*mo); } else if(busday.compare("Sunday") == 0){ day_mo2.push_back(*mo); } else assert(false); } //////////////////////////////////////////////////////////// } tuple_trip->DeleteIfAllowed(); } delete btree_iter; search_trip_id->DeleteIfAllowed(); //////////////////////////////////////////////////////////////////// // cout<<"night_mo "< 0) CreatTableAtStopNight(night_mo,loc,br_id,stop_id,direction, peri1,peri2,count_id); CreatTableAtStop(day_mo1,loc,br_id,stop_id,direction,count_id); CreatTableAtStop(day_mo2,loc,br_id,stop_id,direction,count_id); //////////////////////////////////////////////////////////////////// } } /* check whether thay are in the same day */ bool RoadDenstiy::SameDay(UPoint& up, Periods* peri1) { Interval periods1; peri1->Get(0, periods1); int day1 = up.timeInterval.start.GetDay(); int day2 = periods1.start.GetDay(); if(day1 == day2)return true; else return false; } /* create table at one location for night buses */ void RoadDenstiy::CreatTableAtStopNight(vector& mo_list, Point& loc, int br_id, int stop_id, bool dir, Periods* night1, Periods* night2, int count_id) { Interval periods1; night1->Get(0, periods1); Interval periods2; night2->Get(0, periods2); // cout<<"peri1 "<<*night1<<" peri2 "<<*night2< mo_list1; vector mo_list2; for(unsigned int i = 0;i < mo_list.size();i++){ MPoint mo = mo_list[i]; UPoint up; mo.Get(0, up); double s = up.timeInterval.start.ToDouble(); if( s < e1 || AlmostEqual(s, e1)) mo_list1.push_back(mo_list[i]); else mo_list2.push_back(mo_list[i]); } // cout<<"mo_list1 size "< trip_list, Point& loc, int br_id, int stop_id, bool dir, int count_id) { assert(trip_list.size() >= 2); MPoint start_mo_0 = trip_list[0]; UPoint up1; start_mo_0.Get(0, up1);//the start time of first trip Instant start_time_0 = up1.timeInterval.start; Instant st = start_time_0; GetTimeInstantStop(start_mo_0, loc,st); /////////////cut second and millsecond ///////////////////////////// int second_val_s = st.GetSecond(); // int msecond_val_s = st.GetMillisecond(); // double double_s = st.ToDouble() - // second_val_s/(24.0*60.0*60.0) - // msecond_val_s/(24.0*60.0*60.0*1000.0); double double_s = st.ToDouble();//we should consider second and millisecond st.ReadFrom(double_s); ///////////////////////////////////////////////////////////////// MPoint start_mo_1 = trip_list[1]; UPoint up2; start_mo_1.Get(0, up1);//the start time of second trip Instant start_time_1 = up1.timeInterval.start; /////////// get time interval for schedule /////////////////// double sch_interval = start_time_1.ToDouble() - start_time_0.ToDouble(); assert(sch_interval > 0.0); // cout<<"schedule "< time_span; time_span.start = st; time_span.lc = true; time_span.end = et; time_span.rc = true; Periods* peri = new Periods(0); peri->StartBulkLoad(); peri->MergeAdd(time_span); peri->EndBulkLoad(); // duration.push_back(*peri); // cout<<"periods "<<*peri<GetUOid()); delete bs; duration1.push_back(*peri); unique_id_list.push_back(count_id); schedule_interval.push_back(sch_interval); peri->DeleteIfAllowed(); //////////////////////// check time ////////////////////////////// for(unsigned int i = 0;i < trip_list.size();i++){ MPoint mo = trip_list[i]; Instant temp_instant; GetTimeInstantStop(mo, loc, temp_instant); int second_val = temp_instant.GetSecond(); assert(second_val == second_val_s); } //////////////////////////////////////////////////////////////////////// } /* get the time that the bus arrives at this point(stop) */ void RoadDenstiy::GetTimeInstantStop(MPoint& mo, Point loc, Instant& arrove_t) { const double dist_delta = 0.01; const double stop_time = 30.0/(24.0*60.0*60.0); //30 seconds for buses for(int j = 0;j < mo.GetNoComponents();j++){ UPoint up; mo.Get(j, up); Point loc1 = up.p0; Point loc2 = up.p1; if(loc1.Distance(loc2) < dist_delta && loc1.Distance(loc) < dist_delta){ //find the place Instant st = up.timeInterval.start; Instant et = up.timeInterval.end; double d_st = st.ToDouble(); double d_et = et.ToDouble(); assert(AlmostEqual(fabs(d_st-d_et), stop_time));//check 30 seconds arrove_t = st; return; } } assert(false); } bool CompareGP_P(const GP_Point& gp_p1, const GP_Point& gp_p2) { if(gp_p1.rid < gp_p2.rid) return true; else{ if(gp_p1.rid > gp_p2.rid) return false; else{ if(gp_p1.pos1 < gp_p2.pos1) return true; else return false; } } } /* create nodes relation for road graph jun id, gpoint, point */ void RoadDenstiy::GetRGNodes() { Relation* juns = n->GetJunctions(); vector loc_list; for(int i = 1;i <= juns->GetNoTuples();i++){ Tuple* jun_tuple = juns->GetTuple(i, false); CcInt* rid1 = (CcInt*)jun_tuple->GetAttribute(JUNCTION_ROUTE1_ID); CcInt* rid2 = (CcInt*)jun_tuple->GetAttribute(JUNCTION_ROUTE2_ID); int id1 = rid1->GetIntval(); int id2 = rid2->GetIntval(); Point* junp = (Point*)jun_tuple->GetAttribute(JUNCTION_POS); CcReal* meas1 = (CcReal*)jun_tuple->GetAttribute(JUNCTION_ROUTE1_MEAS); CcReal* meas2 = (CcReal*)jun_tuple->GetAttribute(JUNCTION_ROUTE2_MEAS); double pos1 = meas1->GetRealval(); double pos2 = meas2->GetRealval(); // unique_id_list.push_back(oid); // oid++; // gp_list.push_back(*gp1); // jun_loc_list.push_back(*junp); // // // unique_id_list.push_back(oid); // oid++; // gp_list.push_back(*gp2); // jun_loc_list.push_back(*junp); GP_Point gp_p1(id1, pos1, -1.0, *junp, *junp); GP_Point gp_p2(id2, pos2, -1.0, *junp, *junp); loc_list.push_back(gp_p1); loc_list.push_back(gp_p2); jun_tuple->DeleteIfAllowed(); } juns->Delete(); int oid = 1; sort(loc_list.begin(), loc_list.end(), CompareGP_P); const double delta_dist = 0.001; for(unsigned int i = 0;i < loc_list.size();i++){ // loc_list[i].Print(); if(oid == 1){ GPoint* gp = new GPoint(true, n->GetId(), loc_list[i].rid, loc_list[i].pos1, None); unique_id_list.push_back(oid); oid++; gp_list.push_back(*gp); delete gp; jun_loc_list.push_back(loc_list[i].loc1); rid_list.push_back(loc_list[i].rid); }else{ GPoint last_gp = gp_list[gp_list.size() - 1]; Point last_jun = jun_loc_list[jun_loc_list.size() - 1]; GPoint* gp = new GPoint(true, n->GetId(), loc_list[i].rid, loc_list[i].pos1, None); if(gp->GetRouteId() == last_gp.GetRouteId() && fabs(gp->GetPosition() - last_gp.GetPosition()) < delta_dist && last_jun.Distance(loc_list[i].loc1) < delta_dist){ delete gp; continue; } unique_id_list.push_back(oid); oid++; gp_list.push_back(*gp); delete gp; jun_loc_list.push_back(loc_list[i].loc1); rid_list.push_back(loc_list[i].rid); } } } /* create one connection for road graph, two junction points having the same spatial location */ void RoadDenstiy::GetRGEdges1(Relation* rel, R_Tree<2,TupleId>* rtree) { for(int i = 1;i <= rel->GetNoTuples();i++){ Tuple* jun_tuple = rel->GetTuple(i, false); // int id = ((CcInt*)jun_tuple->GetAttribute(RG_N_JUN_ID))->GetIntval(); // Point* loc = (Point*)jun_tuple->GetAttribute(RG_N_P); int id = ((CcInt*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval(); Point* loc = (Point*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_P); vector neighbor_list; DFTraverse(rel, rtree, rtree->RootRecordId(), *loc, neighbor_list); for(unsigned int i = 0;i < neighbor_list.size();i++){ if(neighbor_list[i] == id)continue; jun_id_list1.push_back(id); jun_id_list2.push_back(neighbor_list[i]); } jun_tuple->DeleteIfAllowed(); } } /* traverse rtree to find the points that have the same spatial location as input */ void RoadDenstiy::DFTraverse(Relation* rel,R_Tree<2,TupleId>* rtree, SmiRecordId adr, Point& loc, vector& oid_list) { const double delta_dist = 0.001; 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* dg_tuple = rel->GetTuple(e.info, false); // Point* q = (Point*)dg_tuple->GetAttribute(RG_N_P); Point* q = (Point*)dg_tuple->GetAttribute(RoadGraph::RG_JUN_P); if(q->Distance(loc) < delta_dist){ int id = // ((CcInt*)dg_tuple->GetAttribute(RG_N_JUN_ID))->GetIntval(); ((CcInt*)dg_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval(); oid_list.push_back(id); } dg_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(loc.Inside(e.box)){ DFTraverse(rel, rtree, e.pointer, loc, oid_list); } } } delete node; } /* two junction points are connected by glines converting gline to line takes a lot of time because the junction point (gpoint ) is get from curve -- dual --TRUE use simpline method 2 seconds for berlin roads use gline2line method 27 seconds */ void RoadDenstiy::GetRGEdges2(Relation* rel) { vector gp_p_list; // int NetId; int NetId = -1; for(int i = 1;i <= rel->GetNoTuples();i++){ Tuple* jun_tuple = rel->GetTuple(i, false); // int oid = ((CcInt*)jun_tuple->GetAttribute(RG_N_JUN_ID))->GetIntval(); // GPoint* gp = (GPoint*)jun_tuple->GetAttribute(RG_N_GP); // Point* loc = (Point*)jun_tuple->GetAttribute(RG_N_P); int oid = ((CcInt*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_ID))->GetIntval(); GPoint* gp = (GPoint*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_GP); Point* loc = (Point*)jun_tuple->GetAttribute(RoadGraph::RG_JUN_P); NetId = gp->GetNetworkId(); GP_Point gp_p(gp->GetRouteId(), gp->GetPosition(), oid, *loc, *loc); gp_p_list.push_back(gp_p); jun_tuple->DeleteIfAllowed(); } sort(gp_p_list.begin(), gp_p_list.end(), CompareGP_P); for(unsigned int i = 0;i < gp_p_list.size();i++){ // gp_p_list[i].Print(); vector sub_list; sub_list.push_back(gp_p_list[i]); int rid = gp_p_list[i].rid; unsigned int j = i + 1; while(j < gp_p_list.size() && gp_p_list[j].rid == sub_list[sub_list.size() - 1].rid){ sub_list.push_back(gp_p_list[j]); j++; } // cout<<"rid "< 1){ // cout<<"rid "<GetRoute(rid); SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(ROUTE_CURVE); for(unsigned int k = 0;k < sub_list.size();k++){ if(k == 0){ jun_id_list1.push_back((int)sub_list[k].pos2); jun_id_list2.push_back((int)sub_list[k + 1].pos2); double pos1 = sub_list[k].pos1; double pos2 = sub_list[k + 1].pos1; GLine* gl = new GLine(0); gl->SetNetworkId(NetId); gl->AddRouteInterval(rid, pos1, pos2); gl->SetDefined(true); gl->SetSorted(false); gl->TrimToSize(); gl_path_list.push_back(*gl); SimpleLine* sub_l = new SimpleLine(0); if(pos1 < pos2) sl->SubLine(pos1, pos2, true, *sub_l); else sl->SubLine(pos2, pos1, true, *sub_l); sline_path_list.push_back(*sub_l); sub_l->DeleteIfAllowed(); gl->DeleteIfAllowed(); }else if(k == sub_list.size() - 1){ jun_id_list1.push_back((int)sub_list[k].pos2); jun_id_list2.push_back((int)sub_list[k - 1].pos2); double pos1 = sub_list[k].pos1; double pos2 = sub_list[k - 1].pos1; GLine* gl = new GLine(0); gl->SetNetworkId(NetId); gl->AddRouteInterval(rid, pos1, pos2); gl->SetDefined(true); gl->SetSorted(false); gl->TrimToSize(); gl_path_list.push_back(*gl); SimpleLine* sub_l = new SimpleLine(0); if(pos2 < pos1) sl->SubLine(pos2, pos1, true, *sub_l); else sl->SubLine(pos1, pos2, true, *sub_l); sline_path_list.push_back(*sub_l); sub_l->DeleteIfAllowed(); gl->DeleteIfAllowed(); }else{ jun_id_list1.push_back((int)sub_list[k].pos2); jun_id_list2.push_back((int)sub_list[k - 1].pos2); double pos1_1 = sub_list[k].pos1; double pos1_2 = sub_list[k - 1].pos1; jun_id_list1.push_back((int)sub_list[k].pos2); jun_id_list2.push_back((int)sub_list[k + 1].pos2); double pos2_1 = sub_list[k].pos1; double pos2_2 = sub_list[k + 1].pos1; GLine* gl1 = new GLine(0); gl1->SetNetworkId(NetId); gl1->AddRouteInterval(rid, pos1_1, pos1_2); gl1->SetDefined(true); gl1->SetSorted(false); gl1->TrimToSize(); gl_path_list.push_back(*gl1); SimpleLine* sub_l1 = new SimpleLine(0); if(pos1_2 < pos1_1) sl->SubLine(pos1_2, pos1_1, true, *sub_l1); else sl->SubLine(pos1_1, pos1_2, true, *sub_l1); sline_path_list.push_back(*sub_l1); sub_l1->DeleteIfAllowed(); gl1->DeleteIfAllowed(); GLine* gl2 = new GLine(0); gl2->SetNetworkId(NetId); gl2->AddRouteInterval(rid, pos2_1, pos2_2); gl2->SetDefined(true); gl2->SetSorted(false); gl2->TrimToSize(); gl_path_list.push_back(*gl2); SimpleLine* sub_l2 = new SimpleLine(0); if(pos2_1 < pos2_2) sl->SubLine(pos2_1, pos2_2, true, *sub_l2); else sl->SubLine(pos2_2, pos2_1, true, *sub_l2); sline_path_list.push_back(*sub_l2); sub_l2->DeleteIfAllowed(); gl2->DeleteIfAllowed(); } } road_tuple->DeleteIfAllowed(); } } } ////////////////////////////////////////////////////////////// ///////////////////Bus Stop/////////////////////////////////// ////////////////////////////////////////////////////////////// ListExpr BusStopProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> DATA"), nl->StringAtom("busstop"), nl->StringAtom("() (int int bool)"), nl->StringAtom("((1 2 TRUE))")))); } /* Output (brid, stopid) */ ListExpr OutBusStop( ListExpr typeInfo, Word value ) { // cout<<"OutBusStop"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList(nl->StringAtom("Route Id:"), nl->IntAtom(bs->GetId())); ListExpr list2 = nl->TwoElemList(nl->StringAtom("Stop Id:"), nl->IntAtom(bs->GetStopId())); ListExpr list3 = nl->TwoElemList(nl->StringAtom("UP:"), nl->BoolAtom(bs->GetUp())); return nl->ThreeElemList(list1,list2, list3); } /* In function */ Word InBusStop( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { // cout<<"length "<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 3){ cout<<"length should be 3"<First(instance); if(!nl->IsAtom(first) || nl->AtomType(first) != IntType){ cout<< "busstop(): brid must be int type"<IntValue(first); ListExpr second = nl->Second(instance); if(!nl->IsAtom(second) || nl->AtomType(second) != IntType){ cout<< "busstop(): stop id must be int type"<IntValue(second); ListExpr third = nl->Third(instance); if(!nl->IsAtom(third) || nl->AtomType(third) != BoolType){ cout<< "busstop(): up/down must be bool type"<BoolValue(third); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// Bus_Stop* bs = new Bus_Stop(true, id1, id2, d); return SetWord(bs); } correct = false; return SetWord(Address(0)); } /* Open an reference object */ bool OpenBusStop(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenBusStop()"<DeleteIfAllowed(); w.addr = 0; } Word CloneBusStop( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneBusStop"<IsEqual( type, "busstop" )); } /* type constructure functions */ Bus_Stop::Bus_Stop():Attribute(){} Bus_Stop::Bus_Stop(bool def, unsigned int id1, unsigned int id2, bool d): Attribute(def), br_id(id1), stop_id(id2), up_down(d) { SetDefined(def); } Bus_Stop::Bus_Stop(const Bus_Stop& bs): Attribute(bs.IsDefined()), br_id(bs.br_id), stop_id(bs.stop_id), up_down(bs.up_down) { SetDefined(bs.IsDefined()); } Bus_Stop& Bus_Stop::operator=(const Bus_Stop& bs) { SetDefined(bs.IsDefined()); if(IsDefined()){ br_id = bs.GetId(); stop_id = bs.GetStopId(); up_down = bs.up_down; } return *this; } void* Bus_Stop::Cast(void* addr) { return new (addr)Bus_Stop; } ostream& operator<<(ostream& o, const Bus_Stop& bs) { if(bs.IsDefined()){ o<<"br_id "<< bs.GetId()<<" " <<"stop id "< 0); return uoid; } bool Bus_Stop::operator==(const Bus_Stop& bs) { if(!IsDefined() || !bs.IsDefined()) return false; if(br_id == bs.GetId() && stop_id == bs.GetStopId() && up_down == bs.GetUp()) return true; return false; } ostream& Bus_Stop::Print(ostream& os) const { return os<<*this; } ////////////////////////////////////////////////////////////// //////////////////////bus route/////////////////////////////// ////////////////////////////////////////////////////////////// ListExpr BusRouteProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> DATA"), nl->StringAtom("busroute"), nl->StringAtom("((id, up) (*))"), nl->StringAtom("((1 true)((((2.0 2.0 3.0 3.0)))))")))); } /* Open an reference object */ bool OpenBusRoute(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenBusRoute()"<DeleteIfAllowed(); w.addr = 0; } Word CloneBusRoute( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneBusRoute"<IsEqual( type, "busroute" )); } /* In function */ Word InBusRoute( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { // cout<<"length "<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 2){ cout<<"length should be 2"<First(instance); if(nl->ListLength(first) != 2){ cout<< "busroute(): the first part should have two parameters"<First(first); if(!nl->IsAtom(first1) || nl->AtomType(first1) != IntType){ cout<< "busroute(): bus route id must be int type"<IntValue(first1); ListExpr first2 = nl->Second(first); if(!nl->IsAtom(first2) || nl->AtomType(first2) != BoolType){ cout<< "busroute(): bus route up/down must be bool type"<BoolValue(first2); Bus_Route* br = new Bus_Route(br_id, d); ListExpr geo_list = nl->Second(instance); br->StartBulkLoad(); int count = 0; while(!nl->IsEmpty(geo_list)){ ListExpr geo_first = nl->First(geo_list); geo_list = nl->Rest(geo_list); if(nl->ListLength(geo_first) != 1){ cout<< "busroute(): segment list should have length 1"<First(geo_first), errorPos, errorInfo, correct).addr; // cout<Length()<Add(sl, count); count++; } br->EndBulkLoad(); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// return SetWord(br); } correct = false; return SetWord(Address(0)); } /* Output a sequence of bus segments */ ListExpr OutBusRoute( ListExpr typeInfo, Word value ) { // cout<<"OutBusRoute"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList( nl->IntAtom(br->GetId()), nl->BoolAtom(br->GetUp())); ListExpr list2 = nl->TheEmptyList(); if(!br->IsEmpty()){ ListExpr last = list2; bool first = true; for(int i = 0;i < br->Size();i++){ SimpleLine sl(0); br->Get(i, sl); ListExpr geo_list = OutSimpleLine(nl->TheEmptyList(), SetWord(&sl)); ListExpr flatseg = nl->OneElemList(geo_list); if(first == true){ list2 = nl->OneElemList( flatseg ); last = list2; first = false; }else{ last = nl->Append( last, flatseg ); } } } return nl->TwoElemList(list1,list2); } Bus_Route::Bus_Route() { } Bus_Route::Bus_Route(const Bus_Route& br): StandardSpatialAttribute<2>(br.IsDefined()), elem_list(0), seg_list(0), br_id(br.GetId()), up_down(br.GetUp()) { if(IsDefined()){ elem_list.clean(); seg_list.clean(); Bus_Route* b_r = const_cast(&br); for(int i = 0;i < b_r->Size();i++){ BR_Elem elem; b_r->GetElem(i, elem); elem_list.Append(elem); } for(int i = 0;i < b_r->SegSize();i++){ HalfSegment hs; b_r->GetSeg(i, hs); seg_list.Append(hs); } } } Bus_Route& Bus_Route::operator=(const Bus_Route& br) { if(!br.IsDefined()) return *this; br_id = br.GetId(); up_down = br.GetUp(); elem_list.clean(); seg_list.clean(); Bus_Route* b_r = const_cast(&br); for(int i = 0;i < b_r->Size();i++){ BR_Elem elem; b_r->GetElem(i, elem); elem_list.Append(elem); } for(int i = 0;i < b_r->SegSize();i++){ HalfSegment hs; b_r->GetSeg(i, hs); seg_list.Append(hs); } SetDefined(true); return *this; } void Bus_Route::GetElem(int i, BR_Elem& elem) { assert(0 <= i && i < elem_list.Size()); elem_list.Get(i, elem); } void Bus_Route::GetSeg(int i, HalfSegment& hs) { assert(0 <= i && i < seg_list.Size()); seg_list.Get(i, hs); } void* Bus_Route::Cast(void* addr) { return new (addr)Bus_Route; } const Rectangle<2> Bus_Route::BoundingBox(const Geoid* geoid) const { Rectangle<2> bbox; for( int i = 0; seg_list.Size(); i++ ){ HalfSegment hs ; seg_list.Get(i, hs); if( i == 0 ){ bbox = hs.BoundingBox(); }else bbox = bbox.Union(hs.BoundingBox()); } return bbox; } /* add a new element to the result */ void Bus_Route::Add(SimpleLine* sl, int count) { BR_Elem br_elem; br_elem.br_seg_id = count; br_elem.start_pos = seg_list.Size(); int no = 0; for(int i = 0;i < sl->Size();i++){ HalfSegment hs; sl->Get(i, hs); if(!hs.IsLeftDomPoint()) continue; seg_list.Append(hs); no++; } br_elem.no = no; elem_list.Append(br_elem); } /* add a new element to the result, only a segment */ void Bus_Route::Add2(HalfSegment hs, int count) { BR_Elem br_elem; br_elem.br_seg_id = count; br_elem.start_pos = seg_list.Size(); int no = 0; seg_list.Append(hs); no++; br_elem.no = no; elem_list.Append(br_elem); } /* get a bus segment from the dbarray */ void Bus_Route::Get(int i, SimpleLine& sl) { // cout<GetId()){ cout<<"route id is different for the bus stop and route"<SetDefined(false); return; } if(bs->GetStopId() < 1 || (int)bs->GetStopId() > Size()){ cout<<"invalid bus stop id"<SetDefined(false); return; } if(bs->GetUp() != GetUp()){ cout<<"bus stop and bus route have different directions"<SetDefined(false); return; } SimpleLine sl1(0); Get(bs->GetStopId() - 1, sl1); SimpleLine sl2(0); Get(bs->GetStopId(), sl2); Point sp1, sp2, ep1, ep2; assert(sl1.AtPosition(0.0, sl1.GetStartSmaller(), sp1)); assert(sl1.AtPosition(sl1.Length(), sl1.GetStartSmaller(), ep1)); assert(sl2.AtPosition(0.0, sl2.GetStartSmaller(), sp2)); assert(sl2.AtPosition(sl2.Length(), sl2.GetStartSmaller(), ep2)); if(AlmostEqual(sp1, sp2) || AlmostEqual(sp1, ep2)){ *p = sp1; }else if(AlmostEqual(ep1, sp2) || AlmostEqual(ep1, ep2)){ *p = ep1; }else assert(false); } /* get the point of a metro stop it is different from the bus route. in metro network, the up and down direction have the same route (geometry). the segment connecting two endpoints */ void Bus_Route::GetMetroStopGeoData(Bus_Stop* ms, Point* p) { if(GetId() != ms->GetId()){ cout<<"route id is different for the bus stop and route"<SetDefined(false); return; } if(ms->GetStopId() < 1 || (int) ms->GetStopId() > Size() + 2 ){ cout<<"invalid bus stop id"<SetDefined(false); return; } if(ms->GetUp() != GetUp()){ cout<<"bus stop and bus route have different directions"<SetDefined(false); return; } HalfSegment hs1, hs2; if(ms->GetStopId() == 1){ if(ms->GetUp()){ GetSeg(0, hs1); GetSeg(1, hs2); }else{ GetSeg(SegSize() - 1, hs1); GetSeg(SegSize() - 2, hs2); } Point lp1 = hs1.GetLeftPoint(); Point rp1 = hs1.GetRightPoint(); Point lp2 = hs2.GetLeftPoint(); Point rp2 = hs2.GetRightPoint(); if(AlmostEqual(lp1, lp2) || AlmostEqual(lp1, rp2)){ *p = rp1; }else if(AlmostEqual(rp1, lp2) || AlmostEqual(rp1, rp2)){ *p = lp1; }else assert(false); }else if ((int)ms->GetStopId() == SegSize() + 1){ if(ms->GetUp()){ GetSeg(SegSize() - 1, hs1); GetSeg(SegSize() - 2, hs2); }else{ GetSeg(0, hs1); GetSeg(1, hs2); } Point lp1 = hs1.GetLeftPoint(); Point rp1 = hs1.GetRightPoint(); Point lp2 = hs2.GetLeftPoint(); Point rp2 = hs2.GetRightPoint(); if(AlmostEqual(lp1, lp2) || AlmostEqual(lp1, rp2)){ *p = rp1; }else if(AlmostEqual(rp1, lp2) || AlmostEqual(rp1, rp2)){ *p = lp1; }else assert(false); } else{ if(ms->GetUp()){ int index1 = ms->GetStopId() - 2; int index2 = ms->GetStopId() - 1; GetSeg(index1, hs1); GetSeg(index2, hs2); }else{ int index1 = ms->GetStopId(); int index2 = ms->GetStopId() - 1; GetSeg(SegSize() - index1, hs1); GetSeg(SegSize() - index2, hs2); } Point lp1 = hs1.GetLeftPoint(); Point rp1 = hs1.GetRightPoint(); Point lp2 = hs2.GetLeftPoint(); Point rp2 = hs2.GetRightPoint(); if(AlmostEqual(lp1, lp2) || AlmostEqual(lp1, rp2)){ *p = lp1; }else if(AlmostEqual(rp1, lp2) || AlmostEqual(rp1, rp2)){ *p = rp1; }else assert(false); } } double Bus_Route::Length() { if(!IsDefined() || IsEmpty() == true) return 0.0; double l = 0.0; for(int i = 0;i < seg_list.Size();i++){ HalfSegment hs; seg_list.Get(i, hs); l += hs.Length(); } return l; } void Bus_Route::StartBulkLoad() { } /* check whether two consequent segments are connected */ void Bus_Route::EndBulkLoad() { for(int i = 0;i < Size() - 1;i++){ SimpleLine sl1(0), sl2(0); Get(i, sl1); Get(i + 1, sl2); ////////////check the end point of the first bus segment///////. ////////////and the start point of the second bus segment////// Point sp1, ep1; Point sp2, ep2; assert(sl1.AtPosition(0.0, sl1.GetStartSmaller(), sp1)); assert(sl1.AtPosition(sl1.Length(), sl1.GetStartSmaller(), ep1)); assert(sl2.AtPosition(0.0, sl2.GetStartSmaller(), sp2)); assert(sl2.AtPosition(sl2.Length(), sl2.GetStartSmaller(), ep2)); // cout<<" sp1 "<TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> DATA"), nl->StringAtom("busnetwork"), nl->StringAtom("((def, id))"), nl->StringAtom("((TRUE 1))")))); } /* output the bus network */ ListExpr OutBusNetwork( ListExpr typeInfo, Word value ) { // cout<<"OutBusNetwork"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList( nl->StringAtom("Bus Network Id:"), nl->IntAtom(bn->GetId())); // return nl->OneElemList(list1); ////////////////out put bus stops relation//////////////////////////////// ListExpr bs_list = nl->TheEmptyList(); Relation* bs_rel = bn->GetBS_Rel(); if(bs_rel != NULL){ bool bFirst = true; ListExpr xNext = nl->TheEmptyList(); ListExpr xLast = nl->TheEmptyList(); for(int i = 1;i <= bs_rel->GetNoTuples();i++){ Tuple* node_tuple = bs_rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)node_tuple->GetAttribute(BusNetwork::BN_BS); ListExpr stop_list = OutBusStop(nl->TheEmptyList(),SetWord(bs)); xNext = stop_list; if(bFirst){ bs_list = nl->OneElemList(xNext); xLast = bs_list; bFirst = false; }else xLast = nl->Append(xLast,xNext); node_tuple->DeleteIfAllowed(); } } // return nl->TwoElemList(list1, bs_list); //////////////////////output bus routes relation/////////////////////////// ListExpr br_list = nl->TheEmptyList(); Relation* br_rel = bn->GetBR_Rel(); if(br_rel != NULL){ bool bFirst = true; ListExpr xNext = nl->TheEmptyList(); ListExpr xLast = nl->TheEmptyList(); for(int i = 1;i <= br_rel->GetNoTuples();i++){ Tuple* node_tuple = br_rel->GetTuple(i, false); Bus_Route* br = (Bus_Route*)node_tuple->GetAttribute(BusNetwork::BN_BR); ListExpr stop_list = OutBusRoute(nl->TheEmptyList(),SetWord(br)); xNext = stop_list; if(bFirst){ br_list = nl->OneElemList(xNext); xLast = br_list; bFirst = false; }else xLast = nl->Append(xLast,xNext); node_tuple->DeleteIfAllowed(); } } //////////////////////////////////////////////////////////////////////// ////////////////no output bus trips relation: too much data/////////////// ////////////////////////////////////////////////////////////////////////// return nl->ThreeElemList(list1, bs_list, br_list); } /* In function. there is not nested list expression here. */ Word InBusNetwork( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { // cout<<"length "<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 2){ cout<<"length should be 2"<First(instance); ListExpr second = nl->Second(instance); if(!nl->IsAtom(first) || nl->AtomType(first) != BoolType){ cout<< "busnetwork(): definition must be bool type"<BoolValue(first); if(!nl->IsAtom(second) || nl->AtomType(second) != IntType){ cout<< "busnetwork(): bus network id must be int type"<IntValue(second); BusNetwork* bn = new BusNetwork(d, id); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// return SetWord(bn); } correct = false; return SetWord(Address(0)); } bool SaveBusNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { BusNetwork* bn = (BusNetwork*)value.addr; return bn->Save(valueRecord, offset, typeInfo); } BusNetwork* BusNetwork::Open(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { return new BusNetwork(valueRecord, offset, typeInfo); } bool OpenBusNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { value.addr = BusNetwork::Open(valueRecord, offset, typeInfo); return value.addr != NULL; } Word CreateBusNetwork(const ListExpr typeInfo) { // cout<<"CreateBusNetwork()"<(w.addr); w.addr = 0; } Word CloneBusNetwork( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneBusNetwork"<IsEqual( type, "busnetwork" )); } BusNetwork::BusNetwork(): def(false), bn_id(0), graph_init(false), graph_id(0), max_bus_speed(0), min_br_oid(0), min_bt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_bs(NULL), routes_rel(NULL), btree_br(NULL), btree_bs_uoid(NULL), rtree_bs(NULL), btree_br_uoid(NULL), bustrips_rel(NULL), btree_trip_oid(NULL), btree_trip_br_id(NULL) { } BusNetwork::BusNetwork(bool d, unsigned int i): def(d), bn_id(i), graph_init(false), graph_id(0), max_bus_speed(0), min_br_oid(0), min_bt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_bs(NULL), routes_rel(NULL), btree_br(NULL), btree_bs_uoid(NULL), rtree_bs(NULL), btree_br_uoid(NULL), bustrips_rel(NULL), btree_trip_oid(NULL), btree_trip_br_id(NULL) { } /* read the data from record */ BusNetwork::BusNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo): def(false), bn_id(0), graph_init(false), graph_id(0), max_bus_speed(0), min_br_oid(0), min_bt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_bs(NULL), routes_rel(NULL), btree_br(NULL), btree_bs_uoid(NULL), rtree_bs(NULL), btree_br_uoid(NULL), bustrips_rel(NULL), btree_trip_oid(NULL), btree_trip_br_id(NULL) { valueRecord.Read(&def, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Read(&bn_id, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&graph_init, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Read(&graph_id, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&max_bus_speed, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&min_br_oid, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&min_bt_oid, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&start_time, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&end_time, sizeof(double), offset); offset += sizeof(double); ListExpr xType; ListExpr xNumericType; /***********************Open relation for busstops*********************/ nl->ReadFromString(BusStopsInternalTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); stops_rel = Relation::Open(valueRecord, offset, xNumericType); if(!stops_rel) { return; } ///////////////////btree on bus stops on brid/////////////////////////////// nl->ReadFromString(BusStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_bs = BTree::Open(valueRecord, offset, xNumericType); if(!btree_bs) { stops_rel->Delete(); return; } /***********************Open relation for busroutes*********************/ nl->ReadFromString(BusRoutesTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); routes_rel = Relation::Open(valueRecord, offset, xNumericType); if(!routes_rel) { stops_rel->Delete(); delete btree_bs; return; } ///////////////////btree on bus routes////////////////////////////////// nl->ReadFromString(BusRoutesBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_br = BTree::Open(valueRecord, offset, xNumericType); if(!btree_br) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); return; } ///////////////////btree on bus stops on uoid////////////////////////////// nl->ReadFromString(BusStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_bs_uoid = BTree::Open(valueRecord, offset, xNumericType); if(!btree_bs_uoid) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; return; } ///////////////////rtree on bus stops ////////////////////////////// Word xValue; if(!(rtree_bs->Open(valueRecord,offset, BusStopsRTreeTypeInfo,xValue))){ stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; delete btree_bs_uoid; return; } rtree_bs = ( R_Tree<2,TupleId>* ) xValue.addr; ///////////////////btree on bus routes unique id//////////////////////////// nl->ReadFromString(BusRoutesBTreeUOidTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_br_uoid = BTree::Open(valueRecord, offset, xNumericType); if(!btree_br_uoid) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; delete btree_bs_uoid; delete rtree_bs; return; } ///////////////open relation storing bus trips////////////////////// nl->ReadFromString(BusTripsTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); bustrips_rel = Relation::Open(valueRecord, offset, xNumericType); if(!bustrips_rel) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; delete btree_bs_uoid; delete rtree_bs; delete btree_br_uoid; return; } ///////////////////btree on bus trips unique id//////////////////////////// nl->ReadFromString(BusTripBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_trip_oid = BTree::Open(valueRecord, offset, xNumericType); if(!btree_trip_oid) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; delete btree_bs_uoid; delete rtree_bs; delete btree_br_uoid; bustrips_rel->Delete(); return; } ///////////////////btree on bus trips bus route id///////////////////////// nl->ReadFromString(BusTripBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_trip_br_id = BTree::Open(valueRecord, offset, xNumericType); if(!btree_trip_br_id) { stops_rel->Delete(); delete btree_bs; routes_rel->Delete(); delete btree_br; delete btree_bs_uoid; delete rtree_bs; delete btree_br_uoid; bustrips_rel->Delete(); delete btree_trip_oid; return; } } BusNetwork::~BusNetwork() { if(stops_rel != NULL) stops_rel->Close(); if(btree_bs != NULL) delete btree_bs; if(routes_rel != NULL) routes_rel->Close(); if(btree_br != NULL) delete btree_br; if(btree_bs_uoid != NULL) delete btree_bs_uoid; if(rtree_bs != NULL) delete rtree_bs; if(btree_br_uoid != NULL) delete btree_br_uoid; if(bustrips_rel != NULL) bustrips_rel->Close(); if(btree_trip_oid != NULL) delete btree_trip_oid; if(btree_trip_br_id != NULL) delete btree_trip_br_id; } bool BusNetwork::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { // cout<<"BusNetwork::Save"<ReadFromString(BusStopsInternalTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!stops_rel->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on bus stops on brid///////////////////////// nl->ReadFromString(BusStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_bs->Save(valueRecord,offset,xNumericType)) return false; ///////////////////bus routes relation///////////////////////////// nl->ReadFromString(BusRoutesTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!routes_rel->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on bus routes//////////////////////////// nl->ReadFromString(BusRoutesBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_br->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on bus stops on uoid/////////////////////// nl->ReadFromString(BusStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_bs_uoid->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////rtree on bus stops /////////////////////// if(!rtree_bs->Save(valueRecord, offset)){ return false; } ///////////////////////btree on bus routes on unique id////////////////////// nl->ReadFromString(BusRoutesBTreeUOidTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_br_uoid->Save(valueRecord,offset,xNumericType)) return false; ///////////////////bus trips relation///////////////////////////// nl->ReadFromString(BusTripsTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!bustrips_rel->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on bus trips on unique id////////////////////// nl->ReadFromString(BusTripBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_trip_oid->Save(valueRecord,offset,xNumericType)) return false; //////////////////btree on bus trips on bus route id////////////////////// nl->ReadFromString(BusTripBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_trip_br_id->Save(valueRecord,offset,xNumericType)) return false; return true; } /* store bus stops relation and the index */ void BusNetwork::LoadStops(Relation* r1) { ListExpr xTypeInfo; nl->ReadFromString(BusStopsInternalTypeInfo, xTypeInfo); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType(xTypeInfo); Relation* s_rel = new Relation(xNumType, true); for(int i = 1;i <= r1->GetNoTuples();i++){ Tuple* bs_tuple = r1->GetTuple(i, false); if(bs_tuple->GetNoAttributes() != 2){ cout<<"bus stops relation schema is wrong"<DeleteIfAllowed(); break; } Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(NODE_BS1); int id = bs->GetId(); Tuple* new_bs_tuple = new Tuple(nl->Second(xNumType)); new_bs_tuple->PutAttribute(BN_ID1, new CcInt(true, id)); new_bs_tuple->PutAttribute(BN_BS, new Bus_Stop(*bs)); new_bs_tuple->PutAttribute(BS_U_OID, new CcInt(true, bs->GetUOid())); Point* bs_loc = (Point*)bs_tuple->GetAttribute(NODE_BS2); // cout<<*bs_loc<PutAttribute(BS_GEO, new Point(*bs_loc)); s_rel->AppendTuple(new_bs_tuple); new_bs_tuple->DeleteIfAllowed(); bs_tuple->DeleteIfAllowed(); } // cout<GetNoTuples()<ToString(ptrList1) + "))))"; // cout<Delete(); ////////////////////////////////////////////////////////////////// //////////////////////btree on bus stops br id///////////////////// /////////////////////////////////////////////////////////////////// ListExpr ptrList2 = listutils::getPtrList(stops_rel); strQuery = "(createbtree (" + BusStopsInternalTypeInfo + "(ptr " + nl->ToString(ptrList2) + "))" + "Br_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_bs = (BTree*)xResult.addr; //////////////////////btree on bus stops uoid///////////////////// ListExpr ptrList3 = listutils::getPtrList(stops_rel); strQuery = "(createbtree (" + BusStopsInternalTypeInfo + "(ptr " + nl->ToString(ptrList3) + "))" + "U_oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_bs_uoid = (BTree*)xResult.addr; //////////////////////rtree on bus stops////////////////////////// ListExpr ptrList4 = listutils::getPtrList(stops_rel); strQuery = "(bulkloadrtree(sortby(addid(feed (" + BusStopsInternalTypeInfo + " (ptr " + nl->ToString(ptrList4) + "))))((Geodata asc))) Geodata)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); rtree_bs = ( R_Tree<2,TupleId>* ) xResult.addr; } /* store bus routes relation as well as some indices */ void BusNetwork:: LoadRoutes(Relation* r2) { ListExpr ptrList1 = listutils::getPtrList(r2); string strQuery = "(consume(feed(" + BusRoutesTypeInfo + "(ptr " + nl->ToString(ptrList1) + "))))"; // cout<::max(); for(int i = 1;i <= routes_rel->GetNoTuples();i++){ Tuple* br_tuple = routes_rel->GetTuple(i, false); int id = ((CcInt*)br_tuple->GetAttribute(BN_BR_OID))->GetIntval(); if(id < temp_id) temp_id = id; br_tuple->DeleteIfAllowed(); } min_br_oid = temp_id; // cout<<"min br oid "<ToString(ptrList2) + "))" + "Br_id)"; // cout<ToString(ptrList3) + "))" + "Oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_br_uoid = (BTree*)xResult.addr; } /* store moving buses and the maximum speed of all buses (for query processing of bus graph) */ void BusNetwork:: LoadBuses(Relation* r3) { ListExpr ptrList1 = listutils::getPtrList(r3); string strQuery = "(consume(feed(" + BusTripsTypeInfo + "(ptr " + nl->ToString(ptrList1) + "))))"; // cout<GetNoTuples()<::max(); for(int i = 1;i <= bustrips_rel->GetNoTuples();i++){ Tuple* bus_tuple = bustrips_rel->GetTuple(i, false); GenMO* mo = (GenMO*)bus_tuple->GetAttribute(BN_BUSTRIP); /////////////get the start and end time of all bus trips////////////// Periods* peri = new Periods(0); mo->DefTime(*peri); Interval time_span; peri->Get(0, time_span); // cout< end_time) end_time = time_span.end.ToDouble(); } peri->DeleteIfAllowed(); ////////////////////////////////////////////////////////////////////// for( int j = 0; j < mo->GetNoComponents(); j++ ){ UGenLoc unit; mo->Get( j, unit ); double pos1 = unit.gloc1.GetLoc().loc1; double pos2 = unit.gloc2.GetLoc().loc1; if(fabs(pos1 - pos2) > 1.0){ double t = unit.timeInterval.end.ToDouble()*86400.0 - unit.timeInterval.start.ToDouble()*86400.0; double speed = fabs(pos1 - pos2)/t; /* cout<<"dist "< max_bus_speed){ max_bus_speed = speed; } } } int id = ((CcInt*)bus_tuple->GetAttribute(BN_BUS_OID))->GetIntval(); if(id < temp_id) temp_id = id; bus_tuple->DeleteIfAllowed(); } min_bt_oid = temp_id; // cout<<"max bus speed "<ToString(ptrList2) + "))" + "Oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_trip_oid = (BTree*)xResult.addr; ////////////////btree on bus trips bus route/////////////////////////// ListExpr ptrList3 = listutils::getPtrList(bustrips_rel); strQuery = "(createbtree (" + BusTripsTypeInfo + "(ptr " + nl->ToString(ptrList3) + "))" + "Br_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_trip_br_id = (BTree*)xResult.addr; // Instant t1(start_time); // Instant t2(end_time); // cout<GetId(); if(id < 1){ cout<<"invalid bus stop"<ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter->GetId(), false); Bus_Route* br = (Bus_Route*)tuple->GetAttribute(BN_BR); if(br->GetUp() == bs->GetUp()){ br->GetBusStopGeoData(bs, p); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter; search_id->DeleteIfAllowed(); } /* set the bus graph id for bus network */ void BusNetwork::SetGraphId(int g_id) { graph_id = g_id; graph_init = true; } /* get the bus graph in bus network */ BusGraph* BusNetwork::GetBusGraph() { if(graph_init == false) return NULL; ListExpr xObjectList = SecondoSystem::GetCatalog()->ListObjects(); xObjectList = nl->Rest(xObjectList); while(!nl->IsEmpty(xObjectList)) { // Next element in list ListExpr xCurrent = nl->First(xObjectList); xObjectList = nl->Rest(xObjectList); // Type of object is at fourth position in list ListExpr xObjectType = nl->First(nl->Fourth(xCurrent)); if(nl->IsAtom(xObjectType) && nl->SymbolValue(xObjectType) == "busgraph"){ // Get name of the bus graph ListExpr xObjectName = nl->Second(xCurrent); string strObjectName = nl->SymbolValue(xObjectName); // Load object to find out the id of the network. Word xValue; bool bDefined; bool bOk = SecondoSystem::GetCatalog()->GetObject(strObjectName, xValue, bDefined); if(!bDefined || !bOk) { // Undefined continue; } BusGraph* bg = (BusGraph*)xValue.addr; if(bg->bg_id == graph_id){ // This is the bus graph we have been looking for return bg; } } } return NULL; } /* close the bus graph */ void BusNetwork::CloseBusGraph(BusGraph* bg) { if(bg == NULL) return; Word xValue; xValue.addr = bg; SecondoSystem::GetCatalog()->CloseObject(nl->SymbolAtom( "busgraph" ), xValue); } /* given a bus stop and time, it returns oid of the moving bus belonging to that bus route and direction as well as coving the time */ struct Id_Time{ int oid; double time; Id_Time(){} Id_Time(int id, double t):oid(id), time(t){} Id_Time(const Id_Time& id_t):oid(id_t.oid), time(id_t.time){} Id_Time& operator=(const Id_Time& id_time) { oid = id_time.oid; time = id_time.time; return *this; } bool operator<(const Id_Time& id_time) const { return time < id_time.time; } void Print() { cout<<"oid "<GetId(); ////////////////////////////////////////////////////////////////// ////////////get the unique id for the bus route///////////////// ////////////////////////////////////////////////////////////////// CcInt* search_id1 = new CcInt(true, br_id); BTreeIterator* btree_iter1 = btree_br->ExactMatch(search_id1); int br_uoid = 0; while(btree_iter1->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter1->GetId(), false); Bus_Route* br = (Bus_Route*)tuple->GetAttribute(BusNetwork::BN_BR); if(br->GetUp() == bs->GetUp()){ br_uoid = ((CcInt*)tuple->GetAttribute(BusNetwork::BN_BR_OID))->GetIntval(); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter1; search_id1->DeleteIfAllowed(); assert(br_uoid > 0); // cout<<"br_uoid "<ExactMatch(search_id2); const double delta_dist = 0.01; vector res_list; while(btree_iter2->Next()){ Tuple* tuple = bustrips_rel->GetTuple(btree_iter2->GetId(), false); int brid = ((CcInt*)tuple->GetAttribute(BN_REFBR_OID))->GetIntval(); assert(brid == br_uoid); MPoint* mo_bus = (MPoint*)tuple->GetAttribute(BN_BUSTRIP_MP); Periods* peri = new Periods(0); mo_bus->DefTime(*peri); // cout<<"periods "<<*peri<Contains(t)){ // cout<<"periods containt instant "<GetNoComponents();i++){ UPoint unit; mo_bus->Get(i, unit); Point p0 = unit.p0; Point p1 = unit.p1; // cout<Distance(p0)<Distance(p0) // <<" dist2 "<Distance(p1)<Distance(p0) < delta_dist && bs_loc->Distance(p1) < delta_dist){ bus_oid = ((CcInt*)tuple->GetAttribute(BN_BUS_OID))->GetIntval(); double delta_t = fabs(unit.timeInterval.start.ToDouble() - t.ToDouble()); Id_Time* id_time = new Id_Time(bus_oid, delta_t); res_list.push_back(*id_time); delete id_time; } } } peri->DeleteIfAllowed(); tuple->DeleteIfAllowed(); } delete btree_iter2; search_id2->DeleteIfAllowed(); sort(res_list.begin(), res_list.end()); // for(unsigned int i = 0;i < res_list.size();i++) // res_list[i].Print(); // cout<<"res_list size "< 0); bus_oid = res_list[0].oid; assert(bus_oid > 0); return bus_oid; } /* given a bus stop and time, it returns mpoint of the moving bus belonging to that bus route and direction as well as coving the time */ int BusNetwork::GetMOBus_MP(Bus_Stop* bs, Point* bs_loc, Instant t, MPoint& mp) { // cout<<"GetMOBus_MP() bs "<<*bs<GetId(); ////////////////////////////////////////////////////////////////// ////////////get the unique id for the bus route///////////////// ////////////////////////////////////////////////////////////////// CcInt* search_id1 = new CcInt(true, br_id); BTreeIterator* btree_iter1 = btree_br->ExactMatch(search_id1); int br_uoid = 0; while(btree_iter1->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter1->GetId(), false); Bus_Route* br = (Bus_Route*)tuple->GetAttribute(BusNetwork::BN_BR); if(br->GetUp() == bs->GetUp()){ br_uoid = ((CcInt*)tuple->GetAttribute(BusNetwork::BN_BR_OID))->GetIntval(); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter1; search_id1->DeleteIfAllowed(); assert(br_uoid > 0); // cout<<"br_uoid "<ExactMatch(search_id2); bool found = false; const double delta_dist = 0.01; vector res_list; while(btree_iter2->Next() && found == false){ Tuple* tuple = bustrips_rel->GetTuple(btree_iter2->GetId(), false); int brid = ((CcInt*)tuple->GetAttribute(BN_REFBR_OID))->GetIntval(); assert(brid == br_uoid); MPoint* mo_bus = (MPoint*)tuple->GetAttribute(BN_BUSTRIP_MP); Periods* peri = new Periods(0); mo_bus->DefTime(*peri); // cout<<"periods "<<*peri<Contains(t)){ // cout<<"periods "<<*peri<GetNoComponents();i++){ UPoint unit; mo_bus->Get(i, unit); Point p0 = unit.p0; Point p1 = unit.p1; if(bs_loc->Distance(p0) < delta_dist && unit.timeInterval.Contains(t)){ mp = *mo_bus; bus_oid = ((CcInt*)tuple->GetAttribute(BN_BUS_OID))->GetIntval(); found = true; break; } } } peri->DeleteIfAllowed(); tuple->DeleteIfAllowed(); } if(bus_oid <= 0) cout<<"time "<DeleteIfAllowed(); assert(bus_oid > 0); return bus_oid; } /* find the bus trip by input oid */ void BusNetwork::GetMOBUS(int trip_id, MPoint& mp, int& br_uid) { CcInt* search_id = new CcInt(true, trip_id); BTreeIterator* btree_iter = btree_trip_oid->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = bustrips_rel->GetTuple(btree_iter->GetId(), false); MPoint* bus_trip = (MPoint*)tuple->GetAttribute(BN_BUSTRIP_MP); int id = ((CcInt*)tuple->GetAttribute(BN_BUS_OID))->GetIntval(); assert(id == trip_id); br_uid = ((CcInt*)tuple->GetAttribute(BN_REFBR_OID))->GetIntval(); mp = *bus_trip; tuple->DeleteIfAllowed(); } delete btree_iter; search_id->DeleteIfAllowed(); assert(br_uid > 0); } /* from the input bus route unique id, find its geo data */ void BusNetwork::GetBusRouteGeoData(int br_uoid, SimpleLine& sl) { CcInt* search_id = new CcInt(true, br_uoid); BTreeIterator* btree_iter = btree_br_uoid->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter->GetId(), false); Bus_Route* br = (Bus_Route*)tuple->GetAttribute(BN_BR); br->GetGeoData(sl); tuple->DeleteIfAllowed(); } delete btree_iter; search_id->DeleteIfAllowed(); } ///////////////////////////////////////////////////////////////////////////// string BN::BusStopsPaveTypeInfo = "(rel (tuple ((Bus_stop busstop) (Pave_loc1 genloc)\ (Pave_loc2 point)(Bus_stop_loc point))))"; string BN::BusTimeTableTypeInfo = "(rel (tuple ((stop_loc point) (bus_stop busstop) (whole_time periods) \ (schedule_interval real) (loc_id int) (bus_uoid int))))"; string BN::RTreeBusStopsPaveTypeInfo = "(rtree (tuple ((Bus_stop busstop) (Pave_loc1 genloc)\ (Pave_loc2 point)(Bus_stop_loc point))) point FALSE)"; BN::BN(BusNetwork* n):bn(n), count(0), resulttype(NULL) { } BN::~BN() { if(resulttype != NULL) delete resulttype; } void BN::GetStops() { Relation* rel = bn->GetBS_Rel(); if(rel == NULL || rel->GetNoTuples() == 0) return; for(int i = 1; i <= rel->GetNoTuples();i++){ Tuple* bs_tuple = rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BusNetwork::BN_BS); bs_list.push_back(*bs); bs_tuple->DeleteIfAllowed(); } } /* copy bus routes from busnetwork */ void BN::GetRoutes() { Relation* rel = bn->GetBR_Rel(); if(rel == NULL || rel->GetNoTuples() == 0) return; for(int i = 1; i <= rel->GetNoTuples();i++){ Tuple* br_tuple = rel->GetTuple(i, false); Bus_Route* br = (Bus_Route*)br_tuple->GetAttribute(BusNetwork::BN_BR); br_list.push_back(*br); br_tuple->DeleteIfAllowed(); } } bool BSCompare(const Bus_Stop& bs1, const Bus_Stop& bs2) { if(bs1.GetId() < bs2.GetId()) return true; else if(bs1.GetId() == bs2.GetId()){ if(bs1.GetStopId() < bs2.GetStopId()){ return true; }else return false; }else return false; } /* map bus stops to the pavements */ void BN::MapBSToPavements(R_Tree<2,TupleId>* rtree, Relation* pave_rel, int w, float para) { // if(type == "Berlin") w = 2*w; // else if(type == "Houston") w = 4*w; // else{ // cout<<"invalid value "< stop_list; for(int i = 1;i <= bn->GetBS_Rel()->GetNoTuples();i++){ Tuple* bs_tuple = bn->GetBS_Rel()->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BusNetwork::BN_BS); stop_list.push_back(*bs); bs_tuple->DeleteIfAllowed(); } // cout<* rtree, Relation* pave_rel, int w) { // w = 2*w; // if(type == "Berlin") w = 2*w; // else if(type == "Houston") w = 4*w; // else{ // cout<<"invalid value "<GetBusStopGeoData(&bs1, &p1); Point p2; bn->GetBusStopGeoData(&bs2, &p2); // cout<<"bs1 "<StartBulkLoad(); if(AlmostEqual(p1.GetX(), p2.GetX())){ double miny = MIN(p1.GetY(), p2.GetY()); double maxy = MAX(p1.GetY(), p2.GetY()); Point lp(true, p1.GetX(), miny - w); Point rp(true, p1.GetX(), maxy + w); HalfSegment hs(true, lp, rp); hs.attr.edgeno = 0; *l += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *l += hs; }else if(AlmostEqual(p1.GetY(), p2.GetY())){ double minx = MIN(p1.GetX(), p2.GetX()); double maxx = MAX(p1.GetX(), p2.GetX()); Point lp(true, minx - w, p1.GetY()); Point rp(true, maxx + w, p1.GetY()); HalfSegment hs(true, lp, rp); hs.attr.edgeno = 0; *l += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *l += hs; }else{ double a = (p1.GetY() - p2.GetY())/(p1.GetX() - p2.GetX()); double b = p1.GetY() - a*p1.GetX(); double minx = MIN(p1.GetX(), p2.GetX()); double maxx = MAX(p1.GetX(), p2.GetX()); minx -= w; maxx += w; Point lp(true, minx, a*minx + b); Point rp(true, maxx, a*maxx + b); HalfSegment hs(true, lp, rp); hs.attr.edgeno = 0; *l += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *l += hs; } l->EndBulkLoad(); //////////////////////////////////////////////////////////////////////////// ////////////////get the intersection point of the line and pavements/////// //////////////////////////////////////////////////////////////////////////// // cout<<"l length: "<Length()<<" dist p1 p2 "< it_p_list; SmiRecordId adr = rtree->RootRecordId(); DFTraverse(rtree, pave_rel, adr, l, it_p_list); l->DeleteIfAllowed(); // cout<= 2); Point midp(true, (p1.GetX() + p2.GetX())/2, (p1.GetY() + p2.GetY())/2); /* for(unsigned int i = 0;i < it_p_list.size();i++){ bs_list.push_back(bs1); Loc loc(0.0, 0.0); GenLoc genloc(1, loc); genloc_list.push_back(genloc); geo_list.push_back(it_p_list[i].loc); }*/ ////////////get the two closest points //////////////////////////// for(unsigned int i = 0;i < it_p_list.size();i++){ it_p_list[i].dist = it_p_list[i].loc.Distance(midp); } vector it_p_list1; vector it_p_list2; if(AlmostEqual(p1.GetX(), p2.GetX())){ for(unsigned int i = 0;i < it_p_list.size();i++){ if(it_p_list[i].loc.GetY() > midp.GetY()){ it_p_list1.push_back(it_p_list[i]); }else it_p_list2.push_back(it_p_list[i]); } }else{ for(unsigned int i = 0;i < it_p_list.size();i++){ if(it_p_list[i].loc.GetX() > midp.GetX()){ it_p_list1.push_back(it_p_list[i]); }else it_p_list2.push_back(it_p_list[i]); } } ////////////////////////////////////////////////////////////////////////// ///////////////map each point to its corresponding bus stop/////////////// ///////////////////////////////////////////////////////////////////////// // cout<GetTuple(it_p_list1[0].tid, false); int oid1 = ((CcInt*)pave_tuple1->GetAttribute(DualGraph::OID))->GetIntval(); Region* reg1 = (Region*)pave_tuple1->GetAttribute(DualGraph::PAVEMENT); Point q1 = it_p_list1[0].loc; Loc loc1(q1.GetX() - reg1->BoundingBox().MinD(0), q1.GetY() - reg1->BoundingBox().MinD(1)); GenLoc genloc1(oid1, loc1); assert(q1.Inside(*reg1)); // if(q1.Inside(*reg1) == false){ // cout<<"oid1 "<<"q1 "<DeleteIfAllowed(); bs_list.push_back(bs1); genloc_list.push_back(genloc1); geo_list.push_back(it_p_list1[0].loc); ///////////////////////////////////////////////////////////////////// Tuple* pave_tuple2 = pave_rel->GetTuple(it_p_list2[0].tid, false); int oid2 = ((CcInt*)pave_tuple2->GetAttribute(DualGraph::OID))->GetIntval(); Region* reg2 = (Region*)pave_tuple2->GetAttribute(DualGraph::PAVEMENT); Point q2 = it_p_list2[0].loc; Loc loc2(q2.GetX() - reg2->BoundingBox().MinD(0), q2.GetY() - reg2->BoundingBox().MinD(1)); GenLoc genloc2(oid2, loc2); assert(q2.Inside(*reg2)); // if(q2.Inside(*reg2) == false){ // cout<<"oid2 "<DeleteIfAllowed(); bs_list.push_back(bs2); genloc_list.push_back(genloc2); geo_list.push_back(it_p_list2[0].loc); // cout<<"tid1 "<GetTuple(it_p_list1[0].tid, false); int oid1 = ((CcInt*)pave_tuple1->GetAttribute(DualGraph::OID))->GetIntval(); Region* reg1 = (Region*)pave_tuple1->GetAttribute(DualGraph::PAVEMENT); Point q1 = it_p_list1[0].loc; Loc loc1(q1.GetX() - reg1->BoundingBox().MinD(0), q1.GetY() - reg1->BoundingBox().MinD(1)); GenLoc genloc1(oid1, loc1); assert(q1.Inside(*reg1)); // if(q1.Inside(*reg1) == false){ // cout<<"oid1 "<DeleteIfAllowed(); bs_list.push_back(bs2); genloc_list.push_back(genloc1); geo_list.push_back(it_p_list1[0].loc); ///////////////////////////////////////////////////////////////////// Tuple* pave_tuple2 = pave_rel->GetTuple(it_p_list2[0].tid, false); int oid2 = ((CcInt*)pave_tuple2->GetAttribute(DualGraph::OID))->GetIntval(); Region* reg2 = (Region*)pave_tuple2->GetAttribute(DualGraph::PAVEMENT); Point q2 = it_p_list2[0].loc; Loc loc2(q2.GetX() - reg2->BoundingBox().MinD(0), q2.GetY() - reg2->BoundingBox().MinD(1)); GenLoc genloc2(oid2, loc2); assert(q2.Inside(*reg2)); // if(q2.Inside(*reg2) == false){ // cout<<"oid2 "<DeleteIfAllowed(); bs_list.push_back(bs1); genloc_list.push_back(genloc2); geo_list.push_back(it_p_list2[0].loc); // cout<<"tid1 "<* rtree, Relation* rel, SmiRecordId adr, Line* l, vector& it_p_list) { 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* dg_tuple2 = rel->GetTuple(e.info,false); Region* candi_reg = (Region*)dg_tuple2->GetAttribute(DualGraph::PAVEMENT); // if(l->Intersects(candi_reg->BoundingBox())){ if(l->Intersects(Region(candi_reg->BoundingBox()))){ /* Line* l1 = new Line(0); candi_reg->Boundary(l1); Points* ps = new Points(0); l->Crossings(*l1, *ps); for(int i = 0;i < ps->Size();i++){ Point p; ps->Get(i, p); MyPoint_Tid mpt(p, 0.0, e.info); it_p_list.push_back(mpt); // assert(p.Inside(*candi_reg)); } delete ps; delete l1;*/ for(int i1 = 0;i1 < l->Size();i1++){ HalfSegment hs1; l->Get(i1, hs1); if(hs1.IsLeftDomPoint() == false) continue; for(int i2 = 0;i2 < candi_reg->Size();i2++){ HalfSegment hs2; candi_reg->Get(i2, hs2); if(hs2.IsLeftDomPoint() == false) continue; Point p; if(hs1.Intersection(hs2, p)){ if(p.Inside(*candi_reg)){ MyPoint_Tid mpt(p, 0.0, e.info); it_p_list.push_back(mpt); } // MyPoint_Tid mpt(p, 0.0, e.info); // it_p_list.push_back(mpt); } } } } dg_tuple2->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; // if(l->Intersects(e.box)){ if(l->Intersects(Region(e.box))){ DFTraverse(rtree, rel, e.pointer, l, it_p_list); } } } delete node; } /* for each bus stop, we find its neighbor bus stops. the distance between them in the pavement area is smaller than a threshold value. e,g., 100m */ void BN::BsNeighbors1(DualGraph* dg, VisualGraph* vg, Relation* rel1, Relation* rel2, R_Tree<2,TupleId>* rtree) { // const double neighbor_dist = 200.0; const double neighbor_dist = 100.0; SmiRecordId adr = rtree->RootRecordId(); /////for each bus stop, find the neighbor candidates where the distance/// /////between them is smaller than D in Euclidean space///////////////// ////////////this is done by traversing the RTree////////////////////// for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* bs_pave_tuple = rel2->GetTuple(i, false); Point* loc = (Point*)bs_pave_tuple->GetAttribute(BN_PAVE_LOC2); Bus_Stop* bs1 = (Bus_Stop*)bs_pave_tuple->GetAttribute(BN_BUSSTOP); vector neighbor_list; ////////////Euclidean distance as a bound/////////////////////// DFTraverse2(rtree, rel2, adr , loc, neighbor_list, neighbor_dist); // cout<<"bs "<<*bs<<" "<GetTuple(neighbor_list[j], false); Bus_Stop* bs2 = (Bus_Stop*)tuple2->GetAttribute(BN_BUSSTOP); if(bs1->GetId() != bs2->GetId()){ //different bus routes bs_list1.push_back(*bs1); bs_list2.push_back(*bs2); SimpleLine* sl = new SimpleLine(0); sl->fromLine(*path); path_sl_list.push_back(*sl); // cout<Length()<GetAttribute(BN_BUSLOC); Point* bus_loc2 = (Point*)tuple2->GetAttribute(BN_BUSLOC); Point sl_sp; assert(sl->AtPosition(0.0, true, sl_sp)); double d1 = sl_sp.Distance(*bus_loc1); double d2 = sl_sp.Distance(*bus_loc2); // cout<<"d1 "<AtPosition(sl->Length(), true, sl_ep)); HalfSegment hs1(true, *bus_loc1, sl_sp); HalfSegment hs2(true, *bus_loc2, sl_ep); SimpleLine* sub_sl1 = new SimpleLine(0); sub_sl1->StartBulkLoad(); hs1.attr.edgeno = 0; *sub_sl1 += hs1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *sub_sl1 += hs1; sub_sl1->EndBulkLoad(); sub_path1.push_back(*sub_sl1); SimpleLine* sub_sl2 = new SimpleLine(0); sub_sl2->StartBulkLoad(); hs2.attr.edgeno = 0; *sub_sl2 += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *sub_sl2 += hs2; sub_sl2->EndBulkLoad(); sub_path2.push_back(*sub_sl2); ///////////////////construct the whole path//////////////////// SimpleLine* sl2 = new SimpleLine(0); sl2->StartBulkLoad(); int edgeno = 0; HalfSegment hs_1(true, *bus_loc1, sl_sp); HalfSegment hs_2(true, *bus_loc2, sl_ep); hs_1.attr.edgeno = edgeno++; *sl2 += hs_1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *sl2 += hs_1; hs_2.attr.edgeno = edgeno++; *sl2 += hs_2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *sl2 += hs_2; for(int k = 0;k < sl->Size();k++){ HalfSegment hs; sl->Get(k, hs); if(!hs.IsLeftDomPoint()) continue; HalfSegment new_hs(true, hs.GetLeftPoint(), hs.GetRightPoint()); new_hs.attr.edgeno = edgeno++; *sl2 += new_hs; new_hs.SetLeftDomPoint(!new_hs.IsLeftDomPoint()); *sl2 += new_hs; } sl2->EndBulkLoad(); path2_sl_list.push_back(*sl2); sl2->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// sub_sl1->DeleteIfAllowed(); sub_sl2->DeleteIfAllowed(); }else{ Point sl_ep; assert(sl->AtPosition(sl->Length(), true, sl_ep)); HalfSegment hs1(true, *bus_loc2, sl_sp); HalfSegment hs2(true, *bus_loc1, sl_ep); SimpleLine* sub_sl1 = new SimpleLine(0); sub_sl1->StartBulkLoad(); hs1.attr.edgeno = 0; *sub_sl1 += hs1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *sub_sl1 += hs1; sub_sl1->EndBulkLoad(); sub_path1.push_back(*sub_sl1); SimpleLine* sub_sl2 = new SimpleLine(0); sub_sl2->StartBulkLoad(); hs2.attr.edgeno = 0; *sub_sl2 += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *sub_sl2 += hs2; sub_sl2->EndBulkLoad(); sub_path2.push_back(*sub_sl2); ///////////////////construct the whole path//////////////////// SimpleLine* sl2 = new SimpleLine(0); sl2->StartBulkLoad(); int edgeno = 0; HalfSegment hs_1(true, *bus_loc2, sl_sp); HalfSegment hs_2(true, *bus_loc1, sl_ep); hs_1.attr.edgeno = edgeno++; *sl2 += hs_1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *sl2 += hs_1; hs_2.attr.edgeno = edgeno++; *sl2 += hs_2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *sl2 += hs_2; for(int k = 0;k < sl->Size();k++){ HalfSegment hs; sl->Get(k, hs); if(!hs.IsLeftDomPoint()) continue; HalfSegment new_hs(true, hs.GetLeftPoint(), hs.GetRightPoint()); new_hs.attr.edgeno = edgeno++; *sl2 += new_hs; new_hs.SetLeftDomPoint(!new_hs.IsLeftDomPoint()); *sl2 += new_hs; } sl2->EndBulkLoad(); path2_sl_list.push_back(*sl2); sl2->DeleteIfAllowed(); ////////////////////////////////////////////////////////////// sub_sl1->DeleteIfAllowed(); sub_sl2->DeleteIfAllowed(); } ////////////////////////////////////////////////////// bs_uoid_list.push_back(bs1->GetUOid()); sl->DeleteIfAllowed(); } neighbor_no++; tuple2->DeleteIfAllowed(); } path->DeleteIfAllowed(); } } bs_pave_tuple->DeleteIfAllowed(); } } /* traverse R-tree to find neighbor points (bus stops), but does not include the bus stops that have the same spatial location in space. because this kinds of connection will be discovered later by another edge in bus network graph. */ void BN::DFTraverse2(R_Tree<2,TupleId>* rtree, Relation* rel, SmiRecordId adr, Point* loc, vector& neighbor_list, double dist) { const double delta_dist = 0.001; 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* dg_tuple2 = rel->GetTuple(e.info,false); Point* bus_loc = (Point*)dg_tuple2->GetAttribute(BN_PAVE_LOC2); double d = loc->Distance(*bus_loc); if( d < dist && d > delta_dist){ neighbor_list.push_back(e.info); } dg_tuple2->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(loc->Distance(e.box) < dist){ DFTraverse2(rtree, rel, e.pointer, loc, neighbor_list, dist); } } } delete node; } /* calculate the obstructed distance between the two bus stops. rel1: triangle relation rel2: bus stops and pavements location relation use the same procedure in PaveGraph.cpp WalkSP ShortestPath (calculate the shortest path between two locations on the pavements) */ bool BN::FindNeighbor(int tid1, int tid2, DualGraph* dg, VisualGraph* vg, Relation* rel1, Relation* rel2, double dist, Line* res) { // cout<<"tid1 "<GetTuple(tid1, false); GenLoc* genloc1 = (GenLoc*)tuple1->GetAttribute(BN_PAVE_LOC1); Point* loc_1 = (Point*)tuple1->GetAttribute(BN_PAVE_LOC2); Tuple* tuple2 = rel2->GetTuple(tid2, false); GenLoc* genloc2 = (GenLoc*)tuple2->GetAttribute(BN_PAVE_LOC1); Point* loc_2 = (Point*)tuple2->GetAttribute(BN_PAVE_LOC2); Point loc1 = *loc_1; Point loc2 = *loc_2; // GenLoc gloc1 = *genloc1; // GenLoc gloc2 = *genloc2; GenLoc gloc1(genloc1->GetOid(), genloc1->GetLoc()); GenLoc gloc2(genloc2->GetOid(), genloc2->GetLoc()); tuple1->DeleteIfAllowed(); tuple2->DeleteIfAllowed(); // cout<No_Of_Node(); int oid1 = gloc1.GetOid(); int oid2 = gloc2.GetOid(); oid1 -= dg->min_tri_oid_1; oid2 -= dg->min_tri_oid_1; if(oid1 < 1 || oid1 > no_node_graph){ cout<<"loc1 does not exist"< no_node_graph){ cout<<"loc2 does not exist"<GetNodeRel()->GetTuple(oid1, false); Region* reg1 = (Region*)tuple_1->GetAttribute(DualGraph::PAVEMENT); if(loc1.Inside(*reg1) == false){ tuple_1->DeleteIfAllowed(); cout<<"point1 is not inside the polygon"<GetNodeRel()->GetTuple(oid2, false); Region* reg2 = (Region*)tuple_2->GetAttribute(DualGraph::PAVEMENT); if(loc2.Inside(*reg2) == false){ tuple_1->DeleteIfAllowed(); tuple_2->DeleteIfAllowed(); cout<<"point2 is not inside the polygon"<DeleteIfAllowed(); tuple_2->DeleteIfAllowed(); //////////////////////////////////////////////////////////////// ////////////////find all visibility nodes to start node///////// ///////connect them to the visibility graph///////////////////// priority_queue path_queue; vector expand_path; VGraph* vg1 = new VGraph(dg, NULL, rel1, vg->GetNodeRel()); vg1->GetVisibilityNode(oid1, loc1); assert(vg1->oids1.size() == vg1->p_list.size()); if(vg1->oids1.size() == 1){//start point equasl to triangle vertex double w = loc1.Distance(loc2); path_queue.push(WPath_elem(-1, 0, vg1->oids1[0], w, loc1, 0.0)); expand_path.push_back(WPath_elem(-1, 0, vg1->oids1[0], w, loc1, 0.0)); }else{ double w = loc1.Distance(loc2); path_queue.push(WPath_elem(-1, 0, -1, w, loc1,0.0));//start location expand_path.push_back(WPath_elem(-1, 0, -1, w, loc1,0.0));//start location int prev_index = 0; for(unsigned int i = 0;i < vg1->oids1.size();i++){ int expand_path_size = expand_path.size(); double d = loc1.Distance(vg1->p_list[i]); w = d + vg1->p_list[i].Distance(loc2); path_queue.push(WPath_elem(prev_index, expand_path_size, vg1->oids1[i], w, vg1->p_list[i], d)); expand_path.push_back(WPath_elem(prev_index, expand_path_size, vg1->oids1[i], w, vg1->p_list[i], d)); } } delete vg1; //////////////////////////////////////////////////////////////////////////// ////////////////find all visibility nodes to the end node///////// VGraph* vg2 = new VGraph(dg, NULL, rel1, vg->GetNodeRel()); vg2->GetVisibilityNode(oid2, loc2); assert(vg2->oids1.size() == vg2->p_list.size()); //if the end node equals to triangle vertex. //it can be connected by adjacency list //we don't conenct it to the visibility graph Points* neighbor_end = new Points(0); neighbor_end->StartBulkLoad(); if(vg2->oids1.size() > 1){ for(unsigned int i = 0;i < vg2->oids1.size();i++){ Tuple* loc_tuple = vg->GetNodeRel()->GetTuple(vg2->oids1[i], false); Point* loc = (Point*)loc_tuple->GetAttribute(VisualGraph::LOC); *neighbor_end += *loc; loc_tuple->DeleteIfAllowed(); } neighbor_end->EndBulkLoad(); } /////////////////////searching path/////////////////////////////////// bool find = false; vector mark_flag; for(int i = 1;i <= vg->GetNodeRel()->GetNoTuples();i++) mark_flag.push_back(false); WPath_elem dest; while(path_queue.empty() == false){ WPath_elem top = path_queue.top(); path_queue.pop(); // top.Print(); if(top.real_w > dist){ //already larger than the threshold distance neighbor_end->DeleteIfAllowed(); delete vg2; return false; } if(AlmostEqual(top.loc, loc2)){ find = true; dest = top; break; } //do not consider the start point //if it does not equal to the triangle vertex //its adjacent nodes have been found already and put into the queue if(top.tri_index > 0 && mark_flag[top.tri_index - 1] == false){ vector adj_list; vg->FindAdj(top.tri_index, adj_list); int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ if(mark_flag[adj_list[i] - 1]) continue; int expand_path_size = expand_path.size(); Tuple* loc_tuple = vg->GetNodeRel()->GetTuple(adj_list[i], false); Point* loc = (Point*)loc_tuple->GetAttribute(VisualGraph::LOC); double w1 = top.real_w + top.loc.Distance(*loc); double w2 = w1 + loc->Distance(loc2); path_queue.push(WPath_elem(pos_expand_path, expand_path_size, adj_list[i], w2 ,*loc, w1)); expand_path.push_back(WPath_elem(pos_expand_path, expand_path_size, adj_list[i], w2, *loc, w1)); loc_tuple->DeleteIfAllowed(); mark_flag[top.tri_index - 1] = true; } } ////////////check visibility points to the end point//////////// if(neighbor_end->Size() > 0){ const double delta_dist = 0.1;//in theory, it should be 0.0 if(top.loc.Distance(neighbor_end->BoundingBox()) < delta_dist){ for(unsigned int i = 0;i < vg2->oids1.size();i++){ if(top.tri_index == vg2->oids1[i]){ int pos_expand_path = top.cur_index; int expand_path_size = expand_path.size(); double w1 = top.real_w + top.loc.Distance(loc2); double w2 = w1; path_queue.push(WPath_elem(pos_expand_path, expand_path_size, -1, w2 ,loc2, w1)); expand_path.push_back(WPath_elem(pos_expand_path, expand_path_size, -1, w2, loc2, w1)); break; } } } } /////////////////////////////////////////////////////////////// } neighbor_end->DeleteIfAllowed(); delete vg2; /////////////construct path/////////////////////////////////////////// double len = 0.0; if(find){ res->StartBulkLoad(); while(dest.prev_index != -1){ Point p1 = dest.loc; dest = expand_path[dest.prev_index]; Point p2 = dest.loc; ///////////////////////////////////////////////////// HalfSegment hs; hs.Set(true, p1, p2); hs.attr.edgeno = 0; *res += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *res += hs; ///////////////////////////////////////////////////// } res->EndBulkLoad(); len = res->Length(); } if(len < dist) return true; else return false; } /* for each bus stop, find the bus stops that have the same spatial location but belong to different bus routes. these are the places that people can do transfer. we also return the unique id of the first bus stop */ void BN::BsNeighbors2() { R_Tree<2,TupleId>* rtree = bn->GetBS_RTree(); SmiRecordId adr = rtree->RootRecordId(); Relation* bs_rel = bn->GetBS_Rel(); for(int i = 1;i <= bs_rel->GetNoTuples();i++){ Tuple* bs_tuple = bs_rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BusNetwork::BN_BS); Point* bs_loc = (Point*)bs_tuple->GetAttribute(BusNetwork::BS_GEO); vector neighbor_tid; DFTraverse3(rtree, bs_rel, adr, bs_loc,neighbor_tid); // cout<<"bs "<<*bs<<" neighbor size "<GetTuple(neighbor_tid[j], false); Bus_Stop* bs2 = (Bus_Stop*)bs_tuple2->GetAttribute(BusNetwork::BN_BS); // cout<<"neighbor "<<*bs2<GetUOid()); bs_tuple2->DeleteIfAllowed(); } } bs_tuple->DeleteIfAllowed(); } } /* find bus stops that map to the same spatial point */ void BN::DFTraverse3(R_Tree<2,TupleId>* rtree, Relation* rel, SmiRecordId adr, Point* loc, vector& neighbor_list) { const double delta_dist = 0.001; 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* dg_tuple2 = rel->GetTuple(e.info,false); Point* bus_loc = (Point*)dg_tuple2->GetAttribute(BusNetwork::BS_GEO); double d = loc->Distance(*bus_loc); if(d < delta_dist){ neighbor_list.push_back(e.info); } dg_tuple2->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(loc->Distance(e.box) < delta_dist){ DFTraverse3(rtree, rel, e.pointer, loc, neighbor_list); } } } delete node; } /* find all adjacent nodes of the given node id */ void BN::GetAdjNodeBG1(BusGraph* bg, int nodeid) { if(bg->node_rel == NULL){ cout<<"no bus graph node rel"< bg->node_rel->GetNoTuples()){ cout<<"invalid node id "<node_rel->GetNoTuples()<<" nodes "<edge_rel1->GetNoTuples() + bg->edge_rel2->GetNoTuples() + bg->edge_rel3->GetNoTuples() <<" edges "<node_rel->GetTuple(nodeid, false); Bus_Stop* bs1 = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); // cout<<*bs1< tid_list1; bg->FindAdj1(nodeid, tid_list1); for(unsigned int i = 0;i < tid_list1.size();i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(tid_list1[i], false); Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH1); bs_list1.push_back(*bs1); bs_list2.push_back(*bs2); path_sl_list.push_back(*path); edge_tuple->DeleteIfAllowed(); type_list.push_back(1); } /////////////////////////////////////////////////////////////////////////// //////the second kind of connection (no path; the same spatial location)//// //////////////////////////////////////////////////////////////////////////// vector tid_list2; bg->FindAdj2(nodeid, tid_list2); for(unsigned int i = 0;i < tid_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(tid_list2[i], false); Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); bs_list1.push_back(*bs1); bs_list2.push_back(*bs2); path_sl_list.push_back(*path); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); type_list.push_back(2); } //////////////////////////////////////////////////////////////////// //////the third kind of connection (connected by moving buses)////// //////////////////////////////////////////////////////////////////// vector tid_list3; bg->FindAdj3(nodeid, tid_list3); // cout<<"connection 3 size: "<edge_rel3->GetTuple(tid_list3[i], false); Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); bs_list1.push_back(*bs1); bs_list2.push_back(*bs2); path_sl_list.push_back(*path); edge_tuple->DeleteIfAllowed(); type_list.push_back(3); } bs_tuple->DeleteIfAllowed(); // /* test adjacency list1*/ // for(int i = 1;i <= bg->node_rel->GetNoTuples();i++){ // Tuple* node_tuple = bg->node_rel->GetTuple(i, false); // cout<<*node_tuple< tid_list; // bg->FindAdj1(i, tid_list); // for(unsigned int j = 0;j < tid_list.size();j++){ // Tuple* edge_tuple = bg->edge_rel1->GetTuple(tid_list[j], false); // Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH1); // cout<Length()<DeleteIfAllowed(); // } // node_tuple->DeleteIfAllowed(); // } /*test btree built on node relation*/ // for(int i = 1;i <= bg->node_rel->GetNoTuples();i++){ // Tuple* node_tuple = bg->node_rel->GetTuple(i, false); // Bus_Stop* bs = (Bus_Stop*)node_tuple->GetAttribute(BusGraph::BG_NODE); // // CcInt* search_id = new CcInt(true, bs->GetUOid()); // BTreeIterator* btree_iter = bg->btree_node->ExactMatch(search_id); // // while(btree_iter->Next()){ // cout<<"tid1 "<GetTupleId() // <<"tid2 "<GetId()<DeleteIfAllowed(); // } // /* test adjacency list2*/ // for(int i = 1;i <= bg->node_rel->GetNoTuples();i++){ // Tuple* node_tuple = bg->node_rel->GetTuple(i, false); // // vector tid_list; // bg->FindAdj2(i, tid_list); // for(unsigned int j = 0;j < tid_list.size();j++){ // Tuple* edge_tuple = bg->edge_rel2->GetTuple(tid_list[j], false); // Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2); // edge_tuple->DeleteIfAllowed(); // } // // if(tid_list.size() > 0){ // cout<<*node_tuple<<" neighbor size "<DeleteIfAllowed(); // } // /* test adjacency list3*/ // for(int i = 1;i <= bg->node_rel->GetNoTuples();i++){ // Tuple* node_tuple = bg->node_rel->GetTuple(i, false); // // vector tid_list; // bg->FindAdj3(i, tid_list); // for(unsigned int j = 0;j < tid_list.size();j++){ // Tuple* edge_tuple = bg->edge_rel3->GetTuple(tid_list[j], false); // edge_tuple->DeleteIfAllowed(); // } // // if(tid_list.size() > 0){ // cout<<" neighbor size "<DeleteIfAllowed(); // } } /* get the neighbor nodes of a given bus stop notes: the result may have the same value (type 3). this is becuase some bus routes have night schedule (day schedule (workday and weekend)) (night schedule (0:00-5:00 20:00-24:00)) there can be 4 tuples having the same value */ void BN::GetAdjNodeBG2(BusGraph* bg, Bus_Stop* bs) { int bs_tid = -1; CcInt* search_id = new CcInt(true, bs->GetUOid()); BTreeIterator* btree_iter = bg->btree_node->ExactMatch(search_id); while(btree_iter->Next()){ bs_tid = btree_iter->GetId(); } delete btree_iter; search_id->DeleteIfAllowed(); if(!(1 <= bs_tid && bs_tid <= bg->node_rel->GetNoTuples())){ cout<<"invalid bus stop "<<*bs<GetNoTuples();i++){ Tuple* bs_table_tuple = table_rel->GetTuple(i, false); int bs_uoid = ((CcInt*)bs_table_tuple->GetAttribute(BN_T_BUS_UOID))->GetIntval(); vector tid_list; tid_list.push_back(i); int j = i + 1; while(j <= table_rel->GetNoTuples()){ Tuple* tuple = table_rel->GetTuple(j, false); int bs_uoid2 = ((CcInt*)tuple->GetAttribute(BN_T_BUS_UOID))->GetIntval(); tuple->DeleteIfAllowed(); if(bs_uoid2 == bs_uoid){ tid_list.push_back(j); j++; }else{ i = j - 1; break; } } // cout< table_rel->GetNoTuples()){ bs_table_tuple->DeleteIfAllowed(); break; } } // cout< tid_list, Relation* mo_rel, BTree* btree_mo) { const double delta_dist = 0.01; for(unsigned int i = 0;i < tid_list.size();i++){ Tuple* table_tuple = table_rel->GetTuple(tid_list[i], false); Point* bs_loc = (Point*)table_tuple->GetAttribute(BN_T_GEOBS); Bus_Stop* bs = (Bus_Stop*)table_tuple->GetAttribute(BN_T_BS); Periods* peri = (Periods*)table_tuple->GetAttribute(BN_T_P); double schedu = ((CcReal*)table_tuple->GetAttribute(BN_T_S))->GetRealval(); int bs_uoid = ((CcInt*)table_tuple->GetAttribute(BN_T_BUS_UOID))->GetIntval(); /////////////////find the bus trip.///////////////////////////////// /////////////////get the path to the next bus stop if exists//////////// // int count = 0; CcInt* search_id = new CcInt(true, bs->GetId()); BTreeIterator* btree_iter = btree_mo->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* mo_tuple = mo_rel->GetTuple(btree_iter->GetId(), false); unsigned int bus_r_id = ((CcInt*)mo_tuple->GetAttribute(RoadDenstiy::BR_ID5))->GetIntval(); assert(bus_r_id == bs->GetId()); bool dir = ((CcBool*)mo_tuple->GetAttribute( RoadDenstiy::MO_BUS_DIRECTION))->GetBoolval(); bool find = false; if(dir == bs->GetUp()){ //the same direction MPoint* mo = (MPoint*)mo_tuple->GetAttribute(RoadDenstiy::BUS_TRIP); ///////////////////////////////////////////////////////////////// ////////////////find the bus stop in units/////////////////////// //////////////////////////////////////////////////////////////// int j = 0; for(;j < mo->GetNoComponents();j++){ UPoint up; mo->Get(j, up); Point lp = up.p0; Point rp = up.p1; if(bs_loc->Distance(lp) < delta_dist && bs_loc->Distance(rp) < delta_dist){ // count++; break; } } assert(j < mo->GetNoComponents()); if(j == mo->GetNoComponents() - 1){///last stop in the route // cout<<"the last bus stop"<GetNoComponents();j++){//start from the next unit UPoint up; mo->Get(j, up); Point lp = up.p0; Point rp = up.p1; if(lp.Distance(rp) < delta_dist)//next bus stop break; else{ sub_move.Add(up); time_move += up.timeInterval.end.ToDouble() - up.timeInterval.start.ToDouble(); } } sub_move.EndBulkLoad(); // cout<Length()<GetId(), bs->GetStopId() + 1, bs->GetUp()); ///////////////////////////////////////////////////////////////// ///////////////////////store the result -2/////////////////////// //////////////////////////////////////////////////////////////// bs_uoid_list.push_back(bs_uoid); bs_list1.push_back(*bs); bs_list2.push_back(*neighbor_bs); // bus_trip_list.push_back(sub_move); duration.push_back(*peri); schedule_interval.push_back(schedu); Line traj(0); sub_move.Trajectory(traj); SimpleLine sl_traj(0); sl_traj.fromLine(traj); path_sl_list.push_back(sl_traj); delete neighbor_bs; time_cost_list.push_back(time_move); }else{ Bus_Stop* neighbor_bs = new Bus_Stop(true, bs->GetId(), bs->GetStopId() - 1, bs->GetUp()); ///////////////////////////////////////////////////////////////// ///////////////////////store the result -3/////////////////////// //////////////////////////////////////////////////////////////// bs_uoid_list.push_back(bs_uoid); bs_list1.push_back(*bs); bs_list2.push_back(*neighbor_bs); // bus_trip_list.push_back(sub_move); duration.push_back(*peri); schedule_interval.push_back(schedu); Line traj(0); sub_move.Trajectory(traj); SimpleLine sl_traj(0); sl_traj.fromLine(traj); path_sl_list.push_back(sl_traj); delete neighbor_bs; time_cost_list.push_back(time_move); } assert(j < mo->GetNoComponents()); } /////////////////////////////////////////////////////////////////// find = true; } mo_tuple->DeleteIfAllowed(); if(find)break; } delete btree_iter; search_id->DeleteIfAllowed(); ///////////////////////////////////////////////////////////////////// /* cout<<"count "<DeleteIfAllowed(); } } /* decompose a bus route into a set of segments. the result is a stream of values (1) a segment; (2) the union of two segments each of which is from its bus route a bus route has up and down routes */ void BN::DecomposeBR(Line* l1, Line* l2) { // cout<<"decompose a bus route"<fromLine(*l1); SimpleLine* sl2 = new SimpleLine(0); sl2->fromLine(*l2); SpacePartition* sp = new SpacePartition(); vector seq_halfseg1; //reorder it from start to end vector seq_halfseg2; sp->ReorderLine(sl1, seq_halfseg1); sp->ReorderLine(sl2, seq_halfseg2); sl1->DeleteIfAllowed(); sl2->DeleteIfAllowed(); delete sp; // cout< p.Distance(p2)){ //reorder seq halfseg2 vector temp_list; for(int i = seq_halfseg2.size() - 1;i >= 0;i--){ MyHalfSegment mhs = seq_halfseg2[i]; MyHalfSegment new_mhs(true, mhs.to, mhs.from); } seq_halfseg2.clear(); for(unsigned int i = 0;i < temp_list.size();i++){ seq_halfseg2.push_back(temp_list[i]); } } // cout<StartBulkLoad(); ul->StartBulkLoad(); HalfSegment hs; hs.Set(true, seq_halfseg1[i].from, seq_halfseg1[i].to); int edgeno1 = 0; int edgeno_u = 0; hs.attr.edgeno = edgeno1++; edgeno_u++; *l += hs; *ul += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *l += hs; *ul += hs; l->EndBulkLoad(); line_list1.push_back(*l); l->DeleteIfAllowed(); if( i >= 1){ HalfSegment hs0; hs0.Set(true, seq_halfseg1[i - 1].from, seq_halfseg1[i - 1].to); hs0.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs0; hs0.SetLeftDomPoint(!hs0.IsLeftDomPoint()); *ul += hs0; } if( i + 1 < seq_halfseg1.size()){ HalfSegment hs1; hs1.Set(true, seq_halfseg1[i + 1].from, seq_halfseg1[i + 1].to); hs1.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *ul += hs1; } if(i < seq_halfseg2.size()){ HalfSegment hs2; hs2.Set(true, seq_halfseg2[i].from, seq_halfseg2[i].to); hs2.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *ul += hs2; } if((i + 1) < seq_halfseg2.size()){ HalfSegment hs3; hs3.Set(true, seq_halfseg2[i + 1].from, seq_halfseg2[i + 1].to); hs3.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs3; hs3.SetLeftDomPoint(!hs3.IsLeftDomPoint()); *ul += hs3; } if( i >= 1 && (i - 1) < seq_halfseg2.size() ){ HalfSegment hs4; hs4.Set(true, seq_halfseg2[i - 1].from, seq_halfseg2[i - 1].to); hs4.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs4; hs4.SetLeftDomPoint(!hs4.IsLeftDomPoint()); *ul += hs4; } ul->EndBulkLoad(); line_list2.push_back(*ul); ul->DeleteIfAllowed(); } for(unsigned int i = 0;i < seq_halfseg2.size();i++){ Line* l = new Line(0); Line* ul = new Line(0); l->StartBulkLoad(); ul->StartBulkLoad(); HalfSegment hs; hs.Set(true, seq_halfseg2[i].from, seq_halfseg2[i].to); int edgeno1 = 0; int edgeno_u = 0; hs.attr.edgeno = edgeno1++; edgeno_u++; *l += hs; *ul += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *l += hs; *ul += hs; l->EndBulkLoad(); line_list1.push_back(*l); l->DeleteIfAllowed(); if( i >= 1 ){ HalfSegment hs0; hs0.Set(true, seq_halfseg2[i - 1].from, seq_halfseg2[i - 1].to); hs0.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs0; hs0.SetLeftDomPoint(!hs0.IsLeftDomPoint()); *ul += hs0; } if( (i + 1) < seq_halfseg2.size()){ HalfSegment hs1; hs1.Set(true, seq_halfseg2[i + 1].from, seq_halfseg2[i + 1].to); hs1.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *ul += hs1; } if(i < seq_halfseg1.size()){ HalfSegment hs2; hs2.Set(true, seq_halfseg1[i].from, seq_halfseg1[i].to); hs2.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *ul += hs2; } if((i + 1) < seq_halfseg1.size()){ HalfSegment hs3; hs3.Set(true, seq_halfseg1[i + 1].from, seq_halfseg1[i + 1].to); hs3.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs3; hs3.SetLeftDomPoint(!hs3.IsLeftDomPoint()); *ul += hs3; } if( i >= 1 && (i - 1) < seq_halfseg1.size() ){ HalfSegment hs4; hs4.Set(true, seq_halfseg1[i - 1].from, seq_halfseg1[i - 1].to); hs4.attr.edgeno = edgeno_u; edgeno_u++; *ul += hs4; hs4.SetLeftDomPoint(!hs4.IsLeftDomPoint()); *ul += hs4; } ul->EndBulkLoad(); line_list2.push_back(*ul); ul->DeleteIfAllowed(); } // cout<<"list1 size "<TextAtom(); nl->AppendText(examplelist, "createbusgraph(,,)"); return nl->TwoElemList( nl->TwoElemList(nl->StringAtom("Creation"), nl->StringAtom("Example Creation")), nl->TwoElemList(examplelist, nl->StringAtom("let bg=createbusgraph(id,e-rel,n-rel)"))); } bool BusGraph::CheckBusGraph(ListExpr type, ListExpr& errorInfo) { // cout<<"CheckBusGraph()"<IsEqual(type, "busgraph"); } int BusGraph::SizeOfBusGraph() { // cout<<"SizeOfBusGraph()"< (w.addr); w.addr = NULL; } Word BusGraph::CreateBusGraph(const ListExpr typeInfo) { // cout<<"CreateBusGraph()"<Out(typeInfo); } bool BusGraph::SaveBusGraph(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"SaveBusGraph()"<Save(valueRecord, offset, typeInfo); return result; } bool BusGraph::OpenBusGraph(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenBusGraph()"<Close(); if(btree_node != NULL) delete btree_node; if(edge_rel1 != NULL) edge_rel1->Close(); if(edge_rel2 != NULL) edge_rel2->Close(); if(edge_rel3 != NULL) edge_rel3->Close(); } BusGraph::BusGraph(ListExpr in_xValue,int in_iErrorPos, ListExpr& inout_xErrorInfo, bool& inout_bCorrect): bg_id(0), min_t(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), edge_rel3(NULL), adj_list3(0), entry_adj_list3(0) { // cout<<"BusGraph::BusGraph(ListExpr)"<ReadFromString(NodeInternalTypeInfo,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(NodeBTreeTypeInfo,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(EdgeTypeInfo1, 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::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(EdgeTypeInfo2, 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::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); /***********************Open relation for edge3*********************/ nl->ReadFromString(EdgeTypeInfo3, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); edge_rel3 = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType); if(!edge_rel3) { node_rel->Delete(); delete btree_node; edge_rel1->Delete(); adj_list1.clean(); entry_adj_list1.clean(); edge_rel2->Delete(); adj_list2.clean(); entry_adj_list2.clean(); return; } /////////////////open adjacency list3//////////////////////////////// bufsize = DbArray::headerSize(); offset = 0; buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; assert(buf != NULL); adj_list3.restoreHeader(buf,offset); free(buf); offset = 0; buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); assert(buf != NULL); entry_adj_list3.restoreHeader(buf,offset); inout_iOffset += bufsize; free(buf); } ListExpr BusGraph::Out(ListExpr typeInfo) { // cout<<"Out()"<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); Bus_Stop* bs = (Bus_Stop*)node_tuple->GetAttribute(BG_NODE); xNext = OutBusStop(nl->TheEmptyList(),SetWord(bs)); if(bFirst){ xNode = nl->OneElemList(xNext); xLast = xNode; bFirst = false; }else xLast = nl->Append(xLast,xNext); node_tuple->DeleteIfAllowed(); } // cout<< edge_rel1->GetNoTuples() + edge_rel2->GetNoTuples() + // edge_rel3->GetNoTuples()<TwoElemList(nl->IntAtom(bg_id),xNode); } /* save bus network graph */ bool BusGraph::Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset, const ListExpr in_xTypeInfo) { // cout<<"save "<ReadFromString(NodeInternalTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!node_rel->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; ////////////////save btree on nodes/////////////////////////// nl->ReadFromString(NodeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_node->Save(in_xValueRecord, inout_iOffset, xNumericType)) return false; /************************save edge1****************************/ nl->ReadFromString(EdgeTypeInfo1,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(EdgeTypeInfo2,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; /************************save edge3****************************/ nl->ReadFromString(EdgeTypeInfo3,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!edge_rel3->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; /////////////////adjacency list 3////////////////////////////// adj_list3.saveToFile(rf, adj_list3); offset = 0; bufsize = adj_list3.headerSize(); buf = (char*) malloc(bufsize); adj_list3.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; free(buf); entry_adj_list3.saveToFile(rf, entry_adj_list3); offset = 0; buf = (char*) malloc(bufsize); entry_adj_list3.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf,bufsize, inout_iOffset); free(buf); inout_iOffset += bufsize; return true; } /* load a bus graph edge1: the path in the pavement connecting two nearby bus stops edge2: */ void BusGraph::Load(int id, Relation* r1, Relation* edge1, Relation* edge2, Relation* edge3) { // cout<<"BusGraph::Load()"<ReadFromString(NodeInternalTypeInfo, xTypeInfo); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType(xTypeInfo); Relation* s_rel = new Relation(xNumType, true); for(int i = 1;i <= r1->GetNoTuples();i++){ Tuple* bs_tuple = r1->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BG_NODE); Point* bs_loc = (Point*)bs_tuple->GetAttribute(BG_NODE_GEO); Tuple* new_bs_tuple = new Tuple(nl->Second(xNumType)); new_bs_tuple->PutAttribute(BG_NODE, new Bus_Stop(*bs)); new_bs_tuple->PutAttribute(BG_NODE_GEO, new Point(*bs_loc)); new_bs_tuple->PutAttribute(BG_NODE_UOID, new CcInt(true, bs->GetUOid())); s_rel->AppendTuple(new_bs_tuple); new_bs_tuple->DeleteIfAllowed(); bs_tuple->DeleteIfAllowed(); } ListExpr ptrList1 = listutils::getPtrList(s_rel); string strQuery = "(consume(feed(" + NodeInternalTypeInfo + "(ptr " + nl->ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); node_rel = (Relation*)xResult.addr; s_rel->Delete(); ////////////////////////////btree on nodes///////////////////////// ListExpr ptrList2 = listutils::getPtrList(node_rel); strQuery = "(createbtree (" + NodeInternalTypeInfo + "(ptr " + nl->ToString(ptrList2) + "))" + "Bus_uoid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); btree_node = (BTree*)xResult.addr; //////////////////////////////load edges/////////////////////////// LoadEdge1(edge1);///connected by pavements path LoadEdge2(edge2);///same spatial location, doing transfer LoadEdge3(edge3);//moving buses in the same route } /* edges for pavement connectiong */ void BusGraph::LoadEdge1(Relation* r) { ////////////////////////////////////////////////////////////////////// ////////////////////add the tid of the second bus stop///////////////// ////////////////////more efficient for query processing/////////////// ////////////////////////////////////////////////////////////////////// ListExpr ptrList1 = listutils::getPtrList(r); string strQuery = "(consume(feed(" + EdgeTypeInfo1 + "(ptr " + nl->ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel1 = (Relation*)xResult.addr; GenericRelationIterator* edgeiter = edge_rel1->MakeScan(); Tuple* edge_tuple; while((edge_tuple = edgeiter->GetNextTuple()) != 0){ //////////////////////use btree built on node rel//////////////////////// Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BG_E_BS2); int bs2_tid = -1; CcInt* search_id = new CcInt(true, bs2->GetUOid()); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ bs2_tid = btree_iter->GetId(); } delete btree_iter; delete search_id; assert(bs2_tid > 0 && bs2_tid <= node_rel->GetNoTuples()); ///////////////////////////////////////////////////////////////////////// /* int bs2_tid_old = ((CcInt*)edge_tuple->GetAttribute(BG_E_BS2_TID))->GetIntval();*/ vector xIndices; xIndices.push_back(BG_E_BS2_TID); vector xAttrs; xAttrs.push_back(new CcInt(true, bs2_tid)); edge_rel1->UpdateTuple(edge_tuple,xIndices,xAttrs); // cout<<"old "<GetNoTuples()<ToString(ptrList2) + "))" + "Bus_uoid)"; 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* bs_tuple = node_rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BG_NODE); CcInt* nodeid = new CcInt(true, bs->GetUOid()); 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)); delete nodeid; bs_tuple->DeleteIfAllowed(); } delete btree; } /* edges for bus stops with the same spatial location but belong to different bus routes */ void BusGraph::LoadEdge2(Relation* r) { // cout<GetNoTuples()<ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel2 = (Relation*)xResult.addr; GenericRelationIterator* edgeiter = edge_rel2->MakeScan(); Tuple* edge_tuple; while((edge_tuple = edgeiter->GetNextTuple()) != 0){ //////////////////////use btree built on node rel//////////////////////// Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BG_E2_BS2); int bs2_tid = -1; CcInt* search_id = new CcInt(true, bs2->GetUOid()); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ bs2_tid = btree_iter->GetId(); } delete btree_iter; delete search_id; assert(bs2_tid > 0 && bs2_tid <= node_rel->GetNoTuples()); ///////////////////////////////////////////////////////////////////////// /* int bs2_tid_old = ((CcInt*)edge_tuple->GetAttribute(BG_E_BS2_TID))->GetIntval();*/ vector xIndices; xIndices.push_back(BG_E2_BS2_TID); vector xAttrs; xAttrs.push_back(new CcInt(true, bs2_tid)); edge_rel2->UpdateTuple(edge_tuple,xIndices,xAttrs); // cout<<"old "<GetNoTuples()<ToString(ptrList2) + "))" + "Bus_uoid)"; 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* bs_tuple = node_rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BG_NODE); CcInt* nodeid = new CcInt(true, bs->GetUOid()); 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)); delete nodeid; bs_tuple->DeleteIfAllowed(); } delete btree; } /* edges for bus stops belonging to the same route, the bus stops are connected by moving buses */ void BusGraph::LoadEdge3(Relation* e_rel) { // cout<GetNoTuples()<ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel3 = (Relation*)xResult.addr; // Relation* edge_rel3 = (Relation*)xResult.addr; GenericRelationIterator* edgeiter = edge_rel3->MakeScan(); Tuple* edge_tuple; min_t = numeric_limits::max(); while((edge_tuple = edgeiter->GetNextTuple()) != 0){ Periods* peri = (Periods*)edge_tuple->GetAttribute(BG_LIFETIME); Interval periods; peri->Get(0, periods); double t = periods.start.ToDouble(); if(t < min_t) min_t = t; //////////////////////use btree built on node rel//////////////////////// Bus_Stop* bs2 = (Bus_Stop*)edge_tuple->GetAttribute(BG_E3_BS2); int bs2_tid = -1; CcInt* search_id = new CcInt(true, bs2->GetUOid()); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ bs2_tid = btree_iter->GetId(); } delete btree_iter; delete search_id; assert(bs2_tid > 0 && bs2_tid <= node_rel->GetNoTuples()); // int bs2_tid_old = // ((CcInt*)edge_tuple->GetAttribute(BG_E3_BS2_TID))->GetIntval(); ///////////////////////////////////////////////////////////////////////// vector xIndices; xIndices.push_back(BG_E3_BS2_TID); vector xAttrs; xAttrs.push_back(new CcInt(true, bs2_tid)); edge_rel3->UpdateTuple(edge_tuple,xIndices,xAttrs); // cout<<"old "<ToString(ptrList2) + "))" + "Bus_uoid)"; 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* bs_tuple = node_rel->GetTuple(i, false); Bus_Stop* bs = (Bus_Stop*)bs_tuple->GetAttribute(BG_NODE); CcInt* nodeid = new CcInt(true, bs->GetUOid()); BTreeIterator* btree_iter = btree->ExactMatch(nodeid); int start = adj_list3.Size(); while(btree_iter->Next()){ // Tuple* edge_tuple = edge_rel2->GetTuple(btree_iter->GetId(), false); Tuple* edge_tuple = edge_rel3->GetTuple(btree_iter->GetId(), false); adj_list3.Append(edge_tuple->GetTupleId());//get the edge tuple id edge_tuple->DeleteIfAllowed(); } delete btree_iter; int end = adj_list3.Size(); entry_adj_list3.Append(ListEntry(start, end)); delete nodeid; bs_tuple->DeleteIfAllowed(); } delete btree; } /* adjacency list for the first kind of edge (pavements) */ void BusGraph::FindAdj1(int node_id, vector& 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); } } /* adjacency list for the second kind of edge (bus stops with the same spatial location but belong to different bus routes) */ void BusGraph::FindAdj2(int node_id, vector& 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); } } /* adjacency list for the third kind of edge two adjacent bus stops are connected by moving buses */ void BusGraph::FindAdj3(int node_id, vector& list) { ListEntry list_entry; entry_adj_list3.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_list3.Get(j, oid); j++; list.push_back(oid); } } /* for a bus stop, find its tid in the node relation */ int BusGraph::GetBusStop_Tid(Bus_Stop* bs) { if(!bs->IsDefined()) return -1; int bs_tid = -1; CcInt* search_id = new CcInt(true,bs->GetUOid()); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ bs_tid = btree_iter->GetId(); } delete btree_iter; delete search_id; assert(bs_tid > 0 && bs_tid <= node_rel->GetNoTuples()); return bs_tid; } //////////////////////////////////////////////////////////////////////////// ////////////////////////////////navigation in bus network////////////////// ////////////////////////////////////////////////////////////////////////// /* shortest path from one bus stop to another in length */ void BNNav::ShortestPath_Length(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { // cout<<"bus shortest path in length "<GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } priority_queue path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++) visit_flag1.push_back(false); /////////// initialize the queue ////////////////////////////// InitializeQueue1(bs1, bs2, path_queue, expand_queue, bn, bg, start_p, end_p); int bs2_tid = bg->GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< adj_list1; bg->FindAdj1(top.tri_index, adj_list1); pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list1.size();i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id1, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double w = top.real_w + path->Length(); double hw = p->Distance(end_p); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, *path, TM_WALK); path_queue.push(elem); expand_queue.push_back(elem); bs_node_tuple->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id2, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p); bs_node_tuple->DeleteIfAllowed(); BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1); path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w + path->Length(); Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id3, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p); bs_node_tuple->DeleteIfAllowed(); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, *path, TM_BUS); path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } /////////////////////////////////////////////////////////////////////// if(find){ ////////constrcut the result vector id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem elem = expand_queue[id_list[i]]; path_list.push_back(elem.path); // cout<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } } }else{ // cout<<"bs1 ("<<*bs1<<") bs2 ("<<*bs2<<") not reachable "<CloseBusGraph(bg); } /* put the start bus stop into the queue for minimum length */ void BNNav::InitializeQueue1(Bus_Stop* bs1, Bus_Stop* bs2, priority_queue& path_queue, vector& expand_queue, BusNetwork* bn, BusGraph* bg, Point& start_p, Point& end_p) { int cur_size = expand_queue.size(); double w = 0.0; double hw = start_p.Distance(end_p); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); int bs_tid = bg->GetBusStop_Tid(bs1); // cout<<"start bus stop tid "<DeleteIfAllowed(); } /* shortest path from one bus stop to another in time */ void BNNav::ShortestPath_Time(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { BusGraph* bg = bn->GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant bg_min(instanttype); bg_min.ReadFrom(bg->min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(),bg_min.GetMonth(),bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++) visit_flag1.push_back(false); ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max bus speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< adj_list1; bg->FindAdj1(top.tri_index, adj_list1); bool search_flag = true; BNPath_elem temp_elem = top; while(dest.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id1, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, *path, TM_WALK, true);*/ SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id2, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //not useful for time cost */ BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //not useful for time cost elem.type = -1; elem.edge_tid = 0; path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); double sched = ((CcReal*)edge_tuple->GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } double wait_time = 0.0; if(st_int > cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; while(st_int < cur_t_int && st_int <= et_int){ /* Instant temp(instanttype); temp.ReadFrom(st); cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); // temp.ReadFrom(st); // cout<<"t2 "<GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w = top.real_w + wait_time + weight; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id3, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, *path, TM_BUS, true);*/ SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } /* cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; // int no_transfer = 0; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem elem = expand_queue[id_list[i]]; //////////////////////////////////////////////////////////// if(elem.type == TM_WALK){ assert(1 <= elem.edge_tid && elem.edge_tid <= bg->edge_rel1->GetNoTuples()); Tuple* edge_tuple = bg->edge_rel1->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); elem.path = *path; edge_tuple->DeleteIfAllowed(); }else if(elem.type == TM_BUS){ if(elem.edge_tid > 0){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); if(elem.valid) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); if(elem.valid) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); if(elem.valid) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } // cout<<" transfer "<CloseBusGraph(bg); } /* shortest path from one bus stop to another in time edge without any cost, id does not connect walk edge and no cost edge because its previous node has expanded these edges for the edge connected by moving buses, for a route which is accessed for the first time, it records the searching time of the whole periods. in this case, it does not have to start from the begin of the periods for a bus stop */ void BNNav::ShortestPath_TimeNew(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { BusGraph* bg = bn->GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } // cout<<*bs1<<" "<<*bs2<<" "<<*qt< counter_up; vector counter_down; for(int i = 0;i < bn->GetBR_Rel()->GetNoTuples();i++){ counter_up.push_back(0); counter_down.push_back(0); } // cout<min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(),bg_min.GetMonth(),bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++) visit_flag1.push_back(false); ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max bus speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< adj_list1; bg->FindAdj1(top.tri_index, adj_list1); bool search_flag = true; BNPath_elem temp_elem = top; while(dest.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id1, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, *path, TM_WALK, true);*/ SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; //////////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// // if(top.tm == TM_WALK || top.tm == TM_BUS){ if(top.tm == TM_BUS){ vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id2, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //not useful for time cost */ BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //not useful for time cost elem.type = -1; elem.edge_tid = 0; //////////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); double sched = ((CcReal*)edge_tuple->GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); if(et_int < cur_t_int){//end time smaller than curtime edge_tuple->DeleteIfAllowed(); continue; } double wait_time = 0.0; Tuple* bs_top_tuple = bg->node_rel->GetTuple(top.tri_index, false); Bus_Stop* bs_top = (Bus_Stop*)bs_top_tuple->GetAttribute(BusGraph::BG_NODE); if(bs_top->GetUp()){ int last_record = counter_up[bs_top->GetId() - 1]; // cout<<"up "<GetId() - 1]; // cout<<"down "< cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; int record_count = 0; while(st_int < cur_t_int && st_int <= et_int){ if((st_int + 30000) >= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); record_count++; } if(bs_top->GetUp()){ if(counter_up[bs_top->GetId() - 1] == 0) //for the first time counter_up[bs_top->GetId() - 1] = record_count; }else{ if(counter_down[bs_top->GetId() - 1] == 0) //for the first time counter_down[bs_top->GetId() - 1] = record_count; } if(valid == false){ cout<<"should not arrive at here"<DeleteIfAllowed(); ////////////////////////////////////////////////////////////// double weight = ((CcReal*)edge_tuple->GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w = top.real_w + wait_time + weight; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id3, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, *path, TM_BUS, true);*/ ////////////////////////////////////////////////////////////////// SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; ///////////////////////////////////////////////////////////// if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } // cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; // int no_transfer = 0; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem elem = expand_queue[id_list[i]]; //////////////////////////////////////////////////////////// if(elem.type == TM_WALK){ assert(1 <= elem.edge_tid && elem.edge_tid <= bg->edge_rel1->GetNoTuples()); Tuple* edge_tuple = bg->edge_rel1->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); elem.path = *path; edge_tuple->DeleteIfAllowed(); }else if(elem.type == TM_BUS){ if(elem.edge_tid > 0){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); if(elem.valid) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); if(elem.valid) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); if(elem.valid) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } // cout<<" transfer "<CloseBusGraph(bg); } /* initialize the queue: shortest path in time */ void BNNav::InitializeQueue2(Bus_Stop* bs1, Bus_Stop* bs2, priority_queue& path_queue, vector& expand_queue, BusNetwork* bn, BusGraph* bg, Point& start_p, Point& end_p) { int cur_size = expand_queue.size(); double w = 0.0; double hw = start_p.Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); // double hw = 0.0; SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); int bs_tid = bg->GetBusStop_Tid(bs1); // cout<<"start bus stop tid "<DeleteIfAllowed(); } /* shortest path from one bus stop to another in time for the start bus stop, it does not consider the walk segment connection */ void BNNav::ShortestPath_Time2(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { BusGraph* bg = bn->GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"< counter_up; vector counter_down; for(int i = 0;i < bn->GetBR_Rel()->GetNoTuples();i++){ counter_up.push_back(0); counter_down.push_back(0); }*/ vector counter_up(bn->GetBR_Rel()->GetNoTuples(), 0); vector counter_down(bn->GetBR_Rel()->GetNoTuples(), 0); Point start_p, end_p; bn->GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant bg_min(instanttype); bg_min.ReadFrom(bg->min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(),bg_min.GetMonth(),bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; /* vector visit_flag1;////////////bus stop visit vector visit_flag2; vector visit_flag3; vector tm_list1; vector tm_list2; for(int i = 1; i <= bg->node_rel->GetNoTuples();i++){ visit_flag1.push_back(false); visit_flag2.push_back(false); visit_flag3.push_back(0); tm_list1.push_back("empty"); tm_list2.push_back("empty"); }*/ vector visit_flag1(bg->node_rel->GetNoTuples(), false); vector visit_flag2(bg->node_rel->GetNoTuples(), false); vector visit_flag3(bg->node_rel->GetNoTuples(), 0); vector tm_list1(bg->node_rel->GetNoTuples(), "empty"); vector tm_list2(bg->node_rel->GetNoTuples(), "empty"); ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// /////////// initialize the queue ////////////////////////////// InitializeQueue2(bs1, bs2, path_queue, expand_queue, bn, bg, start_p, end_p); int bs2_tid = bg->GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< delta_t){ if(top.tm == TM_BUS){ bool search_flag = true; BNPath_elem temp_elem = top; while(temp_elem.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } vector adj_list1; bg->FindAdj1(top.tri_index, adj_list1); for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id1, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); // BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, // *path, TM_WALK, true); ///////////////////////////////////////////////////// SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id1, w + hw, w, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; ////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); if(visit_flag1[neighbor_id1 - 1] == 0) tm_list1[neighbor_id1 - 1] = "walk"; else tm_list2[neighbor_id1 - 1] = "walk"; visit_flag3[neighbor_id1 - 1]++; } } } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// // if(top.tm == TM_WALK || top.tm == TM_BUS){ if(top.tm == TM_BUS){ vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } if(visit_flag2[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); cur_size = expand_queue.size(); double w = top.real_w; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id2, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //-1, not useful for time cost */ /////////////////////////////////////// BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, *path, -1, false); //-1, not useful for time cost elem.type = -1; elem.edge_tid = 0; ////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); if(visit_flag3[neighbor_id2 - 1] == 0) tm_list1[neighbor_id2 - 1] = "none"; else tm_list2[neighbor_id2 - 1] = "none"; visit_flag2[neighbor_id2 - 1] = true; visit_flag3[neighbor_id2 - 1]++; } } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); double sched = ((CcReal*)edge_tuple->GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } double wait_time = 0.0; /////////////////////////////////////////////////////////////// Tuple* bs_top_tuple = bg->node_rel->GetTuple(top.tri_index, false); Bus_Stop* bs_top = (Bus_Stop*)bs_top_tuple->GetAttribute(BusGraph::BG_NODE); if(bs_top->GetUp()){ int last_record = counter_up[bs_top->GetId() - 1]; st += sched*last_record; st_int = st*86400000; }else{ int last_record = counter_down[bs_top->GetId() - 1]; st += sched*last_record; st_int = st*86400000; } /////////////////////////////////////////////////////////////// if(st_int > cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; int record_count = 0; while(st_int < cur_t_int && st_int <= et_int){ /* Instant temp(instanttype); temp.ReadFrom(st); cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); record_count++; // temp.ReadFrom(st); // cout<<"t2 "<GetUp()){ if(counter_up[bs_top->GetId() - 1] == 0) counter_up[bs_top->GetId() - 1] = record_count; }else{ if(counter_down[bs_top->GetId() - 1] == 0) counter_down[bs_top->GetId() - 1] = record_count; } if(valid == false){ cout<<"should not arrive at here"<DeleteIfAllowed(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); double weight = ((CcReal*)edge_tuple->GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w = top.real_w + wait_time + weight; Tuple* bs_node_tuple = bg->node_rel->GetTuple(neighbor_id3, false); Point* p = (Point*)bs_node_tuple->GetAttribute(BusGraph::BG_NODE_GEO); double hw = p->Distance(end_p)/(bn->GetMaxSpeed()*24.0*60.0*60.0); bs_node_tuple->DeleteIfAllowed(); /* BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, *path, TM_BUS, true);*/ ///////////////////////////////////////////////////// SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size,neighbor_id3, w + hw, w, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; ////////////////////////////////////////////////////// if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); if(visit_flag3[neighbor_id3 - 1] == 0) tm_list1[neighbor_id3 - 1] = "bus"; else tm_list2[neighbor_id3 - 1] = "bus"; visit_flag3[neighbor_id3 - 1]++; } visit_flag1[top.tri_index - 1] = true; } // for(unsigned int i = 0;i < visit_flag3.size();i++){ // if(visit_flag3[i] > 1) { // cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; // int no_transfer = 0; t_cost = 0.0; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem elem = expand_queue[id_list[i]]; //////////////////////////////////////////////////////////// if(elem.type == TM_WALK){ assert(1 <= elem.edge_tid && elem.edge_tid <= bg->edge_rel1->GetNoTuples()); Tuple* edge_tuple = bg->edge_rel1->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); elem.path = *path; edge_tuple->DeleteIfAllowed(); }else if(elem.type == TM_BUS){ if(elem.edge_tid > 0){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; //time cost in seconds // if(elem.valid){ if(elem.valid && time_span.IsValid()){ time_cost_list.push_back((t2.ToDouble() - t1.ToDouble())*86400.0); t_cost += (t2.ToDouble() - t1.ToDouble())*86400.0; }else{ //doing transfer without moving time_cost_list.push_back(0.0); t_cost += 0.0; } Periods* peri = new Periods(0); peri->StartBulkLoad(); // cout<MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; //time cost in seconds // if(elem.valid){ if(elem.valid && time_span.IsValid()){ time_cost_list.push_back((t2.ToDouble() - t1.ToDouble())*86400.0); t_cost += (t2.ToDouble() - t1.ToDouble())*86400.0; }else{ //doing transfer without moving time_cost_list.push_back(0.0); t_cost += 0.0; } Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); // if(elem.valid) if(elem.valid && time_span.IsValid()) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); // if(elem.valid) if(elem.valid && time_span.IsValid()) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } // cout<<" transfer "<CloseBusGraph(bg); } /* shortest path from one bus stop to another in bus transfer */ void BNNav::ShortestPath_Transfer(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { BusGraph* bg = bn->GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant bg_min(instanttype); bg_min.ReadFrom(bg->min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(),bg_min.GetMonth(),bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++){ visit_flag1.push_back(false); } ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max bus speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< adj_list1; bg->FindAdj1(top.tri_index, adj_list1); bool search_flag = true; BNPath_elem2 temp_elem = top; while(dest.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); int w1 = top.weight;///walk is not bus transfer // BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, // *path, TM_WALK, true); SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w; int w1 = top.weight; // BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, // *path, -1, false); //not useful for time cost BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, *path, -1, false); //not useful for time cost elem.type = -1; elem.edge_tid = 0; path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); // output<<"periods "<GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } double wait_time = 0.0; if(st_int > cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; while(st_int < cur_t_int && st_int <= et_int){ /* Instant temp(instanttype); temp.ReadFrom(st); cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); // temp.ReadFrom(st); // cout<<"t2 "<GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w2 = top.real_w + wait_time + weight; int w1; if(fabs(int64_t(wait_time*86400) - 30) <= 2 || (int)(top.real_w*86400.0) == 0) w1 = top.weight; else w1 = top.weight + 1; // BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, // *path, TM_BUS, true); SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////////////////////////////////////////////////////////// ////////////////construct the result////////////////////////////////// ////////////////////////////////////////////////////////////////////// if(find){ ////////constrcut the result // cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem2 elem = expand_queue[id_list[i]]; path_list.push_back(elem.path); if(elem.tm == TM_WALK){ tm_list.push_back(str_tm[elem.tm]); }else if(elem.tm == TM_BUS){ tm_list.push_back(str_tm[elem.tm]); }else{ // assert(false); tm_list.push_back("none"); } //////////////////////////////////////////////////////////////////// ////////////////we also return/////////////////////////////////////// ////////the start and end bus stops connected by the path //////////// //////////////////////////////////////////////////////////////////// char buf1[256], buf2[256]; sprintf(buf1, "br: %d ", bs_last.GetId()); sprintf(buf2, "stop: %d", bs_last.GetStopId()); strcat (buf1, buf2); if(bs_last.GetUp())strcat (buf1, " UP"); else strcat (buf1, " DOWN"); string str1(buf1); bs1_list.push_back(str1); if(i == (int)(id_list.size() - 1)){ string str2(str1); bs2_list.push_back(str2); }else{////////////////the end bus stop Tuple* bs_tuple = bg->node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); if(elem.valid) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); if(elem.valid) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); if(elem.valid) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } }else{ cout<<"bs1 ("<<*bs1<<") bs2 ("<<*bs2<<") not reachable "<CloseBusGraph(bg); } /* shortest path from one bus stop to another in bus transfer walk edge is not expanded twice; only bus edge is expanded by walk edge; only walk edge and bus edge are expanded by no cost edge */ void BNNav::ShortestPath_TransferNew(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { BusGraph* bg = bn->GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant bg_min(instanttype); bg_min.ReadFrom(bg->min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(),bg_min.GetMonth(),bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++){ visit_flag1.push_back(false); } ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max bus speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< adj_list1; bg->FindAdj1(top.tri_index, adj_list1); bool search_flag = true; BNPath_elem2 temp_elem = top; while(dest.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); int w1 = top.weight;///walk is not bus transfer // BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, // *path, TM_WALK, true); SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; ///////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// if(top.tm == TM_WALK || top.tm == TM_BUS){ vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w; int w1 = top.weight; /* BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, *path, -1, false); //not useful for time cost */ /////////////////////////////////////////////////////////////// BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, *path, -1, false); //not useful for time cost elem.type = -1; elem.edge_tid = 0; ////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); // output<<"periods "<GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } double wait_time = 0.0; if(st_int > cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; while(st_int < cur_t_int && st_int <= et_int){ /* Instant temp(instanttype); temp.ReadFrom(st); cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); } if(valid == false){ cout<<"should not arrive at here"<GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w2 = top.real_w + wait_time + weight; int w1; if(fabs(int64_t(wait_time*86400) - 30) <= 2 || (int)(top.real_w*86400.0) == 0) w1 = top.weight; else w1 = top.weight + 1; // BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, // *path, TM_BUS, true); SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////////////////////////////////////////////////////////// ////////////////construct the result////////////////////////////////// ////////////////////////////////////////////////////////////////////// if(find){ ////////constrcut the result // cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem2 elem = expand_queue[id_list[i]]; //////////////////////////////////////////////////////////// if(elem.type == TM_WALK){ assert(1 <= elem.edge_tid && elem.edge_tid <= bg->edge_rel1->GetNoTuples()); Tuple* edge_tuple = bg->edge_rel1->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); elem.path = *path; edge_tuple->DeleteIfAllowed(); }else if(elem.type == TM_BUS){ if(elem.edge_tid > 0){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); if(elem.valid) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); if(elem.valid) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); if(elem.valid) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } }else{ cout<<"bs1 ("<<*bs1<<") bs2 ("<<*bs2<<") not reachable "<CloseBusGraph(bg); } /* shortest path from one bus stop to another in bus transfer for the first bus stop, do not consider walk segment connection */ void BNNav::ShortestPath_Transfer2(Bus_Stop* bs1, Bus_Stop* bs2, Instant* qt) { // cout<<"ShortestPath_Transfer2"<GetBusGraph(); if(bg == NULL){ cout<<"bus graph is invalid"<IsDefined() || !bs2->IsDefined()){ cout<<" bus stops are not defined"<GetBusStopGeoData(bs1, &start_p); bn->GetBusStopGeoData(bs2, &end_p); const double delta_dist = 0.01; if(*bs1 == *bs2 || start_p.Distance(end_p) < delta_dist){ cout<<"two bus stops equal to each other"<CloseBusGraph(bg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant bg_min(instanttype); bg_min.ReadFrom(bg->min_t); assert(bg_min.GetWeekday() == 6);//start from Sunday if(qt->GetWeekday() == 6){ new_st.Set(bg_min.GetYear(), bg_min.GetMonth(), bg_min.GetGregDay(), qt->GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"Sunday"<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"workday --->Monday"< path_queue; vector expand_queue; vector visit_flag1;////////////bus stop visit for(int i = 1; i <= bg->node_rel->GetNoTuples();i++){ visit_flag1.push_back(false); } ////////////////////////////////////////////////////////////////// /////////////from bus network, get the maximum speed of the bus/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max bus speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetBusStop_Tid(bs2); // cout<<"end bus stop tid "< delta_t){ if(top.tm == TM_BUS){ //////////////////////////////////////////////////// bool search_flag = true; BNPath_elem2 temp_elem = top; // while(dest.prev_index != -1){ while(temp_elem.prev_index != -1){ if(temp_elem.tm == TM_BUS){ break; } if(temp_elem.tm == TM_WALK){ search_flag = false; break; } temp_elem = expand_queue[temp_elem.prev_index]; } //////////////////////////////////////////////////// vector adj_list1; bg->FindAdj1(top.tri_index, adj_list1); for(unsigned int i = 0;i < adj_list1.size() && search_flag;i++){ Tuple* edge_tuple = bg->edge_rel1->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E_BS2_TID))->GetIntval(); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); if(visit_flag1[neighbor_id1 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w + path->Length()/(speed_human*24.0*60.0*60.0); int w1 = top.weight;///walk is not bus transfer // BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, // *path, TM_WALK, true); ///////////////////////////////////////////////////////////// SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id1, w1, w2, temp_sl, TM_WALK, true); elem.type = TM_WALK; elem.edge_tid = adj_list1[i]; //////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } } } ///////////////////////////////////////////////////////////////////// //////////////////////connection 2 same spatial location///////////// //////////////////////////////////////////////////////////////////// if(top.tm == TM_WALK || top.tm == TM_BUS){ vector adj_list2; bg->FindAdj2(top.tri_index, adj_list2); for(unsigned int i = 0;i < adj_list2.size();i++){ Tuple* edge_tuple = bg->edge_rel2->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E2_BS2_TID))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); if(visit_flag1[neighbor_id2 - 1]){ edge_tuple->DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w2 = top.real_w; int w1 = top.weight; /* BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, *path, -1, false); //not useful for time cost */ ///////////////////////////////////////////////////////////// BNPath_elem2 elem(pos_expand_path, cur_size, neighbor_id2, w1, w2, *path, -1, false); //not useful for time cost elem.type = -1; elem.edge_tid = 0; /////////////////////////////////////////////////////////////// path_queue.push(elem); expand_queue.push_back(elem); path->DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } } ////////////////////////////////////////////////////////////////////// ////////////////////connection 3 moving buses///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list3; bg->FindAdj3(top.tri_index, adj_list3); int64_t max_64_int = numeric_limits::max(); for(unsigned int i = 0;i < adj_list3.size();i++){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(adj_list3[i], false); int neighbor_id3 = ((CcInt*)edge_tuple->GetAttribute(BusGraph::BG_E3_BS2_TID))->GetIntval(); if(visit_flag1[neighbor_id3 - 1]){ edge_tuple->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current bus stop // cout<<"time at bus stop "<GetAttribute(BusGraph::BG_LIFETIME); Interval periods; peri->Get(0, periods); // output<<"periods "<GetAttribute(BusGraph::BG_SCHEDULE))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } double wait_time = 0.0; if(st_int > cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at bus stop }else{ //most times, it is here, wait for the next schedule bool valid = false; while(st_int < cur_t_int && st_int <= et_int){ /* Instant temp(instanttype); temp.ReadFrom(st); cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); // temp.ReadFrom(st); // cout<<"t2 "<GetAttribute(BusGraph::BG_TIMECOST))->GetRealval(); double w2 = top.real_w + wait_time + weight; int w1; if(fabs(int64_t(wait_time*86400) - 30) <= 2 || (int)(top.real_w*86400.0) == 0) w1 = top.weight; else w1 = top.weight + 1; /* BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, *path, TM_BUS, true);*/ /////////////////////////////////////////////////////// SimpleLine temp_sl(0); BNPath_elem2 elem(pos_expand_path, cur_size,neighbor_id3, w1, w2, temp_sl, TM_BUS, true); elem.type = TM_BUS; elem.edge_tid = adj_list3[i]; /////////////////////////////////////////////////////// if(wait_time > 0.0){ //to the time waiting for bus elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); // output<<"wait time "<node_rel->GetTuple(neighbor_id3, false); // Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); // output<<"extend elem; transfer: "<DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////////////////////////////////////////////////////////// ////////////////construct the result////////////////////////////////// ////////////////////////////////////////////////////////////////////// if(find){ ////////constrcut the result // cout< id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop bs_last = *bs1; Instant t1 = *qt; t_cost = 0.0; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem2 elem = expand_queue[id_list[i]]; //////////////////////////////////////////////////////////// if(elem.type == TM_WALK){ assert(1 <= elem.edge_tid && elem.edge_tid <= bg->edge_rel1->GetNoTuples()); Tuple* edge_tuple = bg->edge_rel1->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH2); elem.path = *path; edge_tuple->DeleteIfAllowed(); }else if(elem.type == TM_BUS){ if(elem.edge_tid > 0){ Tuple* edge_tuple = bg->edge_rel3->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(BusGraph::BG_PATH3); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<node_rel->GetTuple(elem.tri_index, false); Bus_Stop* bs_cur = (Bus_Stop*)bs_tuple->GetAttribute(BusGraph::BG_NODE); char buf_1[256], buf_2[256]; sprintf(buf_1, "br: %d ", bs_cur->GetId()); sprintf(buf_2, "stop: %d", bs_cur->GetStopId()); strcat (buf_1, buf_2); if(bs_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); bs2_list.push_back(str2); bs_last = *bs_cur; bs_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); // if(elem.valid) if(elem.valid && time_span.IsValid()) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the bus t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); // if(elem.valid) if(elem.valid && time_span.IsValid()) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = bs2_list[bs2_list.size() - 1]; ////////the same as last bus stop ////////////////////// bs2_list[bs2_list.size() - 1] = bs1_list[bs1_list.size() - 1]; /////////////moving with bus//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); // if(elem.valid) if(elem.valid && time_span.IsValid()) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); bs1_list.push_back(str1); bs2_list.push_back(str); } } }else{ // cout<<"bs1 ("<<*bs1<<") bs2 ("<<*bs2<<") not reachable "<CloseBusGraph(bg); } /* initialize the queue: shortest path in bus transfer */ void BNNav::InitializeQueue3(Bus_Stop* bs1, Bus_Stop* bs2, priority_queue& path_queue, vector& expand_queue, BusNetwork* bn, BusGraph* bg, Point& start_p, Point& end_p) { int cur_size = expand_queue.size(); int w1 = 0; double w2 = 0.0; SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); int bs_tid = bg->GetBusStop_Tid(bs1); // cout<<"start bus stop tid "<DeleteIfAllowed(); } /* converting from moving buses (mpoint) to genmo */ void BNNav::BusToGenMO(Relation* mo_rel, Relation* br_rel, BTree* btree) { for(int i = 1;i <= mo_rel->GetNoTuples();i++){ Tuple* bus_tuple = mo_rel->GetTuple(i, false); unsigned int br_id = ((CcInt*)bus_tuple->GetAttribute(RoadDenstiy::BR_ID5))->GetIntval(); bool dir = ((CcBool*)bus_tuple->GetAttribute( RoadDenstiy::MO_BUS_DIRECTION))->GetBoolval(); MPoint* mp = (MPoint*)bus_tuple->GetAttribute(RoadDenstiy::BUS_TRIP); MPToGenMO(mp,br_id, dir, br_rel, btree); bus_tuple->DeleteIfAllowed(); } } /* from mpoint, bool (direction), line id to genmo */ void BNNav::MPToGenMO(MPoint* mp,unsigned int br_id, bool dir, Relation* br_rel, BTree* btree) { // cout<<"br id "<StartBulkLoad(); CcInt* search_id = new CcInt(true, br_id); BTreeIterator* btree_iter = btree->ExactMatch(search_id); SimpleLine* sl = new SimpleLine(0); unsigned int bus_line_id = 0; int bus_line_uoid = -1; while(btree_iter->Next()){ Tuple* tuple = br_rel->GetTuple(btree_iter->GetId(), false); Bus_Route* br = (Bus_Route*)tuple->GetAttribute(BusNetwork::BN_BR); if(br->GetUp() == dir){ br->GetGeoData(*sl); assert(br->GetId() == br_id); bus_line_id = ((CcInt*)tuple->GetAttribute(BusNetwork::BN_ID2))->GetIntval(); assert(bus_line_id == br_id); bus_line_uoid = ((CcInt*)tuple->GetAttribute(BusNetwork::BN_BR_OID))->GetIntval(); } tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; assert(bus_line_uoid > 0); double pos1 = -1.0; double pos2 = -1.0; bool up; /////////////find it is increasing or decreasing/////////////////////// UPoint u1, u2; mp->Get(0, u1); mp->Get(mp->GetNoComponents() - 1, u2); assert(sl->AtPoint(u1.p0, true, pos1)); assert(sl->AtPoint(u2.p0, true, pos2)); if(pos1 < pos2) up = true; else up = false; //////////////////////////////////////////////////////////////////////// ///////// for numeric problem, we may not map all points to the sline//// ////////so we find the first point and just simply add the length value// //////first we have to know the relative positon on the route////////// //////////////////////is increasing or decreasing/////////////////////// //////////////////////////////////////////////////////////////////////// for(int i = 0;i < mp->GetNoComponents();i++){ UPoint unit1; mp->Get(i, unit1); ////////////////////the same when we convert it back//////////////// // cout<<"i "<AtPoint(unit1.p0, true, pos1)); assert(sl->AtPoint(unit1.p1, true, pos2)); }else{ double d = unit1.p0.Distance(unit1.p1); pos1 = pos2; if(up){ pos2 += d; }else{ pos2 -= d; } } // cout<<"pos1 "<Add(*unit2); delete unit2; } sl->DeleteIfAllowed(); genmo->EndBulkLoad(); genmo_list.push_back(*genmo); br_id_list.push_back(bus_line_uoid); mp_list.push_back(*mp); genmo->DeleteIfAllowed(); } //////////////////////////////////////////////////////////////////////////// ////////////////// Create UBahn Trains /////////////////////////// //////////////////////////////////////////////////////////////////////////// /* compact storage of time tables. Instead of storing each time instant for every bus trip, it stores the time periods and time interval of schedule for each route */ void UBTrain::CreateTimeTable_Compact() { vector station_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* tuple_stop = rel1->GetTuple(i, false); int lineid = ((CcInt*)tuple_stop->GetAttribute(T_LINEID))->GetIntval(); Point* loc = (Point*)tuple_stop->GetAttribute(T_STOP_LOC); int stopid = ((CcInt*)tuple_stop->GetAttribute(T_STOP_ID))->GetIntval(); BusStop_Ext* bs_e = new BusStop_Ext(lineid,stopid,0.0,*loc,true); station_list.push_back(*bs_e); delete bs_e; tuple_stop->DeleteIfAllowed(); } sort(station_list.begin(), station_list.end()); const double dist_delta = 0.01; unsigned int temp_count = 1; for(unsigned int i = 0;i < station_list.size();i++){ vector station_list_new; station_list_new.push_back(station_list[i]); ////////collect all metro stops mapping to the same 2D point in space///// unsigned int j = i + 1; BusStop_Ext bse = station_list_new[0]; while(j < station_list.size() && station_list[j].loc.Distance(bse.loc) < dist_delta ){ station_list_new.push_back(station_list[j]); j++; } i = j - 1; ///////////////////process train station list new /////////////////////// CreateLocTable_Compact(station_list_new,temp_count); temp_count++; // break; } } /* find the time table for one spatial location Time tables for trains are the same on Sunday and Monday Compact Storage -- [start time of first trip, start time of last trip] schedule time interval */ void UBTrain::CreateLocTable_Compact(vector station_list_new, int count_id) { // cout<<"size "<ExactMatch(search_trip_id); vector trip_up; vector trip_down; bool one_day = false; int bus_day = -1; while(btree_iter->Next()){ Tuple* tuple_trip = rel2->GetTuple(btree_iter->GetId(), false); int br_trip_id = ((CcInt*)tuple_trip->GetAttribute(T_LINE))->GetIntval(); bool trip_direction = ((CcBool*)tuple_trip->GetAttribute(T_UP))->GetBoolval(); assert(br_id == br_trip_id); MPoint* mo = (MPoint*)tuple_trip->GetAttribute(T_TRIP); UPoint up; mo->Get(0, up); if(one_day == false){ bus_day = up.timeInterval.start.GetDay(); one_day = true; if(trip_direction) trip_up.push_back(*mo); else trip_down.push_back(*mo); }else if(up.timeInterval.start.GetDay() == bus_day){//the same day assert(bus_day != -1); // cout<<"bus day "<DeleteIfAllowed(); } delete btree_iter; delete search_trip_id; //////////////////////////////////////////////////////////////////// // cout<<"up size "<& trip_list, Point loc,int br_id, int stop_id, bool dir, int count_id) { assert(trip_list.size() >= 2); MPoint start_mo_0 = trip_list[0]; UPoint up1; start_mo_0.Get(0, up1);//the start time of first trip Instant start_time_0 = up1.timeInterval.start; Instant st = start_time_0; GetTimeInstantStop(start_mo_0, loc,st); /////////////cut second and millsecond /////////////////////////////// int second_val_s = st.GetSecond(); // int msecond_val_s = st.GetMillisecond(); // double double_s = st.ToDouble() - // second_val_s/(24.0*60.0*60.0) - // msecond_val_s/(24.0*60.0*60.0*1000.0); double double_s = st.ToDouble(); st.ReadFrom(double_s); ///////////////////////////////////////////////////////////////// MPoint start_mo_1 = trip_list[1]; UPoint up2; start_mo_1.Get(0, up1);//the start time of second trip Instant start_time_1 = up1.timeInterval.start; /////////// get time interval for schedule /////////////////// double sch_interval = start_time_1.ToDouble() - start_time_0.ToDouble(); assert(sch_interval > 0.0); // cout<<"schedule "< time_span; time_span.start = st; time_span.lc = true; time_span.end = et; time_span.rc = true; Periods* peri = new Periods(0); peri->StartBulkLoad(); peri->MergeAdd(time_span); peri->EndBulkLoad(); // duration.push_back(*peri); // cout<<"periods "<<*peri<DeleteIfAllowed(); //////////////////////// check time ////////////////////////////// for(unsigned int i = 0;i < trip_list.size();i++){ MPoint mo = trip_list[i]; Instant temp_instant; GetTimeInstantStop(mo, loc, temp_instant); int second_val = temp_instant.GetSecond(); assert(second_val == second_val_s); } //////////////////////////////////////////////////////////////////////// } /* get the time that the train arrives at this point(stop) */ void UBTrain::GetTimeInstantStop(MPoint& mo, Point loc, Instant& arrove_t) { const double dist_delta = 0.01; const double stop_time = 10.0/(24.0*60.0*60.0); //10 seconds for trains for(int j = 0;j < mo.GetNoComponents();j++){ UPoint up; mo.Get(j, up); Point loc1 = up.p0; Point loc2 = up.p1; if(loc1.Distance(loc2) < dist_delta && loc1.Distance(loc) < dist_delta){ //find the place Instant st = up.timeInterval.start; Instant et = up.timeInterval.end; double d_st = st.ToDouble(); double d_et = et.ToDouble(); assert(AlmostEqual(fabs(d_st-d_et), stop_time) || fabs(d_st-d_et) > stop_time);//check 10 seconds arrove_t = st; return; } } assert(false); } string UBTrain::TrainsTypeInfo = "(rel (tuple ((lineid int) (Up bool) (Trip mpoint))))"; string UBTrain::UBahnLineInfo = "(rel (tuple ((lineid int) (oid int) (geoData sline))))"; string UBTrain:: UBahnTrainsTypeInfo = "(rel (tuple ((Id int) (Line int) (Up bool) (Trip mpoint) (Schedule_id int))))"; string UBTrain::TrainsStopTypeInfo = "(rel (tuple ((LineId int) (Loc point) (Stop_id int))))"; string UBTrain::TrainsStopExtTypeInfo = "(rel (tuple ((LineId int) (loc point) (stop_id int) (Up bool))))"; string UBTrain::UBahnTrainsTimeTable = "(rel (tuple ((Station_loc point) (Line_id int) (Stop_id int)\ (Train_direction bool) (Whole_time periods) (Schedule_interval real)\ (Loc_id int))))"; /* convert berlintest trains to generic moving objects */ void UBTrain::TrainsToGenMO() { for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* train_tuple = rel1->GetTuple(i, false); int line_id = ((CcInt*)train_tuple->GetAttribute(TRAIN_LINE_ID))->GetIntval(); bool dir = ((CcBool*)train_tuple->GetAttribute(TRAIN_LINE_DIR))->GetBoolval(); MPoint* mp = ((MPoint*)train_tuple->GetAttribute(TRAIN_TRIP)); GenMO* genmo = new GenMO(0); MPToGenMO(mp, genmo, line_id); genmo_list.push_back(*genmo); mp_list.push_back(*mp); br_id_list.push_back(line_id); direction_list.push_back(dir); genmo->DeleteIfAllowed(); train_tuple->DeleteIfAllowed(); // break; } } /* convert a moving point to a generic moving object */ void UBTrain::MPToGenMO(MPoint* mp, GenMO* mo, int l_id) { // cout<<"line id "<StartBulkLoad(); CcInt* search_id = new CcInt(true, l_id); BTreeIterator* btree_iter = btree1->ExactMatch(search_id); SimpleLine* sl = new SimpleLine(0); int ub_line_id = -1; while(btree_iter->Next()){ Tuple* tuple = rel2->GetTuple(btree_iter->GetId(), false); ub_line_id = ((CcInt*)tuple->GetAttribute(UB_LINE_ID))->GetIntval(); SimpleLine* l = (SimpleLine*)tuple->GetAttribute(UB_LINE_GEODATA); *sl = *l; tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; assert(ub_line_id == l_id); // cout<<"line length "<Length()<GetNoComponents();i++){ UPoint unit1; mp->Get(i, unit1); double pos1; double pos2; //////////////////////////////////////////////////////////////////// //////////////the same when we convert it back (TRUE) ///////////// //////////////////////////////////////////////////////////////////// assert(sl->AtPoint(unit1.p0, true, pos1)); assert(sl->AtPoint(unit1.p1, true, pos2)); // cout<<"pos1 "<Add(*unit2); delete unit2; } sl->DeleteIfAllowed(); mo->EndBulkLoad(); } ///////////////////////////////////////////////////////////////////////// ////////////////////create metro from road network/////////////////////// ///////////////////////////////////////////////////////////////////////// string MetroStruct::MetroTripTypeInfo_Com = "(rel (tuple ((mtrip1 genmo)\ (mtrip2 mpoint) (mr_id int) (Up bool) (mr_oid int) (oid int))))"; string MetroStruct::MetroParaInfo = "(rel (tuple ((Para real))))"; /* create metro routes */ void MetroStruct::CreateMRoute(DualGraph* dg, Relation* metro_para) { // int no_mroute = 10; // int no_mroute; // if(type == "Berlin")no_mroute = 10; // else if(type == "Houston") no_mroute = 16; Tuple* m_tuple1 = metro_para->GetTuple(1, false); unsigned int no_mroute = (unsigned int)((CcReal*)m_tuple1->GetAttribute(0))->GetRealval(); m_tuple1->DeleteIfAllowed(); // cout<<"no mroute "< cell_flag; for(int i = 1;i <= dg->node_rel->GetNoTuples();i++){ cell_flag.push_back(false); } ////////////////////////////////////////////////////////////////// ///////////////get the center/////////////////////////////////// //////////////////////////////////////////////////////////////// Rectangle<2> area_box = dg->rtree_node->BoundingBox(); double center_x = (area_box.MinD(0) + area_box.MaxD(0))/2; double center_y = (area_box.MinD(1) + area_box.MaxD(1))/2; Point center(true, center_x, center_y); int center_index = -1; for(int i = 1;i <= dg->node_rel->GetNoTuples();i++){ Tuple* cell_tuple = dg->node_rel->GetTuple(i, false); Region* reg = (Region*)cell_tuple->GetAttribute(DualGraph::PAVEMENT); if(center.Inside(reg->BoundingBox())){ center_index = i; break; } cell_tuple->DeleteIfAllowed(); } assert(center_index >= 1); vector find_cell_list; unsigned int count = 1; // double min_dist = 22000.0;//minimum distance for a ubahn // double min_dist; // double min_dist2; // if(type == "Berlin"){ // min_dist = 25000.0; // min_dist2 = 1500.0; // }else if(type == "Houston"){ // min_dist = 60000.0; // min_dist2 = 6000.0; // }else{ // cout<<"not processed"<GetTuple(2, false); double min_dist = ((CcReal*)m_tuple2->GetAttribute(0))->GetRealval(); m_tuple2->DeleteIfAllowed(); Tuple* m_tuple3 = metro_para->GetTuple(3, false); double min_dist2 = ((CcReal*)m_tuple3->GetAttribute(0))->GetRealval(); m_tuple3->DeleteIfAllowed(); // cout<<"dist1 "<node_rel->GetNoTuples() + 1; if(cell_flag[cell1 - 1]) continue; int cell2 = GetRandom() % dg->node_rel->GetNoTuples() + 1; if(cell_flag[cell2 - 1]) continue; Tuple* cell_tuple1 = dg->node_rel->GetTuple(cell1, false); Tuple* cell_tuple2 = dg->node_rel->GetTuple(cell2, false); Region* reg1 = (Region*)cell_tuple1->GetAttribute(DualGraph::PAVEMENT); Region* reg2 = (Region*)cell_tuple2->GetAttribute(DualGraph::PAVEMENT); if(reg1->BoundingBox().Distance(reg2->BoundingBox()) < min_dist){ cell_tuple2->DeleteIfAllowed(); cell_tuple1->DeleteIfAllowed(); continue; } bool valid = true; for(unsigned int i = 0;i < find_cell_list.size();i++){ Tuple* cell_tuple = dg->node_rel->GetTuple(find_cell_list[i], false); Region* reg = (Region*)cell_tuple->GetAttribute(DualGraph::PAVEMENT); if(reg->BoundingBox().Distance(reg1->BoundingBox()) < min_dist2){ valid = false; break; } if(reg->BoundingBox().Distance(reg2->BoundingBox()) < min_dist2){ valid = false; break; } cell_tuple->DeleteIfAllowed(); } if(valid == false){ cell_tuple2->DeleteIfAllowed(); cell_tuple1->DeleteIfAllowed(); continue; } // cell_reg_list1.push_back(*reg1); // cell_reg_list2.push_back(*reg2); ///////////////////////////////////////////////////////////////// //////////////calculate the metro route connecting two cells//// ////////////////////////////////////////////////////////////////// // cout<<"start "< path_list; if(count <= 4){ vector path_list1; dg->Path_Weight(cell1, center_index, path_list1); vector path_list2; dg->Path_Weight(center_index, cell2, path_list2); for(unsigned int i = 0;i < path_list1.size();i++) path_list.push_back(path_list1[i]); for(unsigned int i = 1;i < path_list2.size();i++) path_list.push_back(path_list2[i]); }else{ dg->Path_Weight(cell1, cell2, path_list); } ///////////////////////////////////////////////////////////////// // cout<DeleteIfAllowed(); cell_tuple1->DeleteIfAllowed(); // break; } } /* create the connection line for two cells */ bool MetroStruct::BuildMetroRoute(vector path_list, DualGraph* dg, int count) { vector ps_list; for(unsigned int i = 0;i < path_list.size();i++){ Tuple* cell_tuple = dg->node_rel->GetTuple(path_list[i], false); Region* reg = (Region*)cell_tuple->GetAttribute(DualGraph::PAVEMENT); Rectangle<2> bbox_reg = reg->BoundingBox(); double x = (bbox_reg.MinD(0) + bbox_reg.MaxD(0))/2; double y = (bbox_reg.MinD(1) + bbox_reg.MaxD(1))/2; Point p(true, x ,y); ps_list.push_back(p); cell_tuple->DeleteIfAllowed(); } SimpleLine* mroute = new SimpleLine(0); mroute->StartBulkLoad(); int edgeno = 0; for(unsigned int i = 0;i < ps_list.size() - 1;i++){ Point lp = ps_list[i]; Point rp = ps_list[i + 1]; HalfSegment hs(true, lp, rp); hs.attr.edgeno = edgeno++; *mroute += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *mroute += hs; } mroute->EndBulkLoad(); const double min_len = 10000.0; if(mroute->Length() < min_len){ mroute->DeleteIfAllowed(); return false; } // mroute_list.push_back(*mroute); ////////////////////////////////////////////////////////////// ////////////////use data type bus route represent the data/// ///////////////////////////////////////////////////////////// SpacePartition* sp = new SpacePartition(); vector seq_halfseg; sp->ReorderLine(mroute, seq_halfseg); mroute->DeleteIfAllowed(); // cout<StartBulkLoad(); int no_1 = 0; for(unsigned int i = 0; i < seq_halfseg.size();i++){ MyHalfSegment mhs = seq_halfseg[i]; HalfSegment hs(true, mhs.from, mhs.to); br1->Add2(hs, no_1); no_1++; } br1->EndBulkLoad(); mroute_list.push_back(*br1); br1->DeleteIfAllowed(); /////////////////////////////////////////////////////////////// Bus_Route* br2 = new Bus_Route(count, false); br2->StartBulkLoad(); int no_2 = 0; for(int i = seq_halfseg.size() - 1;i >= 0;i--){ MyHalfSegment mhs = seq_halfseg[i]; HalfSegment hs(true, mhs.to, mhs.from); br2->Add2(hs, no_2); no_2++; } br2->EndBulkLoad(); mroute_list.push_back(*br2); br2->DeleteIfAllowed(); id_list.push_back(count); id_list.push_back(count); delete sp; ///////////////////////////////////////////////////////////// return true; } /* create metro stops: very important format !!! Up: stop id increases from small to large Down: stop id decreases from large to small 1 2 3 4 5 6 true 1 2 3 4 5 6 false */ void MetroStruct::CreateMStop(Relation* mr) { for(int i = 1;i <= mr->GetNoTuples();i++){ Tuple* mr_tuple = mr->GetTuple(i, false); int mr_id = ((CcInt*)mr_tuple->GetAttribute(MR_ID))->GetIntval(); Bus_Route* mr = (Bus_Route*)mr_tuple->GetAttribute(MR_ROUTE); bool dir = mr->GetUp(); assert(mr_id == (int) mr->GetId()); SimpleLine sl(0); mr->GetGeoData(sl); SpacePartition* sp = new SpacePartition(); vector seq_halfseg; sp->ReorderLine(&sl, seq_halfseg); int s_id = 1; for(unsigned int j = 0;j < seq_halfseg.size();j++){ Bus_Stop ms_stop(true, mr_id, s_id, dir); Point geo_loc = seq_halfseg[j].from; s_id++; mstop_list.push_back(ms_stop); stop_geo_list.push_back(geo_loc); id_list.push_back(mr_id); if(j == seq_halfseg.size() - 1){ Bus_Stop ms_stop2(true, mr_id, s_id, dir); Point geo_loc2 = seq_halfseg[j].to; s_id++; mstop_list.push_back(ms_stop2); stop_geo_list.push_back(geo_loc2); id_list.push_back(mr_id); } } delete sp; mr_tuple->DeleteIfAllowed(); } } /* create moving metros */ void MetroStruct::CreateMTrips(Relation* mr, Periods* peri) { for(int i = 1;i <= mr->GetNoTuples();i++){ Tuple* mr_tuple = mr->GetTuple(i, false); int mr_id = ((CcInt*)mr_tuple->GetAttribute(MR_ID))->GetIntval(); Bus_Route* mr = (Bus_Route*)mr_tuple->GetAttribute(MR_ROUTE); bool dir = mr->GetUp(); int mr_oid = ((CcInt*)mr_tuple->GetAttribute(MR_OID))->GetIntval(); assert(mr_id == (int) mr->GetId()); SimpleLine sl(0); mr->GetGeoData(sl); SpacePartition* sp = new SpacePartition(); vector seq_halfseg; sp->ReorderLine(&sl, seq_halfseg); if(dir){ CreateMetroUp(seq_halfseg, peri, mr_id, mr_oid, dir); }else{ CreateMetroDown(seq_halfseg, peri, mr_id, mr_oid, dir); } delete sp; } /////////////////////////////////////////////////////////////////////// /////////////copy all trips one day before////////////////////////////// ////////////////////////////////////////////////////////////////////// CopyTripOneDayBefore(); } /* create metros up direction */ void MetroStruct::CreateMetroUp(vector& seg_list, Periods* peri, int mr_id, int mr_oid, bool dir) { double metro_speed = 70.0*1000.0/3600.0;// -- 70km h, convert to meter second double time_interval = 30.0/(24.0*60.0*60.0); //time of waiting Interval metro_periods; peri->Get(0, metro_periods); Instant start_time = metro_periods.start; start_time.ReadFrom(start_time.ToDouble() + (GetRandom() % 30)/(24.0*60.0)); // cout<StartBulkLoad(); genmo->StartBulkLoad(); ////////////genmo///////////// ///////////mpoint///////////// Instant st = start_time; Instant et = start_time; Interval up_interval; for(unsigned int i = 0;i < seg_list.size();i++){ Point from_loc = seg_list[i].from; Point to_loc = seg_list[i].to; double dist = from_loc.Distance(to_loc); double time = dist/metro_speed; //////////////////////static unit ///////////////////////////// // et.ReadFrom(st.ToDouble() + 30.0/(24.0*60.0*60.0));//30 seconds et.ReadFrom(st.ToDouble() + time_interval);//30 seconds ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up1 = new UPoint(up_interval,from_loc,from_loc); // cout<<*up<Add(*up1); delete up1; st = et; ///////////////////////////////////////////////////////////// /////////////generic location unit ///////////////////////// //////////////////////////////////////////////////////////// Loc loc1(i + 1, 0.0); Loc loc2(i + 1, 0.0); GenLoc gloc1(mr_oid, loc1); GenLoc gloc2(mr_oid, loc2); int tm = GetTM("Metro"); UGenLoc* unit1 = new UGenLoc(up_interval, gloc1, gloc2, tm); genmo->Add(*unit1); delete unit1; ////////////////moving unit ///////////////////////////////// et.ReadFrom(st.ToDouble() + time/(24.0*60.0*60.0)); ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up2 = new UPoint(up_interval,from_loc,to_loc); // cout<<*up<Add(*up2); delete up2; st = et; ////////////////////////////////////////////////////////////// /////////////generic location unit ////////////////////////// //////////////////////////////////////////////////////////// Loc loc3(i + 1, 0.0); Loc loc4(i + 1 + 1, 0.0); GenLoc gloc3(mr_oid, loc3); GenLoc gloc4(mr_oid, loc4); tm = GetTM("Metro"); UGenLoc* unit2 = new UGenLoc(up_interval, gloc3, gloc4, tm); genmo->Add(*unit2); delete unit2; ///////////////////////////////////////////////////////////// if(i == seg_list.size() - 1){//////the last stop et.ReadFrom(st.ToDouble() + 30.0/(24.0*60.0*60.0));//30 seconds ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up = new UPoint(up_interval,to_loc,to_loc); // cout<<*up<Add(*up); delete up; st = et; ////////////////////////////////////////////////////////////// /////////////generic location unit ////////////////////////// //////////////////////////////////////////////////////////// Loc loc5(i + 1 + 1, 0.0); Loc loc6(i + 1 + 1, 0.0); GenLoc gloc5(mr_oid, loc5); GenLoc gloc6(mr_oid, loc6); tm = GetTM("Metro"); UGenLoc* unit3 = new UGenLoc(up_interval, gloc5, gloc6, tm); genmo->Add(*unit3); delete unit3; } } mo->EndBulkLoad(); genmo->EndBulkLoad(); mtrip_list1.push_back(*genmo); mtrip_list2.push_back(*mo); id_list.push_back(mr_id); mr_oid_list.push_back(mr_oid);//unique object id for a metro route dir_list.push_back(dir); CopyMetroTrip(genmo, mo, peri, start_time, mr_id, mr_oid, dir); mo->DeleteIfAllowed(); genmo->DeleteIfAllowed(); } /* create metros down direction */ void MetroStruct::CreateMetroDown(vector& seg_list, Periods* peri, int mr_id, int mr_oid, bool dir) { double metro_speed = 70.0*1000.0/3600;// -- 70km h, convert to meter minute double time_interval = 30.0/(24.0*60.0*60.0); //time of waiting Interval metro_periods; peri->Get(0, metro_periods); Instant start_time = metro_periods.start; start_time.ReadFrom(start_time.ToDouble() + (GetRandom() % 30)/(24.0*60.0)); MPoint* mo = new MPoint(0); GenMO* genmo = new GenMO(0); mo->StartBulkLoad(); genmo->StartBulkLoad(); ////////////genmo///////////// ///////////mpoint///////////// Instant st = start_time; Instant et = start_time; Interval up_interval; for(int i = seg_list.size() - 1; i >= 0; i--){ Point from_loc = seg_list[i].to; Point to_loc = seg_list[i].from; double dist = from_loc.Distance(to_loc); double time = dist/metro_speed; //////////////////////static unit ///////////////////////////// // et.ReadFrom(st.ToDouble() + 30.0/(24.0*60.0*60.0));//30 seconds et.ReadFrom(st.ToDouble() + time_interval);//30 seconds ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up1 = new UPoint(up_interval,from_loc,from_loc); // cout<<*up<Add(*up1); delete up1; st = et; ///////////////////////////////////////////////////////////// /////////////generic location unit ///////////////////////// //////////////////////////////////////////////////////////// Loc loc1(i + 1 + 1, 0.0); Loc loc2(i + 1 + 1, 0.0); GenLoc gloc1(mr_oid, loc1); GenLoc gloc2(mr_oid, loc2); int tm = GetTM("Metro"); UGenLoc* unit1 = new UGenLoc(up_interval, gloc1, gloc2, tm); genmo->Add(*unit1); delete unit1; ////////////////moving unit ///////////////////////////////// et.ReadFrom(st.ToDouble() + time/(24.0*60.0*60.0)); ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up2 = new UPoint(up_interval,from_loc,to_loc); // cout<<*up<Add(*up2); delete up2; st = et; //////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /////////////generic location unit ////////////////////////// //////////////////////////////////////////////////////////// Loc loc3(i + 1 + 1, 0.0); Loc loc4(i + 1, 0.0); GenLoc gloc3(mr_oid, loc3); GenLoc gloc4(mr_oid, loc4); tm = GetTM("Metro"); UGenLoc* unit2 = new UGenLoc(up_interval, gloc3, gloc4, tm); genmo->Add(*unit2); delete unit2; if(i == 0){//////the last stop et.ReadFrom(st.ToDouble() + 30.0/(24.0*60.0*60.0));//30 seconds ////////////////////create a upoint//////////////////////// up_interval.start = st; up_interval.lc = true; up_interval.end = et; up_interval.rc = false; UPoint* up = new UPoint(up_interval, to_loc, to_loc); // cout<<*up<Add(*up); delete up; st = et; ////////////////////////////////////////////////////////////// /////////////generic location unit ////////////////////////// //////////////////////////////////////////////////////////// Loc loc5(i + 1, 0.0); Loc loc6(i + 1, 0.0); GenLoc gloc5(mr_oid, loc5); GenLoc gloc6(mr_oid, loc6); tm = GetTM("Metro"); UGenLoc* unit3 = new UGenLoc(up_interval, gloc5, gloc6, tm); genmo->Add(*unit3); delete unit3; } } mo->EndBulkLoad(); genmo->EndBulkLoad(); mtrip_list1.push_back(*genmo); mtrip_list2.push_back(*mo); id_list.push_back(mr_id); mr_oid_list.push_back(mr_oid);//unique object id for a metro route dir_list.push_back(dir); CopyMetroTrip(genmo, mo, peri, start_time, mr_id, mr_oid, dir); mo->DeleteIfAllowed(); genmo->DeleteIfAllowed(); } /* copy the metro to have more schedules */ void MetroStruct::CopyMetroTrip(GenMO* genmo, MPoint* mo, Periods* peri, Instant s_time, int mr_id, int mr_oid, bool dir) { Interval metro_periods; peri->Get(0, metro_periods); double schedule = 10.0/(24.0*60.0); Instant new_start = s_time; /////////////////10 minutes for each metro //////////////// new_start.ReadFrom(new_start.ToDouble() + schedule); int sched_id = 1; while(new_start < metro_periods.end){ // cout<<"start time "<StartBulkLoad(); new_genmo->StartBulkLoad(); assert(mo->GetNoComponents() == genmo->GetNoComponents()); for(int i = 0;i < mo->GetNoComponents();i++){ UPoint up; mo->Get(i, up); Instant st = up.timeInterval.start; st.ReadFrom(st.ToDouble() + schedule*sched_id ); Instant et = up.timeInterval.end; et.ReadFrom(et.ToDouble() + schedule*sched_id); up.timeInterval.start = st; up.timeInterval.end = et; new_mo->Add(up); ///////////////////////////////////////////////// //////////genmo units ////////////////////////// ///////////////////////////////////////////////// UGenLoc ugloc; genmo->Get(i, ugloc); // cout<Add(*unit_new); delete unit_new; } new_mo->EndBulkLoad(); new_genmo->EndBulkLoad(); mtrip_list1.push_back(*new_genmo); mtrip_list2.push_back(*new_mo); id_list.push_back(mr_id); mr_oid_list.push_back(mr_oid);//unique object id for a metro route dir_list.push_back(dir); new_mo->DeleteIfAllowed(); new_genmo->DeleteIfAllowed(); new_start.ReadFrom(new_start.ToDouble() + schedule); sched_id++; } } /* copy the metro trips on Sunday */ void MetroStruct::CopyTripOneDayBefore() { int start = 0; int end = mtrip_list1.size(); for(;start < end; start++){ GenMO* genmo = &mtrip_list1[start]; MPoint* mo = &mtrip_list2[start]; int mr_id = id_list[start]; bool dir = dir_list[start]; int mr_oid = mr_oid_list[start]; MPoint* new_mo = new MPoint(0); GenMO* new_genmo = new GenMO(0); new_mo->StartBulkLoad(); new_genmo->StartBulkLoad(); double schedule = 1.0;///////// one day before for(int i = 0;i < mo->GetNoComponents();i++){ UPoint up; mo->Get(i, up); Instant st = up.timeInterval.start; st.ReadFrom(st.ToDouble() - schedule); Instant et = up.timeInterval.end; et.ReadFrom(et.ToDouble() - schedule); up.timeInterval.start = st; up.timeInterval.end = et; new_mo->Add(up); ///////////////////////////////////////////////// //////////genmo units ////////////////////////// ///////////////////////////////////////////////// UGenLoc ugloc; genmo->Get(i, ugloc); // cout<Add(*unit_new); delete unit_new; } new_mo->EndBulkLoad(); new_genmo->EndBulkLoad(); id_list.push_back(mr_id); dir_list.push_back(dir); mr_oid_list.push_back(mr_oid); mtrip_list1.push_back(*new_genmo); mtrip_list2.push_back(*new_mo); new_mo->DeleteIfAllowed(); new_genmo->DeleteIfAllowed(); } } /* create one kind of edges for metro graph where two metro stops have the same spatial location */ void MetroStruct::MsNeighbors1(Relation* r) { // cout<<"MsNeighbors1"< ub_stop_list; for(int i = 1;i <= r->GetNoTuples();i++){ Tuple* ub_tuple = r->GetTuple(i, false); int line_id = ((CcInt*)ub_tuple->GetAttribute(MetroNetwork::M_R_ID))->GetIntval(); Bus_Stop* mr_stop = (Bus_Stop*)ub_tuple->GetAttribute(MetroNetwork::M_STOP); Point* loc = (Point*)ub_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); int stop_id = mr_stop->GetStopId(); bool dir = mr_stop->GetUp(); UBahn_Stop ub_stop(line_id, *loc, stop_id, dir, ub_tuple->GetTupleId()); ub_stop_list.push_back(ub_stop); ub_tuple->DeleteIfAllowed(); } // cout<GetMS_Rel(); for(int i = 1;i <= ms_rel->GetNoTuples();i++){ Tuple* ms_tuple = ms_rel->GetTuple(i, false); /* int line_id = ((CcInt*)ms_tuple->GetAttribute(T_LINEID_EXT))->GetIntval(); Point *loc = (Point*)ms_tuple->GetAttribute(T_STOP_LOC_EXT); int stop_id = ((CcInt*)ms_tuple->GetAttribute(T_STOP_ID_EXT))->GetIntval(); bool dir = ((CcBool*)ms_tuple->GetAttribute(T_DIRECTION))->GetBoolval();*/ int line_id = ((CcInt*)ms_tuple->GetAttribute(MetroNetwork::M_R_ID))->GetIntval(); Bus_Stop* ms = (Bus_Stop*)ms_tuple->GetAttribute(MetroNetwork::M_STOP); Point *loc = (Point*)ms_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); int stop_id = ms->GetStopId(); bool dir = ms->GetUp(); UBahn_Stop ms_stop(line_id, *loc, stop_id, dir, ms_tuple->GetTupleId()); int neighbor_tid = mn->GetMS_Stop_Neighbor(&ms_stop); if(neighbor_tid > 0){ // ms_stop.Print(); Tuple* ms_tuple2 = ms_rel->GetTuple(neighbor_tid, false); // Point *loc2 = (Point*)ms_tuple2->GetAttribute(T_STOP_LOC_EXT); Point *loc2 = (Point*)ms_tuple2->GetAttribute(MetroNetwork::M_STOP_GEO); ConnectionOneRoute(&ms_stop, timetable, btree1, metrotrip, btree2, neighbor_tid, loc2); ms_tuple2->DeleteIfAllowed(); ms_tid_list1.push_back(ms_tuple->GetTupleId()); ms_tid_list2.push_back(neighbor_tid); } ms_tuple->DeleteIfAllowed(); /*if(neighbor_tid > 0){ Tuple* ms_tuple2 = ms_rel->GetTuple(neighbor_tid, false); int line_id2 = ((CcInt*)ms_tuple2->GetAttribute(T_LINEID_EXT))->GetIntval(); Point *loc2 = (Point*)ms_tuple2->GetAttribute(T_STOP_LOC_EXT); int stop_id2 = ((CcInt*)ms_tuple2->GetAttribute(T_STOP_ID_EXT))->GetIntval(); bool dir2 = ((CcBool*)ms_tuple2->GetAttribute(T_DIRECTION))->GetBoolval(); UBahn_Stop ms_stop2(line_id2, *loc2, stop_id2, dir2, ms_tuple2->GetTupleId()); ms_tuple2->DeleteIfAllowed(); ms_stop2.Print(); cout<line_id); BTreeIterator* btree_iter1 = btree1->ExactMatch(search_cell_id1); while(btree_iter1->Next()){ Tuple* tuple = timetable->GetTuple(btree_iter1->GetId(), false); int l_id = ((CcInt*)tuple->GetAttribute(UBTrain::UB_LINE_ID_T))->GetIntval(); assert(l_id == ms_stop->line_id); int s_id = ((CcInt*)tuple->GetAttribute(UBTrain::UB_STOP_ID_T))->GetIntval(); bool dir = ((CcBool*)tuple->GetAttribute(UBTrain::UB_DIR_T))->GetBoolval(); if(s_id == ms_stop->stop_id && dir == ms_stop->d){ Periods* peri = (Periods*)tuple->GetAttribute(UBTrain::UB_PERIODS_T); double sche_int = ((CcReal*)tuple->GetAttribute(UBTrain::UB_INTERVAL_T))->GetRealval(); // cout<<"periods "<<*peri<<" interval "<DeleteIfAllowed(); } delete btree_iter1; delete search_cell_id1; //////////////////////////////////////////////////////////////// //////////////////find the trip connecting two metro stops ///// //////////////////////////////////////////////////////////////// CcInt* search_cell_id2 = new CcInt(true, ms_stop->line_id); BTreeIterator* btree_iter2 = btree2->ExactMatch(search_cell_id2); bool found = false; while(btree_iter2->Next()){ Tuple* tuple = metrotrip->GetTuple(btree_iter2->GetId(), false); /* int l_id = ((CcInt*)tuple->GetAttribute(MetroNetwork::UB_M_LINE_ID))->GetIntval(); assert(l_id == ms_stop->line_id); bool dir = ((CcBool*)tuple->GetAttribute(MetroNetwork::UB_M_LINE_DIR))->GetBoolval();*/ int l_id = ((CcInt*)tuple->GetAttribute(M_R_ID_COM))->GetIntval(); assert(l_id == ms_stop->line_id); bool dir = ((CcBool*)tuple->GetAttribute(M_DIR_COM))->GetBoolval(); // cout<<"l_id "<d){ const double delta_dist = 0.01; // MPoint* mo = (MPoint*)tuple->GetAttribute(MetroNetwork::UB_TRIP2_MO); MPoint* mo = (MPoint*)tuple->GetAttribute(M_MP_COM); /////////////////////////////////////////////////////////// ///////////////find the stop units//////////////////////// ///////////////////////////////////////////////////////// int j = 0; for(;j < mo->GetNoComponents();j++){ UPoint up; mo->Get(j, up); Point lp = up.p0; Point rp = up.p1; if(ms_stop->loc.Distance(lp) < delta_dist && ms_stop->loc.Distance(rp) < delta_dist){ // cout<<"find the stop "<GetNoComponents()); if(j == mo->GetNoComponents() - 1){//last stop, need not process }else{ MPoint sub_move(0); sub_move.StartBulkLoad(); double time_move = 0.0; for(j++;j < mo->GetNoComponents();j++){//start from next unit UPoint up; mo->Get(j, up); Point lp = up.p0; Point rp = up.p1; if(lp.Distance(rp) < delta_dist && Neighbor_loc->Distance(lp) < delta_dist){ //next bus stop break; }else{ sub_move.Add(up); time_move += up.timeInterval.end.ToDouble() - up.timeInterval.start.ToDouble(); } } sub_move.EndBulkLoad(); // cout<<" time cost "<DeleteIfAllowed(); if(found)break; } delete btree_iter2; delete search_cell_id2; assert(found); } /* map a metro stop to a pavement area */ void MetroStruct::MapMSToPave(Relation* rel1, Relation* rel2, R_Tree<2,TupleId>* rtree) { Rectangle<2> bbox = rtree->BoundingBox(); for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* ms_tuple = rel1->GetTuple(i, false); Point* ms_loc = (Point*)ms_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); vector tri_tid_list; double dist = bbox.MaxD(0) - bbox.MinD(0); DFTraverse(rtree, rel2, rtree->RootRecordId(), ms_loc, tri_tid_list, dist); // cout<<"min dist "<GetTuple(tri_tid_list[tri_tid_list.size() - 1], false); int tri_oid = ((CcInt*)pave_tuple->GetAttribute(DualGraph::OID))->GetIntval(); Region* reg = (Region*)pave_tuple->GetAttribute(DualGraph::PAVEMENT); /////////////////////////////////////////////////////////////////// /////////////get the closet point on the region to the ms loc///// /////////////////////////////////////////////////////////////////// SpacePartition* sp = new SpacePartition(); Point ms_loc1 = *ms_loc; Point ms_loc2; for(int j = 0;j < reg->Size();j++){ HalfSegment hs; reg->Get(j, hs); if(!hs.IsLeftDomPoint()) continue; Point cp; sp->GetClosestPoint(hs, ms_loc1, cp); if(j == 0){ ms_loc2 = cp; }else{ if(ms_loc1.Distance(cp) < ms_loc1.Distance(ms_loc2)){ ms_loc2 = cp; } } } delete sp; Rectangle<2> reg_box = reg->BoundingBox(); Loc loc(ms_loc2.GetX() - reg_box.MinD(0), ms_loc2.GetY() - reg_box.MinD(1)); GenLoc gloc(tri_oid, loc); loc_list1.push_back(gloc);/////////generic location in the pavement // id_list.push_back(tri_oid); // neighbor_list.push_back(*reg); // loc_list2.push_back(*ms_loc); Bus_Stop* ms_stop = (Bus_Stop*)ms_tuple->GetAttribute(MetroNetwork::M_STOP); Point* ms_stop_loc = (Point*)ms_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); stop_geo_list.push_back(*ms_stop_loc); mstop_list.push_back(*ms_stop); loc_list2.push_back(ms_loc2); pave_tuple->DeleteIfAllowed(); ms_tuple->DeleteIfAllowed(); } } /* traverse the rtree built on pavement areas and find the clost point to the metro stop */ void MetroStruct::DFTraverse(R_Tree<2,TupleId>* rtree, Relation* rel, SmiRecordId adr, Point* loc, vector& tri_tid_list, double& min_dist) { 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* dg_tuple = rel->GetTuple(e.info, false); Region* reg = (Region*)dg_tuple->GetAttribute(DualGraph::PAVEMENT); double d = reg->Distance(*loc); if(d < min_dist){ tri_tid_list.push_back(e.info); min_dist = d; } dg_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(loc->Distance(e.box) < min_dist){ DFTraverse(rtree, rel, e.pointer, loc, tri_tid_list, min_dist); } } } delete node; } /////////////////////////////////////////////////////////////// //////////////////// metro network///////////////////////////// /////////////////////////////////////////////////////////////// /////////////// used for the real data (ubahn, converting)/////////////////// string MetroNetwork::UBAHNStopsTypeInfo = "(rel (tuple ((LineId int) (loc point) (stop_id int) (Up bool))))"; string MetroNetwork::UBAHNStopsBTreeTypeInfo = "(btree (tuple ((LineId int) (loc point) (stop_id int) (Up bool))) int)"; string MetroNetwork::UBAHNStopsRTreeTypeInfo = "(rtree (tuple ((LineId int)\ (loc point) (stop_id int) (Up bool))) point FALSE)"; string MetroNetwork::UBAHNRoutesTypeInfo = "(rel (tuple ((lineid int)\ (oid int) (geoData sline))))"; string MetroNetwork::UBAHNRotuesBTreeTypeInfo = "(rel (tuple ((lineid int)\ (oid int) (geoData sline))) int)"; string MetroNetwork::MetroStopsTypeInfo = "(rel (tuple ((Ms_stop busstop) (Stop_geodata point) (Mr_id int))))"; string MetroNetwork::MetroStopsBTreeTypeInfo = "(btree (tuple ((Ms_stop busstop) (Stop_geodata point) (Mr_id int))) int)"; string MetroNetwork::MetroStopsRTreeTypeInfo = "(rtree (tuple ((Ms_stop busstop)(Stop_geodata point)\ (Mr_id int))) point FALSE)"; string MetroNetwork::MetroRoutesTypeInfo = "(rel (tuple ((Mr_id int) \ (Mroute busroute) (Oid int))))"; string MetroNetwork::MetroRoutesBTreTypeInfo = "(rel (tuple ((Mr_id int)\ (Mroute busroute) (Oid int))) int)"; string MetroNetwork::MetroTripTypeInfo = "(rel (tuple ((Mtrip1 genmo)\ (Mtrip2 mpoint) (Mr_oid int) (Oid int))))"; string MetroNetwork::MetroTypeBTreeTypeInfo = "(btree (tuple ((Mtrip1 genmo)\ (Mtrip2 mpoint) (Mr_id int) (Oid int))) int)"; string MetroNetwork::MetroPaveTypeInfo = "(rel (tuple ((Loc1 genloc) (Loc2 point) (Ms_stop busstop)\ (Ms_stop_loc point))))"; string MetroNetwork::RTreeMetroPaveTypeInfo = "(rtree (tuple ((Loc1 genloc) (Loc2 point) (Ms_stop busstop)\ (Ms_stop_loc point))) point FALSE)"; ListExpr MetroNetworkProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> DATA"), nl->StringAtom("metronetwork"), nl->StringAtom("((def, id))"), nl->StringAtom("((TRUE 1))")))); } /* In function. there is no nested list expression here. */ Word InMetroNetwork( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { // cout<<"length "<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 2){ cout<<"length should be 2"<First(instance); ListExpr second = nl->Second(instance); if(!nl->IsAtom(first) || nl->AtomType(first) != BoolType){ cout<< "busnetwork(): definition must be bool type"<BoolValue(first); if(!nl->IsAtom(second) || nl->AtomType(second) != IntType){ cout<< "metronetwork(): metro network id must be int type"<IntValue(second); MetroNetwork* mn = new MetroNetwork(d, id); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// return SetWord(mn); } correct = false; return SetWord(Address(0)); } /* output the metro network */ ListExpr OutMetroNetwork( ListExpr typeInfo, Word value ) { // cout<<"OutMetroNetwork"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList( nl->StringAtom("Metro Network Id:"), nl->IntAtom(mn->GetId())); // return nl->OneElemList(list1); ////////////////out put bus stops relation//////////////////////////////// ListExpr bs_list = nl->TheEmptyList(); Relation* bs_rel = mn->GetMS_Rel(); if(bs_rel != NULL){ bool bFirst = true; ListExpr xNext = nl->TheEmptyList(); ListExpr xLast = nl->TheEmptyList(); for(int i = 1;i <= bs_rel->GetNoTuples();i++){ Tuple* node_tuple = bs_rel->GetTuple(i, false); int line_id = ((CcInt*)node_tuple->GetAttribute(MetroNetwork::M_R_ID))->GetIntval(); Bus_Stop* ms = (Bus_Stop*)node_tuple->GetAttribute(MetroNetwork::M_STOP); int stop_id = ms->GetStopId(); bool direction = ms->GetUp(); Point* loc = (Point*)node_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); ListExpr stop_list = nl->FourElemList( nl->IntAtom(line_id), nl->IntAtom(stop_id), nl-> BoolAtom(direction), OutPoint( nl->TheEmptyList(), SetWord(loc) )); xNext = stop_list; if(bFirst){ bs_list = nl->OneElemList(xNext); xLast = bs_list; bFirst = false; }else xLast = nl->Append(xLast,xNext); node_tuple->DeleteIfAllowed(); } } // return nl->TwoElemList(list1, bs_list); //////////////////////output metro routes relation/////////////////////////// ListExpr br_list = nl->TheEmptyList(); Relation* br_rel = mn->GetMR_Rel(); if(br_rel != NULL){ bool bFirst = true; ListExpr xNext = nl->TheEmptyList(); ListExpr xLast = nl->TheEmptyList(); for(int i = 1;i <= br_rel->GetNoTuples();i++){ Tuple* node_tuple = br_rel->GetTuple(i, false); int lineid = ((CcInt*)node_tuple->GetAttribute(MetroNetwork::M_ROUTE_ID))->GetIntval(); Bus_Route* mr = (Bus_Route*)node_tuple->GetAttribute(MetroNetwork::M_ROUTE); SimpleLine mr_sl(0); mr->GetGeoData(mr_sl); ListExpr route_list = nl->TwoElemList( nl->IntAtom(lineid), OutSimpleLine( nl->TheEmptyList(), SetWord(&mr_sl))); xNext = route_list; if(bFirst){ br_list = nl->OneElemList(xNext); xLast = br_list; bFirst = false; }else xLast = nl->Append(xLast,xNext); node_tuple->DeleteIfAllowed(); } } //////////////////////////////////////////////////////////////////////// ////////////////no output bus trips relation: too much data/////////////// ////////////////////////////////////////////////////////////////////////// return nl->ThreeElemList(list1, bs_list, br_list); } bool SaveMetroNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { MetroNetwork* mn = (MetroNetwork*)value.addr; return mn->Save(valueRecord, offset, typeInfo); } bool OpenMetroNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { value.addr = MetroNetwork::Open(valueRecord, offset, typeInfo); return value.addr != NULL; } MetroNetwork* MetroNetwork::Open(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { return new MetroNetwork(valueRecord, offset, typeInfo); } Word CreateMetroNetwork(const ListExpr typeInfo) { // cout<<"CreateMetroNetwork()"<(w.addr); w.addr = 0; } Word CloneMetroNetwork( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneMetroNetwork"<IsEqual( type, "metronetwork" )); } MetroNetwork::MetroNetwork(): def(false), mn_id(0), graph_init(false), graph_id(0), max_metro_speed(0), min_mr_oid(0), min_mt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_ms(NULL), rtree_ms(NULL), routes_rel(NULL), btree_mr(NULL), btree_mr_uoid(NULL), metrotrips_rel(NULL), btree_trip_br_id(NULL), btree_trip_oid(NULL) { } MetroNetwork::MetroNetwork(bool d, unsigned int i): def(d), mn_id(i), graph_init(false), graph_id(0), max_metro_speed(0), min_mr_oid(0), min_mt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_ms(NULL), rtree_ms(NULL), routes_rel(NULL), btree_mr(NULL), btree_mr_uoid(NULL), metrotrips_rel(NULL), btree_trip_br_id(NULL), btree_trip_oid(NULL) { } /* read the data from record */ MetroNetwork::MetroNetwork(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo): def(false), mn_id(0), graph_init(false), graph_id(0), max_metro_speed(0), min_mr_oid(0), min_mt_oid(0), start_time(0), end_time(0), stops_rel(NULL), btree_ms(NULL), rtree_ms(NULL), routes_rel(NULL), btree_mr(NULL), btree_mr_uoid(NULL), metrotrips_rel(NULL), btree_trip_br_id(NULL), btree_trip_oid(NULL) { valueRecord.Read(&def, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Read(&mn_id, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&graph_init, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Read(&graph_id, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&max_metro_speed, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&min_mr_oid, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&min_mt_oid, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Read(&start_time, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&end_time, sizeof(double), offset); offset += sizeof(double); ListExpr xType; ListExpr xNumericType; ////////////////Open relation for metro stops/////////////////////// nl->ReadFromString(MetroStopsTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); stops_rel = Relation::Open(valueRecord, offset, xNumericType); if(!stops_rel) { return; } ///////////////////btree on metro stops on brid/////////////////////////////// nl->ReadFromString(MetroStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_ms = BTree::Open(valueRecord, offset, xNumericType); if(!btree_ms) { stops_rel->Delete(); return; } ///////////////////rtree on metro stops ////////////////////////////// Word xValue; if(!(rtree_ms->Open(valueRecord,offset, MetroStopsRTreeTypeInfo,xValue))){ stops_rel->Delete(); delete btree_ms; return; } rtree_ms = ( R_Tree<2,TupleId>* ) xValue.addr; ///////////////////////////////Open relation for metroroutes/////////////// nl->ReadFromString(MetroRoutesTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); routes_rel = Relation::Open(valueRecord, offset, xNumericType); if(!routes_rel) { stops_rel->Delete(); delete btree_ms; delete rtree_ms; return; } ///////////////////btree on metro routes////////////////////////////////// nl->ReadFromString(MetroRoutesBTreTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_mr = BTree::Open(valueRecord, offset, xNumericType); if(!btree_mr) { stops_rel->Delete(); delete btree_ms; delete rtree_ms; routes_rel->Delete(); return; } ///////////////////btree on metro routes unique oid/////////////////////// nl->ReadFromString(MetroRoutesBTreTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_mr_uoid = BTree::Open(valueRecord, offset, xNumericType); if(!btree_mr_uoid) { stops_rel->Delete(); delete btree_ms; routes_rel->Delete(); delete btree_mr; delete rtree_ms; return; } ///////////////open relation storing metro trips////////////////////// nl->ReadFromString(MetroTripTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); metrotrips_rel = Relation::Open(valueRecord, offset, xNumericType); if(!metrotrips_rel) { stops_rel->Delete(); delete btree_ms; routes_rel->Delete(); delete btree_mr; delete rtree_ms; delete btree_mr_uoid; return; } ///////////////////btree on metro trips metro route id/////////////////////// nl->ReadFromString(MetroTypeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_trip_br_id = BTree::Open(valueRecord, offset, xNumericType); if(!btree_trip_br_id) { stops_rel->Delete(); delete btree_ms; routes_rel->Delete(); delete btree_mr; delete rtree_ms; delete btree_mr_uoid; metrotrips_rel->Delete(); return; } ///////////////////btree on metro trips unique id//////////////////////////// nl->ReadFromString(MetroTypeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_trip_oid = BTree::Open(valueRecord, offset, xNumericType); if(!btree_trip_oid) { stops_rel->Delete(); delete btree_ms; routes_rel->Delete(); delete btree_mr; delete rtree_ms; delete btree_mr_uoid; metrotrips_rel->Delete(); delete btree_trip_br_id; return; } } MetroNetwork::~MetroNetwork() { if(stops_rel != NULL) stops_rel->Close(); if(btree_ms != NULL) delete btree_ms; if(rtree_ms != NULL) delete rtree_ms; if(routes_rel != NULL) routes_rel->Close(); if(btree_mr != NULL) delete btree_mr; if(btree_mr_uoid != NULL) delete btree_mr_uoid; if(metrotrips_rel != NULL) metrotrips_rel->Close(); if(btree_trip_br_id != NULL) delete btree_trip_br_id; if(btree_trip_oid != NULL) delete btree_trip_oid; } bool MetroNetwork::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { // cout<<"MetroNetwork::Save"<ReadFromString(MetroStopsTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!stops_rel->Save(valueRecord,offset,xNumericType)) return false; /////////////////////btree on metro stops on lineid///////////////////////// nl->ReadFromString(MetroStopsBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_ms->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////rtree on metro stops /////////////////////// if(!rtree_ms->Save(valueRecord, offset)){ return false; } ///////////////////metro routes relation/////////////////////////// nl->ReadFromString(MetroRoutesTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!routes_rel->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on metro routes//////////////////////////// nl->ReadFromString(MetroRoutesBTreTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_mr->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on bus routes on unique id/////////////////// nl->ReadFromString(MetroRoutesBTreTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_mr_uoid->Save(valueRecord,offset,xNumericType)) return false; ///////////////////metro trips relation///////////////////////////// nl->ReadFromString(MetroTripTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!metrotrips_rel->Save(valueRecord,offset,xNumericType)) return false; //////////////////btree on metro trips on metro route id///////////////// nl->ReadFromString(MetroTypeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_trip_br_id->Save(valueRecord,offset,xNumericType)) return false; ///////////////////////btree on metro trips on unique id/////////////////// nl->ReadFromString(MetroTypeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_trip_oid->Save(valueRecord,offset,xNumericType)) return false; return true; } /* load stops, routes, and moving metros relation */ void MetroNetwork::Load(unsigned int i, Relation* r1, Relation* r2, Relation* r3) { if(i < 1){ def = false; return; } mn_id = i; LoadStops(r1); /////to get 2D points in space LoadRoutes(r2); //first load bus routes because bus stops access bus routes LoadMetros(r3); //load moving metros def = true; } /* load metro stops relation */ void MetroNetwork::LoadStops(Relation* r) { // cout<<"LoadStops"<ToString(ptrList1) + "))))"; // cout<ToString(ptrList2) + "))" + "Mr_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_ms = (BTree*)xResult.addr; //////////////////////rtree on metro stops////////////////////////// ListExpr ptrList3 = listutils::getPtrList(stops_rel); strQuery = "(bulkloadrtree(sortby(addid(feed (" + MetroStopsTypeInfo + " (ptr " + nl->ToString(ptrList3) + "))))((Stop_geodata asc))) Stop_geodata)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); rtree_ms = ( R_Tree<2,TupleId>* ) xResult.addr; } /* load metro routes relation */ void MetroNetwork::LoadRoutes(Relation* r2) { // cout<<"LoadRotes"<ToString(ptrList1) + "))))"; // cout<::max(); for(int i = 1;i <= routes_rel->GetNoTuples();i++){ Tuple* mr_tuple = routes_rel->GetTuple(i, false); int id = ((CcInt*)mr_tuple->GetAttribute(M_R_OID))->GetIntval(); if(id < temp_id) temp_id = id; mr_tuple->DeleteIfAllowed(); } min_mr_oid = temp_id; // cout<<"min mr oid "<ToString(ptrList2) + "))" + "Mr_id)"; // cout<ToString(ptrList3) + "))" + "Oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_mr_uoid = (BTree*)xResult.addr; } /* load moving metros */ void MetroNetwork::LoadMetros(Relation* r3) { // cout<<"LoadMetros"<ToString(ptrList1) + "))))"; // cout<GetNoTuples()<::max(); for(int i = 1;i <= metrotrips_rel->GetNoTuples();i++){ Tuple* metro_tuple = metrotrips_rel->GetTuple(i, false); MPoint* mo = (MPoint*)metro_tuple->GetAttribute(M_TRIP_MP); /////////////get the start and end time of all bus trips////////////// Periods* peri = new Periods(0); mo->DefTime(*peri); Interval time_span; peri->Get(0, time_span); // cout< end_time) end_time = time_span.end.ToDouble(); } peri->DeleteIfAllowed(); /////////////////////////////////////////////////////////////////////// for( int j = 0; j < mo->GetNoComponents(); j++ ){ UPoint unit; mo->Get( j, unit ); Point pos1 = unit.p0; Point pos2 = unit.p1; if(pos1.Distance(pos2) > 1.0){ double t = unit.timeInterval.end.ToDouble()*86400.0 - unit.timeInterval.start.ToDouble()*86400.0; double speed = pos1.Distance(pos2)/t; /* cout<<"dist "< max_metro_speed){ max_metro_speed = speed; } } } int id = ((CcInt*)metro_tuple->GetAttribute(M_TRIP_OID))->GetIntval(); if(id < temp_id) temp_id = id; metro_tuple->DeleteIfAllowed(); } min_mt_oid = temp_id; // cout<<"max metro speed "<ToString(ptrList2) + "))" + "Mr_oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_trip_br_id = (BTree*)xResult.addr; ////////////////btree on metro trips oid/////////////////////////// ListExpr ptrList3 = listutils::getPtrList(metrotrips_rel); strQuery = "(createbtree (" + MetroTripTypeInfo + "(ptr " + nl->ToString(ptrList3) + "))" + "Oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); btree_trip_oid = (BTree*)xResult.addr; /* Instant t1(start_time); Instant t2(end_time); cout<line_id; int stop_id = ms_stop->stop_id; bool dir = ms_stop->d; CcInt* search_cell_id = new CcInt(true, line_id); BTreeIterator* btree_iter = btree_ms->ExactMatch(search_cell_id); int neighbor_tid = 0; bool found = false; while(btree_iter->Next()){ Tuple* tuple = stops_rel->GetTuple(btree_iter->GetId(), false); int l_id = ((CcInt*)tuple->GetAttribute(M_R_ID))->GetIntval(); assert(l_id == line_id); // bool d = ((CcBool*)tuple->GetAttribute(UB_DIRECTION))->GetBoolval(); Bus_Stop* ms = (Bus_Stop*)tuple->GetAttribute(M_STOP); bool d = ms->GetUp(); if(dir == d){ // int s_id = ((CcInt*)tuple->GetAttribute(UB_STOP_ID))->GetIntval(); int s_id = ms->GetStopId(); if(dir){ if(s_id == stop_id + 1){ neighbor_tid = tuple->GetTupleId(); found = true; } }else{ if(s_id == stop_id - 1){ neighbor_tid = tuple->GetTupleId(); found = true; } } } tuple->DeleteIfAllowed(); if(found)break; } delete btree_iter; delete search_cell_id; return neighbor_tid; } /* set the metro graph id */ void MetroNetwork::SetGraphId(int g_id) { graph_id = g_id; graph_init = true; } /* get the metro graph in metro network */ MetroGraph* MetroNetwork::GetMetroGraph() { if(graph_init == false) return NULL; ListExpr xObjectList = SecondoSystem::GetCatalog()->ListObjects(); xObjectList = nl->Rest(xObjectList); while(!nl->IsEmpty(xObjectList)) { // Next element in list ListExpr xCurrent = nl->First(xObjectList); xObjectList = nl->Rest(xObjectList); // Type of object is at fourth position in list ListExpr xObjectType = nl->First(nl->Fourth(xCurrent)); if(nl->IsAtom(xObjectType) && nl->SymbolValue(xObjectType) == "metrograph"){ // Get name of the metro graph ListExpr xObjectName = nl->Second(xCurrent); string strObjectName = nl->SymbolValue(xObjectName); // Load object to find out the id of the network. Word xValue; bool bDefined; bool bOk = SecondoSystem::GetCatalog()->GetObject(strObjectName, xValue, bDefined); if(!bDefined || !bOk) { // Undefined continue; } MetroGraph* mg = (MetroGraph*)xValue.addr; if(mg->GetMG_ID() == graph_id){ // This is the metro graph we have been looking for return mg; } } } return NULL; } /* close the metro graph */ void MetroNetwork::CloseMetroGraph(MetroGraph* mg) { if(mg == NULL) return; Word xValue; xValue.addr = mg; SecondoSystem::GetCatalog()->CloseObject(nl->SymbolAtom("metrograph"), xValue); } /* get the 2d point of a metro stop */ void MetroNetwork::GetMetroStopGeoData(Bus_Stop* ms, Point* p) { int id = ms->GetId(); if(id < 1){ cout<<"invalid metro stop"<ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter->GetId(), false); Bus_Route* mr = (Bus_Route*)tuple->GetAttribute(M_ROUTE); if(mr->GetUp() == ms->GetUp()){ mr->GetMetroStopGeoData(ms, p); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; } /* get the moving metro pass the metro stop at the input time */ int MetroNetwork::GetMOMetro_Oid(Bus_Stop* ms, Point* ms_loc, Instant& t) { // cout<<"metro stop "<<*ms<<" loc "<<*ms_loc<<" time "<GetId(); ////////////////////////////////////////////////////////////////// ////////////get the unique id for the metro route///////////////// ////////////////////////////////////////////////////////////////// CcInt* search_id1 = new CcInt(true, mr_id); BTreeIterator* btree_iter1 = btree_mr->ExactMatch(search_id1); int mr_uoid = 0; while(btree_iter1->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter1->GetId(), false); Bus_Route* mr = (Bus_Route*)tuple->GetAttribute(M_ROUTE); if(mr->GetUp() == ms->GetUp()){ mr_uoid = ((CcInt*)tuple->GetAttribute(M_R_OID))->GetIntval(); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; assert(mr_uoid > 0); // cout<<"mr_uoid "<ExactMatch(search_id2); const double delta_dist = 0.01; vector res_list; while(btree_iter2->Next()){ Tuple* tuple = metrotrips_rel->GetTuple(btree_iter2->GetId(), false); int mrid = ((CcInt*)tuple->GetAttribute(M_REFMR_OID))->GetIntval(); assert(mrid == mr_uoid); MPoint* mo_metro = (MPoint*)tuple->GetAttribute(M_TRIP_MP); Periods* peri = new Periods(0); mo_metro->DefTime(*peri); // cout<<"periods "<<*peri<Contains(t)){ // cout<<"periods containt instant "<GetNoComponents();i++){ UPoint unit; mo_metro->Get(i, unit); Point p0 = unit.p0; Point p1 = unit.p1; // cout<Distance(p0)<Distance(p0) // <<" dist2 "<Distance(p1)<Distance(p0) < delta_dist && ms_loc->Distance(p1) < delta_dist){ metro_oid = ((CcInt*)tuple->GetAttribute(M_TRIP_OID))->GetIntval(); double delta_t = fabs(unit.timeInterval.start.ToDouble() - t.ToDouble()); Id_Time* id_time = new Id_Time(metro_oid, delta_t); res_list.push_back(*id_time); delete id_time; } } } peri->DeleteIfAllowed(); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; sort(res_list.begin(), res_list.end()); assert(res_list.size() > 0); metro_oid = res_list[0].oid; assert(metro_oid > 0); return metro_oid; } /* given a metro stop and time, it returns mpoint of the moving metro belonging to that metro route and direction as well as covering the time */ int MetroNetwork::GetMOMetro_MP(Bus_Stop* ms, Point* ms_loc, Instant t, MPoint& mp) { // cout<<"metro stop "<<*ms<<" loc "<<*ms_loc<<" time "<GetId(); ////////////////////////////////////////////////////////////////// ////////////get the unique id for the metro route///////////////// ////////////////////////////////////////////////////////////////// CcInt* search_id1 = new CcInt(true, mr_id); BTreeIterator* btree_iter1 = btree_mr->ExactMatch(search_id1); int mr_uoid = 0; while(btree_iter1->Next()){ Tuple* tuple = routes_rel->GetTuple(btree_iter1->GetId(), false); Bus_Route* mr = (Bus_Route*)tuple->GetAttribute(M_ROUTE); if(mr->GetUp() == ms->GetUp()){ mr_uoid = ((CcInt*)tuple->GetAttribute(M_R_OID))->GetIntval(); tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; assert(mr_uoid > 0); // cout<<"mr_uoid "<ExactMatch(search_id2); bool found = false; const double delta_dist = 0.01; vector res_list; while(btree_iter2->Next() && found == false){ Tuple* tuple = metrotrips_rel->GetTuple(btree_iter2->GetId(), false); int mrid = ((CcInt*)tuple->GetAttribute(M_REFMR_OID))->GetIntval(); assert(mrid == mr_uoid); MPoint* mo_metro = (MPoint*)tuple->GetAttribute(M_TRIP_MP); Periods* peri = new Periods(0); mo_metro->DefTime(*peri); if(peri->Contains(t)){ // cout<<"periods "<<*peri<GetNoComponents();i++){ UPoint unit; mo_metro->Get(i, unit); Point p0 = unit.p0; Point p1 = unit.p1; if(ms_loc->Distance(p0) < delta_dist && unit.timeInterval.Contains(t)){ mp = *mo_metro; metro_oid = ((CcInt*)tuple->GetAttribute(M_TRIP_OID))->GetIntval(); found = true; break; } } } peri->DeleteIfAllowed(); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; assert(metro_oid > 0); return metro_oid; } //////////////////////////////////////////////////////////////////////// ////////////////////metro graph///////////////////////////////////////// //////////////////////////////////////////////////////////////////////// string MetroGraph::MGNodeTypeInfo = "(rel (tuple ((Ms_stop busstop) (Stop_geodata point) (Mr_id int))))"; string MetroGraph::MGEdge1TypeInfo = "(rel (tuple ((Ms_stop1_tid int) (Ms_stop2_tid int))))"; string MetroGraph::MGEdge2TypeInfo = "(rel (tuple ((Ms_stop1_tid int)\ (Ms_stop2_tid int) (Whole_time periods)(Schedule_interval real)\ (Path sline) (TimeCost real))))"; string MetroGraph::MGNodeBTreeTypeInfo = "(btree (tuple ((Ms_stop busstop) (Stop_geodata point) (Mr_id int))) int)"; ListExpr MetroGraph::MetroGraphProp() { ListExpr examplelist = nl->TextAtom(); nl->AppendText(examplelist, "createmetrograph(,,)"); return nl->TwoElemList( nl->TwoElemList(nl->StringAtom("Creation"), nl->StringAtom("Example Creation")), nl->TwoElemList(examplelist, nl->StringAtom("let mg=createmetrograph(id,e-rel,n-rel)"))); } bool MetroGraph::CheckMetroGraph(ListExpr type, ListExpr& errorInfo) { // cout<<"CheckMetroGraph()"<IsEqual(type, "metrograph"); } int MetroGraph::SizeOfMetroGraph() { // cout<<"SizeOfMetroGraph()"< (w.addr); w.addr = NULL; } Word MetroGraph::CreateMetroGraph(const ListExpr typeInfo) { // cout<<"MetroMetroGraph()"<Out(typeInfo); } ListExpr MetroGraph::Out(ListExpr typeInfo) { // cout<<"Out()"<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 l_id = ((CcInt*)node_tuple->GetAttribute(MG_NODE_LINE_ID))->GetIntval(); Point* loc = (Point*)node_tuple->GetAttribute(MG_NODE_LOC); int stop_id = ((CcInt*)node_tuple->GetAttribute(MG_NODE_STOP_ID))->GetIntval(); bool dir = ((CcBool*)node_tuple->GetAttribute(MG_NODE_UP))->GetBoolval();*/ int l_id = ((CcInt*)node_tuple->GetAttribute(MG_NODE_MR_ID))->GetIntval(); Point* loc = (Point*)node_tuple->GetAttribute(MG_NODE_STOP_GEO); Bus_Stop* ms_stop = (Bus_Stop*)node_tuple->GetAttribute(MG_NODE_STOP); int stop_id = ms_stop->GetStopId(); bool dir = ms_stop->GetUp(); xNext = nl->FourElemList( nl->IntAtom(l_id), nl->IntAtom(stop_id), nl-> BoolAtom(dir), 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(mg_id),xNode); // return nl->OneElemList(nl->IntAtom(mg_id)); } bool MetroGraph::SaveMetroGraph(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"SaveMetroGraph()"<Save(valueRecord, offset, typeInfo); return result; } bool MetroGraph::OpenMetroGraph(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenMetroGraph()"<Close(); if(btree_node != NULL) delete btree_node; if(edge_rel1 != NULL) edge_rel1->Close(); if(edge_rel2 != NULL) edge_rel2->Close(); } MetroGraph::MetroGraph(ListExpr in_xValue,int in_iErrorPos, ListExpr& inout_xErrorInfo, bool& inout_bCorrect): mg_id(0), min_t(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<<"MetroGraph::MetroGraph(ListExpr)"<ReadFromString(MGNodeTypeInfo,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(MGNodeBTreeTypeInfo,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(MGEdge1TypeInfo, 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::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(MGEdge2TypeInfo, 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::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); } bool MetroGraph::Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset, const ListExpr in_xTypeInfo) { // cout<<"save "<ReadFromString(MGNodeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!node_rel->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; ////////////////save btree on nodes/////////////////////////// nl->ReadFromString(MGNodeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_node->Save(in_xValueRecord, inout_iOffset, xNumericType)) return false; /////////////////////save edge1///////////////////////////// nl->ReadFromString(MGEdge1TypeInfo,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(MGEdge2TypeInfo,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 metro graph from input relations */ void MetroGraph::Load(int g_id, Relation* r1, Relation* edge1, Relation* edge2) { if(g_id <= 0){ cout<<"invalid graph id "<ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); node_rel = (Relation*)xResult.addr; // cout<<"nodes size "<GetNoTuples()<ToString(ptrList2) + "))" + "Mr_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); btree_node = (BTree*)xResult.addr; // cout<GetNoTuples()<<" "<GetNoTuples()<ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel1 = (Relation*)xResult.addr; //////////////////create adjacency list//////////////////////////////////// ListExpr ptrList2 = listutils::getPtrList(edge_rel1); strQuery = "(createbtree (" + MGEdge1TypeInfo + "(ptr " + nl->ToString(ptrList2) + "))" + "Ms_stop1_tid)"; 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 and bus 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); CcInt* nodeid = new CcInt(true, ms_tuple->GetTupleId()); 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<<"start "<DeleteIfAllowed(); } delete btree; } /* metro graph edges: two metro stops are connected by moving metros */ void MetroGraph::LoadEdge2(Relation* edge2) { ListExpr ptrList1 = listutils::getPtrList(edge2); string strQuery = "(consume(feed(" + MGEdge2TypeInfo + "(ptr " + nl->ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel2 = (Relation*)xResult.addr; min_t = numeric_limits::max(); for(int i = 1;i <= edge_rel2->GetNoTuples();i++){ Tuple* edge_tuple = edge_rel2->GetTuple(i, false); Periods* peri = (Periods*)edge_tuple->GetAttribute(MG_EDGE2_PERI); Interval periods; peri->Get(0, periods); double t = periods.start.ToDouble(); if(t < min_t) min_t = t; edge_tuple->DeleteIfAllowed(); } // Instant min_time(instanttype); // min_time.ReadFrom(min_t); // printf("%.10f\n",min_t); // cout<ToString(ptrList2) + "))" + "Ms_stop1_tid)"; 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 and bus 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); CcInt* nodeid = new CcInt(true, ms_tuple->GetTupleId()); 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)); delete nodeid; ms_tuple->DeleteIfAllowed(); } delete btree; } /* find the metro stop tid in the relation */ int MetroGraph::GetMetroStop_Tid(Bus_Stop* ms) { if(!ms->IsDefined()) return -1; int ms_tid = -1; CcInt* search_id = new CcInt(true,ms->GetId()); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* ms_tuple = node_rel->GetTuple(btree_iter->GetId(), false); Bus_Stop* ms_stop = (Bus_Stop*)ms_tuple->GetAttribute(MG_NODE_STOP); int mr_id = ms->GetId(); assert(mr_id == (int) ms->GetId()); if(ms->GetStopId() == ms_stop->GetStopId() && ms->GetUp() == ms_stop->GetUp()){ ms_tid = ms_tuple->GetTupleId(); ms_tuple->DeleteIfAllowed(); break; } ms_tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; assert(ms_tid > 0 && ms_tid <= node_rel->GetNoTuples()); return ms_tid; } /* metro stops have the same spatial location in space */ void MetroGraph::FindAdj1(int node_id, vector& 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 MetroGraph::FindAdj2(int node_id, vector& 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 metro graph and network////////// //////////////////////////////////////////////////////////////////////////// /* shortest path on metro network and graph */ void MNNav::ShortestPath_Time(Bus_Stop* ms1, Bus_Stop* ms2, Instant* qt) { // cout<<"shortest path on metro network"<GetMetroGraph(); if(mg == NULL){ cout<<"metro graph is invalid"<GetNode_Rel()->GetNoTuples()<IsDefined() || !ms2->IsDefined()){ cout<<" metro stops are not defined"<GetMetroStopGeoData(ms1, &start_p); mn->GetMetroStopGeoData(ms2, &end_p); // cout<<"start "<CloseMetroGraph(mg); return; } /////////////////////////build the start time/////////////////////////// Instant new_st(instanttype); Instant mg_min(instanttype); mg_min.ReadFrom(mg->GetMIN_T()); // cout<<"mg_min "<GetHour(), qt->GetMinute(), qt->GetSecond(), qt->GetMillisecond()); // cout<<"mapping start time"< path_queue; vector expand_queue; vector visit_flag1;////////////metro stop visit for(int i = 1; i <= mg->GetNode_Rel()->GetNoTuples();i++) visit_flag1.push_back(false); ////////////////////////////////////////////////////////////////// /////////from metro network, get the maximum speed of the metro/// /////////////for setting heuristic value///////////////////////// /////////////////////////////////////////////////////////////////// // cout<<"max metro speed "<GetMaxSpeed()*60.0*60.0/1000.0<<"km/h"<GetMetroStop_Tid(ms2); // cout<<"end bus stop tid "< adj_list1; mg->FindAdj1(top.tri_index, adj_list1); // cout<<"adj1 size "<GetEdge_Rel1()->GetTuple(adj_list1[i], false); int neighbor_id1 = ((CcInt*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE1_TID2))->GetIntval(); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); // cout<<"neighbor_tid1 "<DeleteIfAllowed(); path->DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double w = top.real_w; Tuple* ms_node_tuple = mg->GetNode_Rel()->GetTuple(neighbor_id1, false); Point* p = (Point*)ms_node_tuple->GetAttribute(MetroGraph::MG_NODE_STOP_GEO); double hw = p->Distance(end_p)/(mn->GetMaxSpeed()*24.0*60.0*60.0); ms_node_tuple->DeleteIfAllowed(); // BNPath_elem elem(pos_expand_path, cur_size, neighbor_id1, w + hw, w, // *path, -1, false); //no useful for time cost BNPath_elem elem(pos_expand_path, cur_size, neighbor_id1, w + hw, w, *path, -1, false); //no useful for time cost elem.type = -1; elem.edge_tid = 0; path_queue.push(elem); expand_queue.push_back(elem); // cout<<"neighbor1 "; // elem.Print(); // cout<DeleteIfAllowed(); edge_tuple->DeleteIfAllowed(); } } ////////////////////////////////////////////////////////////////////// ////////////////////connection 2 moving metros///////////////////////// ////////////////////////////////////////////////////////////////////// vector adj_list2; mg->FindAdj2(top.tri_index, adj_list2); int64_t max_64_int = numeric_limits::max(); // cout<<"ajd2 size "<GetEdge_Rel2()->GetTuple(adj_list2[i], false); int neighbor_id2 = ((CcInt*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE2_TID2))->GetIntval(); // SimpleLine* path = // (SimpleLine*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE2_PATH); // cout<<"neighbor_id2 "<DeleteIfAllowed(); continue; } cur_size = expand_queue.size(); double cur_t = new_st.ToDouble() + top.real_w; Instant cur_inst = new_st; cur_inst.ReadFrom(cur_t); //time to arrive current metro stop // cout<<"time at metro stop "<GetAttribute(MetroGraph::MG_EDGE2_PERI); Interval periods; peri->Get(0, periods); double sched = ((CcReal*)edge_tuple->GetAttribute(MetroGraph:: MG_EDGE2_SCHED))->GetRealval(); double st = periods.start.ToDouble(); double et = periods.end.ToDouble(); int64_t st_int = st*86400000; int64_t et_int = et*86400000; assert(st_int <= max_64_int); assert(et_int <= max_64_int); // cout<<"st "<DeleteIfAllowed(); continue; } // cout<<"st_int "< cur_t_int){//wait for the first start time wait_time += st - cur_t; wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at metro stop }else if(st_int == cur_t_int){ wait_time += 30.0/(24.0*60.0*60.0);//30 seconds at metro stop }else{ //most times, it is here, wait for the next schedule bool valid = false; while(st_int < cur_t_int && st_int <= et_int){ Instant temp(instanttype); temp.ReadFrom(st); // cout<<"t1 "<= cur_t_int){//30 second wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } st += sched; st_int = st * 86400000; if(st_int >= cur_t_int){ wait_time += st + 30.0/(24.0*60.0*60.0) - cur_t; valid = true; break; } assert(st_int <= max_64_int); // temp.ReadFrom(st); // cout<<"t2 "<GetAttribute(MetroGraph:: MG_EDGE2_TIME_COST))->GetRealval(); double w = top.real_w + wait_time + weight; Tuple* ms_node_tuple = mg->GetNode_Rel()->GetTuple(neighbor_id2, false); Point* p = (Point*)ms_node_tuple->GetAttribute(MetroGraph::MG_NODE_STOP_GEO); double hw = p->Distance(end_p)/(mn->GetMaxSpeed()*24.0*60.0*60.0); ms_node_tuple->DeleteIfAllowed(); // BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, // *path, TM_METRO, true); SimpleLine temp_sl(0); BNPath_elem elem(pos_expand_path, cur_size, neighbor_id2, w + hw, w, temp_sl, TM_METRO, true); elem.type = TM_METRO; elem.edge_tid = adj_list2[i]; if(wait_time > 0.0){ //to the time waiting for metro elem.SetW(top.real_w + wait_time); } path_queue.push(elem); expand_queue.push_back(elem); // cout<<"neighbor2 "<DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////////////////////////////////////////////////////////// ////////////////construct the result////////////////////////////////// ////////////////////////////////////////////////////////////////////// if(find){ ////////constrcut the result vector id_list; while(dest.prev_index != -1){ id_list.push_back(dest.cur_index); dest = expand_queue[dest.prev_index]; } id_list.push_back(dest.cur_index); Bus_Stop ms_last = *ms1; Instant t1 = *qt; // int no_transfer = 0; t_cost = 0.0; for(int i = id_list.size() - 1;i >= 0;i--){ BNPath_elem elem = expand_queue[id_list[i]]; if(elem.type == TM_METRO){ if(elem.edge_tid > 0){ Tuple* edge_tuple = mg->GetEdge_Rel2()->GetTuple(elem.edge_tid, false); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE2_PATH); elem.path = *path; edge_tuple->DeleteIfAllowed(); } }else if(elem.type == -1){ }else{ cout<<"should not be here"<GetNode_Rel()->GetTuple(elem.tri_index, false); Bus_Stop* ms_cur = (Bus_Stop*)ms_tuple->GetAttribute(MetroGraph::MG_NODE_STOP); char buf_1[256], buf_2[256]; sprintf(buf_1, "mr: %d ", ms_cur->GetId()); sprintf(buf_2, "stop: %d", ms_cur->GetStopId()); strcat (buf_1, buf_2); if(ms_cur->GetUp()) strcat (buf_1, " UP"); else strcat (buf_1, " DOWN"); string str2(buf_1); ms2_list.push_back(str2); ms_last = *ms_cur; ms_tuple->DeleteIfAllowed(); } ////////////////time duration//////////////////////////////// Instant t2(instanttype); if(elem.b_w == false){ t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri = new Periods(0); peri->StartBulkLoad(); if(elem.valid) peri->MergeAdd(time_span); peri->EndBulkLoad(); peri_list.push_back(*peri); t1 = t2; peri->DeleteIfAllowed(); }else{ //////////to dinstinguish time of waiting for the metro t2.ReadFrom(elem.w + qt->ToDouble()); // cout< time_span; time_span.start = t1; time_span.lc = true; time_span.end = t2; time_span.rc = false; Periods* peri1 = new Periods(0); peri1->StartBulkLoad(); if(elem.valid) peri1->MergeAdd(time_span); peri1->EndBulkLoad(); peri_list.push_back(*peri1); t1 = t2; peri1->DeleteIfAllowed(); SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); path_list[path_list.size() - 1] = *sl; sl->DeleteIfAllowed(); tm_list[tm_list.size() - 1] = "none"; //waiting is no tm string str = ms2_list[ms2_list.size() - 1]; ////////the same as last metro stop ////////////////////// ms2_list[ms2_list.size() - 1] = ms1_list[ms1_list.size() - 1]; /////////////moving with metro//////////////////////////////// t2.ReadFrom(elem.real_w + qt->ToDouble()); // cout<StartBulkLoad(); if(elem.valid) peri2->MergeAdd(time_span); peri2->EndBulkLoad(); peri_list.push_back(*peri2); t1 = t2; peri2->DeleteIfAllowed(); path_list.push_back(elem.path); tm_list.push_back(str_tm[elem.tm]); ms1_list.push_back(str1); ms2_list.push_back(str); } } // cout<<" transfer "<CloseMetroGraph(mg); } /* initialize the queue: shortest path in time */ void MNNav::InitializeQueue(Bus_Stop* ms1, Bus_Stop* ms2, priority_queue& path_queue, vector& expand_queue, MetroNetwork* mn, MetroGraph* mg, Point& start_p, Point& end_p) { int cur_size = expand_queue.size(); double w = 0.0; double hw = start_p.Distance(end_p)/(mn->GetMaxSpeed()*24.0*60.0*60.0); // double hw = 0.0; SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); sl->EndBulkLoad(); int ms_tid = mg->GetMetroStop_Tid(ms1); // cout<<"start metro stop tid "<DeleteIfAllowed(); } /* get adjacent list for a metro graph node */ void MNNav::GetAdjNodeMG(MetroGraph* mg, int nodeid) { if(mg->GetNode_Rel() == NULL){ cout<<"no metro graph node rel"< mg->GetNode_Rel()->GetNoTuples()){ cout<<"invalid node id "<GetNode_Rel()->GetNoTuples()<<" nodes "<GetEdge_Rel1()->GetNoTuples() + mg->GetEdge_Rel2()->GetNoTuples()<<" edges "<GetNode_Rel(); Tuple* ms_tuple = node_rel->GetTuple(nodeid, false); Bus_Stop* ms1 = (Bus_Stop*)ms_tuple->GetAttribute(MetroGraph::MG_NODE_STOP); // cout<<*ms1< tid_list1; mg->FindAdj1(nodeid, tid_list1); for(unsigned int i = 0;i < tid_list1.size();i++){ Tuple* edge_tuple = mg->GetEdge_Rel1()->GetTuple(tid_list1[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE1_TID2))->GetIntval(); edge_tuple->DeleteIfAllowed(); Tuple* ms_neighbor1 = node_rel->GetTuple(neighbor_id, false); Bus_Stop* ms2 = (Bus_Stop*)ms_neighbor1->GetAttribute(MetroGraph::MG_NODE_STOP); SimpleLine* path = new SimpleLine(0); path->StartBulkLoad(); path->EndBulkLoad(); ms_list1.push_back(*ms1); ms_list2.push_back(*ms2); path_list.push_back(*path); path->DeleteIfAllowed(); ms_neighbor1->DeleteIfAllowed(); type_list.push_back(1); } //////////////////////////////////////////////////////////////////// //////the second kind of connection (connected by moving metros)//// //////////////////////////////////////////////////////////////////// vector tid_list2; mg->FindAdj2(nodeid, tid_list2); for(unsigned int i = 0;i < tid_list2.size();i++){ Tuple* edge_tuple = mg->GetEdge_Rel2()->GetTuple(tid_list2[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE2_TID2))->GetIntval(); Tuple* ms_neighbor2 = node_rel->GetTuple(neighbor_id, false); Bus_Stop* ms3 = (Bus_Stop*)ms_neighbor2->GetAttribute(MetroGraph::MG_NODE_STOP); SimpleLine* path = (SimpleLine*)edge_tuple->GetAttribute(MetroGraph::MG_EDGE2_PATH); ms_list1.push_back(*ms1); ms_list2.push_back(*ms3); path_list.push_back(*path); edge_tuple->DeleteIfAllowed(); ms_neighbor2->DeleteIfAllowed(); type_list.push_back(2); } ms_tuple->DeleteIfAllowed(); } void MyToPoint(Network* rn, GPoint* gp, Point& res) { Relation* routes = rn->GetRoutes(); if(routes == NULL){ cout<<"routes loading error"<GetTuple(gp->GetRouteId(), false); SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(ROUTE_CURVE); assert(sl->GetStartSmaller()); assert(sl->AtPosition(gp->GetPosition(), sl->GetStartSmaller(), res)); road_tuple->DeleteIfAllowed(); } /////////////////////////////////////////////////////////////////////// ////////// improve join algorithm, not use symmjoin//////////////////// /////////////////////////////////////////////////////////////////////// string TM_Join::CellBoxTypeInfo = "(rel (tuple ((Cellid int)\ (Cover_area region) (X_id int) (Y_id int))))"; string TM_Join::RoadSectionTypeInfo = "(rel (tuple ((Rid int) (Meas1 real)\ (Meas2 real) (Dual bool) (Curve sline)(CurveStartsSmaller bool)\ (Rrc tid) (Sid int))))"; /* for each cell, it collects the number of route section intersecting it */ void TM_Join::Road_Cell_Join(Relation* rel1, Relation* rel2, R_Tree<2,TupleId>* rtree) { // cout<GetNoTuples()<<" "<GetNoTuples()< cell_area_list(rel2->GetNoTuples(), Region(0)); for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* cell_tuple = rel2->GetTuple(i, false); int cellid = ((CcInt*)cell_tuple->GetAttribute(TM_JOIN_ID))->GetIntval(); Region* reg = (Region*)cell_tuple->GetAttribute(TM_JOIN_AREA); cell_area_list[cellid - 1] = *reg; cell_tuple->DeleteIfAllowed(); } vector cell_list; vector sec_id_list(rel2->GetNoTuples(), 0); for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* road_tuple = rel1->GetTuple(i, false); int sec_id = ((CcInt*)road_tuple->GetAttribute(SECTION_SID))->GetIntval(); SimpleLine* sl = (SimpleLine*)road_tuple->GetAttribute(SECTION_CURVE); Line* l = new Line(0); sl->toLine(*l); vector tid_list; DFTraverse(rel2, rtree, rtree->RootRecordId(), l, tid_list); // cout<<"rid "< 0){ for(unsigned int j = 0;j < tid_list.size();j++){ Tuple* cell_tuple = rel2->GetTuple(tid_list[j], false); int cell_id = ((CcInt*)cell_tuple->GetAttribute(TM_JOIN_ID))->GetIntval(); cell_list.push_back(cell_id); cell_tuple->DeleteIfAllowed(); if(sec_id_list[cell_id - 1] == 0){ sec_id_list[cell_id - 1] = sec_id; } } } l->DeleteIfAllowed(); road_tuple->DeleteIfAllowed(); } sort(cell_list.begin(), cell_list.end()); for(unsigned int i = 0;i < cell_list.size();i++){ int cell_id = cell_list[i]; unsigned int j = i + 1; int count = 1; while(j < cell_list.size() && cell_list[j] == cell_id){ count++; j++; } i = j - 1; sec_list.push_back(sec_id_list[cell_id - 1]); id_list.push_back(cell_id); count_list.push_back(count); area_list.push_back(cell_area_list[cell_id - 1]); } // for(unsigned int i = 0;i < id_list.size();i++) // cout<* rtree, SmiRecordId adr, Line* l, vector& id_list) { 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* tuple = rel->GetTuple(e.info,false); Region* reg =(Region*)tuple->GetAttribute(TM_JOIN_AREA); if(l->Intersects(*reg)){ id_list.push_back(e.info); } tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; // if(l->Intersects(e.box)){ if(l->Intersects(Region(e.box))){ DFTraverse(rel, rtree, e.pointer, l, id_list); } } } delete node; } /* for each bus or metro stop, find the pavement areas nearby */ void TM_Join::NearStopPave(Space* sp, string type) { Pavement* pm = sp->LoadPavement(IF_REGION); DualGraph* dg = pm->GetDualGraph(); if(type == "Bus"){ BusNetwork* bn = sp->LoadBusNetwork(IF_BUSNETWORK); NearBusStopPave(bn, dg); sp->CloseBusNetwork(bn); }else if(type == "Metro"){ MetroNetwork* mn = sp->LoadMetroNetwork(IF_METRONETWORK); NearMetroStopPave(mn, dg); sp->CloseMetroNetwork(mn); }else{ cout<<"invalid type "<CloseDualGraph(dg); sp->ClosePavement(pm); } /* for each bus stop, find its nearby pavement areas. For the roads data Houston, if all pavement areas are randomly selected, some may not find bus stops nearby */ void TM_Join::NearBusStopPave(BusNetwork* bn, DualGraph* dg) { Relation* bs_rel = bn->GetBS_Rel(); Relation* tri_rel = dg->node_rel_sort; R_Tree<2,TupleId>* rtree = dg->rtree_node; vector unique_id_list; for(int i = 1;i <= bs_rel->GetNoTuples();i++){ Tuple* bs_tuple = bs_rel->GetTuple(i, false); Point* bs_loc = (Point*)bs_tuple->GetAttribute(BusNetwork::BS_GEO); // cout<<*bs_loc< tid_list; DFTraverseBMS(rtree, rtree->RootRecordId(), tri_rel, *bs_loc, tid_list, NEARBUSSTOP); for(unsigned int j = 0;j < tid_list.size();j++){ unique_id_list.push_back(tid_list[j]); } bs_tuple->DeleteIfAllowed(); } // cout<::iterator it = unique(unique_id_list.begin(), unique_id_list.end()); unique_id_list.resize( it - unique_id_list.begin() ); // cout<GetTuple(*it, false); int oid = ((CcInt*)tri_tuple->GetAttribute(DualGraph::OID))->GetIntval(); int rid = ((CcInt*)tri_tuple->GetAttribute(DualGraph::RID))->GetIntval(); Region* reg = (Region*)tri_tuple->GetAttribute(DualGraph::PAVEMENT); // cout<DeleteIfAllowed(); } } /* for each metro stop, find its nearby pavement areas */ void TM_Join::NearMetroStopPave(MetroNetwork* mn, DualGraph* dg) { // cout<<"metro stop"<GetMS_Rel(); Relation* tri_rel = dg->node_rel_sort; R_Tree<2,TupleId>* rtree = dg->rtree_node; vector unique_id_list; for(int i = 1;i <= ms_rel->GetNoTuples();i++){ Tuple* ms_tuple = ms_rel->GetTuple(i, false); Point* ms_loc = (Point*)ms_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); // cout<<*ms_loc< tid_list; DFTraverseBMS(rtree, rtree->RootRecordId(), tri_rel, *ms_loc, tid_list, NEARMETROSTOP); // cout<DeleteIfAllowed(); } // cout<::iterator it = unique(unique_id_list.begin(), unique_id_list.end()); unique_id_list.resize( it - unique_id_list.begin() ); // cout<GetTuple(*it, false); int oid = ((CcInt*)tri_tuple->GetAttribute(DualGraph::OID))->GetIntval(); int rid = ((CcInt*)tri_tuple->GetAttribute(DualGraph::RID))->GetIntval(); Region* reg = (Region*)tri_tuple->GetAttribute(DualGraph::PAVEMENT); // cout<DeleteIfAllowed(); } } /* traverse the rtree to find nearby pavement areas for bus and metro stops */ void TM_Join::DFTraverseBMS(R_Tree<2,TupleId>* rtree, SmiRecordId adr, Relation* rel, Point query_loc, vector& tid_list, double max_dist) { ////should be consist with the one used in GeneralType.cpp///// // const double max_dist = NEARBUSSTOP; 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* dg_tuple = rel->GetTuple(e.info, false); Region* reg = (Region*)dg_tuple->GetAttribute(DualGraph::PAVEMENT); if(reg->Distance(query_loc, NULL) < max_dist){ tid_list.push_back(e.info); } dg_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(query_loc.Distance(e.box) < max_dist){ DFTraverseBMS(rtree, e.pointer, rel, query_loc, tid_list, max_dist); } } } delete node; } /* for each bus or metro stop, find the buildings nearby */ void TM_Join::NearStopBuilding(Space* sp, string type) { IndoorInfra* i_infra = sp->LoadIndoorInfra(IF_GROOM); if(i_infra == NULL){ cout<<"indoor infrastructure does not exist "<BuildingType_Rel(); R_Tree<2,TupleId>* rtree = i_infra->BuildingRTree(); if(type == "Bus"){ BusNetwork* bn = sp->LoadBusNetwork(IF_BUSNETWORK); if(bn == NULL){ cout<<"bus network does not exist "<CloseBusNetwork(bn); }else if(type == "Metro"){ MetroNetwork* mn = sp->LoadMetroNetwork(IF_METRONETWORK); if(mn == NULL){ cout<<"metro network does not exist"<CloseMetroNetwork(mn); }else{ cout<<"invalid type "<CloseIndoorInfra(i_infra); } /* for each bus stop, find all buildings nearby */ void TM_Join::NearBusStopBuilding(BusNetwork* bn, Relation* build_rel, R_Tree<2,TupleId>* rtree) { Relation* bs_rel = bn->GetBS_Rel(); vector unique_id_list; for(int i = 1;i <= bs_rel->GetNoTuples();i++){ Tuple* bs_tuple = bs_rel->GetTuple(i, false); Point* bs_loc = (Point*)bs_tuple->GetAttribute(BusNetwork::BS_GEO); // cout<<*bs_loc< tid_list; DFTraverseBMS2(rtree, rtree->RootRecordId(), build_rel, *bs_loc, tid_list, NEARBUSSTOP); for(unsigned int j = 0;j < tid_list.size();j++){ unique_id_list.push_back(tid_list[j]); } bs_tuple->DeleteIfAllowed(); } // cout<::iterator it = unique(unique_id_list.begin(), unique_id_list.end()); unique_id_list.resize( it - unique_id_list.begin() ); // cout<GetTuple(*it, false); int Tid = *it; int type = ((CcInt*)tuple->GetAttribute(IndoorInfra::INDOORIF_BUILD_TYPE))->GetIntval(); Rectangle<2>* reg = (Rectangle<2>*)tuple->GetAttribute(IndoorInfra::INDOORIF_GEODATA); // cout<DeleteIfAllowed(); } } /* for each metro stop, find all buildings nearby */ void TM_Join::NearMetroStopBuilding(MetroNetwork* mn, Relation* build_rel, R_Tree<2,TupleId>* rtree) { Relation* ms_rel = mn->GetMS_Rel(); vector unique_id_list; for(int i = 1;i <= ms_rel->GetNoTuples();i++){ Tuple* ms_tuple = ms_rel->GetTuple(i, false); Point* ms_loc = (Point*)ms_tuple->GetAttribute(MetroNetwork::M_STOP_GEO); // cout<<*ms_loc< tid_list; DFTraverseBMS2(rtree, rtree->RootRecordId(), build_rel, *ms_loc, tid_list, NEARMETROSTOP); // cout<DeleteIfAllowed(); } // cout<::iterator it = unique(unique_id_list.begin(), unique_id_list.end()); unique_id_list.resize( it - unique_id_list.begin() ); // cout<GetTuple(*it, false); int Tid = *it; int type = ((CcInt*)tuple->GetAttribute(IndoorInfra::INDOORIF_BUILD_TYPE))->GetIntval(); Rectangle<2>* reg = (Rectangle<2>*)tuple->GetAttribute(IndoorInfra::INDOORIF_GEODATA); // cout<DeleteIfAllowed(); } } /* traverse the rtree to find nearby pavement areas for bus and metro stops */ void TM_Join::DFTraverseBMS2(R_Tree<2,TupleId>* rtree, SmiRecordId adr, Relation* rel, Point query_loc, vector& tid_list, double max_dist) { ////should be consist with the one used in GeneralType.cpp///// // const double max_dist = NEARBUSSTOP; 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* dg_tuple = rel->GetTuple(e.info, false); Rectangle<2>* reg = (Rectangle<2>*)dg_tuple->GetAttribute(IndoorInfra::INDOORIF_GEODATA); if(query_loc.Distance(*reg) < max_dist){ tid_list.push_back(e.info); } dg_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<2> e = (R_TreeInternalEntry<2>&)(*node)[j]; if(query_loc.Distance(e.box) < max_dist){ DFTraverseBMS2(rtree, e.pointer, rel, query_loc, tid_list, max_dist); } } } delete node; }