void TransimsNet::Lane_Use (void) { int i, num; Dtime start, end; //---- get the pocket length ---- Link_Detail_Map_Itr detail_itr; Dir_Data *dir_ptr; Lane_Use_Data lane_use_rec, *lane_use_ptr; Show_Message (String ("Creating Lane Use Data -- Record")); Set_Progress (); for (detail_itr = detail_map.begin (); detail_itr != detail_map.end (); detail_itr++) { if (Use_Permission (detail_itr->second.Use (), ANY)) continue; num = detail_itr->second.Period ()->Num_Periods (); lane_use_rec.Dir_Index (detail_itr->first); lane_use_rec.Low_Lane (detail_itr->second.Low_Lane ()); lane_use_rec.High_Lane (detail_itr->second.High_Lane ()); if (Use_Permission (detail_itr->second.Use (), NONE)) { lane_use_rec.Type (PROHIBIT); lane_use_rec.Use (ANY); } else { lane_use_rec.Type (LIMIT); lane_use_rec.Use (detail_itr->second.Use ()); } for (i=0; i < num; i++) { detail_itr->second.Period ()->Period_Range (i, start, end); lane_use_rec.Start (start); lane_use_rec.End (end); lane_use_array.push_back (lane_use_rec); } } num = (int) lane_use_array.size (); if (num > 0) { while (num--) { lane_use_ptr = &lane_use_array [num]; dir_ptr = &dir_array [lane_use_ptr->Dir_Index ()]; lane_use_ptr->Next_Index (dir_ptr->First_Lane_Use ()); dir_ptr->First_Lane_Use (num); } } }
void ConvertTrips::Parking_Check (void) { bool link_flag; int count; Convert_Location *loc_ptr; Link_Data *link_ptr; link_flag = Network_File_Flag (LINK); count = 0; for (loc_ptr = (Convert_Location *) location_data.First (); loc_ptr != NULL; loc_ptr = (Convert_Location *) location_data.Next ()) { if (loc_ptr->Zone () == 0) continue; if (loc_ptr->Org_Parking () != 0 && loc_ptr->Des_Parking () != 0) continue; if (link_flag) { link_ptr = link_data.Get (loc_ptr->Link ()); if (link_ptr == NULL) { Error ("link %d was Not Found", loc_ptr->Link ()); } if (!Use_Permission (link_ptr->Use (), CAR)) continue; } if (count == 0) { Print (2, "No Parking Lot at Activity Locations..."); } if (!(count % 10)) { Print (1, "\t"); } count++; Print (0, "%d ", loc_ptr->ID ()); } if (count) { Warning ("%d Activity Locations have No Parking Lot", count); } }
void SideFriction::Stop_Delay (void) { int stop, stops, run, runs, dir, route, period, lane, ln, time; int stop_id, offset, low, high, length, start, link_dir, num; char buffer [FIELD_BUFFER]; Stop_Data *stop_ptr; Line_Data *line_ptr; Link_Data *link_ptr; Dir_Data *dir_ptr; Offset_Data *offset_ptr; Link_Use_Data *use_ptr; Show_Message ("Estimate Transit Stop Delay -- Route"); Set_Progress (100); //---- read each route ---- for (line_ptr = line_data.First_Key (); line_ptr; line_ptr = line_data.Next_Key ()) { Show_Progress (); route = line_ptr->Route (); stops = line_ptr->Stops (); runs = line_ptr->Runs (); if (route_flag) { if (!select_routes.In_Range (route)) continue; } if (!select_modes [line_ptr->Mode ()]) continue; for (stop=1; stop <= stops; stop++) { stop_id = line_ptr->Stop (stop); //---- check for stop in the subarea ---- if (subarea_flag) { offset_ptr = stop_offset.Get (stop_id); if (offset_ptr == NULL) continue; if (!In_Polygon (offset_ptr->X (), offset_ptr->Y (), &select_subarea.points)) continue; } //---- find the stop link ---- stop_ptr = stop_data.Get (stop_id); if (stop_ptr == NULL) { Warning ("Route %d Stop %d was Not Found", route, line_ptr->Stop (stop)); continue; } link_ptr = link_data.Get (stop_ptr->Link ()); if (link_ptr == NULL) { Warning ("Stop Link %d was Not Found", stop_ptr->Link ()); continue; } if (stop_ptr->Dir () == 0) { dir = link_ptr->AB_Dir (); offset = stop_ptr->Offset (); low = link_ptr->Aoffset (); high = link_ptr->Boffset (); } else { dir = link_ptr->BA_Dir (); offset = link_ptr->Length () - stop_ptr->Offset (); low = link_ptr->Boffset (); high = link_ptr->Aoffset (); } dir_ptr = dir_data [dir]; if (dir_ptr == NULL) { Warning ("Stop Link %d Direction %d was Not Found", stop_ptr->Link (), stop_ptr->Dir ()); continue; } link_dir = stop_ptr->Link_Dir (); lane = dir_ptr->Left () + dir_ptr->Thru (); high = link_ptr->Length () - high; length = stop_length; offset -= length; if (offset < low) { offset = low; if (offset + length > high) length = high - offset; } else if (offset + length > high) { offset = high - length; if (offset < low) { offset = low; length = high - low; } } //---- add a lane blockage for each run ---- for (run=1; run < runs; run++) { time = Resolve (line_ptr->Schedule (run, stop)); period = transit_periods.In_Index (time); if (period == 0) continue; start = time - Resolve (stop_times [period]); if (start < 0) start = 0; ln = lane; if (dir_ptr->TOD_List () > 0) { for (num = dir_ptr->TOD_List (); num; num = use_ptr->TOD_List ()) { use_ptr = link_use_data [num]; if (use_ptr->Length () > 0) continue; if (use_ptr->Low_Lane () > lane || lane > use_ptr->High_Lane ()) continue; if (Use_Permission (use_ptr->Use (), BUS)) continue; if (use_ptr->End () < Round (start) || use_ptr->Start () > Round (time)) continue; ln = use_ptr->Low_Lane () - 1; break; } } if (ln <= dir_ptr->Left ()) continue; new_file->Link (stop_ptr->Link ()); new_file->Dir (stop_ptr->Dir ()); new_file->Lane (ln); new_file->Use (Use_Code (Use_Code ("BUS"))); new_file->Type (Restrict_Code (ONLY)); new_file->Start (time_step.Format_Step (start)); new_file->End (time_step.Format_Step (time)); new_file->Offset (UnRound (offset)); new_file->Length (UnRound (length)); str_fmt (buffer, sizeof (buffer), "Route %d Stop %d Run %d", route, stop_id, run); new_file->Notes (buffer); if (!new_file->Write ()) { Error ("Writing %s", new_file->File_Type ()); } new_use++; } } } End_Progress (); }
void ConvertTrips::Parking_Check (void) { int loc, count, best, best_diff, diff, offset, park; Convert_Loc_Itr loc_itr; Location_Data *loc_ptr; Parking_Data *park_ptr; Parking_Itr park_itr; Link_Data *link_ptr; Int_Map_Itr map_itr; Show_Message ("Assigning Parking Locations -- Record"); Set_Progress (); count = 0; for (loc=0, loc_itr = convert_array.begin (); loc_itr != convert_array.end (); loc_itr++, loc++) { Show_Progress (); if (loc_itr->Org_Parking () >= 0 && loc_itr->Des_Parking () >= 0) continue; loc_ptr = &location_array [loc]; if (loc_ptr->Zone () < 0) continue; //---- look for a direct index match ----- map_itr = parking_map.find (loc_ptr->Location ()); if (map_itr != parking_map.end ()) { park_ptr = &parking_array [map_itr->second]; if (park_ptr->Link_Dir () == loc_ptr->Link_Dir () && park_ptr->Offset () == loc_ptr->Offset ()) { if (loc_itr->Org_Parking () < 0) loc_itr->Org_Parking (map_itr->second); if (loc_itr->Des_Parking () < 0) loc_itr->Des_Parking (map_itr->second); continue; } } //---- look for parking lots on the same link ----- best = -1; best_diff = 0; link_ptr = &link_array [loc_ptr->Link ()]; if (Use_Permission (link_ptr->Use (), CAR)) { offset = link_ptr->Length () - loc_ptr->Offset (); for (park=0, park_itr = parking_array.begin (); park_itr != parking_array.end (); park_itr++, park++) { if (park_itr->Link () != loc_ptr->Link ()) continue; if (park_itr->Dir () == loc_ptr->Dir ()) { if (park_itr->Offset () == loc_ptr->Offset ()) { best = park; break; } diff = abs (park_itr->Offset () - loc_ptr->Offset ()); } else { if (park_itr->Offset () == offset) { best = park; best_diff = 0; continue; } else { diff = abs (park_itr->Offset () - offset); } } if (best < 0 || diff < best_diff) { best = park; best_diff = diff; } } } if (best >= 0) { if (loc_itr->Org_Parking () < 0) loc_itr->Org_Parking (best); if (loc_itr->Des_Parking () < 0) loc_itr->Des_Parking (best); continue; } if (count == 0) { Print (2, "No Parking Lot for Activity Locations..."); } if (!(count % 10)) { Print (1, "\t"); } count++; Print (0, String ("%d ") % loc_ptr->Location ()); } if (count) { Warning (String ("%d Activity Locations have No Parking Lot") % count); } End_Progress (); }
bool Path_Builder::Best_Lane_Use (int index, Dtime time, double len_factor, Dtime &ttime, Dtime &delay, int &cost, int &group) { int i, num, tt, cst, imp, lanes, type, grp, use_type [2], costs [2], best [2]; Dtime ttimes [2], delays [2]; double factor; Dir_Data *dir_ptr; Lane_Use_Data *use_ptr; Int_Map_Stat map_stat; Lane_Use_Period *period_ptr; Link_Dir_Data *use_index; dir_ptr = &exe->dir_array [index]; if (path_param.delay_flag) { ttimes [0] = exe->perf_period_array.Travel_Time (index, time, len_factor, forward_flag); if (dir_ptr->Use_Index () >= 0) { ttimes [1] = exe->perf_period_array.Travel_Time (dir_ptr->Use_Index (), time, len_factor, forward_flag); } } if (ttimes [0] < 0 && ttimes [1] <= 0) return (false); if (ttimes [0] == 0) ttimes [0] = dir_ptr->Time0 (); if (ttimes [1] == 0) ttimes [1] = dir_ptr->Time0 (); ttime = ttimes [0]; delay = 0; cost = group = 0; //---- find the time period ---- index = dir_ptr->First_Lane_Use (); if (index < 0) return (true); for (period_ptr = &exe->use_period_array [index]; ; period_ptr = &exe->use_period_array [++index]) { if (period_ptr->Start () <= time && time < period_ptr->End ()) break; if (period_ptr->Periods () == 0) return (true); } //---- set the lane group data ---- best [0] = best [1] = 0; delays [0] = delays [1] = 0; costs [0] = costs [1] = 0; use_type [0] = (period_ptr->Lanes (0) == 0) ? PROHIBIT : APPLY; use_type [1] = (period_ptr->Lanes (1) == 0) ? PROHIBIT : APPLY; type = path_param.traveler_type; num = period_ptr->Records (); index = period_ptr->Index (); for (i=0; i < num; i++, index++) { use_index = &exe->use_period_index [index]; use_ptr = &exe->lane_use_array [use_index->Link ()]; grp = use_index->Dir (); if (use_type [grp] == PROHIBIT) continue; lanes = use_ptr->High_Lane () - use_ptr->Low_Lane () + 1; if (lanes >= period_ptr->Lanes (grp)) { if (path_param.veh_type < 0 || use_ptr->Min_Veh_Type () < 0 || (use_ptr->Min_Veh_Type () <= path_param.veh_type && path_param.veh_type <= use_ptr->Max_Veh_Type ())) { if (type == 0 || use_ptr->Min_Traveler () < 0 || (use_ptr->Min_Traveler () <= type && type <= use_ptr->Max_Traveler ())) { if (Use_Permission (use_ptr->Use (), path_param.use)) { if (use_ptr->Type () == APPLY) { cst = use_ptr->Toll (); tt = use_ptr->Min_Delay (); if (use_ptr->Max_Delay () > use_ptr->Min_Delay ()) { map_stat = lane_use_delay.insert (Int_Map_Data (use_index->Link_Dir (), 0)); if (map_stat.second) { map_stat.first->second = DTOI ((use_ptr->Max_Delay () - use_ptr->Min_Delay ()) * path_param.random.Probability ()); } tt += map_stat.first->second; } imp = Resolve (tt * path_param.value_time + cst * path_param.value_cost); if (imp < best [grp] || best [grp] == 0) { delays [grp] = tt; costs [grp] = cst; best [grp] = imp; } use_type [grp] = APPLY; } else if (use_ptr->Type () == PROHIBIT) { use_type [grp] = PROHIBIT; } else if (use_ptr->Type () == REQUIRE) { use_type [1-grp] = PROHIBIT; } continue; } } } if (use_ptr->Type () == LIMIT) { use_type [grp] = PROHIBIT; } } } //---- select the best lane group ---- if (use_type [0] == PROHIBIT && use_type [1] == PROHIBIT) return (false); if (use_type [0] == APPLY && use_type [1] == APPLY) { best [0] += Resolve (ttimes [0] * path_param.value_time); best [1] += Resolve (ttimes [1] * path_param.value_time); if (random_flag) { factor = 1.0 + path_param.random_imped * (path_param.random.Probability () - 0.5) / 100.0; best [1] = DTOI (best [1] * factor); } if (best [1] > 0 && best [0] > 0) { group = (best [1] < best [0]) ? 1 : 0; } else { group = 0; } } else if (use_type [0] == APPLY) { group = 0; } else { group = 1; } delay = delays [group]; cost = costs [group]; ttime = ttimes [group]; return ((ttime > 0)); }
void TransimsNet::Pocket_Lanes (void) { int i, index, dir_index, to_index, turn_type, pocket_type, length, len, max_len, lanes, thru, num; bool left_flag, left_turn, right_turn, left_merge, right_merge, detail_lane_flag; Link_Itr link_itr; Link_Data *link_ptr; Dir_Data *dir_ptr, *to_ptr; Connect_Data *connect_ptr; Int_Map_Stat map_stat; Pocket_Index map_index; Pocket_Warrant_Map_Itr map_itr; Pocket_Warrant *warrant_ptr; Pocket_Data pocket_rec, *pocket_ptr;; Link_Detail_Map_Itr detail_itr; Show_Message (String ("Creating Pocket Lanes -- Record")); Set_Progress (); for (link_itr = link_array.begin (); link_itr != link_array.end (); link_itr++) { Show_Progress (); if (link_itr->Type () == EXTERNAL || !Use_Permission (link_itr->Use (), CAR)) continue; map_index.Area_Type (link_itr->Area_Type ()); max_len = link_itr->Length () - link_itr->Aoffset () - link_itr->Boffset (); //---- process each direction ---- for (i=0; i < 2; i++) { if (i == 0) { dir_index = link_itr->AB_Dir (); } else { dir_index = link_itr->BA_Dir (); } if (dir_index < 0) continue; dir_ptr = &dir_array [dir_index]; left_turn = right_turn = left_merge = right_merge = detail_lane_flag = false; thru = 0; if (link_detail_flag) { detail_itr = detail_map.find (dir_index); if (detail_itr != detail_map.end ()) { thru = detail_itr->second.Left_Thru () + detail_itr->second.Thru () + detail_itr->second.Right_Thru (); lanes = detail_itr->second.Left () + thru + detail_itr->second.Right () + detail_itr->second.Left_Merge () + detail_itr->second.Right_Merge (); detail_lane_flag = (lanes > 0); } } //---- process turn pockets ---- map_index.From_Type (link_itr->Type ()); for (index = dir_ptr->First_Connect (); index >= 0; index = connect_ptr->Next_Index ()) { connect_ptr = &connect_array [index]; turn_type = connect_ptr->Type (); if (turn_type == THRU || turn_type == UTURN) continue; pocket_type = -1; left_flag = false; length = lanes = 0; to_index = connect_ptr->To_Index (); to_ptr = &dir_array [to_index]; link_ptr = &link_array [to_ptr->Link ()]; map_index.To_Type (link_ptr->Type ()); map_itr = pocket_warrant_map.find (map_index); if (map_itr != pocket_warrant_map.end ()) { warrant_ptr = &pocket_warrants [map_itr->second]; //---- check the pocket criteria ---- switch (turn_type) { case LEFT: case L_SPLIT: case L_MERGE: left_flag = true; pocket_type = LEFT_TURN; length = warrant_ptr->Left_Length (); lanes = warrant_ptr->Left_Lanes (); break; case RIGHT: case R_SPLIT: case R_MERGE: pocket_type = RIGHT_TURN; length = warrant_ptr->Right_Length (); lanes = warrant_ptr->Right_Lanes (); break; default: pocket_type = AUX_LANE; length = lanes = 0; break; } } else { if (!detail_lane_flag) continue; if (length == 0) { length = MAX (link_itr->Aoffset (), link_itr->Boffset ()) * 3; if (length > link_itr->Length () / 2) length = link_itr->Length () / 2; } if (length == 0) length = link_itr->Length () / 3; } if (detail_lane_flag) { pocket_type = AUX_LANE; len = lanes = 0; switch (turn_type) { case LEFT: case L_SPLIT: case L_MERGE: if (detail_itr->second.Left () > 0 && (dir_ptr->Lanes () <= thru || detail_itr->second.Right () > 0)) { left_flag = true; pocket_type = LEFT_TURN; len = detail_itr->second.LT_Length (); lanes = detail_itr->second.Left (); } break; case RIGHT: case R_SPLIT: case R_MERGE: if (detail_itr->second.Right () > 0 && dir_ptr->Lanes () <= thru) { pocket_type = RIGHT_TURN; len = detail_itr->second.RT_Length (); lanes = detail_itr->second.Right (); } break; default: break; } if (len > 0) length = len; if (length == 0 && lanes > 0) { length = MAX (link_itr->Aoffset (), link_itr->Boffset ()) * 3; if (length > link_itr->Length () / 2) length = link_itr->Length () / 2; } if (length == 0) length = link_itr->Length () / 3; } if (lanes == 0 || length == 0 || max_len < length / 2) continue; if (length >= max_len) { length = max_len * 9 / 10; } if (pocket_type == LEFT_TURN || pocket_type == RIGHT_TURN) { if (pocket_type == LEFT_TURN) { if (left_turn) continue; left_turn = true; } else { if (right_turn) continue; right_turn = true; } len = (dir_ptr->Dir () == 0) ? link_itr->Boffset () : link_itr->Aoffset (); pocket_rec.Length (length + len); pocket_rec.Offset (link_itr->Length () - pocket_rec.Length ()); } else { pocket_rec.Length (length); pocket_rec.Offset (0); } num = (int) pocket_array.size (); pocket_rec.Dir_Index (dir_index); pocket_rec.Next_Index (dir_ptr->First_Pocket ()); dir_ptr->First_Pocket (num); pocket_rec.Type (pocket_type); pocket_rec.Lanes (lanes); if (left_flag) { if (dir_ptr->Left () < pocket_rec.Lanes ()) { dir_ptr->Left (pocket_rec.Lanes ()); } } else if (dir_ptr->Right () < pocket_rec.Lanes ()) { dir_ptr->Right (pocket_rec.Lanes ()); } pocket_array.push_back (pocket_rec); npocket++; } //---- process merge pockets ---- map_index.To_Type (link_itr->Type ()); for (index = dir_ptr->First_Connect_From (); index >= 0; index = connect_ptr->Next_From ()) { connect_ptr = &connect_array [index]; turn_type = connect_ptr->Type (); if (turn_type == THRU || turn_type == UTURN) continue; pocket_type = -1; left_flag = false; length = lanes = 0; to_index = connect_ptr->Dir_Index (); to_ptr = &dir_array [to_index]; link_ptr = &link_array [to_ptr->Link ()]; map_index.From_Type (link_ptr->Type ()); map_itr = pocket_warrant_map.find (map_index); if (map_itr != pocket_warrant_map.end ()){ warrant_ptr = &pocket_warrants [map_itr->second]; //---- check the pocket criteria ---- switch (turn_type) { case L_MERGE: case LEFT: case L_SPLIT: left_flag = true; case R_MERGE: case RIGHT: case R_SPLIT: pocket_type = (left_flag) ? LEFT_MERGE : RIGHT_MERGE; length = warrant_ptr->Merge_Length (); lanes = warrant_ptr->Merge_Lanes (); break; default: break; } } else { if (!detail_lane_flag) continue; if (length == 0) { length = MAX (link_itr->Aoffset (), link_itr->Boffset ()) * 3; if (length > link_itr->Length () / 2) length = link_itr->Length () / 2; } if (length == 0) length = link_itr->Length () / 3; } if (detail_lane_flag) { len = 0; switch (turn_type) { case L_MERGE: case LEFT: case L_SPLIT: left_flag = true; pocket_type = LEFT_MERGE; len = detail_itr->second.LM_Length (); lanes = detail_itr->second.Left_Merge (); break; case R_MERGE: case RIGHT: case R_SPLIT: pocket_type = RIGHT_MERGE; len = detail_itr->second.RM_Length (); lanes = detail_itr->second.Right_Merge (); break; default: len = lanes = 0; break; } if (len > 0) length = len; if (length == 0) length = max_len / 3; } if (lanes == 0 || length == 0 || max_len < length / 2) continue; if (length >= max_len) { length = max_len * 9 / 10; } if (pocket_type == LEFT_MERGE) { if (left_merge) continue; left_merge = true; } else { if (right_merge) continue; right_merge = true; } len = (dir_ptr->Dir () == 0) ? link_itr->Aoffset () : link_itr->Boffset (); pocket_rec.Offset (0); pocket_rec.Length (length + len); num = (int) pocket_array.size (); pocket_rec.Dir_Index (dir_index); pocket_rec.Next_Index (dir_ptr->First_Pocket ()); dir_ptr->First_Pocket (num); pocket_rec.Type (pocket_type); pocket_rec.Lanes (lanes); if (left_flag) { if (dir_ptr->Left () < pocket_rec.Lanes ()) { dir_ptr->Left (pocket_rec.Lanes ()); } } else if (dir_ptr->Right () < pocket_rec.Lanes ()) { dir_ptr->Right (pocket_rec.Lanes ()); } pocket_array.push_back (pocket_rec); npocket++; } //---- adjust the pocket lengths ---- len = length = 0; for (index = dir_ptr->First_Pocket (); index >= 0; index = pocket_ptr->Next_Index ()) { pocket_ptr = &pocket_array [index]; if (pocket_ptr->Type () == LEFT_TURN || pocket_ptr->Type () == LEFT_MERGE) { length += pocket_ptr->Length (); } else if (pocket_ptr->Type () == RIGHT_TURN || pocket_ptr->Type () == RIGHT_MERGE) { len += pocket_ptr->Length (); } } if (len > link_itr->Length () || length > link_itr->Length ()) { for (index = dir_ptr->First_Pocket (); index >= 0; index = pocket_ptr->Next_Index ()) { pocket_ptr = &pocket_array [index]; if (pocket_ptr->Type () == LEFT_TURN || pocket_ptr->Type () == LEFT_MERGE) { if (length > link_itr->Length ()) { pocket_ptr->Length (pocket_ptr->Length () * link_itr->Length () / length); } } else if (pocket_ptr->Type () == RIGHT_TURN || pocket_ptr->Type () == RIGHT_MERGE) { if (len > link_itr->Length ()) { pocket_ptr->Length (pocket_ptr->Length () * link_itr->Length () / len); } } } } } } End_Progress (); return; }
bool Path_Builder::Destination_Parking (Trip_End_Array *des_ptr, Path_End_Array *to_ptr, int parking) { int index, length, offset, diff, lot, des, imped, ttime, cost, acc, low_imp, hi_imp, tot_imp, tod; bool link_flag, ab_flag; Location_Data *loc_ptr; Link_Data *link_ptr; Parking_Data *lot_ptr; Park_Nest_Itr park_itr; Trip_End_Itr des_itr; Path_End path_end; Path_Data path_data; List_Data *acc_ptr; Access_Data *access_ptr; to_ptr->clear (); low_imp = MAX_INTEGER; hi_imp = 0; park_flag = walk_acc_flag = access_flag = false; for (des=0, des_itr = des_ptr->begin (); des_itr != des_ptr->end (); des_itr++, des++) { if (des_itr->Index () < 0) continue; link_flag = false; loc_ptr = &exe->location_array [des_itr->Index ()]; //---- add the access links to parking ---- if (exe->access_link_flag) { acc = exe->loc_access [des_itr->Index ()].Next (!forward_flag); //---- process each access link to the destination ---- for (; acc >= 0; acc = acc_ptr->Next (ab_flag)) { access_ptr = &exe->access_array [acc]; acc_ptr = &exe->next_access (!forward_flag) [acc]; ab_flag = (access_ptr->From_Type () == LOCATION_ID && access_ptr->From_ID () == des_itr->Index ()); if (access_ptr->Type (!ab_flag) != PARKING_ID) continue; lot = access_ptr->ID (!ab_flag); if (!forward_flag && parking >= 0 && parking != lot) continue; //---- save a parking connection ---- lot_ptr = &exe->parking_array [lot]; if (lot_ptr->Link () == loc_ptr->Link ()) link_flag = true; path_end.Clear (); path_end.Trip_End (des); path_end.End_Type (LOCATION_ID); path_end.Type (LINK_ID); path_end.Index (lot_ptr->Link ()); if (lot_ptr->Dir () == 1) { link_ptr = &exe->link_array [lot_ptr->Link ()]; path_end.Offset (link_ptr->Length () - lot_ptr->Offset ()); } else { path_end.Offset (lot_ptr->Offset ()); } path_data.Clear (); tot_imp = 0; tod = des_itr->Time (); //--- save the access link attributes ---- ttime = access_ptr->Time (); length = (int) (ttime * param.walk_speed + 0.5); cost = Round (access_ptr->Cost ()); imped = DTOI (ttime * param.value_walk + cost * param.value_cost); tot_imp += imped; tod += ((!forward_flag) ? ttime : -ttime); path_data.Imped (imped); path_data.Time (ttime); path_data.Length (length); path_data.Cost (cost); path_data.Walk (length); path_data.Mode (WALK_MODE); path_data.From (acc); path_data.Type (ACCESS_ID); if (ab_flag) path_data.Dir (1); path_end.push_back (path_data); //---- calculate the parking attributes ---- cost = ttime = 0; for (park_itr = lot_ptr->begin (); park_itr != lot_ptr->end (); park_itr++) { if (park_itr->Start () <= tod && tod <= park_itr->End ()) { if (park_itr->Use () == 0 || Use_Permission (park_itr->Use (), param.use)) { if (!forward_flag) { ttime = park_itr->Time_Out (); } else { cost = DTOI (park_itr->Hourly () * parking_duration.Hours ()); if (cost > park_itr->Daily ()) { cost = park_itr->Daily (); } ttime = park_itr->Time_In (); cost = Round (cost); } break; } else { park_flag = true; } } } imped = DTOI (ttime * param.value_park + cost * param.value_cost); //---- add the parking penalty ---- if (forward_flag && param.park_pen_flag) { imped += exe->park_penalty [lot]; } tot_imp += imped; tod += (!forward_flag) ? ttime : -ttime; //---- save the parking lot attributes ---- path_data.Clear (); path_data.Imped (imped); path_data.Time (ttime); path_data.Cost (cost); path_data.Mode (OTHER_MODE); path_data.From (lot); path_data.Type (PARKING_ID); path_end.push_back (path_data); //---- check the impedance range ---- if (tot_imp < low_imp) low_imp = tot_imp; if (tot_imp > hi_imp) hi_imp = tot_imp; path_data.Clear (); path_end.push_back (path_data); to_ptr->push_back (path_end); } } if (link_flag) continue; //---- find the closest parking lot on the link ---- diff = MAX_INTEGER; lot = -1; index = loc_ptr->Link (); link_ptr = &exe->link_array [index]; if (loc_ptr->Dir () == 1) { offset = link_ptr->Length () - loc_ptr->Offset (); } else { offset = loc_ptr->Offset (); } for (index = exe->link_parking [index]; index >= 0; index = exe->next_parking [index]) { if (!forward_flag && parking >= 0 && parking != index) continue; lot_ptr = &exe->parking_array [index]; if (lot_ptr->Dir () == 1) { length = abs (link_ptr->Length () - lot_ptr->Offset () - offset); } else { length = abs (lot_ptr->Offset () - offset); } if (length <= diff) { diff = length; lot = index; if ((!forward_flag && parking >= 0) || (length <= near_offset && loc_ptr->Location () == lot_ptr->Parking ())) break; } } if (lot < 0) continue; if (diff > near_offset && !Use_Permission (link_ptr->Use (), WALK)) { walk_acc_flag = true; continue; } //---- save a parking lot ---- lot_ptr = &exe->parking_array [lot]; path_end.Clear (); path_end.Trip_End (des); path_end.End_Type (LOCATION_ID); path_end.Type (LINK_ID); path_end.Index (lot_ptr->Link ()); if (lot_ptr->Dir () == 1) { path_end.Offset (link_ptr->Length () - lot_ptr->Offset ()); } else { path_end.Offset (lot_ptr->Offset ()); } path_data.Clear (); tot_imp = 0; tod = des_itr->Time (); //---- walk from the location to the link ---- length = loc_ptr->Setback (); if (length < 1) length = 1; if (!param.walk_detail && diff > near_offset) length += diff; ttime = (int) (length / param.walk_speed + 0.5); imped = DTOI (ttime * param.value_walk); tot_imp += imped; tod += (!forward_flag) ? ttime : -ttime; path_data.Imped (imped); path_data.Time (ttime); path_data.Length (length); path_data.Walk (length); path_data.Mode (WALK_MODE); path_data.From (des_itr->Index ()); path_data.Type (LOCATION_ID); path_end.push_back (path_data); //---- walk along the link ---- if (param.walk_detail && diff > near_offset) { length = diff; ttime = (int) (length / param.walk_speed + 0.5); imped = DTOI (ttime * param.value_walk); tot_imp += imped; tod += (!forward_flag) ? ttime : -ttime; path_data.Imped (imped); path_data.Time (ttime); path_data.Length (length); path_data.Walk (length); path_data.Mode (WALK_MODE); path_data.From (lot_ptr->Link ()); path_data.Type (LINK_ID); if (!forward_flag) { if (path_end.Offset () < offset) path_data.Dir (1); } else { if (path_end.Offset () > offset) path_data.Dir (1); } path_end.push_back (path_data); } //---- calculate the parking attributes ---- cost = ttime = 0; for (park_itr = lot_ptr->begin (); park_itr != lot_ptr->end (); park_itr++) { if (park_itr->Start () <= tod && tod <= park_itr->End ()) { if (park_itr->Use () == 0 || Use_Permission (park_itr->Use (), param.use)) { if (!forward_flag) { ttime = park_itr->Time_Out (); } else { cost = DTOI (park_itr->Hourly () * parking_duration.Hours ()); if (cost > park_itr->Daily ()) { cost = park_itr->Daily (); } ttime = park_itr->Time_In (); cost = Round (cost); } break; } else { park_flag = true; } } } imped = DTOI (ttime * param.value_park + cost * param.value_cost); //---- add the parking penalty ---- if (forward_flag && param.park_pen_flag) { imped += exe->park_penalty [lot]; } tot_imp += imped; //---- save the parking lot attributes ---- path_data.Clear (); path_data.Imped (imped); path_data.Time (ttime); path_data.Cost (cost); path_data.Mode (OTHER_MODE); path_data.From (lot); path_data.Type (PARKING_ID); path_end.push_back (path_data); //---- check the impedance range ---- if (tot_imp < low_imp) low_imp = tot_imp; if (tot_imp > hi_imp) hi_imp = tot_imp; path_data.Clear (); path_end.push_back (path_data); to_ptr->push_back (path_end); } if (low_imp < MAX_INTEGER) { imp_diff = hi_imp - low_imp; } else { imp_diff = 0; } access_flag = (to_ptr->size () == 0); return (!access_flag); }
void TransitNet::Read_Route (void) { int i, node, node0, route, veh_type, mode, begin, end, num_in, tot_time, spd_time; int run_time, cum_time, offset, headway, speed, dwell; double ttime, factor; bool first, stop_flag; Use_Type use; AB_Data *ab_ptr; Dir_Path_Data *dir_ptr, *last_dir; Route_Node rnode_rec, *rnode_ptr; Driver_Data *driver_ptr; Path_Node *path_ptr; Route_Data *route_ptr; //---- read the route file ---- Show_Message ("Reading Route Header and Nodes Files -- Record"); Set_Progress (100); num_in = 0; for (route_ptr = route_data.First (); route_ptr; route_ptr = route_data.Next ()) { Show_Progress (); route_node.Reset (); first = true; begin = end = 0; route = route_ptr->Route (); mode = route_ptr->Mode (); use = (mode <= EXPRESS_BUS) ? BUS : RAIL; run_time = Round (route_ptr->Min_Time ()); for (i=1; i <= num_periods; i++) { headway = route_ptr->Headway (i); if (headway <= 0) continue; offset = route_ptr->Offset (i); if (offset < 0) { offset = (int) (headway * random.Probability () + 0.5); route_ptr->Offset (i, offset); } } //---- read the node records ---- rnode_rec.Dwell (0); rnode_rec.TTime (0); node0 = 0; for (i=1; i <= route_ptr->Nodes (); i++) { node = route_ptr->Node (i); if (node < 0) { stop_flag = false; node = -node; } else { stop_flag = true; } if (dwell_flag) { dwell = route_ptr->Dwell (i); } else { if (stop_flag) { dwell = min_dwell; } else { dwell = 0; } } ttime = route_ptr->Time (i); speed = route_ptr->Speed (i); //---- check the node file ---- if (node_data.Get_Index (node) > 0) { if (first) { rnode_rec.Node (node); rnode_rec.Dir (0); rnode_rec.Add_Dwell (Round (dwell)); rnode_rec.Add_TTime (Round (ttime)); if (!route_node.Add (&rnode_rec)) { Error ("Insufficient Memory for Route Nodes"); } } else { //---- find the link(s) between route nodes ---- ab_ptr = ab_key.Get (node0, node); if (ab_ptr == NULL) { //---- attempt to build a minimum distance path ---- Node_Path (node0, node, use); if (path_node.Num_Records () == 0) { //---- try to build an auto path ---- Node_Path (node0, node, CAR); if (path_node.Num_Records () != 0) { Warning ("Path from %d and %d on Route %d includes Use Restrinctions", node0, node, route); } } if (path_node.Num_Records () == 0) { Warning ("No Path between Nodes %d and %d on Route %d", node0, node, route); break; } else { //---- calculate the network travel time for the path ---- tot_time = spd_time = 0; for (path_ptr = path_node.First (); path_ptr; path_ptr = path_node.Next ()) { dir_ptr = dir_data [path_ptr->Dir ()]; tot_time += dir_ptr->Time0 (); if (speed_flag && speed > 0) { spd_time += Round ((double) dir_ptr->Length () / speed); } } //---- check the transit travel time ---- if (ttime == 0.0) { if (spd_time > 0) { ttime = UnRound (spd_time) + dwell; tot_time = spd_time; } else { ttime = UnRound (tot_time) + dwell; } } else if (ttime < UnRound (tot_time)) { Warning ("Route %d Node %d to %d travel time %.1lf < %.1lf", route, node0, node, ttime, UnRound (tot_time)); } //---- distribute the transit travel time to each link on the path ---- if (tot_time < 1) tot_time = 1; factor = ttime / UnRound (tot_time); for (path_ptr = path_node.Last (); path_ptr; path_ptr = path_node.Previous ()) { rnode_rec.Node (path_ptr->Node ()); rnode_rec.Dir (path_ptr->Dir ()); dir_ptr = dir_data [path_ptr->Dir ()]; ttime = dir_ptr->Time0 () * factor; rnode_rec.TTime ((int) (ttime + 0.5)); rnode_rec.Dwell (Round (dwell)); if (!route_node.Add (&rnode_rec)) { Error ("Insufficient Memory for Route Nodes"); } } } } else { //---- calculate and check the transit travel time ---- rnode_rec.Node (node); rnode_rec.Dir (ab_ptr->dir); dir_ptr = dir_data [ab_ptr->dir]; if (!Use_Permission (dir_ptr->Use (), use)) { Warning ("Link %d does Not Permit %s Service", dir_ptr->Link (), Transit_Code ((Transit_Type) mode)); } if (ttime == 0.0) { if (speed_flag && speed > 0) { ttime = (double) dir_ptr->Length () / speed + dwell; } else { ttime = UnRound (dir_ptr->Time0 ()) + dwell; } } else if (ttime < UnRound (dir_ptr->Time0 ())) { Warning ("Route %d Link %d travel time %.1lf < %.1lf", route, dir_ptr->Link (), ttime, UnRound (dir_ptr->Time0 ())); } rnode_rec.Add_Dwell (Round (dwell)); rnode_rec.Add_TTime (Round (ttime)); if (!route_node.Add (&rnode_rec)) { Error ("Insufficient Memory for Route Nodes"); } } } rnode_rec.Dwell (0); rnode_rec.TTime (0); first = false; end = 0; node0 = node; } else { //---- remove route nodes that were collapsed from the network ---- if (first) { begin++; } else { rnode_rec.Add_Dwell (Round (dwell)); rnode_rec.Add_TTime (Round (ttime)); } end++; } } if (route_node.Num_Records () <= 1) { Warning ("Route %d has Missing Node Records", route); continue; } if (begin) { Print (1, "%d Node%sat the Beginning of Route %d did Not Exist", begin, ((begin > 1) ? "s " : " "), route); end_warnings++; } if (end) { Print (1, "%d Node%sat the End of Route %d did Not Exist", end, ((end > 1) ? "s " : " "), route); end_warnings++; } //---- add route to the edit list ---- if (!edit_list.Add (route)) { Error ("Adding Route to the Edit List"); } //---- check for an existing route ---- driver_ptr = driver_data.Get (route); if (driver_ptr == NULL) { driver_ptr = driver_data.New_Record (true); driver_ptr->Route (route); if (!driver_data.Add ()) { Error ("Adding Transit Driver Data"); } driver_ptr = driver_data.Record (); } //---- create the driver data --- driver_ptr->Links (route_node.Num_Records () - 1); switch (mode) { case LOCAL_BUS: veh_type = 4; break; case EXPRESS_BUS: veh_type = 5; break; case TROLLEY: veh_type = 6; break; case STREETCAR: veh_type = 7; break; case LRT: veh_type = 8; break; case RAPIDRAIL: veh_type = 9; break; case REGIONRAIL: veh_type = 10; break; } driver_ptr->Type (veh_type); driver_ptr->Sub_Type (0); //---- process each route node ---- node0 = 0; last_dir = NULL; cum_time = 0; for (i=0, rnode_ptr = route_node.First (); rnode_ptr; rnode_ptr = route_node.Next (), i++) { node = rnode_ptr->Node (); if (node0 == 0) { node0 = node; continue; } ab_ptr = ab_key.Get (node0, node); if (ab_ptr == NULL) { Error ("No Link between Nodes %d and %d on Route %d", node0, node, route); } node0 = node; rnode_ptr->Dir (ab_ptr->dir); dir_ptr = dir_data [ab_ptr->dir]; //---- check the travel time ---- if (rnode_ptr->TTime () == 0) { rnode_ptr->TTime (dir_ptr->Time0 () + rnode_ptr->Dwell ()); } cum_time += rnode_ptr->TTime (); //---- save the driver link ---- driver_ptr->Link_Dir (i, dir_ptr->Link_Dir ()); //---- check the connection ---- if (last_dir != NULL && connect_flag) { if (connect_data.Get (last_dir->Link_Dir (), dir_ptr->Link_Dir ()) == NULL) { Warning ("No Connection from Link %d to %d on Route %d", last_dir->Link (), dir_ptr->Link (), route); connect_warnings++; } } last_dir = dir_ptr; } //---- adjust the link travel times to match the run time ---- if (run_time > 0 && cum_time > 0 && run_time != cum_time) { ttime = (double) run_time / cum_time; cum_time = 0; for (rnode_ptr = route_node.First (); rnode_ptr; rnode_ptr = route_node.Next ()) { cum_time += run_time = (int) (rnode_ptr->TTime () * ttime + 0.5); rnode_ptr->TTime (run_time); } } route_ptr->Min_Time (Resolve (cum_time)); //---- save the transit route ----- Save_Route (route_ptr); num_in++; } End_Progress (); Print (1, "Number of Transit Routes = %d", num_in); }
bool Sim_Method::Cell_Use (Travel_Step &step) { int lane, lanes, cell; Sim_Dir_Ptr sim_dir_ptr; Sim_Lane_Ptr lane_ptr = 0; Cell_Data cell_rec = step.sim_veh_ptr->front (); if (cell_rec.Index () == step.Dir_Index ()) { if (step.sim_dir_ptr == 0) { step.sim_dir_ptr = &exe->sim_dir_array [cell_rec.Index ()]; } sim_dir_ptr = step.sim_dir_ptr; } else { sim_dir_ptr = &exe->sim_dir_array [cell_rec.Index ()]; } if (sim_dir_ptr->Method () != MESOSCOPIC) return (true); lanes = sim_dir_ptr->Lanes (); cell = cell_rec.Cell (); for (lane = 0; lane < lanes; lane++) { lane_ptr = sim_dir_ptr->Lane (lane); if (Cell_Use (lane_ptr, lane, cell, step)) return (true); } Dtime max_time = exe->step + param.max_wait_time; if (use_update_time < max_time) { int i, index, num; Lane_Use_Data *use_ptr; Lane_Use_Period *period_ptr; Link_Dir_Data *use_index; Use_Type use = step.veh_type_ptr->Use (); int veh_type = step.sim_veh_ptr->Type (); int type = step.sim_traveler_ptr->Type (); Dir_Data *dir_ptr = &exe->dir_array [cell_rec.Index ()]; index = dir_ptr->First_Lane_Use (); if (index < 0) goto use_error; for (period_ptr = &exe->use_period_array [index]; ; period_ptr = &exe->use_period_array [++index]) { if (period_ptr->Start () >= use_update_time && period_ptr->Start () <= max_time) break; if (period_ptr->Periods () == 0) goto use_error; } num = period_ptr->Records (); index = period_ptr->Index (); for (i=0; i < num; i++, index++) { use_index = &exe->use_period_index [index]; use_ptr = &exe->lane_use_array [use_index->Link ()]; if (use_ptr->Offset () > 0 || use_ptr->Length () > 0) { int offset = cell * param.cell_size; if (use_ptr->Offset () > offset || offset > (use_ptr->Offset () + use_ptr->Length ())) continue; } if (use_ptr->Type () == PROHIBIT) { if (!Use_Permission (use_ptr->Use (), use)) { if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) { if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (true); } else { return (true); } } } else if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (true); } else { return (true); } } } else { if (Use_Permission (use_ptr->Use (), use)) { if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type >= use_ptr->Min_Veh_Type () && veh_type <= use_ptr->Max_Veh_Type ()) { if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type >= use_ptr->Min_Traveler () && type <= use_ptr->Max_Traveler ()) return (true); } else { return (true); } } } else if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type >= use_ptr->Min_Traveler () && type <= use_ptr->Max_Traveler ()) return (true); } else { return (true); } } } } } use_error: step.Problem (USE_PROBLEM); step.Status (1); return (false); }
bool Sim_Method::Cell_Use (Sim_Lane_Data *lane_ptr, int lane, int cell, Travel_Step &step, bool use_flag) { int i, index, num, seed; Lane_Use_Data *use_ptr; Lane_Use_Period *period_ptr; Link_Dir_Data *use_index; int type = step.sim_traveler_ptr->Type (); int veh_type = step.sim_veh_ptr->Type (); Use_Type use = step.veh_type_ptr->Use (); step.Delay (0); if (use_flag) { if (use != BUS && use != HOV2 && use != HOV3 && use != HOV4) return (false); if (Use_Permission (lane_ptr->Use (), SOV)) return (false); } if (!Use_Permission (lane_ptr->Use (), use)) return (false); if (veh_type >= 0 && lane_ptr->Min_Veh_Type () >= 0) { if (lane_ptr->Type () == PROHIBIT) { if (veh_type >= lane_ptr->Min_Veh_Type () && veh_type <= lane_ptr->Max_Veh_Type ()) return (false); } else { if (veh_type < lane_ptr->Min_Veh_Type () || veh_type > lane_ptr->Max_Veh_Type ()) return (false); } } if (type > 0 && lane_ptr->Min_Traveler () > 0) { if (lane_ptr->Type () == PROHIBIT) { if (type >= lane_ptr->Min_Traveler () && type <= lane_ptr->Max_Traveler ()) return (false); } else { if (type < lane_ptr->Min_Traveler () || type > lane_ptr->Max_Traveler ()) return (false); } } index = lane_ptr->First_Use (); if (index < 0) return (true); period_ptr = &exe->use_period_array [index]; num = period_ptr->Records (); index = period_ptr->Index (); for (i=0; i < num; i++, index++) { use_index = &exe->use_period_index [index]; use_ptr = &exe->lane_use_array [use_index->Link ()]; if (use_ptr->Offset () > 0 || use_ptr->Length () > 0) { int offset = cell * param.cell_size; if (use_ptr->Offset () > offset || offset > (use_ptr->Offset () + use_ptr->Length ())) continue; } if (use_ptr->Type () == REQUIRE) { if (!Use_Permission (use_ptr->Use (), use)) continue; if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue; } if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue; } return (lane >= use_ptr->Low_Lane () && lane <= use_ptr->High_Lane ()); } else { if (lane < use_ptr->Low_Lane () || lane > use_ptr->High_Lane ()) continue; if (use_ptr->Type () == PROHIBIT) { if (use_flag && !Use_Permission (use_ptr->Use (), SOV)) return (false); if (!Use_Permission (use_ptr->Use (), use)) continue; if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue; } if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue; } return (false); } else if (use_ptr->Type () == LIMIT) { if (use_flag && Use_Permission (use_ptr->Use (), SOV)) return (false); if (!Use_Permission (use_ptr->Use (), use)) return (false); if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) return (false); } if (type > 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) return (false); } return (true); } else if (use_ptr->Type () == APPLY) { if (!Use_Permission (use_ptr->Use (), use)) continue; if (veh_type >= 0 && use_ptr->Min_Veh_Type () >= 0) { if (veh_type < use_ptr->Min_Veh_Type () || veh_type > use_ptr->Max_Veh_Type ()) continue; } if (type >= 0 && use_ptr->Min_Traveler () > 0) { if (type < use_ptr->Min_Traveler () || type > use_ptr->Max_Traveler ()) continue; } if (use_ptr->Min_Delay () > 0 || use_ptr->Max_Delay () > 0) { if (use_ptr->Offset () > 0 || use_ptr->Length () > 0) { if (cell != (use_ptr->Offset () + (use_ptr->Length () / 2)) / param.cell_size) break; } else { if (cell != (int) (lane_ptr->size () / 2)) break; } int diff = 0; if (use_ptr->Max_Delay () > use_ptr->Min_Delay ()) { seed = abs (index + exe->Random_Seed () + step.Vehicle () + lane); diff = DTOI ((use_ptr->Max_Delay () - use_ptr->Min_Delay ()) * exe->random.Probability (seed)); } step.Delay (use_ptr->Min_Delay () + diff); } break; } } } return (true); }
bool Path_Builder::Transit_Access (Path_End_Array *from_ptr, Path_End_Array *to_ptr, bool best_flag) { int index, imped, length, offset, path, dir, xfer; int from, from_type, from_index, from_cost, from_len, from_walk; int to, to_type, to_index, to_cost, to_len, to_walk; unsigned from_imp, to_imp, hi_imp; Dtime from_time, to_time, ttime, ttim; bool ab_flag, to_flag, exit_flag; double factor; Path_End_Itr from_itr, to_itr; Link_Data *link_ptr; Path_Data path_data; Path_Ptr path_ptr; Path_Itr path_itr; Transit_Sort_Itr sort_itr; Transit_Path_Index path_index; Stop_Data *stop_ptr; //---- initialize the path building ---- exit_flag = false; path = 0; xfer = -1; for (from=0, from_itr = from_ptr->begin (); from_itr != from_ptr->end (); from_itr++, from++) { if (from_itr->Index () < 0) continue; from_type = from_itr->Type (); from_index = from_itr->Index (); path_ptr = &from_itr->back (); from_imp = path_ptr->Imped (); from_time = path_ptr->Time (); from_len = path_ptr->Length (); from_cost = path_ptr->Cost (); from_walk = path_ptr->Walk(); //---- process access points ---- if (from_type == NODE_ID || from_type == STOP_ID) { to_type = from_type; to_index = from_index; to_imp = from_imp; to_time = from_time; to_len = from_len; to_cost = from_cost; to_walk = from_walk; //---- check for a destintion ---- if ((to_type == NODE_ID && node_to_flag && node_to [to_index] == 1) || (to_type == STOP_ID && stop_to_flag && stop_to [to_index] == 1)) { to_flag = false; for (to=0, to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++, to++) { if (to_itr->Type () != to_type || to_index != to_itr->Index ()) continue; if (to_imp + imp_diff >= max_imp) continue; path_ptr = &to_itr->back (); if (to_imp >= path_ptr->Imped ()) continue; //---- save the destination totals ---- path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir (0); path_ptr->Xfer (xfer); path_ptr->Status (1); to_flag = true; if (best_flag) { max_imp = to_imp + imp_diff; exit_flag = true; } } //---- update the max impedance ---- if (to_flag) { if (best_flag) continue; hi_imp = 0; for (to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++) { path_ptr = &to_itr->back (); if (path_ptr->Imped () < MAX_IMPEDANCE) { to_imp = path_ptr->Imped () + imp_diff; if (to_imp > hi_imp) hi_imp = to_imp; } else { hi_imp = MAX_IMPEDANCE; break; } } if (hi_imp > 0 && hi_imp < max_imp) max_imp = hi_imp; exit_flag = true; } } //---- consider adding the node or stop to the processing list ---- if (to_type == NODE_ID) { path_ptr = &node_path [path] [to_index]; } else { path_ptr = &board_path [path] [to_index]; } if (to_imp >= path_ptr->Imped ()) continue; //---- add the new path to the queue ---- path_index.Index (to_index); path_index.Type (to_type); path_index.Path (path); if (param.sort_method) { //---- remove the previous path from the queue ---- if (path_ptr->Status () == 1) { for (sort_itr = transit_sort.find (path_ptr->Imped ()); sort_itr != transit_sort.end (); sort_itr++) { if (sort_itr->second == path_index) { transit_sort.erase (sort_itr); break; } else if (sort_itr->first > path_ptr->Imped ()) { break; } } } transit_sort.insert (Transit_Sort_Data (to_imp, path_index)); } else { if (path_ptr->Status () == 0) { next_index.push_back (path_index); } else if (path_ptr->Status () == 2) { next_index.push_front (path_index); } } path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir (0); path_ptr->Xfer (xfer); path_ptr->Status (1); continue; } //---- process the link offset ---- if (from_type != LINK_ID) continue; link_ptr = &exe->link_array [from_index]; if (!Use_Permission (link_ptr->Use (), WALK)) { use_flag = true; continue; } offset = from_itr->Offset (); //---- check for destinations on the same link ---- if (link_to_flag && link_to [from_index] == 1) { to_flag = false; for (to=0, to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++, to++) { if (to_itr->Type () != from_type || from_index != to_itr->Index ()) continue; //---- calculate and check the distance ---- if (forward_flag) { length = to_itr->Offset () - offset; } else { length = offset - to_itr->Offset (); } ab_flag = (length >= 0); if (!ab_flag) length = -length; to_len = from_len + length; if (walk_flag && to_len >= param.max_walk) { length_flag = true; continue; } //---- calculate and check the time ---- ttime = (int) (length / param.walk_speed + 0.5); if (forward_flag) { to_time = from_time + ttime; if (to_time > time_limit) { time_flag = true; continue; } } else { to_time = from_time - ttime; if (to_time < time_limit) { time_flag = true; continue; } } to_walk = from_walk + length; //---- calculate and check the impedance ---- imped = DTOI (ttime * param.value_walk); if (imped < 1) imped = 1; if (walk_flag && to_len > param.walk_pen) { factor = (double) to_len / param.walk_pen; factor = ((factor * factor) - 1) * param.walk_fac + 1; imped = DTOI (imped * factor); } else if (random_flag) { imped = DTOI (imped * (1.0 + param.random_imped * (param.random.Probability () - 0.5) / 100.0)); } to_imp = from_imp + imped; if (to_imp + imp_diff >= max_imp) continue; path_ptr = &to_itr->back (); if (to_imp >= path_ptr->Imped ()) continue; to_cost = from_cost; //---- save the destination totals ---- path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir ((ab_flag) ? 0 : 1); path_ptr->Xfer (xfer); path_ptr->Status (1); to_flag = true; if (best_flag) { max_imp = to_imp + imp_diff; exit_flag = true; } } //---- update the max impedance ---- if (to_flag) { if (best_flag) continue; hi_imp = 0; for (to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++) { path_ptr = &to_itr->back (); if (path_ptr->Imped () < MAX_IMPEDANCE) { to_imp = path_ptr->Imped () + imp_diff; if (to_imp > hi_imp) hi_imp = to_imp; } else { hi_imp = MAX_IMPEDANCE; break; } } if (hi_imp > 0 && hi_imp < max_imp) max_imp = hi_imp; exit_flag = true; } } //---- check for transit stops on the link ---- for (index = exe->link_stop [from_index]; index >= 0; index = exe->next_stop [index]) { stop_ptr = &exe->stop_array [index]; if (stop_ptr->Dir () == 0) { length = stop_ptr->Offset () - offset; } else { length = link_ptr->Length () - stop_ptr->Offset () - offset; } if (!forward_flag) length = -length; ab_flag = (length >= 0); if (!ab_flag) length = -length; //---- calculate and check the length ---- to_walk = from_walk + length; if (walk_flag && to_walk >= param.max_walk) { length_flag = true; continue; } //---- calculate and check the time ---- ttim = (int) (length / param.walk_speed + 0.5); //---- check the time schedule ---- if (forward_flag) { to_time = from_time + ttim; if (to_time > time_limit) { time_flag = true; continue; } } else { to_time = from_time - ttim; if (to_time < time_limit) { time_flag = true; continue; } } to_len = from_len + length; to_cost = from_cost; //---- check the impedance ---- imped = DTOI (ttim * param.value_walk); if (imped < 1) imped = 1; if (walk_flag && to_walk > param.walk_pen) { factor = (double) to_walk / param.walk_pen; factor = ((factor * factor) - 1) * param.walk_fac + 1; imped = DTOI (imped * factor); } to_imp = from_imp + imped; if (to_imp >= max_imp) continue; //---- check for a destintion stop ---- if (stop_to_flag && stop_to [index] == 1) { to_flag = false; for (to=0, to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++, to++) { if (to_itr->Type () != STOP_ID || index != to_itr->Index ()) continue; if (to_imp + imp_diff >= max_imp) continue; path_ptr = &to_itr->back (); if (to_imp >= path_ptr->Imped ()) continue; //---- save the destination totals ---- path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir ((ab_flag) ? 0 : 1); path_ptr->Xfer (xfer); path_ptr->Status (1); to_flag = true; if (best_flag) { max_imp = to_imp + imp_diff; exit_flag = true; } } //---- update the max impedance ---- if (to_flag) { if (best_flag) continue; hi_imp = 0; for (to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++) { path_ptr = &to_itr->back (); if (path_ptr->Imped () < MAX_IMPEDANCE) { to_imp = path_ptr->Imped () + imp_diff; if (to_imp > hi_imp) hi_imp = to_imp; } else { hi_imp = MAX_IMPEDANCE; break; } } if (hi_imp > 0 && hi_imp < max_imp) max_imp = hi_imp; exit_flag = true; } } //---- check the current path ---- path_ptr = &board_path [path] [index]; if (to_imp >= path_ptr->Imped ()) continue; //---- add the new path to the queue ---- path_index.Index (index); path_index.Type (STOP_ID); path_index.Path (path); if (param.sort_method) { //---- remove the previous path from the queue ---- if (path_ptr->Status () == 1) { for (sort_itr = transit_sort.find (path_ptr->Imped ()); sort_itr != transit_sort.end (); sort_itr++) { if (sort_itr->second == path_index) { transit_sort.erase (sort_itr); break; } else if (sort_itr->first > path_ptr->Imped ()) { break; } } } transit_sort.insert (Transit_Sort_Data (to_imp, path_index)); } else { if (path_ptr->Status () == 0) { next_index.push_back (path_index); } else if (path_ptr->Status () == 2) { next_index.push_front (path_index); } } to_cost = from_cost; path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir ((ab_flag) ? 0 : 1); path_ptr->Xfer (xfer); path_ptr->Status (1); } //---- process each direction ---- for (dir=0; dir < 2; dir++) { //---- calculate and check the distance ---- if (dir == 0) { to_index = link_ptr->Bnode (); length = link_ptr->Length () - offset; } else { to_index = link_ptr->Anode (); length = offset; } to_walk = from_walk + length; if (to_walk >= param.max_walk) { length_flag = true; continue; } //---- calculate and check the time ---- ttime = (int) (length / param.walk_speed + 0.5); if (forward_flag) { to_time = from_time + ttime; if (to_time > time_limit) { time_flag = true; continue; } } else { to_time = from_time - ttime; if (to_time < time_limit) { time_flag = true; continue; } } to_len = from_len + length; to_cost = from_cost; //---- calculate and check the impedance ---- imped = DTOI (ttime * param.value_walk); if (imped < 1) imped = 1; if (walk_flag && to_walk > param.walk_pen) { factor = (double) to_walk / param.walk_pen; factor = ((factor * factor) - 1) * param.walk_fac + 1; imped = DTOI (imped * factor); } else if (random_flag) { imped = DTOI (imped * (1.0 + param.random_imped * (param.random.Probability () - 0.5) / 100.0)); } to_imp = from_imp + imped; if (to_imp >= max_imp) continue; //---- check for a destintion node ---- if (node_to_flag && node_to [to_index] == 1) { to_flag = false; for (to=0, to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++, to++) { if (to_itr->Type () != NODE_ID || to_index != to_itr->Index ()) continue; if (to_imp + imp_diff >= max_imp) continue; path_ptr = &to_itr->back (); if (to_imp >= path_ptr->Imped ()) continue; //---- save the destination totals ---- path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir ((forward_flag) ? dir : (1 - dir)); path_ptr->Xfer (xfer); path_ptr->Status (1); to_flag = true; if (best_flag) { max_imp = to_imp + imp_diff; exit_flag = true; } } //---- update the max impedance ---- if (to_flag) { if (best_flag) continue; hi_imp = 0; for (to_itr = to_ptr->begin (); to_itr != to_ptr->end (); to_itr++) { path_ptr = &to_itr->back (); if (path_ptr->Imped () < MAX_IMPEDANCE) { to_imp = path_ptr->Imped () + imp_diff; if (to_imp > hi_imp) hi_imp = to_imp; } else { hi_imp = MAX_IMPEDANCE; break; } } if (hi_imp > 0 && hi_imp < max_imp) max_imp = hi_imp; exit_flag = true; } } //---- check the current path ---- path_ptr = &node_path [path] [to_index]; if (to_imp >= path_ptr->Imped ()) continue; //---- add the record to the queue ---- path_index.Index (to_index); path_index.Type (NODE_ID); path_index.Path (path); if (param.sort_method) { //---- remove the previous path from the queue ---- if (path_ptr->Status () == 1) { for (sort_itr = transit_sort.find (path_ptr->Imped ()); sort_itr != transit_sort.end (); sort_itr++) { if (sort_itr->second == path_index) { transit_sort.erase (sort_itr); break; } else if (sort_itr->first > path_ptr->Imped ()) { break; } } } transit_sort.insert (Transit_Sort_Data (to_imp, path_index)); } else { if (path_ptr->Status () == 0) { next_index.push_back (path_index); } else if (path_ptr->Status () == 2) { next_index.push_front (path_index); } } path_ptr->Imped (to_imp); path_ptr->Time (to_time); path_ptr->Length (to_len); path_ptr->Cost (to_cost); path_ptr->Walk (to_walk); path_ptr->Mode (WALK_MODE); path_ptr->From (from); path_ptr->Type (FROM_ID); path_ptr->Path (path); path_ptr->Dir ((forward_flag) ? dir : (1 - dir)); path_ptr->Xfer (xfer); path_ptr->Status (1); } } return (exit_flag); }