Ejemplo n.º 1
0
void LinkSum::Perf_Detail_Report (void)
{
	int i, j, k, k1, lanes, max_lanes, tod_list, index, flow_index;
	double base_time, loaded_time, length, len, base, diff, value, percent, flow, factor;
	Dtime low, high, tod;
	bool connect_flag;
	String units, vmt, lane_mi;

	Link_Itr link_itr;
	Dir_Data *dir_ptr;
	Link_Perf_Period_Itr period_itr;
	Link_Perf_Array *period_ptr;
	Link_Perf_Data perf_data;
	Flow_Time_Period_Itr turn_itr;
	Flow_Time_Array *compare_ptr;
	Flow_Time_Data *turn_ptr;
	Lane_Use_Period *use_ptr;
	Connect_Data *connect_ptr;
	Doubles_Itr itr;

	Show_Message ("Creating the Network Performance Details Report -- Record");
	Set_Progress ();

	//---- clear the summary bins -----

	for (j=0, itr = sum_bin.begin (); itr != sum_bin.end (); itr++, j++) {
		itr->assign (NUM_SUM_BINS, 0.0);
	}	
	connect_flag = System_Data_Flag (CONNECTION) && (turn_perf_array.size () > 0) && (compare_turn_array.size () > 0);

	//---- process each link ----

	for (link_itr = link_array.begin (); link_itr != link_array.end (); link_itr++) {
		Show_Progress ();

		if (select_flag && link_itr->Use () == 0) continue;

		length = UnRound (link_itr->Length ());
		len = 0;

		for (i=0; i < 2; i++) {
			if (i) {
				if (link_itr->Use () == -1) continue;
				index = link_itr->BA_Dir ();
			} else {
				if (link_itr->Use () == -2) continue;
				index = link_itr->AB_Dir ();
			}
			if (index < 0) continue;
			dir_ptr = &dir_array [index];
			flow_index = dir_ptr->Flow_Index ();

			base_time = dir_ptr->Time0 ();
			if (base_time <= 0.0) continue;

			tod_list = dir_ptr->First_Lane_Use ();

			max_lanes = dir_ptr->Lanes ();
			if (max_lanes < 1) max_lanes = 1;
			lanes = max_lanes;

			if (len == 0) {
				len = length;
			} else {
				len = 0;
			}

			//---- process each time period ----

			for (j=0, period_itr = link_perf_array.begin (); period_itr != link_perf_array.end (); period_itr++, j++) {
				if (tod_list >= 0) {

					//---- get the time period ----

					sum_periods.Period_Range (j, low, high);
					tod = (low + high + 1) / 2;

					lanes = max_lanes;
					k = tod_list;

					for (use_ptr = &use_period_array [k]; ; use_ptr = &use_period_array [++k]) {
						if (use_ptr->Start () <= tod && tod < use_ptr->End ()) {
							lanes = use_ptr->Lanes0 () + use_ptr->Lanes1 ();
							break;
						}
						if (use_ptr->Periods () == 0) break;
					}
				}
				perf_data = period_itr->Total_Link_Perf (index, flow_index);

				loaded_time = perf_data.Time ();
				flow = perf_data.Flow ();

				sum_bin [j] [LINKS] += 1;
				sum_bin [j] [LENGTH] += len;
				sum_bin [j] [LANES] += lanes * length;
				sum_bin [j] [VMT] += flow * length;
				sum_bin [j] [VHT] += flow * loaded_time;
				sum_bin [j] [VHD] += flow * (loaded_time - base_time);
				sum_bin [j] [TIME_RATIO] += (double) loaded_time / base_time;
				sum_bin [j] [DENSITY] += perf_data.Density ();
				sum_bin [j] [MAX_DEN] = MAX (sum_bin [j] [MAX_DEN], perf_data.Max_Density ());
				sum_bin [j] [QUEUE] += perf_data.Queue ();
				sum_bin [j] [MAX_QUEUE] = MAX (sum_bin [j] [MAX_QUEUE], perf_data.Max_Queue ());
				sum_bin [j] [FAILURE] += perf_data.Failure ();

				if (Ratio_Flag ()) {
					sum_bin [j] [CONG_VMT] += perf_data.Ratio_VMT ();
					sum_bin [j] [CONG_VHT] += perf_data.Ratio_VHT ();
					sum_bin [j] [CONG_TIME] += perf_data.Ratio_Count ();
					sum_bin [j] [COUNT] += perf_data.Occupancy ();
				}

				if (compare_flag) {
					period_ptr = &compare_link_array [j];
					perf_data = period_ptr->Total_Link_Perf (index, flow_index);

					loaded_time = perf_data.Time ();
					flow = perf_data.Flow ();

					sum_bin [j] [VMT+PREV] += flow * length;
					sum_bin [j] [VHT+PREV] += flow * loaded_time;
					sum_bin [j] [VHD+PREV] += flow * (loaded_time - base_time);
					sum_bin [j] [TIME_RATIO+PREV] += (double) loaded_time / base_time;
					sum_bin [j] [DENSITY+PREV] += perf_data.Density ();
					sum_bin [j] [MAX_DEN+PREV] = MAX (sum_bin [j] [MAX_DEN+PREV], perf_data.Max_Density ());
					sum_bin [j] [QUEUE+PREV] += perf_data.Queue ();
					sum_bin [j] [MAX_QUEUE+PREV] = MAX (sum_bin [j] [MAX_QUEUE+PREV], perf_data.Max_Queue ());
					sum_bin [j] [FAILURE+PREV] += perf_data.Failure ();

					if (Ratio_Flag ()) {
						sum_bin [j] [CONG_VMT+PREV] += perf_data.Ratio_VMT ();
						sum_bin [j] [CONG_VHT+PREV] += perf_data.Ratio_VHT ();
						sum_bin [j] [CONG_TIME+PREV] += perf_data.Ratio_Count ();
						sum_bin [j] [COUNT+PREV] += perf_data.Occupancy ();
					}
				}
			}

			//---- get the turning movements ----

			if (connect_flag) {
				for (k=dir_ptr->First_Connect (); k >= 0; k = connect_ptr->Next_Index ()) {
					connect_ptr = &connect_array [k];

					if (connect_ptr->Type () != LEFT && connect_ptr->Type () != RIGHT &&
						connect_ptr->Type () != UTURN) continue;

					for (j=0, turn_itr = turn_perf_array.begin (); turn_itr != turn_perf_array.end (); turn_itr++, j++) {
						turn_ptr = &turn_itr->at (k);

						sum_bin [j] [TURNS] += turn_ptr->Flow ();

						if (compare_flag) {
							compare_ptr = &compare_turn_array [j];
							turn_ptr = &compare_ptr->at (k);

							sum_bin [j] [TURNS+PREV] += turn_ptr->Flow ();
						}
					}
				}
			}
		}
	}
	End_Progress ();

	//---- print the report ----

	Header_Number (PERF_DETAIL);

	if (!Break_Check (num_inc * 16)) {
		Print (1);
		Perf_Detail_Header ();
	}
	if (Metric_Flag ()) {
		factor = 1.0 / 1000.0;
		units = "Kilometers";
		vmt = "VKT";
		lane_mi = "km";
	} else {
		factor = 1.0 / MILETOFEET;
		units = "Miles";
		vmt = "VMT";
		lane_mi = "mi";
	}
	tod.Hours (1);

	for (i=0; i <= num_inc; i++) {
		len = sum_bin [i] [LINKS];
		if (len == 0.0) continue;

		if (i < num_inc) {
			for (k = 0; k <= COUNT; k++) {
				k1 = k + PREV;
				if (k < VMT) {
					sum_bin [num_inc] [k] = MAX (sum_bin [i] [k], sum_bin [num_inc] [k]);

					if (compare_flag) {
						sum_bin [num_inc] [k1] = MAX (sum_bin [i] [k1], sum_bin [num_inc] [k1]);
					}
				} else {
					sum_bin [num_inc] [k] += sum_bin [i] [k];

					if (compare_flag) {
						sum_bin [num_inc] [k1] += sum_bin [i] [k1];
					}
				}
			}
		}
		if (i < num_inc && sum_bin [i] [VHT] == 0.0 && (!compare_flag || sum_bin [i] [VHT+PREV] == 0.0)) continue;
		if (i) {
			if (!Break_Check ((Ratio_Flag () ? 19 : 16))) {
				Print (1);
			}
		}
		Print (1, String ("Time Period%22c") % BLANK);
		if (i == num_inc) {
			Print (0, "       Total");
			len *= num_inc;
		} else {
			Print (0, String ("%12.12s") % sum_periods.Range_Format (i));
		}
		Print (1, String ("Number of Links                 %13.2lf") % sum_bin [i] [LINKS]);
		Print (1, String ("Number of Roadway %-10.10s    %13.2lf") % units % (sum_bin [i] [LENGTH] * factor));
		Print (1, String ("Number of Lane %-10.10s       %13.2lf") % units % (sum_bin [i] [LANES] * factor));
		Print (1, String ("Vehicle %-20.20s    %13.2lf") % (units + " of Travel") % (sum_bin [i] [VMT] * factor));
		if (compare_flag) {
			base = sum_bin [i] [VMT+PREV] * factor;
			diff = sum_bin [i] [VMT] * factor - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Vehicle Hours of Travel         %13.2lf") % (sum_bin [i] [VHT] / tod));
		if (compare_flag) {
			base = sum_bin [i] [VHT+PREV] / tod;
			diff = sum_bin [i] [VHT] / tod - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}	
		Print (1, String ("Vehicle Hours of Delay          %13.2lf") % (sum_bin [i] [VHD] / tod));
		if (compare_flag) {
			base = sum_bin [i] [VHD+PREV] / tod;
			diff = sum_bin [i] [VHD] / tod - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Number of Queued Vehicles       %13.2lf") % UnRound (sum_bin [i] [QUEUE]));
		if (compare_flag) {
			base = sum_bin [i] [QUEUE+PREV];
			diff = sum_bin [i] [QUEUE] - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Maximum Queued Vehicles         %13.2lf") % sum_bin [i] [MAX_QUEUE]);
		if (compare_flag) {
			base = sum_bin [i] [MAX_QUEUE+PREV];
			diff = sum_bin [i] [MAX_QUEUE] - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Number of Cycle Failures        %13.2lf") % sum_bin [i] [FAILURE]);
		if (compare_flag) {
			base = sum_bin [i] [FAILURE+PREV];
			diff = sum_bin [i] [FAILURE] - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Number of Turning Movements     %13.2lf") % sum_bin [i] [TURNS]);
		if (compare_flag) {
			base = sum_bin [i] [TURNS+PREV];
			diff = sum_bin [i] [TURNS] - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Average Link Time Ratio         %13.2lf") % (sum_bin [i] [TIME_RATIO] / len));
		if (compare_flag) {
			base = sum_bin [i] [TIME_RATIO+PREV] / len;
			diff = sum_bin [i] [TIME_RATIO] / len - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Average Link Density (/ln-%s)   %13.2lf") % lane_mi % UnRound (sum_bin [i] [DENSITY] / len));
		if (compare_flag) {
			base = UnRound (sum_bin [i] [DENSITY+PREV] / len);
			diff = UnRound (sum_bin [i] [DENSITY] / len) - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		Print (1, String ("Maximum Link Density (/ln-%s)   %13.2lf") % lane_mi % UnRound (sum_bin [i] [MAX_DEN]));
		if (compare_flag) {
			base = UnRound (sum_bin [i] [MAX_DEN+PREV]);
			diff = UnRound (sum_bin [i] [MAX_DEN]) - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}
		length = sum_bin [i] [VMT] * factor;
		loaded_time = sum_bin [i] [VHT] / tod;
		if (loaded_time == 0.0) {
			loaded_time = length;
		} else {
			loaded_time = length / loaded_time;
		}
		Print (1, String ("Average %-19.19s     %13.2lf") % (units + " per Hour") % loaded_time);
		if (compare_flag) {
			length = sum_bin [i] [VMT+PREV] * factor;
			base = sum_bin [i] [VHT+PREV] / tod;
			if (base == 0.0) {
				base = length;
			} else {
				base = length / base;
			}
			diff = loaded_time - base;

			Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
		}

		if (Ratio_Flag ()) {
			value = sum_bin [i] [VMT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [i] [CONG_VMT] / value;

			Print (1, String ("Percent %s Congested           %13.2lf") % vmt % percent);
			if (compare_flag) {
				value = sum_bin [i] [VMT+PREV];
				if (value == 0.0) value = 1.0;
				base = 100.0 * sum_bin [i] [CONG_VMT+PREV] / value;
				diff = percent - base;

				Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
			}
			value = sum_bin [i] [VHT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [i] [CONG_VHT] / value;

			Print (1, String ("Percent VHT Congested           %13.2lf") % percent);
			if (compare_flag) {
				value = sum_bin [i] [VHT+PREV];
				if (value == 0.0) value = 1.0;
				base = 100.0 * sum_bin [i] [CONG_VHT+PREV] / value;
				diff = percent - base;

				Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
			}
			value = sum_bin [i] [COUNT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [i] [CONG_TIME] / value;

			Print (1, String ("Percent Time Congested          %13.2lf") % percent);
			if (compare_flag) {
				value = sum_bin [i] [COUNT+PREV];
				if (value == 0.0) value = 1.0;
				base = 100.0 * sum_bin [i] [CONG_TIME+PREV] / value;
				diff = percent - base;

				Print (0, String (" %13.2lf %13.2lf  (%.2lf%%)") % base % diff % ((base > 0.0) ? (100.0 * diff / base) : 0.0) % FINISH);
			}
		}
	}
	Header_Number (0);
}
Ejemplo n.º 2
0
void LinkSum::Zone_Summary (void)
{
	int i, j, z, count, link, nrec, nzone, index, flow_index;
	double factor, vmt, vht, flow;
	Dtime time;

	Link_Data *link_ptr;
	Link_Perf_Period_Itr period_itr;
	Flow_Time_Data flow_data;

	Link_Loc_Map_Itr loc_itr, first_itr;
	Doubles dbl;
	Doubles_Itr itr;
	Int_Map_Itr map_itr;

	Show_Message ("Summarize Activity Locations on Links -- Record");
	Set_Progress ();

	link = count = nrec = 0;
	link_ptr = 0;

	for (loc_itr = first_itr = link_location.begin (); loc_itr != link_location.end (); loc_itr++) {
		Show_Progress ();

		if (loc_itr->second.link == link) {
			count++;
		} else {
			if (link > 0) {
				link_ptr = &link_array [link];

				if (!select_flag || link_ptr->Use () != 0) {
					first_itr->second.count = count;
				}
			}
			first_itr = loc_itr;
			link = loc_itr->second.link;
			count = 1;
		}
	}
	Set_Progress ();

	//---- set the count data for all records ----

	link = 0;

	for (loc_itr = link_location.begin (); loc_itr != link_location.end (); loc_itr++) {
		Show_Progress ();

		if (loc_itr->second.link == link) {
			loc_itr->second.count = count;
		} else {
			link = loc_itr->second.link;
			count = loc_itr->second.count;
		}
		if (count > 0) {
			nrec += count;
			zone_list.insert (Int_Map_Data (loc_itr->second.zone, (int) zone_list.size ()));
		}
	}
	nzone = (int) zone_list.size ();

	Break_Check (4);

	Print (2, "Number of Link Locations = ") << nrec;
	Print (1, "Number of Selected Zones = ") << nzone;

	//---- allocate space for zone summaries ----

	zone_vmt.assign (num_inc, dbl);
	zone_vht.assign (num_inc, dbl);

	for (itr = zone_vmt.begin (); itr != zone_vmt.end (); itr++) {
		itr->assign (nzone, 0.0);
	}
	for (itr = zone_vht.begin (); itr != zone_vht.end (); itr++) {
		itr->assign (nzone, 0.0);
	}

	//---- summarizes link data by zone ----

	link = 0;

	for (loc_itr = link_location.begin (); loc_itr != link_location.end (); loc_itr++) {
		Show_Progress ();

		if (loc_itr->second.count == 0) continue;
		
		if (loc_itr->second.link != link) {
			link = loc_itr->second.link;
			link_ptr = &link_array [link];
		}
		map_itr = zone_list.find (loc_itr->second.zone);
		if (map_itr == zone_list.end ()) continue;

		z = map_itr->second;

		factor = UnRound (link_ptr->Length ()) / loc_itr->second.count; 

		//---- process each direction ----

		for (i=0; i < 2; i++) {
			if (i) {
				if (link_ptr->Use () == -1) continue;
				index = link_ptr->BA_Dir ();
			} else {
				if (link_ptr->Use () == -2) continue;
				index = link_ptr->AB_Dir ();
			}
			if (index < 0) continue;
			flow_index = dir_array [index].Flow_Index ();

			for (j=0, period_itr = link_perf_array.begin (); period_itr != link_perf_array.end (); period_itr++, j++) {
				flow_data = period_itr->Total_Flow_Time (index, flow_index);

				flow = flow_data.Flow ();
				time = flow_data.Time ();

				if (flow > 0) {
					vmt = flow * factor;
					vht = flow * time / loc_itr->second.count;

					zone_vmt [j] [z] += vmt;
					zone_vht [j] [z] += vht;
				}
			}
		}
	}
	End_Progress ();
}
Ejemplo n.º 3
0
void LinkSum::Program_Control (void)
{
	int i, field, ngroup, num;
	bool binary;
	String key, token;

	Location_File *location_file;
	Db_Field *fld;	
	Doubles dbl;
	Doubles_Itr itr;

	//---- set the equivalence flags ----

	Zone_Equiv_Flag (Check_Control_Key (NEW_GROUP_TRAVEL_FILE));

	group_select = Set_Control_Flag (SELECT_BY_LINK_GROUP);
	Link_Equiv_Flag (group_select || Report_Flag (LINK_GROUP) || Report_Flag (TRAVEL_TIME) || 
		Report_Flag (GROUP_REPORT) || Report_Flag (GROUP_SUMMARY) || Check_Control_Key (NEW_GROUP_SUMMARY_FILE));

	//---- open network files ----

	Data_Service::Program_Control ();

	Read_Select_Keys ();

	turn_flag = System_File_Flag (TURN_DELAY);
	
	Print (2, String ("%s Control Keys:") % Program ());	

	//---- open the compare performance file ----
	
	key = Get_Control_String (COMPARE_PERFORMANCE_FILE);

	if (!key.empty ()) {
		compare_file.File_Type ("Compare Performance File");
		Print (1);

		if (Check_Control_Key (COMPARE_PERFORMANCE_FORMAT)) {
			compare_file.Dbase_Format (Get_Control_String (COMPARE_PERFORMANCE_FORMAT));
		}
		compare_file.Open (Project_Filename (key));
		compare_flag = true;
	}
	num_inc = sum_periods.Num_Periods ();
	if (num_inc < 1) num_inc = 1;

	cap_factor = (double) sum_periods.Range_Length () / (Dtime (1, HOURS) * num_inc);
	if (cap_factor <= 0.0) cap_factor = 1.0;

	//---- open the compare link map file ----
	
	key = Get_Control_String (COMPARE_LINK_MAP_FILE);

	if (!key.empty ()) {
		link_map_file.File_Type ("Compare Link Map File");
		Print (1);

		if (Check_Control_Key (COMPARE_LINK_MAP_FORMAT)) {
			link_map_file.Dbase_Format (Get_Control_String (COMPARE_LINK_MAP_FORMAT));
		}
		link_map_file.Open (Project_Filename (key));
		link_map_flag = true;
	}

	//---- get minimum volume ----
	
	minimum_volume = Get_Control_Double (MINIMUM_LINK_VOLUME);

	//---- person-based statistics ----

	person_flag = Get_Control_Flag (PERSON_BASED_STATISTICS);

	//---- get the select by link group flag ----

	group_select = Get_Control_Flag (SELECT_BY_LINK_GROUP);
	if (group_select || select_subareas || select_polygon || select_facilities) select_flag = true;

	//---- turning movement data ----

	if (turn_flag) {

		//---- open the compare turn delays file ----
	
		key = Get_Control_String (COMPARE_TURN_DELAY_FILE);

		if (!key.empty ()) {
			turn_compare_file.File_Type ("Compare Turn Delay File");
			Print (1);

			if (Check_Control_Key (COMPARE_TURN_DELAY_FORMAT)) {
				turn_compare_file.Dbase_Format (Get_Control_String (COMPARE_TURN_DELAY_FORMAT));
			}
			turn_compare_file.Open (Project_Filename (key));
			turn_compare_flag = true;
		}

		//---- select turn nodes----
	
		key = exe->Get_Control_Text (TURN_NODE_RANGE);

		if (!key.empty () && !key.Equals ("ALL")) {
			if (!turn_range.Add_Ranges (key)) {
				exe->Error ("Adding Turn Node Ranges");
			}
		}
	}

	//---- create link activity file ----

	key = Get_Control_String (NEW_LINK_ACTIVITY_FILE);

	if (!key.empty ()) {
		if (!System_File_Flag (LOCATION)) {
			Error ("A Location File is needed for the Link Activity File");
		}
		location_file = System_Location_File ();
		binary = (location_file->Record_Format () == BINARY);

		Print (1);
		activity_file.File_Type ("New Link Activity File");

		if (Check_Control_Key (NEW_LINK_ACTIVITY_FORMAT)) {
			activity_file.Dbase_Format (Get_Control_String (NEW_LINK_ACTIVITY_FORMAT));
		}
		activity_file.Create (Project_Filename (key));

		//---- copy location field name ----

		key = Get_Control_Text (COPY_LOCATION_FIELDS);
		if (key.empty ()) {
			Error ("Location Field Names are Required for Link Activity File");
		}
		link_db.File_Type ("Link Location Database");

		//---- set required fields ----

		link_db.Add_Field ("LINK", DB_INTEGER, 10);
		activity_file.Add_Field ("LINK", DB_INTEGER, 10);

		//---- copy selected fields ----

		while (!key.Split (token)) {
			field = location_file->Field_Number (token);
			if (field < 0) {
				Error (String ("Field %s was Not Found in the Location File") % token);
			}
			field_list.push_back (field);

			fld = location_file->Field (field);

			link_db.Add_Field (fld->Name (), fld->Type (), fld->Size (), fld->Units (), binary);
			activity_file.Add_Field (fld->Name (), fld->Type (), fld->Size (), fld->Units (), binary);
		}
		activity_file.Write_Header ();
		activity_flag = true;
	}

	//---- create zone travel file ----

	key = Get_Control_String (NEW_ZONE_TRAVEL_FILE);

	if (!key.empty ()) {
		if (!System_File_Flag (LOCATION)) {
			Error ("A Location File is needed for the Zone Travel File");
		}
		Print (1);
		zone_file.File_Type ("New Zone Travel File");

		if (Check_Control_Key (NEW_ZONE_TRAVEL_FORMAT)) {
			zone_file.Dbase_Format (Get_Control_String (NEW_ZONE_TRAVEL_FORMAT));
		}
		zone_file.Create (Project_Filename (key));
		zone_flag = true;
	}

	//---- create zone group travel file ----

	key = Get_Control_String (NEW_GROUP_TRAVEL_FILE);

	if (!key.empty ()) {
		if (!System_File_Flag (LOCATION)) {
			Error ("A Location File is needed for the Group Travel File");
		}
		Print (1);
		group_file.File_Type ("New Group Travel File");

		if (Check_Control_Key (NEW_GROUP_TRAVEL_FORMAT)) {
			group_file.Dbase_Format (Get_Control_String (NEW_GROUP_TRAVEL_FORMAT));
		}
		group_file.Create (Project_Filename (key));
		group_flag = true;
	}

	if (!activity_flag && !zone_flag && !group_flag) {
		System_File_False (LOCATION);
	}

	//---- get the number of direction groups ----

	ngroup = Highest_Control_Group (NEW_LINK_DIRECTION_FILE, 0);

	if (ngroup > 0) {
		Dir_Group group, *group_ptr;

		//---- process each group ----

		for (i=1; i <= ngroup; i++) {
			key = Get_Control_String (NEW_LINK_DIRECTION_FILE, i);
			if (key.empty ()) continue;

			Print (1);
			dir_group.push_back (group);
			group_ptr = &dir_group.back ();

			group_ptr->group = i;
			group_ptr->file = new Link_Direction_File ();
			group_ptr->file->File_Type (String ("New Link Direction File #%d") % i);

			if (Check_Control_Key (NEW_LINK_DIRECTION_FORMAT, i)) {
				group_ptr->file->Dbase_Format (Get_Control_String (NEW_LINK_DIRECTION_FORMAT, i));
			}
			group_ptr->file->Lane_Use_Flows (Lane_Use_Flows ());
			group_ptr->file->Create (Project_Filename (key));

			//---- get the field name ----

			key = Get_Control_Text (NEW_LINK_DIRECTION_FIELD, i);
			if (key.empty ()) {
				Error (String ("New Link Direction Field #%d is Missing") % i);
			}
			group_ptr->field = Performance_Code (key);

			group_ptr->index = Get_Control_Flag (NEW_LINK_DIRECTION_INDEX, i);
			
			group_ptr->flip = Get_Control_Flag (NEW_LINK_DIRECTION_FLIP, i);

			if (group_ptr->flip && !compare_flag) {
				Warning ("Link Direction Flipping requires Comparison Data");
				group_ptr->flip = false;
			}
			Set_Link_Dir (group_ptr);
		}
	}

	//---- get the number of groups ----

	ngroup = Highest_Control_Group (NEW_LINK_DATA_FILE, 0);

	if (ngroup > 0) {
		Data_Group group, *group_ptr;

		//---- process each group ----

		for (i=1; i <= ngroup; i++) {
			key = Get_Control_String (NEW_LINK_DATA_FILE, i);
			if (key.empty ()) continue;

			Print (1);
			data_group.push_back (group);
			group_ptr = &data_group.back ();

			group_ptr->group = i;
			group_ptr->file = new Link_Data_File ();
			group_ptr->file->File_Type (String ("New Link Data File #%d") % i);

			if (Check_Control_Key (NEW_LINK_DATA_FORMAT, i)) {
				group_ptr->file->Dbase_Format (Get_Control_String (NEW_LINK_DATA_FORMAT, i));
			}
			group_ptr->file->Lane_Use_Flows (Lane_Use_Flows ());
			group_ptr->file->Create (Project_Filename (key));

			//---- get the field name ----

			key = Get_Control_Text (NEW_LINK_DATA_FIELD, i);
			if (key.empty ()) {
				Error (String ("New Link Data Field #%d is Missing") % i);
			}
			group_ptr->field = Performance_Code (key);

			Set_Link_Data (group_ptr);
		}
	}

	//---- data summary file ----

	key = Get_Control_String (NEW_DATA_SUMMARY_FILE);

	if (!key.empty ()) {
		Print (1);
		summary_file.File_Type ("New Data Summary File");

		if (Check_Control_Key (NEW_DATA_SUMMARY_FORMAT)) {
			summary_file.Dbase_Format (Get_Control_String (NEW_DATA_SUMMARY_FORMAT));
		}
		summary_file.Add_Field ("MEASURE", DB_STRING, 40);
		summary_file.Add_Field ("VALUE", DB_DOUBLE, 12.2);
		if (compare_flag) summary_file.Add_Field ("COMPARE", DB_DOUBLE, 12.2);

		summary_file.Create (Project_Filename (key));
		summary_flag = true;

		//---- data summary periods ----

		if (!Control_Key_Empty (NEW_DATA_SUMMARY_PERIODS)) {
			periods_flag = data_periods.Add_Ranges (Get_Control_Text (NEW_DATA_SUMMARY_PERIODS));
		}

		//---- data summary ratios ----

		if (Check_Control_Key (NEW_DATA_SUMMARY_RATIOS)) {
			Double_List list;
			Dbl_Itr itr;

			Get_Control_List (NEW_DATA_SUMMARY_RATIOS, list);

			for (i=0, itr = list.begin (); itr != list.end (); itr++, i++) {
				if (i > 0 && *itr >= 1.0) {
					data_ratios.push_back (Round (*itr * 100.0));
					ratios_flag = true;
				}
			}
		}
	}

	//---- group summary file ----

	key = Get_Control_String (NEW_GROUP_SUMMARY_FILE);

	if (!key.empty ()) {
		Print (1);
		group_sum_file.File_Type ("New Group Summary File");

		if (Check_Control_Key (NEW_GROUP_SUMMARY_FORMAT)) {
			group_sum_file.Dbase_Format (Get_Control_String (NEW_GROUP_SUMMARY_FORMAT));
		}
		group_sum_file.Add_Field ("MEASURE", DB_STRING, 40);
		group_sum_file.Add_Field ("VALUE", DB_DOUBLE, 12.2);
		if (compare_flag) group_sum_file.Add_Field ("COMPARE", DB_DOUBLE, 12.2);

		group_sum_file.Create (Project_Filename (key));
		group_sum_flag = true;
	}

	//---- read report types ----

	List_Reports ();

	if (!compare_flag && (Report_Flag (TIME_CHANGE) || Report_Flag (VOLUME_CHANGE) ||
		Report_Flag (TOP_TIME_CHANGE) || Report_Flag (TOP_VOL_CHANGE) || Report_Flag (RELATIVE_GAP))) {

		Error ("A Compare Performance File is Required for Change Reports");
	}

	//---- process support data ----

	if (Link_Equiv_Flag ()) {
		link_equiv.Read (Report_Flag (LINK_EQUIV));
	}

	if (group_flag) {
		zone_equiv.Read (Report_Flag (ZONE_EQUIV));
	}

	//---- allocate work space ----

	if (periods_flag || ratios_flag) {
		num = (periods_flag) ? (int) data_periods.size () : 1;
		num += (ratios_flag) ? (int) data_ratios.size () : 1;
		if (num_inc + 1 > num) {
			num = num_inc + 1;
		}
	} else {
		num = num_inc + 1;
	}
	sum_bin.assign (num, dbl);

	for (itr = sum_bin.begin (); itr != sum_bin.end (); itr++) {
		itr->assign (NUM_SUM_BINS, 0.0);
	}
} 
Ejemplo n.º 4
0
void LinkSum::Perf_Detail_File (void)
{
	int i, j, k, k1, lanes, max_lanes, tod_list, index, flow_index;
	int text_field, value_field, compare_field;
	double base_time, loaded_time, length, len, value, percent, flow, factor;
	String buffer, units, vmt, lane_mi;
	bool connect_flag;
	Dtime low, high, tod;

	Link_Itr link_itr;
	Dir_Data *dir_ptr;
	Link_Perf_Period_Itr period_itr;
	Link_Perf_Array *period_ptr;
	Link_Perf_Data perf_data;
	Flow_Time_Period_Itr turn_itr;
	Flow_Time_Array *compare_ptr;
	Flow_Time_Data *turn_ptr;
	Lane_Use_Period *use_ptr;
	Connect_Data *connect_ptr;
	Doubles_Itr itr;

	Show_Message ("Writing Performance Data File -- Record");
	Set_Progress ();

	text_field = detail_file.Field_Number ("MEASURE");
	value_field = detail_file.Field_Number ("VALUE");
	compare_field = detail_file.Field_Number ("COMPARE");

	//---- clear the summary bins -----

	for (itr = sum_bin.begin (); itr != sum_bin.end (); itr++) {
		itr->assign (NUM_SUM_BINS, 0.0);
	}
	connect_flag = System_Data_Flag (CONNECTION) && (turn_perf_array.size () > 0) && (compare_turn_array.size () > 0);

	//---- process each link ----

	for (link_itr = link_array.begin (); link_itr != link_array.end (); link_itr++) {
		Show_Progress ();

		if (select_flag && link_itr->Use () == 0) continue;

		len = UnRound (link_itr->Length ());

		for (i=0; i < 2; i++) {
			if (i) {
				if (link_itr->Use () == -1) continue;
				index = link_itr->BA_Dir ();
			} else {
				if (link_itr->Use () == -2) continue;
				index = link_itr->AB_Dir ();
			}
			if (index < 0) continue;
			dir_ptr = &dir_array [index];
			flow_index = dir_ptr->Flow_Index ();

			base_time = dir_ptr->Time0 ().Seconds ();
			if (base_time <= 0.0) continue;

			tod_list = dir_ptr->First_Lane_Use ();

			max_lanes = dir_ptr->Lanes ();
			if (max_lanes < 1) max_lanes = 1;
			lanes = max_lanes;

			for (j=0, period_itr = link_perf_array.begin (); period_itr != link_perf_array.end (); period_itr++, j++) {
				if (tod_list >= 0) {

					//---- get the time period ----

					sum_periods.Period_Range (j, low, high);
					tod = (low + high + 1) / 2;

					lanes = max_lanes;
					k = tod_list;

					for (use_ptr = &use_period_array [k]; ; use_ptr = &use_period_array [++k]) {
						if (use_ptr->Start () <= tod && tod < use_ptr->End ()) {
							lanes = use_ptr->Lanes0 () + use_ptr->Lanes1 ();
							break;
						}
						if (use_ptr->Periods () == 0) break;
					}
				}
				perf_data = period_itr->Total_Link_Perf (index, flow_index);

				loaded_time = perf_data.Time ().Seconds ();
				flow = perf_data.Flow ();

				sum_bin [j] [LINKS] += 1;
				sum_bin [j] [LENGTH] += len;
				sum_bin [j] [LANES] += lanes * len;
				sum_bin [j] [VMT] += flow * len;
				sum_bin [j] [VHT] += flow * loaded_time;
				sum_bin [j] [VHD] += flow * (loaded_time - base_time);
				sum_bin [j] [TIME_RATIO] += (double) loaded_time / base_time;
				sum_bin [j] [DENSITY] += perf_data.Density ();
				sum_bin [j] [MAX_DEN] = MAX (sum_bin [j] [MAX_DEN], perf_data.Max_Density ());
				sum_bin [j] [QUEUE] += perf_data.Queue ();
				sum_bin [j] [MAX_QUEUE] = MAX (sum_bin [j] [MAX_QUEUE], perf_data.Max_Queue ());
				sum_bin [j] [FAILURE] += perf_data.Failure ();

				if (Ratio_Flag ()) {
					sum_bin [j] [CONG_VMT] += perf_data.Ratio_VMT ();
					sum_bin [j] [CONG_VHT] += perf_data.Ratio_VHT ();
					sum_bin [j] [CONG_TIME] += perf_data.Ratio_Count ();
					sum_bin [j] [COUNT] += perf_data.Occupancy ();
				}

				if (compare_flag) {
					period_ptr = &compare_link_array [j];

					perf_data = period_ptr->Total_Link_Perf (index, flow_index);

					loaded_time = perf_data.Time ();
					flow = perf_data.Flow ();

					sum_bin [j] [VMT+PREV] += flow * len;
					sum_bin [j] [VHT+PREV] += flow * loaded_time;
					sum_bin [j] [VHD+PREV] += flow * (loaded_time - base_time);
					sum_bin [j] [TIME_RATIO+PREV] += (double) loaded_time / base_time;
					sum_bin [j] [DENSITY+PREV] += perf_data.Density ();
					sum_bin [j] [MAX_DEN+PREV] = MAX (sum_bin [j] [MAX_DEN+PREV], perf_data.Max_Density ());
					sum_bin [j] [QUEUE+PREV] += perf_data.Queue ();
					sum_bin [j] [MAX_QUEUE+PREV] = MAX (sum_bin [j] [MAX_QUEUE+PREV], perf_data.Max_Queue ());
					sum_bin [j] [FAILURE+PREV] += perf_data.Failure ();

					if (Ratio_Flag ()) {
						sum_bin [j] [CONG_VMT+PREV] += perf_data.Ratio_VMT ();
						sum_bin [j] [CONG_VHT+PREV] += perf_data.Ratio_VHT ();
						sum_bin [j] [CONG_TIME+PREV] += perf_data.Ratio_Count ();
						sum_bin [j] [COUNT+PREV] += perf_data.Occupancy ();
					}
				}
			}

			//---- get the turning movements ----

			if (connect_flag) {
				for (k=dir_ptr->First_Connect (); k >= 0; k = connect_ptr->Next_Index ()) {
					connect_ptr = &connect_array [k];

					if (connect_ptr->Type () != LEFT && connect_ptr->Type () != RIGHT &&
						connect_ptr->Type () != UTURN) continue;

					for (j=0, turn_itr = turn_perf_array.begin (); turn_itr != turn_perf_array.end (); turn_itr++, j++) {
						turn_ptr = &turn_itr->at (k);

						sum_bin [j] [TURNS] += turn_ptr->Flow ();

						if (compare_flag) {
							compare_ptr = &compare_turn_array [j];
							turn_ptr = &compare_ptr->at (k);

							sum_bin [j] [TURNS+PREV] += turn_ptr->Flow ();
						}
					}
				}
			}
		}
	}
	End_Progress ();

	//---- write the data ----
	
	if (Metric_Flag ()) {
		factor = 1.0 / 1000.0;
		units = "Kilometers";
		vmt = "VKT";
		lane_mi = "km)";
	} else {
		factor = 1.0 / MILETOFEET;
		units = "Miles";
		vmt = "VMT";
		lane_mi = "mi)";
	}
	tod.Hours (1);

	for (j=0; j <= num_inc; j++) {
		len = sum_bin [j] [LINKS];
		if (len == 0.0) continue;

		if (j == num_inc) {
			buffer = "Time Period Total";
			len *= num_inc;
		} else {
			buffer = String ("Time Period %12.12s") % sum_periods.Range_Format (j);

			for (k = 0; k <= COUNT; k++) {
				k1 = k + PREV;
				if (k < VMT) {
					sum_bin [num_inc] [k] = MAX (sum_bin [j] [k], sum_bin [num_inc] [k]);

					if (compare_flag) {
						sum_bin [num_inc] [k1] = MAX (sum_bin [j] [k1], sum_bin [num_inc] [k1]);
					}
				} else {
					sum_bin [num_inc] [k] += sum_bin [j] [k];

					if (compare_flag) {
						sum_bin [num_inc] [k1] += sum_bin [j] [k1];
					}
				}
			}
		}
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, 0.0);
		if (compare_flag) detail_file.Put_Field (compare_field, 0.0);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Number of Links"));
		detail_file.Put_Field (value_field, sum_bin [j] [LINKS]);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [LINKS]);
		detail_file.Write ();

		buffer = "Number of Roadway " + units;
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, sum_bin [j] [LENGTH] * factor);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [LENGTH] * factor);
		detail_file.Write ();

		buffer = "Number of Lane " + units;
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, sum_bin [j] [LANES] * factor);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [LANES] * factor);
		detail_file.Write ();

		buffer = "Vehicle " + units + " of Travel";
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, sum_bin [j] [VMT] * factor);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [VMT+PREV] * factor);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Vehicle Hours of Travel"));
		detail_file.Put_Field (value_field, sum_bin [j] [VHT] / tod);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [VHT+PREV] / tod);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Vehicle Hours of Delay"));
		detail_file.Put_Field (value_field, sum_bin [j] [VHD] / tod);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [VHD+PREV] / tod);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Number of Queued Vehicles"));
		detail_file.Put_Field (value_field, UnRound (sum_bin [j] [QUEUE]));
		if (compare_flag) detail_file.Put_Field (compare_field, UnRound (sum_bin [j] [QUEUE+PREV]));
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Maximum Queued Vehicles"));
		detail_file.Put_Field (value_field, sum_bin [j] [MAX_QUEUE]);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [MAX_QUEUE+PREV]);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Number of Cycle Failures"));
		detail_file.Put_Field (value_field, sum_bin [j] [FAILURE]);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [FAILURE+PREV]);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Number of Turning Movements"));
		detail_file.Put_Field (value_field, sum_bin [j] [TURNS]);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [TURNS+PREV]);
		detail_file.Write ();

		detail_file.Put_Field (text_field, String ("Average Link Time Ratio"));
		detail_file.Put_Field (value_field, sum_bin [j] [TIME_RATIO] / len);
		if (compare_flag) detail_file.Put_Field (compare_field, sum_bin [j] [TIME_RATIO+PREV] / len);
		detail_file.Write ();

		buffer = "Average Link Density (/ln-" + lane_mi;
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, UnRound (sum_bin [j] [DENSITY] / len));
		if (compare_flag) detail_file.Put_Field (compare_field, UnRound (sum_bin [j] [DENSITY+PREV] / len));
		detail_file.Write ();

		buffer = "Maximum Link Density (/ln-" + lane_mi;
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, UnRound (sum_bin [j] [MAX_DEN]));
		if (compare_flag) detail_file.Put_Field (compare_field, UnRound (sum_bin [j] [MAX_DEN+PREV]));
		detail_file.Write ();

		length = sum_bin [j] [VMT] * factor;
		loaded_time = sum_bin [j] [VHT] / tod;
		if (loaded_time == 0.0) {
			loaded_time = length;
		} else {
			loaded_time = length / loaded_time;
		}
		buffer = "Average " + units + " Per Hour";
		detail_file.Put_Field (text_field, buffer);
		detail_file.Put_Field (value_field, loaded_time);

		if (compare_flag) {
			length = sum_bin [j] [VMT+PREV] * factor;
			loaded_time = sum_bin [j] [VHT+PREV] / tod;
			if (loaded_time == 0.0) {
				loaded_time = length;
			} else {
				loaded_time = length / loaded_time;
			}
			detail_file.Put_Field (compare_field, loaded_time);
		}
		detail_file.Write ();

		if (Ratio_Flag ()) {
			value = sum_bin [j] [VMT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [j] [CONG_VMT] / value;

			if (Metric_Flag ()) {
				buffer = "Percent VKT Congested";
			} else {
				buffer = "Percent VMT Congested";
			}
			detail_file.Put_Field (text_field, buffer);
			detail_file.Put_Field (value_field, percent);
			if (compare_flag) {
				value = sum_bin [j] [VMT+PREV];
				if (value == 0.0) value = 1.0;
				percent = 100.0 * sum_bin [j] [CONG_VMT+PREV] / value;

				detail_file.Put_Field (compare_field, percent);
			}
			detail_file.Write ();

			value = sum_bin [j] [VHT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [j] [CONG_VHT] / value;

			detail_file.Put_Field (text_field, String ("Percent VHT Congested"));
			detail_file.Put_Field (value_field, percent);
			if (compare_flag) {
				value = sum_bin [j] [VHT+PREV];
				if (value == 0.0) value = 1.0;
				percent = 100.0 * sum_bin [j] [CONG_VHT+PREV] / value;

				detail_file.Put_Field (compare_field, percent);
			}
			detail_file.Write ();

			value = sum_bin [j] [COUNT];
			if (value == 0.0) value = 1.0;
			percent = 100.0 * sum_bin [j] [CONG_TIME] / value;

			detail_file.Put_Field (text_field, String ("Percent Time Congested"));
			detail_file.Put_Field (value_field, percent);
			if (compare_flag) {
				value = sum_bin [j] [COUNT+PREV];
				if (value == 0.0) value = 1.0;
				percent = 100.0 * sum_bin [j] [CONG_TIME+PREV] / value;

				detail_file.Put_Field (compare_field, percent);
			}
			detail_file.Write ();
		}
	}
}