Exemple #1
0
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);
		}
	}
} 
Exemple #2
0
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);
	}
}
Exemple #3
0
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 ();
}
Exemple #4
0
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 ();
}
Exemple #5
0
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));
}
Exemple #6
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;
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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);
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}